#include #include "strings.h" #include "types.h" /* Global string interning system */ static struct { char strings[MAX_STRINGS][MAX_STRING_LEN]; usize nstrings; bool initialized; } table = { 0 }; /* Initialize the global string interning system */ void strings_init(void) { table.nstrings = 0; table.initialized = true; } /* Process escape sequences in a string */ static usize escape(const char *src, usize src_len, char *dst, usize dst_size) { usize dst_idx = 0; for (usize i = 0; i < src_len && dst_idx < dst_size - 1; i++) { if (src[i] == '\\' && i + 1 < src_len) { switch (src[i + 1]) { case 'n': dst[dst_idx++] = '\n'; i++; /* Skip the next character */ break; case 't': dst[dst_idx++] = '\t'; i++; break; case 'r': dst[dst_idx++] = '\r'; i++; break; case '\\': dst[dst_idx++] = '\\'; i++; break; case '"': dst[dst_idx++] = '"'; i++; break; case '0': dst[dst_idx++] = '\0'; i++; break; default: /* Unknown escape sequence, keep the backslash */ dst[dst_idx++] = src[i]; break; } } else { dst[dst_idx++] = src[i]; } } dst[dst_idx] = '\0'; return dst_idx; } /* Find an existing interned string */ static const char *find(const char *str) { for (usize i = 0; i < table.nstrings; i++) { if (!strcmp(table.strings[i], str)) { return table.strings[i]; } } return NULL; } /* Intern a raw string without escape sequence processing */ static const char *strings_alloc_raw(const char *str) { /* Check if already interned */ const char *existing = find(str); if (existing) { return existing; } char *slot = table.strings[table.nstrings++]; strncpy(slot, str, MAX_STRING_LEN); return slot; } /* Intern a string with escape sequence processing */ const char *strings_alloc_len(const char *str, u16 len) { /* Process escape sequences first */ char escaped[MAX_STRING_LEN]; escape(str, len, escaped, MAX_STRING_LEN); return strings_alloc_raw(escaped); } /* Intern a string with escape sequence processing */ const char *strings_alloc(const char *str) { return strings_alloc_len(str, strlen(str)); }