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.

refactor: consolidate base64, improve fs encoding, and clean up io/utils

+371 -304
+10
include/base64.h
··· 1 + #ifndef BASE64_H 2 + #define BASE64_H 3 + 4 + #include <stdint.h> 5 + #include <stddef.h> 6 + 7 + char *ant_base64_encode(const uint8_t *data, size_t len, size_t *out_len); 8 + uint8_t *ant_base64_decode(const char *data, size_t len, size_t *out_len); 9 + 10 + #endif
+20 -4
include/modules/buffer.h
··· 3 3 4 4 #include <stdint.h> 5 5 #include <stddef.h> 6 - 7 - void init_buffer_module(void); 8 - void cleanup_buffer_module(void); 9 - size_t buffer_get_external_memory(void); 6 + #include "types.h" 10 7 11 8 typedef struct { 12 9 uint8_t *data; ··· 44 41 size_t byte_offset; 45 42 size_t byte_length; 46 43 } DataViewData; 44 + 45 + void init_buffer_module(void); 46 + void cleanup_buffer_module(void); 47 + void free_array_buffer_data(ArrayBufferData *data); 48 + size_t buffer_get_external_memory(void); 49 + 50 + ArrayBufferData *create_array_buffer_data(size_t length); 51 + jsval_t create_arraybuffer_obj(struct js *js, ArrayBufferData *buffer); 52 + 53 + jsval_t create_typed_array( 54 + struct js *js, TypedArrayType type, ArrayBufferData *buffer, 55 + size_t byte_offset, size_t length, const char *type_name 56 + ); 57 + 58 + jsval_t create_typed_array_with_buffer( 59 + struct js *js, TypedArrayType type, ArrayBufferData *buffer, 60 + size_t byte_offset, size_t length, 61 + const char *type_name, jsval_t arraybuffer_obj 62 + ); 47 63 48 64 #endif
+24 -1
include/modules/io.h
··· 7 7 8 8 extern bool io_no_color; 9 9 10 + typedef struct { 11 + jsoff_t *visited; 12 + int count; 13 + int capacity; 14 + } inspect_visited_t; 15 + 10 16 #define C(color) (io_no_color ? "" : (color)) 11 17 #define C_RESET C("\x1b[0m") 12 18 #define C_BOLD C("\x1b[1m") ··· 23 29 24 30 void init_console_module(void); 25 31 void print_value_colored(const char *str, FILE *stream); 26 - void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream); 32 + void print_repl_value(ant_t *js, jsval_t val, FILE *stream); 33 + 34 + void inspect_object( 35 + ant_t *js, jsval_t obj, 36 + FILE *stream, int depth, 37 + inspect_visited_t *visited 38 + ); 39 + 40 + void inspect_value( 41 + ant_t *js, jsval_t val, 42 + FILE *stream, int depth, 43 + inspect_visited_t *visited 44 + ); 45 + 46 + jsval_t console_print( 47 + ant_t *js, jsval_t *args, 48 + int nargs, const char *color, FILE *stream 49 + ); 27 50 28 51 #endif
+1
include/utils.h
··· 15 15 uint64_t hash_key(const char *key, size_t len); 16 16 17 17 int hex_digit(char c); 18 + char hex_char(int v); 18 19 int is_typescript_file(const char *filename); 19 20 20 21 void *try_oom(size_t size);
+2 -1
meson/deps/meson.build
··· 109 109 uthash_dep = subproject('uthash').get_variable('uthash_dep') 110 110 yyjson_dep = subproject('yyjson').get_variable('yyjson_dep') 111 111 uuidv7_dep = subproject('uuidv7').get_variable('uuidv7_dep') 112 + base64_dep = subproject('aklomp-base64').get_variable('base64_dep') 112 113 argtable3_dep = subproject('argtable3').get_variable('argtable3_dep') 113 114 minicoro_dep = subproject('minicoro').get_variable('minicoro_dep') 114 115 crprintf_dep = subproject('crprintf').get_variable('crprintf_dep') ··· 207 208 208 209 ant_deps = [ 209 210 libffi_dep, uuid_dep, crprintf_dep, 210 - llhttp, pcre2_dep, libuv_dep, 211 + llhttp, pcre2_dep, libuv_dep, base64_dep, 211 212 argtable3_dep, tlsuv_dep, libsodium_dep, 212 213 yyjson_dep, minicoro_dep, uuidv7_dep, 213 214 openssl_dep, zlib_dep, uthash_dep,
+10 -72
src/ant.c
··· 10 10 #include "common.h" 11 11 #include "arena.h" 12 12 #include "utils.h" 13 + #include "base64.h" 13 14 #include "runtime.h" 14 15 #include "internal.h" 15 16 #include "sugar.h" ··· 20219 20220 return tov(result); 20220 20221 } 20221 20222 20222 - static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 20223 - 20224 20223 static jsval_t builtin_btoa(struct js *js, jsval_t *args, int nargs) { 20225 20224 if (nargs < 1) return js_mkerr(js, "btoa requires 1 argument"); 20226 20225 ··· 20233 20232 jsoff_t str_len, str_off = vstr(js, str_val, &str_len); 20234 20233 const char *str = (char *) &js->mem[str_off]; 20235 20234 20236 - for (jsoff_t i = 0; i < str_len; i++) { 20237 - if ((unsigned char)str[i] > 255) { 20238 - return js_mkerr(js, "btoa: character out of range"); 20239 - } 20240 - } 20241 - 20242 - size_t out_len = ((str_len + 2) / 3) * 4; 20243 - char *out = (char *)ant_calloc(out_len + 1); 20235 + size_t out_len; 20236 + char *out = ant_base64_encode((const uint8_t *)str, str_len, &out_len); 20244 20237 if (!out) return js_mkerr(js, "out of memory"); 20245 20238 20246 - size_t i = 0, j = 0; 20247 - while (i < str_len) { 20248 - size_t remaining = str_len - i; 20249 - uint32_t a = (unsigned char)str[i++]; 20250 - uint32_t b = (remaining > 1) ? (unsigned char)str[i++] : 0; 20251 - uint32_t c = (remaining > 2) ? (unsigned char)str[i++] : 0; 20252 - uint32_t triple = (a << 16) | (b << 8) | c; 20253 - 20254 - out[j++] = base64_chars[(triple >> 18) & 0x3F]; 20255 - out[j++] = base64_chars[(triple >> 12) & 0x3F]; 20256 - out[j++] = (remaining > 1) ? base64_chars[(triple >> 6) & 0x3F] : '='; 20257 - out[j++] = (remaining > 2) ? base64_chars[triple & 0x3F] : '='; 20258 - } 20259 - out[j] = '\0'; 20239 + jsval_t result = js_mkstr(js, out, out_len); 20240 + free(out); 20260 20241 20261 - jsval_t result = js_mkstr(js, out, j); 20262 - free(out); 20263 20242 return result; 20264 20243 } 20265 20244 20266 - static const int8_t decode_table[256] = { 20267 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20268 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20269 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 20270 - 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, 20271 - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 20272 - 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, 20273 - -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 20274 - 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, 20275 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20276 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20277 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20278 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20279 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20280 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20281 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 20282 - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 20283 - }; 20284 - 20285 20245 static jsval_t builtin_atob(struct js *js, jsval_t *args, int nargs) { 20286 20246 if (nargs < 1) return js_mkerr(js, "atob requires 1 argument"); 20287 20247 ··· 20293 20253 20294 20254 jsoff_t str_len, str_off = vstr(js, str_val, &str_len); 20295 20255 const char *str = (char *) &js->mem[str_off]; 20296 - 20297 20256 if (str_len == 0) return js_mkstr(js, "", 0); 20298 - if (str_len % 4 != 0) return js_mkerr(js, "atob: invalid base64 string"); 20299 20257 20300 - size_t out_len = (str_len / 4) * 3; 20301 - if (str_len > 0 && str[str_len - 1] == '=') out_len--; 20302 - if (str_len > 1 && str[str_len - 2] == '=') out_len--; 20303 - 20304 - char *out = (char *)ant_calloc(out_len + 1); 20305 - if (!out) return js_mkerr(js, "out of memory"); 20306 - 20307 - size_t i = 0, j = 0; 20308 - while (i < str_len) { 20309 - int8_t a = decode_table[(unsigned char)str[i++]]; 20310 - int8_t b = decode_table[(unsigned char)str[i++]]; 20311 - int8_t c = (str[i] == '=') ? 0 : decode_table[(unsigned char)str[i]]; i++; 20312 - int8_t d = (str[i] == '=') ? 0 : decode_table[(unsigned char)str[i]]; i++; 20313 - 20314 - if (a < 0 || b < 0 || (str[i-2] != '=' && c < 0) || (str[i-1] != '=' && d < 0)) { 20315 - free(out); 20316 - return js_mkerr(js, "atob: invalid character in base64 string"); 20317 - } 20318 - 20319 - uint32_t triple = ((uint32_t)a << 18) | ((uint32_t)b << 12) | ((uint32_t)c << 6) | (uint32_t)d; 20320 - if (j < out_len) out[j++] = (triple >> 16) & 0xFF; 20321 - if (j < out_len) out[j++] = (triple >> 8) & 0xFF; 20322 - if (j < out_len) out[j++] = triple & 0xFF; 20323 - } 20258 + size_t out_len; 20259 + uint8_t *out = ant_base64_decode(str, str_len, &out_len); 20260 + if (!out) return js_mkerr(js, "atob: invalid base64 string"); 20324 20261 20325 - jsval_t result = js_mkstr(js, out, out_len); 20262 + jsval_t result = js_mkstr(js, (char *)out, out_len); 20326 20263 free(out); 20264 + 20327 20265 return result; 20328 20266 } 20329 20267
+26
src/base64.c
··· 1 + #include <stdlib.h> 2 + #include <libbase64.h> 3 + #include "base64.h" 4 + 5 + char *ant_base64_encode(const uint8_t *data, size_t len, size_t *out_len) { 6 + size_t encoded_len = 4 * ((len + 2) / 3); 7 + char *result = malloc(encoded_len + 1); 8 + if (!result) return NULL; 9 + 10 + base64_encode((const char *)data, len, result, out_len, 0); 11 + result[*out_len] = '\0'; 12 + return result; 13 + } 14 + 15 + uint8_t *ant_base64_decode(const char *data, size_t len, size_t *out_len) { 16 + size_t decoded_len = (len / 4) * 3 + 3; 17 + uint8_t *result = malloc(decoded_len); 18 + if (!result) return NULL; 19 + 20 + if (!base64_decode(data, len, (char *)result, out_len, 0)) { 21 + free(result); 22 + return NULL; 23 + } 24 + 25 + return result; 26 + }
+10 -71
src/modules/buffer.c
··· 12 12 #include "ant.h" 13 13 #include "errors.h" 14 14 #include "arena.h" 15 + #include "base64.h" 15 16 #include "internal.h" 16 17 #include "runtime.h" 17 18 ··· 116 117 static jsval_t js_buffer_toBase64(struct js *js, jsval_t *args, int nargs); 117 118 static jsval_t js_buffer_write(struct js *js, jsval_t *args, int nargs); 118 119 119 - static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 120 - 121 - static const unsigned char base64_decode_table[256] = { 122 - ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7, 123 - ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15, 124 - ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23, 125 - ['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31, 126 - ['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39, 127 - ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47, 128 - ['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55, 129 - ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63, 130 - }; 131 - 132 - static char *base64_encode(const uint8_t *data, size_t len, size_t *out_len) { 133 - size_t encoded_len = 4 * ((len + 2) / 3); 134 - char *result = malloc(encoded_len + 1); 135 - if (!result) return NULL; 136 - 137 - size_t j = 0; 138 - for (size_t i = 0; i < len; i += 3) { 139 - uint32_t octet_a = i < len ? data[i] : 0; 140 - uint32_t octet_b = i + 1 < len ? data[i + 1] : 0; 141 - uint32_t octet_c = i + 2 < len ? data[i + 2] : 0; 142 - uint32_t triple = (octet_a << 16) + (octet_b << 8) + octet_c; 143 - 144 - result[j++] = base64_chars[(triple >> 18) & 0x3F]; 145 - result[j++] = base64_chars[(triple >> 12) & 0x3F]; 146 - result[j++] = (i + 1 < len) ? base64_chars[(triple >> 6) & 0x3F] : '='; 147 - result[j++] = (i + 2 < len) ? base64_chars[triple & 0x3F] : '='; 148 - } 149 - 150 - result[j] = '\0'; 151 - *out_len = j; 152 - return result; 153 - } 154 - 155 - static uint8_t *base64_decode(const char *data, size_t len, size_t *out_len) { 156 - if (len % 4 != 0) return NULL; 157 - 158 - size_t decoded_len = len / 4 * 3; 159 - if (len > 0 && data[len - 1] == '=') decoded_len--; 160 - if (len > 1 && data[len - 2] == '=') decoded_len--; 161 - 162 - uint8_t *result = malloc(decoded_len); 163 - if (!result) return NULL; 164 - 165 - size_t j = 0; 166 - for (size_t i = 0; i < len; i += 4) { 167 - uint32_t sextet_a = base64_decode_table[(unsigned char)data[i]]; 168 - uint32_t sextet_b = base64_decode_table[(unsigned char)data[i + 1]]; 169 - uint32_t sextet_c = data[i + 2] == '=' ? 0 : base64_decode_table[(unsigned char)data[i + 2]]; 170 - uint32_t sextet_d = data[i + 3] == '=' ? 0 : base64_decode_table[(unsigned char)data[i + 3]]; 171 - uint32_t triple = (sextet_a << 18) + (sextet_b << 12) + (sextet_c << 6) + sextet_d; 172 - 173 - if (j < decoded_len) result[j++] = (triple >> 16) & 0xFF; 174 - if (j < decoded_len) result[j++] = (triple >> 8) & 0xFF; 175 - if (j < decoded_len) result[j++] = triple & 0xFF; 176 - } 177 - 178 - *out_len = decoded_len; 179 - return result; 180 - } 181 - 182 - static ArrayBufferData *create_array_buffer_data(size_t length) { 120 + ArrayBufferData *create_array_buffer_data(size_t length) { 183 121 ArrayBufferData *data = ant_calloc(sizeof(ArrayBufferData) + length); 184 122 if (!data) return NULL; 185 123 ··· 202 140 return data; 203 141 } 204 142 205 - static void free_array_buffer_data(ArrayBufferData *data) { 143 + void free_array_buffer_data(ArrayBufferData *data) { 206 144 if (!data) return; 207 145 data->ref_count--; 208 146 if (data->ref_count <= 0) { ··· 424 362 S_DONE: return true; 425 363 } 426 364 427 - static jsval_t create_arraybuffer_obj(struct js *js, ArrayBufferData *buffer) { 365 + jsval_t create_arraybuffer_obj(struct js *js, ArrayBufferData *buffer) { 428 366 jsval_t ab_obj = js_mkobj(js); 429 367 jsval_t ab_proto = js_get_ctor_proto(js, "ArrayBuffer", 11); 430 368 if (is_special_object(ab_proto)) js_set_proto(js, ab_obj, ab_proto); ··· 436 374 return ab_obj; 437 375 } 438 376 439 - static jsval_t create_typed_array_with_buffer( 377 + jsval_t create_typed_array_with_buffer( 440 378 struct js *js, TypedArrayType type, ArrayBufferData *buffer, 441 379 size_t byte_offset, size_t length, const char *type_name, jsval_t arraybuffer_obj 442 380 ) { ··· 468 406 return obj; 469 407 } 470 408 471 - static jsval_t create_typed_array( 409 + jsval_t create_typed_array( 472 410 struct js *js, TypedArrayType type, ArrayBufferData *buffer, 473 411 size_t byte_offset, size_t length, const char *type_name 474 412 ) { 475 413 jsval_t ab_obj = create_arraybuffer_obj(js, buffer); 476 - return create_typed_array_with_buffer(js, type, buffer, byte_offset, length, type_name, ab_obj); 414 + jsval_t result = create_typed_array_with_buffer(js, type, buffer, byte_offset, length, type_name, ab_obj); 415 + free_array_buffer_data(buffer); return result; 477 416 } 478 417 479 418 typedef struct { ··· 1329 1268 1330 1269 if (encoding == ENC_BASE64) { 1331 1270 size_t decoded_len; 1332 - uint8_t *decoded = base64_decode(str, len, &decoded_len); 1271 + uint8_t *decoded = ant_base64_decode(str, len, &decoded_len); 1333 1272 if (!decoded) return js_mkerr(js, "Failed to decode base64"); 1334 1273 1335 1274 ArrayBufferData *buffer = create_array_buffer_data(decoded_len); ··· 1436 1375 1437 1376 if (encoding == ENC_BASE64) { 1438 1377 size_t out_len; 1439 - char *encoded = base64_encode(data, len, &out_len); 1378 + char *encoded = ant_base64_encode(data, len, &out_len); 1440 1379 if (!encoded) return js_mkerr(js, "Failed to encode base64"); 1441 1380 1442 1381 jsval_t result = js_mkstr(js, encoded, out_len);
+130 -19
src/modules/fs.c
··· 11 11 #include <errno.h> 12 12 13 13 #include "ant.h" 14 + #include "utf8.h" 15 + #include "utils.h" 16 + #include "base64.h" 14 17 #include "errors.h" 15 18 #include "internal.h" 16 19 #include "runtime.h" 17 20 18 21 #include "modules/fs.h" 22 + #include "modules/buffer.h" 19 23 #include "modules/symbol.h" 20 24 21 25 #define fs_err_code(js, code, op, path) ({ \ ··· 25 29 }) 26 30 27 31 typedef enum { 32 + FS_ENC_NONE = 0, 33 + FS_ENC_UTF8, 34 + FS_ENC_UTF16LE, 35 + FS_ENC_LATIN1, 36 + FS_ENC_BASE64, 37 + FS_ENC_BASE64URL, 38 + FS_ENC_HEX, 39 + FS_ENC_ASCII, 40 + } fs_encoding_t; 41 + 42 + static fs_encoding_t parse_encoding(struct js *js, jsval_t arg) { 43 + size_t len; 44 + const char *str = NULL; 45 + 46 + if (vtype(arg) == T_STR) str = js_getstr(js, arg, &len); 47 + else if (vtype(arg) == T_OBJ) { 48 + jsval_t enc = js_get(js, arg, "encoding"); 49 + if (vtype(enc) == T_STR) str = js_getstr(js, enc, &len); 50 + } 51 + 52 + if (!str) return FS_ENC_NONE; 53 + 54 + if (len == 4 && memcmp(str, "utf8", 4) == 0) return FS_ENC_UTF8; 55 + if (len == 5 && memcmp(str, "utf-8", 5) == 0) return FS_ENC_UTF8; 56 + if (len == 7 && memcmp(str, "utf16le", 7) == 0) return FS_ENC_UTF16LE; 57 + if (len == 4 && memcmp(str, "ucs2", 4) == 0) return FS_ENC_UTF16LE; 58 + if (len == 5 && memcmp(str, "ucs-2", 5) == 0) return FS_ENC_UTF16LE; 59 + if (len == 6 && memcmp(str, "latin1", 6) == 0) return FS_ENC_LATIN1; 60 + if (len == 6 && memcmp(str, "binary", 6) == 0) return FS_ENC_LATIN1; 61 + if (len == 6 && memcmp(str, "base64", 6) == 0) return FS_ENC_BASE64; 62 + if (len == 9 && memcmp(str, "base64url", 9) == 0) return FS_ENC_BASE64URL; 63 + if (len == 3 && memcmp(str, "hex", 3) == 0) return FS_ENC_HEX; 64 + if (len == 5 && memcmp(str, "ascii", 5) == 0) return FS_ENC_ASCII; 65 + 66 + return FS_ENC_NONE; 67 + } 68 + 69 + static jsval_t encode_data(struct js *js, const char *data, size_t len, fs_encoding_t enc) { 70 + switch (enc) { 71 + case FS_ENC_UTF8: 72 + case FS_ENC_LATIN1: 73 + case FS_ENC_ASCII: return js_mkstr(js, data, len); 74 + 75 + case FS_ENC_HEX: { 76 + char *out = malloc(len * 2); 77 + if (!out) return js_mkerr(js, "Out of memory"); 78 + for (size_t i = 0; i < len; i++) { 79 + out[i * 2] = hex_char((unsigned char)data[i] >> 4); 80 + out[i * 2 + 1] = hex_char(data[i]); 81 + } 82 + jsval_t result = js_mkstr(js, out, len * 2); 83 + free(out); return result; 84 + } 85 + 86 + case FS_ENC_BASE64: { 87 + size_t out_len; 88 + char *out = ant_base64_encode((const uint8_t *)data, len, &out_len); 89 + if (!out) return js_mkerr(js, "Out of memory"); 90 + jsval_t result = js_mkstr(js, out, out_len); 91 + free(out); return result; 92 + } 93 + 94 + case FS_ENC_BASE64URL: { 95 + size_t out_len; 96 + char *out = ant_base64_encode((const uint8_t *)data, len, &out_len); 97 + if (!out) return js_mkerr(js, "Out of memory"); 98 + for (size_t i = 0; i < out_len; i++) { 99 + if (out[i] == '+') out[i] = '-'; 100 + else if (out[i] == '/') out[i] = '_'; 101 + } 102 + while (out_len > 0 && out[out_len - 1] == '=') out_len--; 103 + jsval_t result = js_mkstr(js, out, out_len); 104 + free(out); return result; 105 + } 106 + 107 + case FS_ENC_UTF16LE: { 108 + const unsigned char *s = (const unsigned char *)data; 109 + char *out = malloc((len / 2) * 4); 110 + if (!out) return js_mkerr(js, "Out of memory"); 111 + size_t j = 0; 112 + for (size_t i = 0; i + 1 < len; i += 2) { 113 + uint32_t cp = s[i] | (s[i + 1] << 8); 114 + bool is_hi = cp >= 0xD800 && cp <= 0xDBFF && i + 3 < len; 115 + uint32_t lo = is_hi ? s[i + 2] | (s[i + 3] << 8) : 0; 116 + bool is_pair = is_hi && lo >= 0xDC00 && lo <= 0xDFFF; 117 + if (is_pair) { cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00); i += 2; } 118 + j += utf8_encode(cp, out + j); 119 + } 120 + jsval_t result = js_mkstr(js, out, j); 121 + free(out); return result; 122 + } 123 + 124 + default: return js_mkstr(js, data, len); 125 + } 126 + } 127 + 128 + typedef enum { 28 129 FS_OP_READ, 29 130 FS_OP_WRITE, 30 131 FS_OP_UNLINK, ··· 38 139 } fs_op_type_t; 39 140 40 141 typedef struct fs_request_s { 142 + uv_fs_t uv_req; 41 143 struct js *js; 42 144 jsval_t promise; 43 - uv_fs_t uv_req; 44 - fs_op_type_t op_type; 45 145 char *path; 46 146 char *data; 147 + char *error_msg; 47 148 size_t data_len; 149 + fs_op_type_t op_type; 150 + fs_encoding_t encoding; 48 151 uv_file fd; 49 152 int completed; 50 153 int failed; 51 - char *error_msg; 52 154 } fs_request_t; 53 155 54 156 static UT_array *pending_requests = NULL; ··· 66 168 67 169 static void remove_pending_request(fs_request_t *req) { 68 170 if (!req || !pending_requests) return; 69 - 70 - fs_request_t **p = NULL; 71 - unsigned int i = 0; 171 + unsigned int len = utarray_len(pending_requests); 72 172 73 - while ((p = (fs_request_t**)utarray_next(pending_requests, p))) { 74 - if (*p == req) { 75 - utarray_erase(pending_requests, i, 1); 76 - break; 77 - } i++; 173 + for (unsigned int i = 0; i < len; i++) { 174 + if (*(fs_request_t**)utarray_eltptr(pending_requests, i) != req) continue; 175 + utarray_erase(pending_requests, i, 1); break; 78 176 } 79 177 } 80 178 179 + static jsval_t fs_read_to_uint8array(struct js *js, const char *data, size_t len) { 180 + ArrayBufferData *ab = create_array_buffer_data(len); 181 + if (!ab) return js_mkundef(); 182 + memcpy(ab->data, data, len); 183 + jsval_t result = create_typed_array(js, TYPED_ARRAY_UINT8, ab, 0, len, "Uint8Array"); 184 + if (vtype(result) == T_ERR) free_array_buffer_data(ab); 185 + return result; 186 + } 187 + 81 188 static void complete_request(fs_request_t *req) { 82 189 if (req->failed) { 83 190 const char *err_msg = req->error_msg ? req->error_msg : "Unknown error"; 84 191 jsval_t err = js_mkstr(req->js, err_msg, strlen(err_msg)); 85 192 js_reject_promise(req->js, req->promise, err); 86 193 } else { 87 - jsval_t result; 88 - if ((req->op_type == FS_OP_READ || req->op_type == FS_OP_READ_BYTES) && req->data) { 194 + jsval_t result = js_mkundef(); 195 + if (req->op_type == FS_OP_READ && req->data) { 196 + if (req->encoding != FS_ENC_NONE) 197 + result = encode_data(req->js, req->data, req->data_len, req->encoding); 198 + else result = fs_read_to_uint8array(req->js, req->data, req->data_len); 199 + } else if (req->op_type == FS_OP_READ_BYTES && req->data) 89 200 result = js_mkstr(req->js, req->data, req->data_len); 90 - } else if (req->op_type == FS_OP_STAT) { 91 - result = js_mkundef(); 92 - } else result = js_mkundef(); 93 201 js_resolve_promise(req->js, req->promise, result); 94 202 } 95 203 ··· 386 494 return js_mkerr(js, "Failed to read entire file"); 387 495 } 388 496 389 - data[file_size] = '\0'; 390 - jsval_t result = js_mkstr(js, data, file_size); 497 + fs_encoding_t enc = (nargs > 1) ? parse_encoding(js, args[1]) : FS_ENC_NONE; 498 + jsval_t result = (enc != FS_ENC_NONE) 499 + ? encode_data(js, data, file_size, enc) 500 + : fs_read_to_uint8array(js, data, file_size); 501 + 391 502 free(data); 392 - 393 503 return result; 394 504 } 395 505 ··· 458 568 459 569 req->js = js; 460 570 req->op_type = FS_OP_READ; 571 + req->encoding = (nargs > 1) ? parse_encoding(js, args[1]) : FS_ENC_NONE; 461 572 req->promise = js_mkpromise(js); 462 573 req->path = strndup(path, path_len); 463 574 req->uv_req.data = req;
+119 -122
src/modules/io.c
··· 17 17 18 18 bool io_no_color = false; 19 19 20 - #define ANSI_RED "\x1b[31m" 21 - #define ANSI_YELLOW "\x1b[33m" 22 - #define ANSI_CYAN "\x1b[36m" 23 - #define ANSI_MAGENTA "\x1b[35m" 24 - #define ANSI_RESET "\x1b[0m" 25 - 26 - #define JSON_KEY "\x1b[0m" 20 + #define JSON_KEY "\x1b[0m" 27 21 #define JSON_STRING "\x1b[32m" 28 22 #define JSON_NUMBER "\x1b[33m" 29 - #define JSON_BOOL "\x1b[35m" 30 - #define JSON_NULL "\x1b[90m" 31 - #define JSON_BRACE "\x1b[37m" 32 - #define JSON_FUNC "\x1b[36m" 33 - #define JSON_TAG "\x1b[34m" 34 - #define JSON_REF "\x1b[90m" 35 - #define JSON_WHITE "\x1b[97m" 36 - 37 - typedef struct { 38 - jsoff_t *visited; 39 - int count; 40 - int capacity; 41 - } inspect_visited_t; 42 - 43 - static void io_putc(int c, FILE *stream) { fputc(c, stream); } 44 - static void io_puts(const char *s, FILE *stream) { fputs(s, stream); } 45 - static void inspect_object_full(struct js *js, jsval_t obj, FILE *stream, int depth, inspect_visited_t *visited); 23 + #define JSON_BOOL "\x1b[35m" 24 + #define JSON_NULL "\x1b[90m" 25 + #define JSON_BRACE "\x1b[37m" 26 + #define JSON_FUNC "\x1b[36m" 27 + #define JSON_TAG "\x1b[34m" 28 + #define JSON_REF "\x1b[90m" 29 + #define JSON_WHITE "\x1b[97m" 46 30 47 31 static void io_print(const char *str, FILE *stream) { 48 32 if (!io_no_color) { ··· 51 35 } 52 36 53 37 static void *states[] = {&&normal, &&esc, &&csi, &&done}; 54 - const char *p = str; 55 - char c; 38 + const char *p = str; char c; 56 39 57 40 goto *states[0]; 58 41 59 - normal: 60 - c = *p++; 61 - if (!c) goto *states[3]; 62 - if (c == '\x1b') goto *states[1]; 63 - fputc(c, stream); 64 - goto *states[0]; 42 + normal: { 43 + c = *p++; 44 + if (!c) goto *states[3]; 45 + if (c == '\x1b') goto *states[1]; 46 + fputc(c, stream); 47 + goto *states[0]; 48 + } 65 49 66 - esc: 67 - c = *p++; 68 - if (!c) goto *states[3]; 69 - if (c == '[') goto *states[2]; 70 - fputc('\x1b', stream); 71 - fputc(c, stream); 72 - goto *states[0]; 50 + esc: { 51 + c = *p++; 52 + if (!c) goto *states[3]; 53 + if (c == '[') goto *states[2]; 54 + fputc('\x1b', stream); 55 + fputc(c, stream); 56 + goto *states[0]; 57 + } 73 58 74 - csi: 75 - c = *p++; 76 - if (!c) goto *states[3]; 77 - if ((c >= '0' && c <= '9') || c == ';') goto *states[2]; 78 - if (c != 'm') fputc(c, stream); 79 - goto *states[0]; 80 - 81 - done: 82 - return; 59 + csi: { 60 + c = *p++; 61 + if (!c) goto *states[3]; 62 + if ((c >= '0' && c <= '9') || c == ';') goto *states[2]; 63 + if (c != 'm') fputc(c, stream); 64 + goto *states[0]; 65 + } 66 + 67 + done: return; 83 68 } 84 69 85 70 enum char_class { ··· 115 100 116 101 #define KEYWORD(kw, color) \ 117 102 if (memcmp(p, kw, sizeof(kw) - 1) == 0 && !isalnum((unsigned char)p[sizeof(kw) - 1]) && p[sizeof(kw) - 1] != '_') { \ 118 - io_puts(color, stream); io_puts(kw, stream); io_puts(ANSI_RESET, stream); \ 103 + fputs(color, stream); fputs(kw, stream); fputs(C_RESET, stream); \ 119 104 p += sizeof(kw) - 1; goto next; \ 120 105 } 121 106 122 107 #define EMIT_UNTIL(end_char, color) \ 123 - io_puts(color, stream); \ 124 - while (*p && *p != end_char) io_putc(*p++, stream); \ 125 - if (*p == end_char) io_putc(*p++, stream); \ 126 - io_puts(ANSI_RESET, stream); goto next; 108 + fputs(color, stream); \ 109 + while (*p && *p != end_char) fputc(*p++, stream); \ 110 + if (*p == end_char) fputc(*p++, stream); \ 111 + fputs(C_RESET, stream); goto next; 127 112 128 113 #define EMIT_TYPE(tag, len, color) \ 129 114 if (!(is_key && brace_depth > 0) && memcmp(p, tag, len) == 0) { \ 130 - io_puts(color, stream); io_puts(tag, stream); io_puts(ANSI_RESET, stream); \ 115 + fputs(color, stream); fputs(tag, stream); fputs(C_RESET, stream); \ 131 116 p += len; goto next; \ 132 117 } 133 118 ··· 158 143 159 144 quote: 160 145 string_char = *p; 161 - io_puts((is_key && brace_depth > 0) ? JSON_KEY : JSON_STRING, stream); 162 - io_putc(*p++, stream); 146 + fputs((is_key && brace_depth > 0) ? JSON_KEY : JSON_STRING, stream); 147 + fputc(*p++, stream); 163 148 while (*p) { 164 - if (*p == '\\' && p[1]) { io_putc(*p++, stream); io_putc(*p++, stream); continue; } 165 - if (*p == string_char) { io_putc(*p++, stream); break; } 166 - io_putc(*p++, stream); 149 + if (*p == '\\' && p[1]) { fputc(*p++, stream); fputc(*p++, stream); continue; } 150 + if (*p == string_char) { fputc(*p++, stream); break; } 151 + fputc(*p++, stream); 167 152 } 168 - io_puts(ANSI_RESET, stream); 153 + fputs(C_RESET, stream); 169 154 goto next; 170 155 171 156 lbrace: 172 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 157 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 173 158 brace_depth++; is_key = true; goto next; 174 159 175 160 rbrace: 176 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 161 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 177 162 brace_depth--; is_key = false; goto next; 178 163 179 164 lbrack: ··· 190 175 case 'U': if (memcmp(p + 2, "int8Contents]", 13) == 0) { EMIT_UNTIL(']', JSON_FUNC) } break; 191 176 case 'P': if (memcmp(p + 2, "romise]", 7) == 0) { EMIT_UNTIL(']', JSON_TAG) } break; 192 177 } 193 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 178 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 194 179 array_depth++; is_key = false; goto next; 195 180 196 181 rbrack: 197 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 182 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 198 183 array_depth--; is_key = false; goto next; 199 184 200 185 colon: 201 - io_putc(*p++, stream); is_key = false; goto next; 186 + fputc(*p++, stream); is_key = false; goto next; 202 187 203 188 separator: 204 - io_putc(*p++, stream); 189 + fputc(*p++, stream); 205 190 is_key = (brace_depth > 0 && array_depth == 0); 206 191 goto next; 207 192 208 193 number: 209 - io_puts(JSON_NUMBER, stream); 194 + fputs(JSON_NUMBER, stream); 210 195 while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') 211 - io_putc(*p++, stream); 212 - io_puts(ANSI_RESET, stream); 196 + fputc(*p++, stream); 197 + fputs(C_RESET, stream); 213 198 goto next; 214 199 215 200 minus: 216 201 if (p[1] >= '0' && p[1] <= '9') { 217 - io_puts(JSON_NUMBER, stream); io_putc(*p++, stream); 202 + fputs(JSON_NUMBER, stream); fputc(*p++, stream); 218 203 while ((*p >= '0' && *p <= '9') || *p == '.' || *p == 'e' || *p == 'E' || *p == '+' || *p == '-') 219 - io_putc(*p++, stream); 220 - io_puts(ANSI_RESET, stream); 204 + fputc(*p++, stream); 205 + fputs(C_RESET, stream); 221 206 goto next; 222 207 } 223 - io_putc(*p++, stream); goto next; 208 + fputc(*p++, stream); goto next; 224 209 225 210 lt: 226 211 if (memcmp(p, "<ref", 4) == 0) { EMIT_UNTIL('>', JSON_REF) } 227 - if (memcmp(p, "<pen", 4) == 0) { is_key = false; EMIT_UNTIL('>', ANSI_CYAN) } 228 - if (memcmp(p, "<rej", 4) == 0) { is_key = false; EMIT_UNTIL('>', ANSI_CYAN) } 212 + if (memcmp(p, "<pen", 4) == 0) { is_key = false; EMIT_UNTIL('>', C_CYAN) } 213 + if (memcmp(p, "<rej", 4) == 0) { is_key = false; EMIT_UNTIL('>', C_CYAN) } 229 214 230 215 if (p[1] == '>' || (isxdigit((unsigned char)p[1]) && isxdigit((unsigned char)p[2]))) { 231 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); 232 - io_puts(JSON_WHITE, stream); 233 - while (*p && *p != '>') io_putc(*p++, stream); 234 - io_puts(ANSI_RESET, stream); 235 - if (*p == '>') { io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); } 216 + fputs(JSON_BRACE, stream); fputc(*p++, stream); 217 + fputs(JSON_WHITE, stream); 218 + while (*p && *p != '>') fputc(*p++, stream); 219 + fputs(C_RESET, stream); 220 + if (*p == '>') { fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); } 236 221 goto next; 237 222 } 238 223 239 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 224 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 240 225 goto next; 241 226 242 227 gt: 243 - io_puts(JSON_BRACE, stream); io_putc(*p++, stream); io_puts(ANSI_RESET, stream); 228 + fputs(JSON_BRACE, stream); fputc(*p++, stream); fputs(C_RESET, stream); 244 229 goto next; 245 230 246 231 alpha: ··· 259 244 260 245 ident: 261 246 if (is_key && brace_depth > 0) { 262 - io_puts(JSON_KEY, stream); 263 - while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') io_putc(*p++, stream); 264 - io_puts(ANSI_RESET, stream); 247 + fputs(JSON_KEY, stream); 248 + while (isalnum((unsigned char)*p) || *p == '_' || *p == '$') fputc(*p++, stream); 249 + fputs(C_RESET, stream); 265 250 goto next; 266 251 } 267 - io_putc(*p++, stream); goto next; 252 + fputc(*p++, stream); goto next; 268 253 269 254 other: 270 - io_putc(*p++, stream); goto next; 255 + fputc(*p++, stream); goto next; 271 256 } 272 257 273 258 #undef KEYWORD 274 259 #undef EMIT_UNTIL 275 260 276 - void console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream) { 277 - if (color && !io_no_color) io_puts(color, stream); 261 + void print_repl_value(struct js *js, jsval_t val, FILE *stream) { 262 + if (vtype(val) == T_STR) { 263 + char *str = js_getstr(js, val, NULL); 264 + fprintf(stream, "%s'%s'%s\n", C(JSON_STRING), str ? str : "", C(C_RESET)); 265 + return; 266 + } 267 + 268 + char cbuf[512]; 269 + js_cstr_t cstr = js_to_cstr(js, val, cbuf, sizeof(cbuf)); 270 + 271 + if (vtype(val) == T_ERR) fprintf(stderr, "%s\n", cstr.ptr); else { 272 + print_value_colored(cstr.ptr, stream); 273 + fputc('\n', stream); 274 + } 275 + 276 + if (cstr.needs_free) free((void *)cstr.ptr); 277 + } 278 + 279 + jsval_t console_print(struct js *js, jsval_t *args, int nargs, const char *color, FILE *stream) { 280 + if (color && !io_no_color) fputs(color, stream); 278 281 279 282 for (int i = 0; i < nargs; i++) { 280 - const char *space = i == 0 ? "" : " "; 281 - io_puts(space, stream); 282 - if (vtype(args[i]) == T_STR) { 283 - char *str = js_getstr(js, args[i], NULL); 284 - io_print(str ? str : "", stream); 285 - } else { 286 - char cbuf_stack[512]; js_cstr_t cstr = js_to_cstr( 287 - js, args[i], cbuf_stack, sizeof(cbuf_stack) 288 - ); 289 - if (color && !io_no_color) io_puts(ANSI_RESET, stream); 283 + if (i) fputc(' ', stream); 284 + char cbuf[512]; 285 + js_cstr_t cstr = js_to_cstr(js, args[i], cbuf, sizeof(cbuf)); 286 + 287 + if (vtype(args[i]) == T_STR) io_print(cstr.ptr, stream); else { 288 + if (color && !io_no_color) fputs(C_RESET, stream); 290 289 print_value_colored(cstr.ptr, stream); 291 - if (color && !io_no_color) io_puts(color, stream); 292 - if (cstr.needs_free) free((void *)cstr.ptr); 290 + if (color && !io_no_color) fputs(color, stream); 293 291 } 292 + 293 + if (cstr.needs_free) free((void *)cstr.ptr); 294 294 } 295 295 296 - if (color && !io_no_color) io_puts(ANSI_RESET, stream); 297 - io_putc('\n', stream); 296 + if (color && !io_no_color) fputs(C_RESET, stream); 297 + fputc('\n', stream); 298 + 299 + return js_mkundef(); 298 300 } 299 301 300 302 static jsval_t js_console_log(struct js *js, jsval_t *args, int nargs) { 301 - console_print(js, args, nargs, NULL, stdout); 302 - return js_mkundef(); 303 + return console_print(js, args, nargs, NULL, stdout); 303 304 } 304 305 305 306 static jsval_t js_console_error(struct js *js, jsval_t *args, int nargs) { 306 - console_print(js, args, nargs, ANSI_RED, stderr); 307 - return js_mkundef(); 307 + return console_print(js, args, nargs, C_RED, stderr); 308 308 } 309 309 310 310 static jsval_t js_console_warn(struct js *js, jsval_t *args, int nargs) { 311 - console_print(js, args, nargs, ANSI_YELLOW, stderr); 312 - return js_mkundef(); 311 + return console_print(js, args, nargs, C_YELLOW, stderr); 313 312 } 314 313 315 314 static jsval_t js_console_assert(struct js *js, jsval_t *args, int nargs) { ··· 318 317 bool is_truthy = js_truthy(js, args[0]); 319 318 if (is_truthy) return js_mkundef(); 320 319 321 - io_puts("Assertion failed", stderr); 320 + fputs("Assertion failed", stderr); 322 321 if (nargs > 1) { 323 - io_puts(": ", stderr); 322 + fputs(": ", stderr); 324 323 console_print(js, args + 1, nargs - 1, NULL, stderr); 325 324 return js_mkundef(); 326 325 } 327 326 328 - io_putc('\n', stderr); 327 + fputc('\n', stderr); 329 328 return js_mkundef(); 330 329 } 331 330 332 331 static jsval_t js_console_trace(struct js *js, jsval_t *args, int nargs) { 333 - io_puts("Trace", stderr); 332 + fputs("Trace", stderr); 334 333 if (nargs > 0) { 335 - io_puts(": ", stderr); 334 + fputs(": ", stderr); 336 335 console_print(js, args, nargs, NULL, stderr); 337 - } else io_putc('\n', stderr); 336 + } else fputc('\n', stderr); 338 337 339 338 js_print_stack_trace(stderr); 340 339 return js_mkundef(); 341 340 } 342 341 343 342 static jsval_t js_console_info(struct js *js, jsval_t *args, int nargs) { 344 - console_print(js, args, nargs, ANSI_CYAN, stdout); 345 - return js_mkundef(); 343 + return console_print(js, args, nargs, C_CYAN, stdout); 346 344 } 347 345 348 346 static jsval_t js_console_debug(struct js *js, jsval_t *args, int nargs) { 349 - console_print(js, args, nargs, ANSI_MAGENTA, stdout); 350 - return js_mkundef(); 347 + return console_print(js, args, nargs, C_MAGENTA, stdout); 351 348 } 352 349 353 350 static jsval_t js_console_clear(struct js *js, jsval_t *args, int nargs) { ··· 508 505 v->visited[v->count++] = off; 509 506 } 510 507 511 - static void inspect_value(struct js *js, jsval_t val, FILE *stream, int depth, inspect_visited_t *visited) { 508 + void inspect_value(ant_t *js, jsval_t val, FILE *stream, int depth, inspect_visited_t *visited) { 512 509 int t = vtype(val); 513 510 514 511 if (t == T_UNDEF) { fprintf(stream, "undefined"); return; } ··· 532 529 533 530 if (t == T_OBJ || t == T_FUNC || t == T_PROMISE || t == T_ARR) { 534 531 if (depth > 10) fprintf(stream, "<%s @%" PRIu64 " ...>", get_type_name(t), (uint64_t)vdata(val)); 535 - else inspect_object_full(js, val, stream, depth, visited); 532 + else inspect_object(js, val, stream, depth, visited); 536 533 return; 537 534 } 538 535 ··· 544 541 fprintf(stream, "<%s rawtype=%d data=%" PRIu64 ">", get_type_name(t), vtype(val), (uint64_t)vdata(val)); 545 542 } 546 543 547 - static void inspect_object_full(struct js *js, jsval_t obj, FILE *stream, int depth, inspect_visited_t *visited) { 544 + void inspect_object(ant_t *js, jsval_t obj, FILE *stream, int depth, inspect_visited_t *visited) { 548 545 int type = vtype(obj); 549 546 jsoff_t obj_off = (jsoff_t)vdata(obj); 550 547
+1 -14
src/repl.c
··· 588 588 history_add(&history, multiline_buf); 589 589 590 590 jsval_t eval_result = js_eval(js, multiline_buf, multiline_len); 591 - js_run_event_loop(js); 592 - 593 - char cbuf_stack[512]; js_cstr_t cstr = js_to_cstr( 594 - js, eval_result, cbuf_stack, sizeof(cbuf_stack) 595 - ); 596 - 597 - if (vtype(eval_result) == T_ERR) 598 - fprintf(stderr, "%s\n", cstr.ptr); 599 - else if (vtype(eval_result) == T_STR) 600 - printf("%s\n", cstr.ptr ? cstr.ptr : ""); 601 - else { 602 - print_value_colored(cstr.ptr, stdout); 603 - printf("\n"); 604 - } if (cstr.needs_free) free((void *)cstr.ptr); 591 + js_run_event_loop(js); print_repl_value(js, eval_result, stdout); 605 592 606 593 free(multiline_buf); 607 594 multiline_buf = NULL;
+4
src/utils.c
··· 21 21 return val ? val : (c == '0' ? 0 : -1); 22 22 } 23 23 24 + char hex_char(int v) { 25 + return "0123456789abcdef"[v & 0x0f]; 26 + } 27 + 24 28 uint64_t hash_key(const char *key, size_t len) { 25 29 uint64_t hash = 14695981039346656037ULL; 26 30 size_t i = 0;
+14
vendor/aklomp-base64.wrap
··· 1 + [wrap-file] 2 + directory = base64-0.5.2 3 + source_url = https://github.com/aklomp/base64/archive/refs/tags/v0.5.2.tar.gz 4 + source_filename = base64-0.5.2.tar.gz 5 + source_hash = 723a0f9f4cf44cf79e97bcc315ec8f85e52eb104c8882942c3f2fba95acc080d 6 + source_fallback_url = https://wrapdb.mesonbuild.com/v2/aklomp-base64_0.5.2-1/get_source/base64-0.5.2.tar.gz 7 + patch_filename = aklomp-base64_0.5.2-1_patch.zip 8 + patch_url = https://wrapdb.mesonbuild.com/v2/aklomp-base64_0.5.2-1/get_patch 9 + patch_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/aklomp-base64_0.5.2-1/aklomp-base64_0.5.2-1_patch.zip 10 + patch_hash = 9805354b8c0333fe0123c10d8c62356ef1d0d67a2689a348d18f73bddc1e2b10 11 + wrapdb_version = 0.5.2-1 12 + 13 + [provide] 14 + dependency_names = base64