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.

add no-color flag to disable colored output

+138 -57
+3
include/modules/io.h
··· 2 2 #define IO_H 3 3 4 4 #include <stdio.h> 5 + #include <stdbool.h> 6 + 7 + extern bool io_no_color; 5 8 6 9 void init_console_module(void); 7 10 void print_value_colored(const char *str, FILE *stream);
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.2.1.12') 77 + version_conf.set('ANT_VERSION', '0.2.1.13') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+8 -1
src/main.c
··· 136 136 struct arg_lit *help = arg_lit0("h", "help", "display this help and exit"); 137 137 struct arg_lit *version = arg_lit0("v", "version", "display version information and exit"); 138 138 struct arg_lit *debug = arg_litn("d", "debug", 0, 10, "dump VM state (can be repeated for more detail)"); 139 + struct arg_lit *no_color = arg_lit0(NULL, "no-color", "disable colored output"); 139 140 struct arg_str *eval = arg_str0("e", "eval", "<script>", "evaluate script"); 140 141 struct arg_lit *print = arg_lit0("p", "print", "evaluate script and print result"); 141 142 struct arg_int *gct = arg_int0(NULL, "gct", "<threshold>", "set garbage collection threshold"); ··· 145 146 struct arg_file *file = arg_file0(NULL, NULL, "<module.js>", "JavaScript module file to execute"); 146 147 struct arg_end *end = arg_end(20); 147 148 148 - void *argtable[] = {help, version, debug, eval, print, gct, initial_mem, max_mem, localstorage_file, file, end}; 149 + void *argtable[] = { 150 + help, version, debug, no_color, 151 + eval, print, gct, initial_mem, 152 + max_mem, localstorage_file, file, end 153 + }; 154 + 149 155 int nerrors = arg_parse(argc, argv, argtable); 150 156 151 157 if (help->count > 0) { ··· 180 186 181 187 if (initial_mem->count > 0) initial_size = (size_t)initial_mem->ival[0] * 1024 * 1024; 182 188 if (max_mem->count > 0) max_size = (size_t)max_mem->ival[0] * 1024 * 1024; 189 + if (no_color->count > 0) io_no_color = true; 183 190 184 191 struct js *js = js_create_dynamic(initial_size, max_size); 185 192
+126 -55
src/modules/io.c
··· 10 10 #include "modules/io.h" 11 11 #include "modules/symbol.h" 12 12 13 + bool io_no_color = false; 14 + 13 15 #define ANSI_RED "\x1b[31m" 14 16 #define ANSI_YELLOW "\x1b[33m" 15 17 #define ANSI_CYAN "\x1b[36m" ··· 26 28 #define JSON_TAG "\x1b[34m" 27 29 #define JSON_REF "\x1b[90m" 28 30 31 + static void io_putc(int c, FILE *stream) { fputc(c, stream); } 32 + static void io_puts(const char *s, FILE *stream) { fputs(s, stream); } 33 + 34 + static void io_print(const char *str, FILE *stream) { 35 + if (!io_no_color) { 36 + fputs(str, stream); 37 + return; 38 + } 39 + 40 + static void *states[] = {&&normal, &&esc, &&csi, &&done}; 41 + const char *p = str; 42 + char c; 43 + 44 + goto *states[0]; 45 + 46 + normal: 47 + c = *p++; 48 + if (!c) goto *states[3]; 49 + if (c == '\x1b') goto *states[1]; 50 + fputc(c, stream); 51 + goto *states[0]; 52 + 53 + esc: 54 + c = *p++; 55 + if (!c) goto *states[3]; 56 + if (c == '[') goto *states[2]; 57 + fputc('\x1b', stream); 58 + fputc(c, stream); 59 + goto *states[0]; 60 + 61 + csi: 62 + c = *p++; 63 + if (!c) goto *states[3]; 64 + if ((c >= '0' && c <= '9') || c == ';') goto *states[2]; 65 + if (c != 'm') fputc(c, stream); 66 + goto *states[0]; 67 + 68 + done: 69 + return; 70 + } 71 + 29 72 void print_value_colored(const char *str, FILE *stream) { 73 + if (io_no_color) { 74 + io_print(str, stream); 75 + return; 76 + } 77 + 30 78 bool in_string = false; 31 79 bool escape_next = false; 32 80 bool is_key = true; ··· 35 83 36 84 for (const char *p = str; *p; p++) { 37 85 if (escape_next) { 38 - fputc(*p, stream); 86 + io_putc(*p, stream); 39 87 escape_next = false; 40 88 continue; 41 89 } 42 90 43 91 if (*p == '\\' && in_string) { 44 - fputc(*p, stream); 92 + io_putc(*p, stream); 45 93 escape_next = true; 46 94 continue; 47 95 } ··· 49 97 if (*p == '\'' || *p == '"') { 50 98 if (!in_string) { 51 99 bool use_key_color = is_key && bracket_depth > 0; 52 - fprintf(stream, "%s%c", use_key_color ? JSON_KEY : JSON_STRING, *p); 100 + io_puts(use_key_color ? JSON_KEY : JSON_STRING, stream); 101 + io_putc(*p, stream); 53 102 in_string = true; 54 103 string_char = *p; 55 104 } else if (*p == string_char) { 56 - fprintf(stream, "%c%s", *p, ANSI_RESET); 105 + io_putc(*p, stream); 106 + io_puts(ANSI_RESET, stream); 57 107 in_string = false; 58 108 string_char = 0; 59 109 } else { 60 - fputc(*p, stream); 110 + io_putc(*p, stream); 61 111 } 62 112 continue; 63 113 } 64 114 65 115 if (in_string) { 66 - fputc(*p, stream); 116 + io_putc(*p, stream); 67 117 continue; 68 118 } 69 119 70 120 if (*p == '[' && strncmp(p, "[Function", 9) == 0) { 71 - fprintf(stream, "%s", JSON_FUNC); 72 - while (*p && *p != ']') fputc(*p++, stream); 73 - if (*p == ']') fputc(*p, stream); 74 - fprintf(stream, "%s", ANSI_RESET); 121 + io_puts(JSON_FUNC, stream); 122 + while (*p && *p != ']') io_putc(*p++, stream); 123 + if (*p == ']') io_putc(*p, stream); 124 + io_puts(ANSI_RESET, stream); 75 125 continue; 76 126 } 77 127 78 128 if (*p == '[' && strncmp(p, "[Circular", 9) == 0) { 79 - fprintf(stream, "%s", JSON_REF); 80 - while (*p && *p != ']') fputc(*p++, stream); 81 - if (*p == ']') fputc(*p, stream); 82 - fprintf(stream, "%s", ANSI_RESET); 129 + io_puts(JSON_REF, stream); 130 + while (*p && *p != ']') io_putc(*p++, stream); 131 + if (*p == ']') io_putc(*p, stream); 132 + io_puts(ANSI_RESET, stream); 83 133 continue; 84 134 } 85 135 86 136 if (*p == '<' && strncmp(p, "<ref", 4) == 0) { 87 - fprintf(stream, "%s", JSON_REF); 88 - while (*p && *p != '>') fputc(*p++, stream); 89 - if (*p == '>') fputc(*p, stream); 90 - fprintf(stream, "%s", ANSI_RESET); 137 + io_puts(JSON_REF, stream); 138 + while (*p && *p != '>') io_putc(*p++, stream); 139 + if (*p == '>') io_putc(*p, stream); 140 + io_puts(ANSI_RESET, stream); 91 141 continue; 92 142 } 93 143 94 144 if (strncmp(p, "Object [", 8) == 0) { 95 - fprintf(stream, "%sObject [", JSON_TAG); 145 + io_puts(JSON_TAG, stream); 146 + io_puts("Object [", stream); 96 147 p += 7; 97 - while (*p && *p != ']') fputc(*++p, stream); 98 - fprintf(stream, "%s", ANSI_RESET); 148 + while (*p && *p != ']') io_putc(*++p, stream); 149 + io_puts(ANSI_RESET, stream); 99 150 continue; 100 151 } 101 152 102 153 if (*p == ':') { 103 - fputc(*p, stream); 154 + io_putc(*p, stream); 104 155 is_key = false; 105 156 continue; 106 157 } 107 158 108 159 if (*p == ',' || *p == '\n') { 109 - fputc(*p, stream); 160 + io_putc(*p, stream); 110 161 is_key = true; 111 162 continue; 112 163 } 113 164 114 165 if (*p == '{' || *p == '[') { 115 - fprintf(stream, "%s%c%s", JSON_BRACE, *p, ANSI_RESET); 166 + io_puts(JSON_BRACE, stream); 167 + io_putc(*p, stream); 168 + io_puts(ANSI_RESET, stream); 116 169 bracket_depth++; 117 170 is_key = true; 118 171 continue; 119 172 } 120 173 121 174 if (*p == '}' || *p == ']') { 122 - fprintf(stream, "%s%c%s", JSON_BRACE, *p, ANSI_RESET); 175 + io_puts(JSON_BRACE, stream); 176 + io_putc(*p, stream); 177 + io_puts(ANSI_RESET, stream); 123 178 bracket_depth--; 124 179 continue; 125 180 } 126 181 127 182 if (strncmp(p, "true", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') { 128 - fprintf(stream, "%strue%s", JSON_BOOL, ANSI_RESET); 183 + io_puts(JSON_BOOL, stream); 184 + io_puts("true", stream); 185 + io_puts(ANSI_RESET, stream); 129 186 p += 3; 130 187 continue; 131 188 } 132 189 133 190 if (strncmp(p, "false", 5) == 0 && !isalnum((unsigned char)p[5]) && p[5] != '_') { 134 - fprintf(stream, "%sfalse%s", JSON_BOOL, ANSI_RESET); 191 + io_puts(JSON_BOOL, stream); 192 + io_puts("false", stream); 193 + io_puts(ANSI_RESET, stream); 135 194 p += 4; 136 195 continue; 137 196 } 138 197 139 198 if (strncmp(p, "null", 4) == 0 && !isalnum((unsigned char)p[4]) && p[4] != '_') { 140 - fprintf(stream, "%snull%s", JSON_NULL, ANSI_RESET); 199 + io_puts(JSON_NULL, stream); 200 + io_puts("null", stream); 201 + io_puts(ANSI_RESET, stream); 141 202 p += 3; 142 203 continue; 143 204 } 144 205 145 206 if (strncmp(p, "undefined", 9) == 0 && !isalnum((unsigned char)p[9]) && p[9] != '_') { 146 - fprintf(stream, "%sundefined%s", JSON_NULL, ANSI_RESET); 207 + io_puts(JSON_NULL, stream); 208 + io_puts("undefined", stream); 209 + io_puts(ANSI_RESET, stream); 147 210 p += 8; 148 211 continue; 149 212 } 150 213 151 214 if (strncmp(p, "Infinity", 8) == 0 && !is_key) { 152 - fprintf(stream, "%sInfinity%s", JSON_NUMBER, ANSI_RESET); 215 + io_puts(JSON_NUMBER, stream); 216 + io_puts("Infinity", stream); 217 + io_puts(ANSI_RESET, stream); 153 218 p += 7; 154 219 continue; 155 220 } 156 221 157 222 if (strncmp(p, "NaN", 3) == 0 && !isalnum((unsigned char)p[3]) && p[3] != '_' && !is_key) { 158 - fprintf(stream, "%sNaN%s", JSON_NUMBER, ANSI_RESET); 223 + io_puts(JSON_NUMBER, stream); 224 + io_puts("NaN", stream); 225 + io_puts(ANSI_RESET, stream); 159 226 p += 2; 160 227 continue; 161 228 } 162 229 163 230 if ((*p >= '0' && *p <= '9') || (*p == '-' && p[1] >= '0' && p[1] <= '9')) { 164 - fprintf(stream, "%s", JSON_NUMBER); 165 - if (*p == '-') fputc(*p++, stream); 231 + io_puts(JSON_NUMBER, stream); 232 + if (*p == '-') io_putc(*p++, stream); 166 233 while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') { 167 - fputc(*p, stream); 234 + io_putc(*p, stream); 168 235 if (!((p[1] >= '0' && p[1] <= '9') || p[1] == '.' || p[1] == 'e' || p[1] == 'E' || p[1] == '+' || p[1] == '-')) break; 169 236 p++; 170 237 } 171 - fprintf(stream, "%s", ANSI_RESET); 238 + io_puts(ANSI_RESET, stream); 172 239 continue; 173 240 } 174 241 175 242 if (is_key && bracket_depth > 0 && (isalpha((unsigned char)*p) || *p == '_' || *p == '$')) { 176 - fprintf(stream, "%s", JSON_KEY); 243 + io_puts(JSON_KEY, stream); 177 244 while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') { 178 - fputc(*p, stream); 245 + io_putc(*p, stream); 179 246 if (!(isalnum((unsigned char)p[1]) || p[1] == '_' || p[1] == '$')) break; 180 247 p++; 181 248 } 182 - fprintf(stream, "%s", ANSI_RESET); 249 + io_puts(ANSI_RESET, stream); 183 250 continue; 184 251 } 185 252 186 - fputc(*p, stream); 253 + io_putc(*p, stream); 187 254 } 188 255 } 189 256 190 257 static void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream) { 191 - if (color) fprintf(stream, "%s", color); 258 + if (color && !io_no_color) io_puts(color, stream); 192 259 193 260 for (int i = 0; i < nargs; i++) { 194 261 const char *space = i == 0 ? "" : " "; 195 - fprintf(stream, "%s", space); 262 + io_puts(space, stream); 196 263 197 264 if (js_type(args[i]) == JS_STR) { 198 265 char *str = js_getstr(js, args[i], NULL); 199 - fprintf(stream, "%s", str); 266 + io_print(str, stream); 200 267 } else { 201 268 const char *str = js_str(js, args[i]); 202 - if (color) fprintf(stream, "%s", ANSI_RESET); 269 + if (color && !io_no_color) io_puts(ANSI_RESET, stream); 203 270 print_value_colored(str, stream); 204 - if (color) fprintf(stream, "%s", color); 271 + if (color && !io_no_color) io_puts(color, stream); 205 272 } 206 273 } 207 274 208 - if (color) fprintf(stream, "%s", ANSI_RESET); 209 - fputc('\n', stream); 275 + if (color && !io_no_color) io_puts(ANSI_RESET, stream); 276 + io_putc('\n', stream); 210 277 } 211 278 212 279 static jsval_t js_console_log(struct js *js, jsval_t *args, int nargs) { ··· 230 297 bool is_truthy = js_truthy(js, args[0]); 231 298 if (is_truthy) return js_mkundef(); 232 299 233 - fprintf(stderr, "%sAssertion failed", ANSI_RED); 300 + if (!io_no_color) io_puts(ANSI_RED, stderr); 301 + io_puts("Assertion failed", stderr); 234 302 if (nargs > 1) { 235 - fprintf(stderr, ": "); 303 + io_puts(": ", stderr); 236 304 for (int i = 1; i < nargs; i++) { 237 305 const char *space = i == 1 ? "" : " "; 238 - fprintf(stderr, "%s", space); 306 + io_puts(space, stderr); 239 307 240 308 if (js_type(args[i]) == JS_STR) { 241 309 char *str = js_getstr(js, args[i], NULL); 242 - fprintf(stderr, "%s", str); 310 + io_print(str, stderr); 243 311 } else { 244 312 const char *str = js_str(js, args[i]); 245 - fprintf(stderr, "%s", str); 313 + io_print(str, stderr); 246 314 } 247 315 } 248 316 } 249 - fprintf(stderr, "%s\n", ANSI_RESET); 317 + if (!io_no_color) io_puts(ANSI_RESET, stderr); 318 + io_putc('\n', stderr); 250 319 251 320 return js_mkundef(); 252 321 } ··· 258 327 char *str = js_getstr(js, args[0], NULL); 259 328 fprintf(stderr, "%s", str); 260 329 } 261 - fprintf(stderr, "\n"); 262 330 331 + fprintf(stderr, "\n"); 263 332 js_print_stack_trace(stderr); 264 333 265 334 return js_mkundef(); ··· 278 347 static jsval_t js_console_clear(struct js *js, jsval_t *args, int nargs) { 279 348 (void)args; 280 349 (void)nargs; 281 - fprintf(stdout, "\033[2J\033[H"); 282 - fflush(stdout); 350 + if (!io_no_color) { 351 + fprintf(stdout, "\033[2J\033[H"); 352 + fflush(stdout); 353 + } 283 354 return js_mkundef(); 284 355 } 285 356