summaryrefslogtreecommitdiff
path: root/util/util.h
blob: 49f10d611bfba4670a7f65cbdef9126c31473afa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#ifdef __GNUC__
#define FATAL __attribute__((noreturn))
#else
#define FATAL
#endif

typedef uint8_t byte;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef long long vlong;
typedef unsigned long long uvlong;

typedef struct Htab Htab;
typedef struct Bitset Bitset;
typedef struct Optctx Optctx;
typedef struct Str Str;
typedef struct Strbuf Strbuf;

struct Htab {
	size_t nelt;
	size_t ndead;
	size_t sz;
	ulong (*hash)(void *k);
	int (*cmp)(void *a, void *b);
	void **keys;
	void **vals;
	ulong *hashes;
	char *dead;
};

struct Bitset {
	size_t nchunks;
	size_t *chunks;
};

struct Optctx {
	/* public exports */
	char *optarg;
	char **args;
	size_t nargs;

	/* internal state */
	char *optstr;
	char **optargs;
	size_t noptargs;
	size_t argidx;
	int optdone; /* seen -- */
	int finished;
	char *curarg;
};

struct Str {
	size_t len;
	char *buf;
};

struct Strbuf {
	char *buf;
	size_t sz;
	size_t len;
};

/* string buffer */
Strbuf *mksb();
char *sbfin(Strbuf *sb);
void sbputs(Strbuf *sb, char *s);
void sbputb(Strbuf *sb, char b);

/* bit sets */
Bitset *mkbs(void);
void bsfree(Bitset *bs);
Bitset *bsdup(Bitset *bs);
Bitset *bsclear(Bitset *bs);
void delbs(Bitset *bs);
void bsput(Bitset *bs, size_t elt);
void bsdel(Bitset *bs, size_t elt);
void bsunion(Bitset *a, Bitset *b);
void bsintersect(Bitset *a, Bitset *b);
void bsdiff(Bitset *a, Bitset *b);
int bseq(Bitset *a, Bitset *b);
int bsissubset(Bitset *set, Bitset *sub);
int bsisempty(Bitset *set);
int bsiter(Bitset *bs, size_t *elt);
size_t bsmax(Bitset *bs);
size_t bscount(Bitset *bs);

/* inline for speed */
static inline int bshas(Bitset *bs, size_t elt)
{
	size_t eltidx, eltshift;

	if (elt >= bs->nchunks * 8 * sizeof(size_t))
		return 0;
	eltidx = elt / (8 * sizeof(size_t));
	eltshift = elt % (8 * sizeof(size_t));
	return (bs->chunks[eltidx] & (1ULL << eltshift)) != 0;
}


/* hash tables */
Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2));
void htfree(Htab *ht);
int htput(Htab *ht, void *k, void *v);
void htdel(Htab *ht, void *k);
void *htget(Htab *ht, void *k);
int hthas(Htab *ht, void *k);
void **htkeys(Htab *ht, size_t *nkeys);
ulong strhash(void *key);
int streq(void *a, void *b);
ulong strlithash(void *key);
int strliteq(void *a, void *b);
ulong ptrhash(void *key);
int ptreq(void *a, void *b);
ulong inthash(uint64_t key);
int inteq(uint64_t a, uint64_t b);

/* util functions */
void *zalloc(size_t size);
void *xalloc(size_t size);
void *zrealloc(void *p, size_t oldsz, size_t size);
void *xrealloc(void *p, size_t size);
void die(char *msg, ...) FATAL;
char *strdupn(char *s, size_t len);
char *xstrdup(char *s);
char *strjoin(char *u, char *v);
void *memdup(void *mem, size_t len);
size_t bprintf(char *buf, size_t len, char *fmt, ...);

/* indented printf */
void indentf(int depth, char *fmt, ...);
void findentf(FILE *fd, int depth, char *fmt, ...);
void vfindentf(FILE *fd, int depth, char *fmt, va_list ap);

/* serializing/unserializing */
void be64(vlong v, byte buf[8]);
vlong host64(byte buf[8]);
void be32(long v, byte buf[4]);
long host32(byte buf[4]);
static inline intptr_t ptoi(void *p) { return (intptr_t)p; }
static inline void *itop(intptr_t i) { return (void *)i; }

void wrbuf(FILE *fd, void *buf, size_t sz);
void rdbuf(FILE *fd, void *buf, size_t sz);
char rdbyte(FILE *fd);
void wrbyte(FILE *fd, char val);
char rdbyte(FILE *fd);
void wrint(FILE *fd, long val);
long rdint(FILE *fd);
void wrstr(FILE *fd, char *val);
char *rdstr(FILE *fd);
void wrlenstr(FILE *fd, Str str);
void rdlenstr(FILE *fd, Str *str);
void wrflt(FILE *fd, double val);
double rdflt(FILE *fd);
void wrbool(FILE *fd, int val);
int rdbool(FILE *fd);

size_t max(size_t a, size_t b);
size_t min(size_t a, size_t b);
size_t align(size_t sz, size_t a);

/* list funcs */
/* hack; nl is void* b/c void*** is incompatible with T*** */
void lappend( void *l, size_t *len, void *n);
void lcat(void *dst, size_t *ndst, void *src, size_t nsrc);
void linsert(void *l, size_t *len, size_t idx, void *n);
void *lpop(void *l, size_t *len);
void ldel(void *l, size_t *len, size_t idx);
void lfree(void *l, size_t *len);

/* suffix replacement */
char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap);