MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

introduce color macros for console output

+716 -30
+33
include/cli/cprintf.h
··· 1 + #ifndef CPRINTF_H 2 + #define CPRINTF_H 3 + 4 + #include <stdio.h> 5 + #include <stddef.h> 6 + 7 + extern bool io_no_color; 8 + 9 + typedef struct program_t program_t; 10 + 11 + program_t *cprintf_compile(const char *fmt); 12 + int cprintf_exec(program_t *prog, FILE *stream, ...); 13 + int csprintf_inner(program_t *prog, char *buf, size_t size, ...); 14 + 15 + #define cprintf(fmt, ...) ({ \ 16 + static program_t *_cp_prog_ = NULL; \ 17 + if (!_cp_prog_) _cp_prog_ = cprintf_compile(fmt); \ 18 + cprintf_exec(_cp_prog_, stdout, ##__VA_ARGS__); \ 19 + }) 20 + 21 + #define cfprintf(stream, fmt, ...) ({ \ 22 + static program_t *_cp_prog_ = NULL; \ 23 + if (!_cp_prog_) _cp_prog_ = cprintf_compile(fmt); \ 24 + cprintf_exec(_cp_prog_, stream, ##__VA_ARGS__); \ 25 + }) 26 + 27 + #define csprintf(buf, size, fmt, ...) ({ \ 28 + static program_t *_cp_prog_ = NULL; \ 29 + if (!_cp_prog_) _cp_prog_ = cprintf_compile(fmt); \ 30 + csprintf_inner(_cp_prog_, buf, size, ##__VA_ARGS__); \ 31 + }) 32 + 33 + #endif
+14
include/modules/io.h
··· 7 7 8 8 extern bool io_no_color; 9 9 10 + #define C(color) (io_no_color ? "" : (color)) 11 + #define C_RESET C("\x1b[0m") 12 + #define C_BOLD C("\x1b[1m") 13 + #define C_DIM C("\x1b[2m") 14 + #define C_UL C("\x1b[4m") 15 + #define C_UL_OFF C("\x1b[24m") 16 + #define C_GREEN C("\x1b[32m") 17 + #define C_YELLOW C("\x1b[33m") 18 + #define C_BLUE C("\x1b[34m") 19 + #define C_MAGENTA C("\x1b[35m") 20 + #define C_CYAN C("\x1b[36m") 21 + #define C_WHITE C("\x1b[37m") 22 + #define C_RED C("\x1b[31m") 23 + 10 24 void init_console_module(void); 11 25 void print_value_colored(const char *str, FILE *stream); 12 26 void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream);
+2 -1
include/utils.h
··· 12 12 } cstr_buf_t; 13 13 14 14 const char *ant_semver(void); 15 + char *resolve_js_file(const char *filename); 15 16 uint64_t hash_key(const char *key, size_t len); 16 17 18 + int hex_digit(char c); 17 19 int is_typescript_file(const char *filename); 18 - char *resolve_js_file(const char *filename); 19 20 int ant_version(void *argtable[]); 20 21 21 22 void *try_oom(size_t size);
+1
meson.build
··· 36 36 'src/snapshot.c', 37 37 'src/esm/remote.c', 38 38 'src/cli/pkg.c', 39 + 'src/cli/cprintf.c', 39 40 ) + files(module_files) 40 41 41 42 include = include_directories('include')
+647
src/cli/cprintf.c
··· 1 + /* 2 + * cprintf - printf with inline color tags, powered by a register-based VM 3 + * 4 + * usage: 5 + * cprintf("<red>error:</red> something went wrong\n"); 6 + * cprintf("<bold><cyan>info:</cyan></bold> hello %s\n", name); 7 + * cprintf("<#ff8800>orange text</#ff8800>\n"); 8 + * cprintf(" <pad=18><green>%s</green></pad> %s\n", cmd->name, cmd->desc); 9 + * 10 + * supported tags: 11 + * <red> <green> <yellow> <blue> <magenta> <cyan> <white> <black> 12 + * <gray/grey> <bright_red> <bright_green> ... etc 13 + * <bg_red> <bg_green> ... <bg_#RGB> <bg_#RRGGBB> 14 + * <bold> <dim> <ul> (underline) 15 + * <#RRGGBB> or <#RGB> for arbitrary 24-bit foreground colors 16 + * <pad=N> ... </pad> - right-pad contents to N visible columns 17 + * <rpad=N> ... </rpad> - left-pad (right-align) contents to N visible columns 18 + * </tagname> or </> to reset 19 + * 20 + */ 21 + 22 + #include "utils.h" 23 + #include "cli/cprintf.h" 24 + 25 + #include <ctype.h> 26 + #include <stdio.h> 27 + #include <stdarg.h> 28 + #include <string.h> 29 + #include <stdlib.h> 30 + #include <stdint.h> 31 + 32 + typedef enum { 33 + OP_NOP = 0, 34 + OP_EMIT_LIT, 35 + OP_EMIT_FMT, 36 + OP_SET_FG, 37 + OP_SET_BG, 38 + OP_SET_FG_RGB, 39 + OP_SET_BG_RGB, 40 + OP_SET_BOLD, 41 + OP_SET_DIM, 42 + OP_SET_UL, 43 + OP_STYLE_FLUSH, 44 + OP_STYLE_RESET, 45 + OP_PAD_BEGIN, 46 + OP_RPAD_BEGIN, 47 + OP_PAD_END, 48 + OP_HALT, 49 + OP_MAX 50 + } opcode_t; 51 + 52 + typedef struct { 53 + uint32_t op; 54 + uint32_t operand; 55 + } instruction_t; 56 + 57 + typedef enum { 58 + COL_NONE = 0, 59 + COL_BLACK = 30, COL_RED, COL_GREEN, COL_YELLOW, 60 + COL_BLUE, COL_MAGENTA, COL_CYAN, COL_WHITE, 61 + COL_GRAY = 90, COL_BRIGHT_RED, COL_BRIGHT_GREEN, COL_BRIGHT_YELLOW, 62 + COL_BRIGHT_BLUE, COL_BRIGHT_MAGENTA, COL_BRIGHT_CYAN, COL_BRIGHT_WHITE, 63 + COL_RGB = 0xFF 64 + } color_t; 65 + 66 + #define UNPACK_R(c) (((c)>>16)&0xFF) 67 + #define UNPACK_G(c) (((c)>>8)&0xFF) 68 + #define UNPACK_B(c) ((c)&0xFF) 69 + 70 + #define PACK_RGB(r,g,b) \ 71 + (((uint32_t)(r)<<16)|((uint32_t)(g)<<8)|(uint32_t)(b)) 72 + 73 + typedef struct { 74 + size_t mark; 75 + int width; 76 + int right_align; 77 + } pad_entry_t; 78 + 79 + typedef struct { 80 + uint32_t fg; 81 + uint32_t bg; 82 + uint32_t fg_rgb; 83 + uint32_t bg_rgb; 84 + 85 + int bold; 86 + int dim; 87 + int ul; 88 + 89 + pad_entry_t pad_stack[8]; 90 + int pad_depth; 91 + } vm_regs_t; 92 + 93 + struct program_t { 94 + instruction_t *code; 95 + size_t code_len; 96 + size_t code_cap; 97 + char *literals; 98 + size_t lit_len; 99 + size_t lit_cap; 100 + }; 101 + 102 + static program_t *program_new(void) { 103 + program_t *p = calloc(1, sizeof(*p)); 104 + *p = (program_t){ 105 + .code_cap = 32, 106 + .code = malloc(32 * sizeof(instruction_t)), 107 + .lit_cap = 256, 108 + .literals = malloc(256), 109 + }; 110 + return p; 111 + } 112 + 113 + static void emit_op(program_t *p, uint32_t op, uint32_t operand) { 114 + if (p->code_len >= p->code_cap) { 115 + p->code_cap *= 2; 116 + p->code = realloc(p->code, p->code_cap * sizeof(instruction_t)); 117 + } 118 + p->code[p->code_len++] = (instruction_t){ op, operand }; 119 + } 120 + 121 + static uint32_t add_literal(program_t *p, const char *s, size_t len) { 122 + while (p->lit_len + len + 1 > p->lit_cap) { 123 + p->lit_cap *= 2; 124 + p->literals = realloc(p->literals, p->lit_cap); 125 + } 126 + 127 + uint32_t off = (uint32_t)p->lit_len; 128 + memcpy(p->literals + p->lit_len, s, len); 129 + 130 + p->literals[p->lit_len + len] = '\0'; 131 + p->lit_len += len + 1; 132 + 133 + return off; 134 + } 135 + 136 + typedef struct { 137 + const char *name; 138 + int nlen; 139 + color_t col; 140 + } color_entry_t; 141 + 142 + static const color_entry_t fg_colors[] = { 143 + {"black",5,COL_BLACK}, {"red",3,COL_RED}, {"green",5,COL_GREEN}, 144 + {"yellow",6,COL_YELLOW}, {"blue",4,COL_BLUE}, {"magenta",7,COL_MAGENTA}, 145 + {"cyan",4,COL_CYAN}, {"white",5,COL_WHITE}, 146 + {"gray",4,COL_GRAY}, {"grey",4,COL_GRAY}, 147 + {"bright_red",10,COL_BRIGHT_RED}, {"bright_green",12,COL_BRIGHT_GREEN}, 148 + {"bright_yellow",13,COL_BRIGHT_YELLOW}, {"bright_blue",11,COL_BRIGHT_BLUE}, 149 + {"bright_magenta",14,COL_BRIGHT_MAGENTA}, {"bright_cyan",11,COL_BRIGHT_CYAN}, 150 + {"bright_white",12,COL_BRIGHT_WHITE}, 151 + }; 152 + 153 + static const color_entry_t bg_colors[] = { 154 + {"bg_black",8,COL_BLACK}, {"bg_red",6,COL_RED}, {"bg_green",8,COL_GREEN}, 155 + {"bg_yellow",9,COL_YELLOW}, {"bg_blue",7,COL_BLUE}, {"bg_magenta",10,COL_MAGENTA}, 156 + {"bg_cyan",7,COL_CYAN}, {"bg_white",8,COL_WHITE}, 157 + }; 158 + 159 + static const color_entry_t seg_bg_colors[] = { 160 + {"black",5,COL_BLACK}, {"red",3,COL_RED}, {"green",5,COL_GREEN}, 161 + {"yellow",6,COL_YELLOW}, {"blue",4,COL_BLUE}, {"magenta",7,COL_MAGENTA}, 162 + {"cyan",4,COL_CYAN}, {"white",5,COL_WHITE}, 163 + }; 164 + 165 + #define FG_COUNT (sizeof(fg_colors)/sizeof(fg_colors[0])) 166 + #define BG_COUNT (sizeof(bg_colors)/sizeof(bg_colors[0])) 167 + #define SEG_BG_COUNT (sizeof(seg_bg_colors)/sizeof(seg_bg_colors[0])) 168 + 169 + static int parse_hex_rgb(const char *hex, int len, uint32_t *rgb) { 170 + int r, g, b; 171 + if (len == 4) { 172 + int r1=hex_digit(hex[1]), g1=hex_digit(hex[2]), b1=hex_digit(hex[3]); 173 + if (r1<0||g1<0||b1<0) return 0; 174 + r=r1*17; g=g1*17; b=b1*17; 175 + } else if (len == 7) { 176 + int r1=hex_digit(hex[1]),r2=hex_digit(hex[2]); 177 + int g1=hex_digit(hex[3]),g2=hex_digit(hex[4]); 178 + int b1=hex_digit(hex[5]),b2=hex_digit(hex[6]); 179 + if (r1<0||r2<0||g1<0||g2<0||b1<0||b2<0) return 0; 180 + r=r1*16+r2; g=g1*16+g2; b=b1*16+b2; 181 + } else return 0; 182 + *rgb = PACK_RGB(r, g, b); 183 + return 1; 184 + } 185 + 186 + static int compile_hex_fg(program_t *p, const char *tag, int len) { 187 + uint32_t rgb; 188 + if (!parse_hex_rgb(tag, len, &rgb)) return 0; 189 + emit_op(p, OP_SET_FG_RGB, rgb); 190 + return 1; 191 + } 192 + 193 + static int compile_hex_bg(program_t *p, const char *hex, int hlen) { 194 + uint32_t rgb; 195 + if (!parse_hex_rgb(hex, hlen, &rgb)) return 0; 196 + emit_op(p, OP_SET_BG_RGB, rgb); 197 + return 1; 198 + } 199 + 200 + static int tag_eq(const char *tag, int len, const char *lit) { 201 + int ll = (int)strlen(lit); 202 + return len == ll && memcmp(tag, lit, ll) == 0; 203 + } 204 + 205 + static int tag_prefix(const char *tag, int len, const char *pfx) { 206 + int pl = (int)strlen(pfx); 207 + return len > pl && memcmp(tag, pfx, pl) == 0; 208 + } 209 + 210 + static int match_fg(program_t *p, const char *s, int len) { 211 + for (int i = 0; i < (int)FG_COUNT; i++) if ( 212 + len == fg_colors[i].nlen && memcmp(s, fg_colors[i].name, len) == 0) { 213 + emit_op(p, OP_SET_FG, fg_colors[i].col); return 1; 214 + } 215 + return 0; 216 + } 217 + 218 + static int match_bg(program_t *p, const char *s, int len) { 219 + for (int i = 0; i < (int)BG_COUNT; i++) if ( 220 + len == bg_colors[i].nlen && memcmp(s, bg_colors[i].name, len) == 0) { 221 + emit_op(p, OP_SET_BG, bg_colors[i].col); return 1; 222 + } 223 + return 0; 224 + } 225 + 226 + static int match_seg_bg(program_t *p, const char *s, int len) { 227 + for (int i = 0; i < (int)SEG_BG_COUNT; i++) if ( 228 + len == seg_bg_colors[i].nlen && memcmp(s, seg_bg_colors[i].name, len) == 0) { 229 + emit_op(p, OP_SET_BG, seg_bg_colors[i].col); return 1; 230 + } 231 + return 0; 232 + } 233 + 234 + typedef struct { 235 + const char *name; 236 + int nlen; 237 + int op; 238 + } attr_entry_t; 239 + 240 + static const attr_entry_t attrs[] = { 241 + { "bold", 4, OP_SET_BOLD }, 242 + { "dim", 3, OP_SET_DIM }, 243 + { "ul", 2, OP_SET_UL }, 244 + }; 245 + 246 + #define ATTR_COUNT (sizeof(attrs) / sizeof(attrs[0])) 247 + 248 + static int match_attr(program_t *p, const char *s, int len) { 249 + for (int i = 0; i < (int)ATTR_COUNT; i++) if ( 250 + len == attrs[i].nlen && memcmp(s, attrs[i].name, len) == 0) { 251 + emit_op(p, attrs[i].op, 1); return 1; 252 + } 253 + return 0; 254 + } 255 + 256 + static const char *next_seg(const char *cur, const char *end, int *out_len) { 257 + const char *sep = cur; 258 + while (sep < end && *sep != '_') sep++; 259 + *out_len = (int)(sep - cur); 260 + return sep; 261 + } 262 + 263 + static int compile_tag(program_t *p, const char *tag, int len, int closing) { 264 + if (closing) { 265 + if (tag_eq(tag, len, "pad") || tag_eq(tag, len, "rpad")) emit_op(p, OP_PAD_END, 0); 266 + else emit_op(p, OP_STYLE_RESET, 0); 267 + return 1; 268 + } 269 + 270 + if (tag_prefix(tag, len, "pad=")) { emit_op(p, OP_PAD_BEGIN, (uint32_t)atoi(tag + 4)); return 1; } 271 + if (tag_prefix(tag, len, "rpad=")) { emit_op(p, OP_RPAD_BEGIN, (uint32_t)atoi(tag + 5)); return 1; } 272 + 273 + if (match_attr(p, tag, len)) { emit_op(p, OP_STYLE_FLUSH, 0); return 1; } 274 + if (match_fg(p, tag, len)) { emit_op(p, OP_STYLE_FLUSH, 0); return 1; } 275 + if (match_bg(p, tag, len)) { emit_op(p, OP_STYLE_FLUSH, 0); return 1; } 276 + 277 + if (tag[0] == '#') { 278 + if (!compile_hex_fg(p, tag, len)) return 0; 279 + emit_op(p, OP_STYLE_FLUSH, 0); return 1; 280 + } 281 + 282 + if (tag_prefix(tag, len, "bg_#")) { 283 + if (!compile_hex_bg(p, tag + 3, len - 3)) return 0; 284 + emit_op(p, OP_STYLE_FLUSH, 0); return 1; 285 + } 286 + 287 + const char *seg = tag; 288 + const char *end = tag + len; 289 + int emitted = 0; 290 + 291 + while (seg < end) { 292 + int slen; 293 + const char *sep = next_seg(seg, end, &slen); 294 + 295 + if (match_attr(p, seg, slen)) { 296 + } else if (tag_eq(seg, slen, "bg") && sep < end) { 297 + seg = sep + 1; 298 + sep = next_seg(seg, end, &slen); 299 + if (!match_seg_bg(p, seg, slen)) return 0; 300 + } else if (!match_fg(p, seg, slen)) return 0; 301 + 302 + emitted++; 303 + seg = (sep < end) ? sep + 1 : end; 304 + } 305 + 306 + if (emitted) { emit_op(p, OP_STYLE_FLUSH, 0); return 1; } 307 + return 0; 308 + } 309 + 310 + static void flush_lit(program_t *p, const char *lit, const char *end) { 311 + if (end <= lit) return; 312 + uint32_t off = add_literal(p, lit, end - lit); 313 + emit_op(p, OP_EMIT_LIT, off); 314 + } 315 + 316 + static const char *scan_tag(program_t *p, const char *ptr, const char **lit) { 317 + flush_lit(p, *lit, ptr); 318 + 319 + const char *start = ptr + 1; 320 + int closing = 0; 321 + if (*start == '/') { closing = 1; start++; } 322 + 323 + if (closing && *start == '>') { 324 + emit_op(p, OP_STYLE_RESET, 0); 325 + *lit = start + 1; 326 + return *lit; 327 + } 328 + 329 + const char *end = start; 330 + while (*end && *end != '>') end++; 331 + 332 + if (*end == '>' && compile_tag(p, start, (int)(end - start), closing)) { 333 + *lit = end + 1; 334 + return *lit; 335 + } 336 + 337 + uint32_t off = add_literal(p, "<", 1); 338 + emit_op(p, OP_EMIT_LIT, off); 339 + *lit = ptr + 1; 340 + return *lit; 341 + } 342 + 343 + typedef enum { 344 + ARG_NONE = 0, 345 + ARG_INT, 346 + ARG_LONG, 347 + ARG_LLONG, 348 + ARG_SIZE, 349 + ARG_DOUBLE, 350 + ARG_CSTR, 351 + ARG_PTR, 352 + ARG_WINT, 353 + ARG_WSTR, 354 + } arg_class_t; 355 + 356 + static arg_class_t classify_arg(const char *spec, int len) { 357 + char conv = spec[len - 1]; 358 + if (conv == '%' || conv == 'n') return ARG_NONE; 359 + if (conv == 's') return ARG_CSTR; 360 + if (conv == 'p') return ARG_PTR; 361 + if (conv == 'f' || conv == 'F' || conv == 'e' || conv == 'E' || 362 + conv == 'g' || conv == 'G' || conv == 'a' || conv == 'A') 363 + return ARG_DOUBLE; 364 + 365 + const char *p = spec + 1; 366 + while (*p == '-' || *p == '+' || *p == ' ' || *p == '#' || *p == '0') p++; 367 + if (*p == '*') p++; else while (*p >= '0' && *p <= '9') p++; 368 + if (*p == '.') { p++; if (*p == '*') p++; else while (*p >= '0' && *p <= '9') p++; } 369 + 370 + if (p[0] == 'z') return ARG_SIZE; 371 + if (p[0] == 'l' && p[1] == 'l') return ARG_LLONG; 372 + if (p[0] == 'l' && conv == 'c') return ARG_WINT; 373 + if (p[0] == 'l' && conv == 's') return ARG_WSTR; 374 + if (p[0] == 'l') return ARG_LONG; 375 + if (p[0] == 'j') return ARG_LLONG; 376 + 377 + return ARG_INT; 378 + } 379 + 380 + static const char *scan_fmt(program_t *p, const char *ptr, const char **lit) { 381 + flush_lit(p, *lit, ptr); 382 + 383 + const char *fs = ptr + 1; 384 + while (*fs=='-'||*fs=='+'||*fs==' '||*fs=='#'||*fs=='0') fs++; 385 + if (*fs == '*') fs++; else while (*fs >= '0' && *fs <= '9') fs++; 386 + if (*fs == '.') { fs++; if (*fs == '*') fs++; else while (*fs >= '0' && *fs <= '9') fs++; } 387 + while (*fs=='h'||*fs=='l'||*fs=='L'||*fs=='z'||*fs=='j'||*fs=='t') fs++; 388 + if (*fs) fs++; 389 + 390 + uint32_t off = add_literal(p, ptr, fs - ptr); 391 + arg_class_t cls = classify_arg(ptr, (int)(fs - ptr)); 392 + emit_op(p, OP_EMIT_FMT, off | ((uint32_t)cls << 28)); 393 + *lit = fs; 394 + return fs; 395 + } 396 + 397 + static const char *scan_percent_escape(program_t *p, const char *ptr, const char **lit) { 398 + flush_lit(p, *lit, ptr); 399 + uint32_t off = add_literal(p, "%%", 2); 400 + emit_op(p, OP_EMIT_LIT, off); 401 + *lit = ptr + 2; 402 + return *lit; 403 + } 404 + 405 + program_t *cprintf_compile(const char *fmt) { 406 + program_t *p = program_new(); 407 + const char *ptr = fmt; 408 + const char *lit = ptr; 409 + 410 + while (*ptr) { 411 + if (*ptr == '<') 412 + ptr = scan_tag(p, ptr, &lit); 413 + else if (*ptr == '%' && ptr[1] && ptr[1] != '%') 414 + ptr = scan_fmt(p, ptr, &lit); 415 + else if (*ptr == '%' && ptr[1] == '%') 416 + ptr = scan_percent_escape(p, ptr, &lit); 417 + else ptr++; 418 + } 419 + 420 + flush_lit(p, lit, ptr); 421 + emit_op(p, OP_HALT, 0); 422 + return p; 423 + } 424 + 425 + static size_t visible_len(const char *s, size_t n) { 426 + size_t vis = 0; 427 + for (size_t i = 0; i < n; i++) { 428 + if (s[i] == '\x1b') while (++i < n && !isalpha(s[i])); 429 + else vis++; 430 + } 431 + return vis; 432 + } 433 + 434 + int cprintf_vm_exec(program_t *prog, FILE *stream, va_list ap) { 435 + vm_regs_t regs = {0}; 436 + 437 + size_t cap = 512, pos = 0; 438 + char *out = malloc(cap); 439 + if (!out) return -1; 440 + 441 + #define ENSURE(n) ({ \ 442 + while (pos + (n) + 1 > cap) { \ 443 + cap *= 2; out = realloc(out, cap); \ 444 + if (!out) return -1; \ 445 + }}) 446 + 447 + #define OUT_STR(s, l) ({ ENSURE(l); memcpy(out+pos, s, l); pos += (l); }) 448 + #define OUT_CSTR(s) ({ size_t _l = strlen(s); OUT_STR(s, _l); }) 449 + 450 + const instruction_t *ip = prog->code; 451 + static const void *dispatch[OP_MAX] = { 452 + [OP_NOP] = &&op_nop, 453 + [OP_EMIT_LIT] = &&op_emit_lit, 454 + [OP_EMIT_FMT] = &&op_emit_fmt, 455 + [OP_SET_FG] = &&op_set_fg, 456 + [OP_SET_BG] = &&op_set_bg, 457 + [OP_SET_FG_RGB] = &&op_set_fg_rgb, 458 + [OP_SET_BG_RGB] = &&op_set_bg_rgb, 459 + [OP_SET_BOLD] = &&op_set_bold, 460 + [OP_SET_DIM] = &&op_set_dim, 461 + [OP_SET_UL] = &&op_set_ul, 462 + [OP_STYLE_FLUSH] = &&op_style_flush, 463 + [OP_STYLE_RESET] = &&op_style_reset, 464 + [OP_PAD_BEGIN] = &&op_pad_begin, 465 + [OP_RPAD_BEGIN] = &&op_rpad_begin, 466 + [OP_PAD_END] = &&op_pad_end, 467 + [OP_HALT] = &&op_halt, 468 + }; 469 + 470 + #define DISPATCH() goto *dispatch[ip->op] 471 + #define NEXT() do { ip++; DISPATCH(); } while(0) 472 + 473 + DISPATCH(); 474 + 475 + op_nop: NEXT(); 476 + 477 + op_emit_lit: { 478 + OUT_CSTR(prog->literals + ip->operand); 479 + NEXT(); 480 + } 481 + 482 + op_emit_fmt: { 483 + uint32_t lit_off = ip->operand & 0x0FFFFFFF; 484 + arg_class_t cls = (arg_class_t)(ip->operand >> 28); 485 + const char *spec = prog->literals + lit_off; 486 + 487 + char tmp[256]; 488 + va_list ap_copy; 489 + va_copy(ap_copy, ap); 490 + 491 + #pragma GCC diagnostic push 492 + #pragma GCC diagnostic ignored "-Wformat-nonliteral" 493 + int n = vsnprintf(tmp, sizeof(tmp), spec, ap_copy); 494 + va_end(ap_copy); 495 + 496 + if (n > 0 && (size_t)n < sizeof(tmp)) { 497 + OUT_STR(tmp, (size_t)n); 498 + } else if (n > 0) { 499 + ENSURE((size_t)n); 500 + va_copy(ap_copy, ap); 501 + vsnprintf(out + pos, (size_t)n + 1, spec, ap_copy); 502 + va_end(ap_copy); 503 + pos += (size_t)n; 504 + } 505 + #pragma GCC diagnostic pop 506 + 507 + switch (cls) { 508 + case ARG_INT: (void)va_arg(ap, int); break; 509 + case ARG_LONG: (void)va_arg(ap, long); break; 510 + case ARG_LLONG: (void)va_arg(ap, long long); break; 511 + case ARG_SIZE: (void)va_arg(ap, size_t); break; 512 + case ARG_DOUBLE: (void)va_arg(ap, double); break; 513 + case ARG_CSTR: (void)va_arg(ap, const char *); break; 514 + case ARG_PTR: (void)va_arg(ap, void *); break; 515 + case ARG_WINT: (void)va_arg(ap, wint_t); break; 516 + case ARG_WSTR: (void)va_arg(ap, wchar_t *); break; 517 + case ARG_NONE: break; 518 + } 519 + NEXT(); 520 + } 521 + 522 + op_set_fg: { 523 + regs.fg = ip->operand; 524 + NEXT(); 525 + } 526 + 527 + op_set_bg: { 528 + regs.bg = ip->operand; 529 + NEXT(); 530 + } 531 + 532 + op_set_bold: { 533 + regs.bold = ip->operand; 534 + NEXT(); 535 + } 536 + 537 + op_set_dim: { 538 + regs.dim = ip->operand; 539 + NEXT(); 540 + } 541 + 542 + op_set_ul: { 543 + regs.ul = ip->operand; 544 + NEXT(); 545 + } 546 + 547 + op_set_fg_rgb: { 548 + regs.fg = COL_RGB; 549 + regs.fg_rgb = ip->operand; 550 + NEXT(); 551 + } 552 + 553 + op_set_bg_rgb: { 554 + regs.bg = COL_RGB; 555 + regs.bg_rgb = ip->operand; 556 + NEXT(); 557 + } 558 + 559 + op_style_reset: { 560 + regs.fg = COL_NONE; regs.bg = COL_NONE; 561 + regs.fg_rgb = 0; regs.bg_rgb = 0; 562 + regs.bold = 0; regs.dim = 0; regs.ul = 0; 563 + if (!io_no_color) { OUT_CSTR("\x1b[0m"); } 564 + NEXT(); 565 + } 566 + 567 + op_pad_begin: { 568 + if (regs.pad_depth < 8) regs.pad_stack[regs.pad_depth++] 569 + = (pad_entry_t){ pos, (int)ip->operand, 0 }; 570 + NEXT(); 571 + } 572 + 573 + op_rpad_begin: { 574 + if (regs.pad_depth < 8) regs.pad_stack[regs.pad_depth++] 575 + = (pad_entry_t){ pos, (int)ip->operand, 1 }; 576 + NEXT(); 577 + } 578 + 579 + op_style_flush: { 580 + if (!io_no_color) { 581 + char esc[128]; 582 + int n = snprintf(esc, sizeof(esc), "\x1b[0m"); 583 + if (regs.bold) n += snprintf(esc+n, sizeof(esc)-n, "\x1b[1m"); 584 + if (regs.dim) n += snprintf(esc+n, sizeof(esc)-n, "\x1b[2m"); 585 + if (regs.ul) n += snprintf(esc+n, sizeof(esc)-n, "\x1b[4m"); 586 + if (regs.fg == COL_RGB) 587 + n += snprintf(esc+n, sizeof(esc)-n, "\x1b[38;2;%d;%d;%dm", 588 + UNPACK_R(regs.fg_rgb), UNPACK_G(regs.fg_rgb), UNPACK_B(regs.fg_rgb)); 589 + else if (regs.fg) 590 + n += snprintf(esc+n, sizeof(esc)-n, "\x1b[%dm", regs.fg); 591 + if (regs.bg == COL_RGB) 592 + n += snprintf(esc+n, sizeof(esc)-n, "\x1b[48;2;%d;%d;%dm", 593 + UNPACK_R(regs.bg_rgb), UNPACK_G(regs.bg_rgb), UNPACK_B(regs.bg_rgb)); 594 + else if (regs.bg) 595 + n += snprintf(esc+n, sizeof(esc)-n, "\x1b[%dm", regs.bg + 10); 596 + OUT_STR(esc, (size_t)n); 597 + } 598 + NEXT(); 599 + } 600 + 601 + op_pad_end: { 602 + if (regs.pad_depth <= 0) NEXT(); 603 + regs.pad_depth--; 604 + pad_entry_t pe = regs.pad_stack[regs.pad_depth]; 605 + size_t vis = visible_len(out + pe.mark, pos - pe.mark); 606 + if ((size_t)pe.width <= vis) NEXT(); 607 + 608 + size_t pad_n = pe.width - vis; 609 + ENSURE(pad_n); 610 + if (pe.right_align) { 611 + memmove(out + pe.mark + pad_n, out + pe.mark, pos - pe.mark); 612 + memset(out + pe.mark, ' ', pad_n); 613 + } else memset(out + pos, ' ', pad_n); 614 + 615 + pos += pad_n; 616 + NEXT(); 617 + } 618 + 619 + op_halt: { 620 + out[pos] = '\0'; 621 + int ret = (int)fwrite(out, 1, pos, stream); 622 + free(out); return ret; 623 + } 624 + 625 + #undef ENSURE 626 + #undef OUT_STR 627 + #undef OUT_CSTR 628 + } 629 + 630 + int cprintf_exec(program_t *prog, FILE *stream, ...) { 631 + va_list ap; va_start(ap, stream); 632 + int ret = cprintf_vm_exec(prog, stream, ap); 633 + 634 + va_end(ap); 635 + return ret; 636 + } 637 + 638 + int csprintf_inner(program_t *prog, char *buf, size_t size, ...) { 639 + FILE *f = fmemopen(buf, size, "w"); 640 + if (!f) return -1; 641 + 642 + va_list ap; va_start(ap, size); 643 + int ret = cprintf_vm_exec(prog, f, ap); 644 + 645 + va_end(ap); fclose(f); 646 + return ret; 647 + }
+1 -15
src/cli/pkg.c
··· 15 15 #include "utils.h" 16 16 #include "config.h" 17 17 #include "progress.h" 18 + #include "modules/io.h" 18 19 19 - extern bool io_no_color; 20 20 bool pkg_verbose = false; 21 - 22 - #define C(color) (io_no_color ? "" : (color)) 23 - #define C_RESET C("\x1b[0m") 24 - #define C_BOLD C("\x1b[1m") 25 - #define C_DIM C("\x1b[2m") 26 - #define C_UL C("\x1b[4m") 27 - #define C_UL_OFF C("\x1b[24m") 28 - #define C_GREEN C("\x1b[32m") 29 - #define C_YELLOW C("\x1b[33m") 30 - #define C_BLUE C("\x1b[34m") 31 - #define C_MAGENTA C("\x1b[35m") 32 - #define C_CYAN C("\x1b[36m") 33 - #define C_WHITE C("\x1b[37m") 34 - #define C_RED C("\x1b[31m") 35 21 36 22 static void progress_callback(void *user_data, pkg_phase_t phase, uint32_t current, uint32_t total, const char *message) { 37 23 progress_t *progress = (progress_t *)user_data;
+10 -7
src/main.c
··· 2 2 #include <arena.h> 3 3 4 4 #include <oxc.h> 5 - #include <cli/pkg.h> 6 5 #include <stdio.h> 7 6 #include <stdlib.h> 8 7 #include <string.h> ··· 19 18 #include "snapshot.h" 20 19 #include "esm/remote.h" 21 20 #include "internal.h" 21 + 22 + #include "cli/pkg.h" 23 + #include "cli/cprintf.h" 22 24 23 25 #include "modules/builtin.h" 24 26 #include "modules/buffer.h" ··· 85 87 } 86 88 87 89 static void print_subcommands(void) { 88 - printf("Commands:\n"); 90 + cprintf("<bold>Commands:</>\n"); 89 91 for (const subcommand_t *cmd = subcommands; cmd->name; cmd++) { 90 - printf(" %-12s %s\n", cmd->name, cmd->desc); 92 + cprintf(" <pad=18>%s</pad> %s\n", cmd->name, cmd->desc); 91 93 } 94 + cprintf("\n <pad=18><command> <bold_cyan>--help</></pad> Print help text for command.\n"); 92 95 printf("\n"); 93 96 } 94 97 ··· 284 287 int nerrors = arg_parse(argc, argv, argtable); 285 288 286 289 if (help->count > 0) { 287 - printf("Ant sized JavaScript\n\n"); 288 - printf("Usage: ant [options] [module.js]\n"); 289 - printf(" ant <command> [args]\n\n"); 290 + cprintf("<bold_red>Ant</> is a tiny JavaScript runtime and package manager (%s)\n\n", ANT_VERSION); 291 + printf("%sUsage: ant %s[...options] %s[module.js]\n%s", C_BOLD, C_CYAN, C_YELLOW, C_RESET); 292 + printf("%s ant <command> %s[...args]%s\n\n", C_BOLD, C_CYAN, C_RESET); 290 293 print_subcommands(); 291 294 printf("If no module file is specified, ant starts in REPL mode.\n\n"); 292 - printf("Options:\n"); 295 + printf("%sOptions:%s\n", C_BOLD, C_RESET); 293 296 printf(" %-28s %s\n", "--verbose", "enable verbose output"); 294 297 printf(" %-28s %s\n", "--no-color", "disable colored output"); 295 298 arg_print_glossary(stdout, argtable, " %-28s %s\n");
+1 -7
src/modules/uri.c
··· 6 6 #include "errors.h" 7 7 #include "runtime.h" 8 8 #include "utf8.h" 9 + #include "utils.h" 9 10 #include "modules/uri.h" 10 11 11 12 static const unsigned char uri_unreserved[256] = { ··· 51 52 52 53 static int is_valid_continuation(unsigned char c) { 53 54 return (c & 0xC0) == 0x80; 54 - } 55 - 56 - static int hex_digit(char c) { 57 - if (c >= '0' && c <= '9') return c - '0'; 58 - if (c >= 'A' && c <= 'F') return c - 'A' + 10; 59 - if (c >= 'a' && c <= 'f') return c - 'a' + 10; 60 - return -1; 61 55 } 62 56 63 57 static int is_lone_surrogate(const unsigned char *str, int seq_len) {
+7
src/utils.c
··· 32 32 return ant_semver_buf; 33 33 } 34 34 35 + int hex_digit(char c) { 36 + if (c >= '0' && c <= '9') return c - '0'; 37 + if (c >= 'A' && c <= 'F') return c - 'A' + 10; 38 + if (c >= 'a' && c <= 'f') return c - 'a' + 10; 39 + return -1; 40 + } 41 + 35 42 uint64_t hash_key(const char *key, size_t len) { 36 43 uint64_t hash = 14695981039346656037ULL; 37 44 size_t i = 0;