struct list { struct list *prev, *next; }; struct array { void *val; size_t len, cap; }; struct treenode { unsigned long long key; void *child[2]; int height; bool new; /* set by treeinsert if this node was newly allocated */ }; extern char *argv0; #define LEN(a) (sizeof(a) / sizeof((a)[0])) #define ALIGNDOWN(x, n) ((x) & -(n)) #define ALIGNUP(x, n) ALIGNDOWN((x) + (n) - 1, n) void warn(const char *, ...); void fatal(const char *fmt, ...); void *reallocarray(void *, size_t, size_t); void *xreallocarray(void *, size_t, size_t); void *xmalloc(size_t); char *progname(char *, char *); void listinsert(struct list *, struct list *); void listremove(struct list *); #define listelement(list, type, member) (type *)((char *)list - offsetof(type, member)) void *arrayadd(struct array *, size_t); void arrayaddptr(struct array *, void *); void arrayaddbuf(struct array *, const void *, size_t); void *arraylast(struct array *, size_t); #define arrayforeach(a, m) for (m = (a)->val; m != (void *)((char *)(a)->val + (a)->len); ++m) /* map */ struct map { size_t len, cap; struct mapkey *keys; void **vals; }; struct mapkey { unsigned long hash; const void *str; size_t len; }; void mapkey(struct mapkey *, const void *, size_t); void mapinit(struct map *, size_t); void mapfree(struct map *, void(void *)); void **mapput(struct map *, struct mapkey *); void *mapget(struct map *, struct mapkey *); /* tree */ void *treeinsert(void **, unsigned long long, size_t);