aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2025-08-24 22:53:21 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2025-08-27 11:46:25 +0200
commit8e478e06c2c09e8d74fcaa6cca84f7db14d23265 (patch)
treec1913a33402c9b63f6cbc1288d05d1ef4c48bb7c /src
parentdd2c70e878e4bc7fcf26f33523a45f0d854a29e4 (diff)
improved testing & src cleanup
Diffstat (limited to 'src')
-rw-r--r--src/json.c23
-rw-r--r--src/testing.c28
2 files changed, 43 insertions, 8 deletions
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 <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;
+}