diff --git a/examples/embed/embed.c b/examples/embed/embed.c index 609a740..82cca43 100644 --- a/examples/embed/embed.c +++ b/examples/embed/embed.c @@ -25,7 +25,7 @@ static void print_header(int num, const char *title) { } static struct js *create_js_runtime(void *stack_base) { - struct js *js = js_create_dynamic(0, 0); + struct js *js = js_create_dynamic(); if (!js) { fprintf(stderr, "Failed to create JS runtime\n"); return NULL; diff --git a/include/ant.h b/include/ant.h index c043f6e..f2345db 100644 --- a/include/ant.h +++ b/include/ant.h @@ -38,7 +38,7 @@ #define JS_DESC_C (1 << 2) ant_t *js_create(void *buf, size_t len); -ant_t *js_create_dynamic(size_t initial_size, size_t max_size); +ant_t *js_create_dynamic(); jsval_t js_glob(ant_t *); jsval_t js_mkscope(ant_t *); diff --git a/include/cli/misc.h b/include/cli/misc.h new file mode 100644 index 0000000..9e6f92f --- /dev/null +++ b/include/cli/misc.h @@ -0,0 +1,16 @@ +#ifndef MISC_H +#define MISC_H +#include + +typedef struct { + const char *s; + const char *l; + const char *d; + const char *g; + int opt; +} flag_help_t; + +void print_flags_help(FILE *fp, void **argtable); +void print_flag(FILE *fp, flag_help_t f); + +#endif \ No newline at end of file diff --git a/include/cli/version.h b/include/cli/version.h new file mode 100644 index 0000000..b4b169e --- /dev/null +++ b/include/cli/version.h @@ -0,0 +1,7 @@ +#ifndef VERSION_H +#define VERSION_H + +const char *ant_semver(void); +int ant_version(void *argtable[]); + +#endif \ No newline at end of file diff --git a/include/utils.h b/include/utils.h index e342cec..4debe5e 100644 --- a/include/utils.h +++ b/include/utils.h @@ -1,6 +1,6 @@ #ifndef ANT_UTILS_H #define ANT_UTILS_H -#define ARGTABLE_COUNT 10 +#define ARGTABLE_COUNT 8 #include #include @@ -11,13 +11,11 @@ typedef struct { char *heap; } cstr_buf_t; -const char *ant_semver(void); char *resolve_js_file(const char *filename); uint64_t hash_key(const char *key, size_t len); int hex_digit(char c); int is_typescript_file(const char *filename); -int ant_version(void *argtable[]); void *try_oom(size_t size); void cstr_free(cstr_buf_t *buf); diff --git a/meson.build b/meson.build index dc3a1ba..3d2019a 100644 --- a/meson.build +++ b/meson.build @@ -36,6 +36,8 @@ lib_sources = files( 'src/snapshot.c', 'src/esm/remote.c', 'src/cli/pkg.c', + 'src/cli/misc.c', + 'src/cli/version.c', 'src/cli/cprintf.c', ) + files(module_files) diff --git a/src/ant.c b/src/ant.c index 8a6a969..f8043b8 100644 --- a/src/ant.c +++ b/src/ant.c @@ -22870,21 +22870,18 @@ ant_t *js_create(void *buf, size_t len) { return js; } -struct js *js_create_dynamic(size_t initial_size, size_t max_size) { - if (initial_size < sizeof(struct js) + esize(T_OBJ)) initial_size = ANT_ARENA_MIN; - if (max_size == 0 || max_size < initial_size) max_size = ANT_ARENA_MAX; - - void *init_buf = ant_calloc(initial_size); +struct js *js_create_dynamic() { + void *init_buf = ant_calloc(ANT_ARENA_MIN); if (init_buf == NULL) return NULL; - struct js *js = js_create(init_buf, initial_size); + struct js *js = js_create(init_buf, ANT_ARENA_MIN); if (js == NULL) { free(init_buf); return NULL; } - uint8_t *arena = (uint8_t *)ant_arena_reserve(max_size); + uint8_t *arena = (uint8_t *)ant_arena_reserve(ANT_ARENA_MAX); if (arena == NULL) { free(init_buf); return NULL; } if (ant_arena_commit(arena, 0, js->size) != 0) { - ant_arena_free(arena, max_size); + ant_arena_free(arena, ANT_ARENA_MAX); free(init_buf); return NULL; } @@ -22892,11 +22889,11 @@ struct js *js_create_dynamic(size_t initial_size, size_t max_size) { js->mem = arena; js->owns_mem = true; - js->max_size = (jsoff_t) max_size; + js->max_size = (jsoff_t) ANT_ARENA_MAX; struct js *new_js = (struct js *)malloc(sizeof(struct js)); if (new_js == NULL) { - ant_arena_free(arena, max_size); + ant_arena_free(arena, ANT_ARENA_MAX); free(init_buf); return NULL; } diff --git a/src/cli/cprintf.c b/src/cli/cprintf.c index d16e4a4..16af2ca 100644 --- a/src/cli/cprintf.c +++ b/src/cli/cprintf.c @@ -48,6 +48,7 @@ typedef enum { OP_PAD_BEGIN, OP_RPAD_BEGIN, OP_PAD_END, + OP_EMIT_SPACES, OP_HALT, OP_MAX } opcode_t; @@ -360,6 +361,11 @@ static int compile_tag(program_t *p, const char *tag, int len, int closing, var_ if (tag_prefix(tag, len, "pad=")) { emit_op(p, OP_PAD_BEGIN, (uint32_t)atoi(tag + 4)); return 1; } if (tag_prefix(tag, len, "rpad=")) { emit_op(p, OP_RPAD_BEGIN, (uint32_t)atoi(tag + 5)); return 1; } + + if (tag_prefix(tag, len, "space=") && tag[len-1] == '/') { + emit_op(p, OP_EMIT_SPACES, (uint32_t)atoi(tag + 6)); + return 1; + } emit_op(p, OP_STYLE_PUSH, 0); @@ -559,6 +565,7 @@ int cprintf_vm_exec(program_t *prog, FILE *stream, va_list ap) { [OP_PAD_BEGIN] = &&op_pad_begin, [OP_RPAD_BEGIN] = &&op_rpad_begin, [OP_PAD_END] = &&op_pad_end, + [OP_EMIT_SPACES] = &&op_emit_spaces, [OP_HALT] = &&op_halt, }; @@ -687,6 +694,14 @@ int cprintf_vm_exec(program_t *prog, FILE *stream, va_list ap) { pos += pad_n; NEXT(); } + + op_emit_spaces: { + size_t n = (size_t)ip->operand; + ENSURE(n); + memset(out + pos, ' ', n); + pos += n; + NEXT(); + } op_style_reset: { if (regs.style_depth > 0) { diff --git a/src/cli/misc.c b/src/cli/misc.c new file mode 100644 index 0000000..6cc6e03 --- /dev/null +++ b/src/cli/misc.c @@ -0,0 +1,37 @@ +#include +#include + +#include "cli/misc.h" +#include "cli/cprintf.h" + +void print_flag(FILE *fp, flag_help_t f) { + const char *s = f.s, *l = f.l, *d = f.d, *g = f.g; + int opt = f.opt; + + char syn[200]; + csprintf(syn, sizeof(syn), + "%s%s%s%s%s%s", + s ? (char[]){'-', s[0], '\0'} : (l ? " " : ""), + s && l ? ", " : "", + l ? "--" : "", + l ? l : "", + d && l && opt ? "[=" : + d && l ? "=" : + d && s ? " " : "", + d ? d : ""); + + cfprintf(fp, "%s %s\n", syn, g); +} + +void print_flags_help(FILE *fp, void **argtable) { + struct arg_hdr **table = (struct arg_hdr **)argtable; + for (int i = 0; !(table[i]->flag & ARG_TERMINATOR); i++) { + struct arg_hdr *hdr = table[i]; + if (!hdr->glossary) continue; + print_flag(fp, (flag_help_t){ + .s = hdr->shortopts, .l = hdr->longopts, + .d = hdr->datatype, .g = hdr->glossary, + .opt = hdr->flag & ARG_HASOPTVALUE, + }); + } +} \ No newline at end of file diff --git a/src/cli/pkg.c b/src/cli/pkg.c index 55a9052..c962536 100644 --- a/src/cli/pkg.c +++ b/src/cli/pkg.c @@ -1,7 +1,6 @@ #include // IWYU pragma: keep #include -#include #include #include #include @@ -12,6 +11,9 @@ #include #include +#include "cli/pkg.h" +#include "cli/version.h" + #include "utils.h" #include "config.h" #include "progress.h" diff --git a/src/cli/version.c b/src/cli/version.c new file mode 100644 index 0000000..02341aa --- /dev/null +++ b/src/cli/version.c @@ -0,0 +1,74 @@ +#include "utils.h" +#include "config.h" + +#include +#include +#include + +static char ant_semver_buf[32]; +static pthread_once_t ant_semver_once = PTHREAD_ONCE_INIT; + +static void ant_semver_init(void) { + const char *s = ANT_VERSION; + int d = 0, i = 0; + while (s[i] && d < 3 && i < 31) { + if (s[i] == '.') d++; + ant_semver_buf[i] = s[i]; i++; + } + ant_semver_buf[i - (d == 3)] = '\0'; +} + +const char *ant_semver(void) { + pthread_once(&ant_semver_once, ant_semver_init); + return ant_semver_buf; +} + +int ant_version(void *argtable[]) { + time_t build_time = (time_t)ANT_BUILD_TIMESTAMP; + time_t now = time(NULL); + long diff = (long)difftime(now, build_time); + + struct { long secs; const char *suffix; } units[] = { + {86400, "d"}, {3600, "h"}, {60, "m"}, {1, "s"} + }; + + const char *suffix = "s"; + long value = diff; + + for (size_t i = 0; i < sizeof(units) / sizeof(units[0]); i++) { + if (diff >= units[i].secs) { + value = diff / units[i].secs; + suffix = units[i].suffix; break; + } + } + + struct tm *tm = gmtime(&build_time); + char date_buf[32]; + strftime(date_buf, sizeof(date_buf), "%Y-%m-%d", tm); + + #define RED "\033[38;5;197m" + #define RESET "\033[0m" + + const char *logo = + RED + " ___ __ __ _____ _ __\n" + " / | ____ / /_ / /___ __ ______ _/ ___/__________(_)___ / /_\n" + " / /| | / __ \\/ __/ __ / / __ `/ | / / __ `/\\__ \\/ ___/ ___/ / __ \\/ __/\n" + " / ___ |/ / / / /_ / /_/ / /_/ /| |/ / /_/ /___/ / /__/ / / / /_/ / /_\n" + "/_/ |_/_/ /_/\\__/ \\____/\\__,_/ |___/\\__,_//____/\\___/_/ /_/ .___/\\__/\n" + " /_/" RESET " by @themackabu\n" + RESET; + + fputs(logo, stdout); + + printf("%s (released %s, %ld%s ago)\n", + ANT_VERSION, + date_buf, + value, suffix + ); + + printf("built for %s\n", ANT_TARGET_TRIPLE); + arg_freetable(argtable, ARGTABLE_COUNT); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 3514fc6..1bd398c 100644 --- a/src/main.c +++ b/src/main.c @@ -20,6 +20,8 @@ #include "internal.h" #include "cli/pkg.h" +#include "cli/misc.h" +#include "cli/version.h" #include "cli/cprintf.h" #include "modules/builtin.h" @@ -267,35 +269,37 @@ int main(int argc, char *argv[]) { argc = filtered_argc; argv = filtered_argv; - struct arg_lit *help = arg_lit0("h", "help", "display this help and exit"); - struct arg_lit *version = arg_lit0("v", "version", "display version information and exit"); - struct arg_lit *version_raw = arg_lit0(NULL, "version-raw", "raw version number for scripts"); struct arg_str *eval = arg_str0("e", "eval", "