aboutsummaryrefslogtreecommitdiffhomepage
path: root/common.h
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
committerlemon <lsof@mailbox.org>2025-12-15 22:39:52 +0100
commit302e24671942051d70707586cf8c605a5815edac (patch)
tree51e25fb6cd7e828c82ce5f17ffc775117121acee /common.h
parentc6c0f2ef35175075e91169113cfe856f29b3eb9a (diff)
create distinct interned string type
Interned strings are used pervasively, so it's a good idea to add a layer of type safety to differentiate them from general cstrs and avoid potential bugs from comparing non-interned and interned strings. Not that that's happened so far that I can remember, but it could. I'm 90% sure it's legal to alias `struct {char c;}` pointers with `char` pointers. This specific typedef gives type safety but with a simple one-way `internstr -> const char *` typecast (with `&istr->c`). Converting the other way around is more intentional: a straight up cast `(internstr)cstr` which sticks out as unchecked and probably wrong, or calling the intern(cstr) function, which is the right way.
Diffstat (limited to 'common.h')
-rw-r--r--common.h7
1 files changed, 4 insertions, 3 deletions
diff --git a/common.h b/common.h
index 061c379..3d2166b 100644
--- a/common.h
+++ b/common.h
@@ -179,7 +179,8 @@ void free(void *);
#define xrealloc(p,n) xrealloc(p, n, __func__)
/* string interning */
-const char *intern(const char *);
+typedef const struct internstr {char c;} *internstr;
+internstr intern(const char *);
/* growable buffer that stores its capacity in the allocated memory */
#define xbnew_(n) (void *)(1 + (size_t *)xcalloc(sizeof(size_t) + (n)))
@@ -404,8 +405,8 @@ struct memfile *getfile(int id);
void addfileline(int id, uint off);
void setfileline(int id, uint off, int line, const char *file);
const char *getfilepos(int *line, int *col, int id, uint off);
-bool isoncefile(int id, const char **guard);
-void markfileonce(int id, const char *guard);
+bool isoncefile(int id, internstr *guard);
+void markfileonce(int id, internstr guard);
void markfileseen(int id);
bool isfileseen(int id);
void closefile(int id);