diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/json.c | 23 | ||||
| -rw-r--r-- | src/testing.c | 28 |
2 files changed, 43 insertions, 8 deletions
@@ -186,22 +186,29 @@ parse_result parse_string(byte *src, uptr start_pos, uptr max_pos) { result.pos = start_pos + 1; // SIMD optimization: process 32 bytes at a time using AVX2 - bytex32 quote_mask = _mm256_set1_epi8('"'); + bytex32 quote_bytes = _mm256_set1_epi8('"'); for (; result.pos + 32 <= max_pos; result.pos += 32) { bytex32 chunk = _mm256_loadu_si256((bytex32 *)(src + result.pos)); - bytex32 cmp = _mm256_cmpeq_epi8(chunk, quote_mask); - i32 mask = _mm256_movemask_epi8(cmp); + i32 quote_mask = + _mm256_movemask_epi8(_mm256_cmpeq_epi8(chunk, quote_bytes)); - if (mask != 0) { - result.pos += stdc_trailing_zeros_ui(mask); - if (src[result.pos - 1] != '\\') break; + if (quote_mask != 0) { + result.pos += stdc_trailing_zeros_ui(quote_mask); + break; }; } // Fall back to original byte-by-byte processing for the remaining bytes - while (src[result.pos] != '"' && src[result.pos - 1] != '\\') { - result.pos++; + for (; result.pos < max_pos; result.pos++) { + if (src[result.pos] == '"') { + uptr backslash_count = 0; + while (backslash_count < result.pos && + src[result.pos - backslash_count - 1] == '\\') { + backslash_count++; + } + if (!(backslash_count & 1)) break; + } } assert_parse(src[result.pos] == '"', "invalid string end", src, result.pos); diff --git a/src/testing.c b/src/testing.c new file mode 100644 index 0000000..937d2dc --- /dev/null +++ b/src/testing.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +#include "../include/assert.h" +#include "../include/memory.h" +#include "../include/str.h" +#include "../include/testing.h" +#include "../include/types.h" + +MemoryFile load_file(Arena *a, const char *filename) { + FILE *file = fopen(filename, "rb"); + assert(file != 0, "failed to open file: %s", filename); + MemoryFile mem_file = {0}; + + // Get file size + fseek(file, 0, SEEK_END); + mem_file.size = ftell(file); + fseek(file, 0, SEEK_SET); + + mem_file.content = new(a, byte, mem_file.size + 1); + + size bytes_read = fread(mem_file.content, 1, mem_file.size, file); + assert(bytes_read == mem_file.size, "failed to read entire file: %s", + filename); + + mem_file.content[mem_file.size] = '\0'; // Null terminate + fclose(file); + return mem_file; +} |
