From 8e478e06c2c09e8d74fcaa6cca84f7db14d23265 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Sun, 24 Aug 2025 22:53:21 +0200 Subject: improved testing & src cleanup --- src/json.c | 23 +++++++++++++++-------- src/testing.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 src/testing.c (limited to 'src') diff --git a/src/json.c b/src/json.c index 8531d48..d3f510f 100644 --- a/src/json.c +++ b/src/json.c @@ -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 + +#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; +} -- cgit v1.3