summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-02-22 11:17:40 -0800
committerOri Bernstein <ori@eigenstate.org>2016-02-22 11:17:40 -0800
commit100ed8406343f027aa442e79fe59c653c8fc02a4 (patch)
tree7f0a173b62530ce94cd9a036dc6badf0d7ad2f3b /parse
parent74707c5daf432fe8310312021eb775e7a716dbe3 (diff)
downloadmc-100ed8406343f027aa442e79fe59c653c8fc02a4.tar.gz
Extract util functions into separate dir from parse/
Diffstat (limited to 'parse')
-rw-r--r--parse/Makefile30
-rw-r--r--parse/bitset.c1
-rw-r--r--parse/dump.c1
-rw-r--r--parse/fold.c1
-rw-r--r--parse/gram.y1
-rw-r--r--parse/htab.c288
-rw-r--r--parse/infer.c1
-rw-r--r--parse/names.c1
-rw-r--r--parse/node.c1
-rw-r--r--parse/parse.h135
-rw-r--r--parse/specialize.c1
-rw-r--r--parse/stab.c1
-rw-r--r--parse/tok.c1
-rw-r--r--parse/type.c1
-rw-r--r--parse/use.c1
-rw-r--r--parse/util.c553
16 files changed, 34 insertions, 984 deletions
diff --git a/parse/Makefile b/parse/Makefile
index 1eaac98..4df4b0c 100644
--- a/parse/Makefile
+++ b/parse/Makefile
@@ -1,21 +1,23 @@
LIB=libparse.a
-OBJ=bitset.o \
- dump.o \
- fold.o \
- gram.o \
- htab.o \
- infer.o \
- names.o \
- node.o \
- specialize.o \
- stab.o \
- tok.o \
- type.o \
- use.o \
- util.o
+OBJ=\
+ bitset.o \
+ dump.o \
+ err.o \
+ fold.o \
+ gram.o \
+ infer.o \
+ names.o \
+ node.o \
+ specialize.o \
+ stab.o \
+ tok.o \
+ type.o \
+ use.o \
GENHDR=gram.h
CLEAN=gram.c gram.h
+DEPS=../util/libutil.a
+
include ../mk/lexyacc.mk
include ../mk/c.mk
diff --git a/parse/bitset.c b/parse/bitset.c
index ac72f6e..ea3c398 100644
--- a/parse/bitset.c
+++ b/parse/bitset.c
@@ -6,6 +6,7 @@
#include <limits.h>
#include <string.h>
+#include "util.h"
#include "parse.h"
#define Sizetbits (CHAR_BIT * sizeof(size_t)) /* used in graph reprs */
diff --git a/parse/dump.c b/parse/dump.c
index c9eb139..7cb7713 100644
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
/* outputs a fully qualified name */
diff --git a/parse/fold.c b/parse/fold.c
index 8edd836..8c58312 100644
--- a/parse/fold.c
+++ b/parse/fold.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
static int getintlit(Node *n, vlong *v)
diff --git a/parse/gram.y b/parse/gram.y
index 732ad9b..5509e90 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -14,6 +14,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
diff --git a/parse/htab.c b/parse/htab.c
deleted file mode 100644
index a8f3633..0000000
--- a/parse/htab.c
+++ /dev/null
@@ -1,288 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <inttypes.h>
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-
-#include "parse.h"
-
-#define Initsz 16
-
-/* Creates a new empty hash table, using 'hash' as the
- * hash funciton, and 'cmp' to verify that there are no
- * hash collisions. */
-Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2))
-{
- Htab *ht;
-
- ht = xalloc(sizeof(Htab));
- ht->nelt = 0;
- ht->ndead = 0;
- ht->sz = Initsz;
- ht->hash = hash;
- ht->cmp = cmp;
- ht->keys = zalloc(Initsz * sizeof(void *));
- ht->vals = zalloc(Initsz * sizeof(void *));
- ht->hashes = zalloc(Initsz * sizeof(void *));
- ht->dead = zalloc(Initsz * sizeof(char));
-
- return ht;
-}
-
-/* Frees a hash table. Passing this function
- * NULL is a no-op. */
-void htfree(Htab *ht)
-{
- if (!ht)
- return;
- free(ht->keys);
- free(ht->vals);
- free(ht->hashes);
- free(ht->dead);
- free(ht);
-}
-
-/* Offsets the hash so that '0' can be
- * used as a 'no valid value */
-static ulong hash(Htab *ht, void *k)
-{
- ulong h;
- h = ht->hash(k);
- if (h == 0)
- return 1;
- else
- return h;
-}
-
-/* Resizes the hash table by copying all
- * the old keys into the right slots in a
- * new table. */
-static void grow(Htab *ht, int sz)
-{
- void **oldk;
- void **oldv;
- ulong *oldh;
- char *oldd;
- int oldsz;
- int i;
-
- oldk = ht->keys;
- oldv = ht->vals;
- oldh = ht->hashes;
- oldd = ht->dead;
- oldsz = ht->sz;
-
- ht->nelt = 0;
- ht->ndead = 0;
- ht->sz = sz;
- ht->keys = zalloc(sz * sizeof(void *));
- ht->vals = zalloc(sz * sizeof(void *));
- ht->hashes = zalloc(sz * sizeof(void *));
- ht->dead = zalloc(sz * sizeof(void *));
-
- for (i = 0; i < oldsz; i++)
- if (oldh[i] && !oldd[i])
- htput(ht, oldk[i], oldv[i]);
-
- free(oldh);
- free(oldk);
- free(oldv);
- free(oldd);
-}
-
-/* Inserts 'k' into the hash table, possibly
- * killing any previous key that compares
- * as equal. */
-int htput(Htab *ht, void *k, void *v)
-{
- int i;
- ulong h;
- int di;
-
- di = 0;
- h = hash(ht, k);
- i = h & (ht->sz - 1);
- while (ht->hashes[i] && !ht->dead[i]) {
- /* second insertion overwrites first. nb, we shouldn't touch the
- * keys for dead values */
- if (ht->hashes[i] == h) {
- if (ht->dead[i])
- break;
- else if (ht->cmp(ht->keys[i], k))
- goto conflicted;
- }
- di++;
- i = (h + di) & (ht->sz - 1);
- }
- ht->nelt++;
-conflicted:
- if (ht->dead[i])
- ht->ndead--;
- ht->hashes[i] = h;
- ht->keys[i] = k;
- ht->vals[i] = v;
- ht->dead[i] = 0;
-
- if (ht->sz < ht->nelt * 2)
- grow(ht, ht->sz * 2);
- if (ht->sz < ht->ndead * 4)
- grow(ht, ht->sz);
- return 1;
-}
-
-/* Finds the index that we would insert
- * the key into */
-static ssize_t htidx(Htab *ht, void *k)
-{
- ssize_t i;
- ulong h;
- int di;
-
- di = 0;
- h = hash(ht, k);
- i = h & (ht->sz - 1);
- while (ht->hashes[i] && !ht->dead[i] && ht->hashes[i] != h) {
-searchmore:
- di++;
- i = (h + di) & (ht->sz - 1);
- }
- if (!ht->hashes[i])
- return -1;
- if ((ht->hashes[i] == h && ht->dead[i]) || !ht->cmp(ht->keys[i], k))
- goto searchmore; /* collision */
- return i;
-}
-
-/* Looks up a key, returning NULL if
- * the value is not present. Note,
- * if NULL is a valid value, you need
- * to check with hthas() to see if it's
- * not there */
-void *htget(Htab *ht, void *k)
-{
- ssize_t i;
-
- i = htidx(ht, k);
- if (i < 0)
- return NULL;
- else
- return ht->vals[i];
-}
-
-void htdel(Htab *ht, void *k)
-{
- ssize_t i;
-
- i = htidx(ht, k);
- if (i < 0)
- return;
- assert(!ht->dead[i]);
- assert(ht->hashes[i]);
- ht->dead[i] = 1;
- ht->nelt--;
- ht->ndead++;
-}
-
-/* Tests for 'k's presence in 'ht' */
-int hthas(Htab *ht, void *k) { return htidx(ht, k) >= 0; }
-
-/* Returns a list of all keys in the hash
- * table, storing the size of the returned
- * array in 'nkeys'. NB: the value returned
- * is allocated on the heap, and it is the
- * job of the caller to free it */
-void **htkeys(Htab *ht, size_t *nkeys)
-{
- void **k;
- size_t i, j;
-
- j = 0;
- k = xalloc(sizeof(void *) * ht->nelt);
- for (i = 0; i < ht->sz; i++)
- if (ht->hashes[i] && !ht->dead[i])
- k[j++] = ht->keys[i];
- *nkeys = ht->nelt;
- return k;
-}
-
-ulong strhash(void *_s)
-{
- char *s;
- ulong h;
- ulong g;
-
- s = _s;
- h = 0;
- while (s && *s) {
- h = ((h << 4) + *s++);
-
- if ((g = (h & 0xF0000000)))
- h ^= (g >> 24);
-
- h &= ~g;
- }
- return h;
-}
-
-int streq(void *a, void *b)
-{
- if (a == b)
- return 1;
- if (a == NULL || b == NULL)
- return 0;
- return !strcmp(a, b);
-}
-
-ulong strlithash(void *_s)
-{
- Str *s;
- ulong h, g, i;
-
- s = _s;
- h = 0;
- for (i = 0; i < s->len; i++) {
- h = ((h << 4) + s->buf[i]);
-
- if ((g = (h & 0xF0000000)))
- h ^= (g >> 24);
-
- h &= ~g;
- }
- return h;
-}
-
-int strliteq(void *_a, void *_b)
-{
- Str *a, *b;
-
- a = _a;
- b = _b;
- if (a == b)
- return 1;
- if (a == NULL || b == NULL)
- return 0;
- if (a->len != b->len)
- return 0;
- return !memcmp(a, b, a->len);
-}
-
-ulong ptrhash(void *key) { return inthash((uintptr_t)key); }
-
-ulong inthash(uint64_t key)
-{
- uintptr_t h;
-
- h = (uintptr_t)key;
- h *= 357913941;
- h ^= h << 24;
- h += ~357913941;
- h ^= h >> 31;
- h ^= h << 31;
- return h;
-}
-
-int inteq(uint64_t a, uint64_t b) { return a == b; }
-
-int ptreq(void *a, void *b) { return a == b; }
diff --git a/parse/infer.c b/parse/infer.c
index 4f4809a..350ea5e 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -12,6 +12,7 @@
#include <unistd.h>
#include <assert.h>
+#include "util.h"
#include "parse.h"
typedef struct Inferstate Inferstate;
diff --git a/parse/names.c b/parse/names.c
index 31f2b4d..f1da72c 100644
--- a/parse/names.c
+++ b/parse/names.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
char *opstr[] = {
diff --git a/parse/node.c b/parse/node.c
index 038eec7..59bfcd2 100644
--- a/parse/node.c
+++ b/parse/node.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
Node **nodes;
diff --git a/parse/parse.h b/parse/parse.h
index 55b530f..1d3599e 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -1,23 +1,6 @@
-#ifdef __GNUC__
-#define FATAL __attribute__((noreturn))
-#else
-#define FATAL
-#endif
-
#define Abiversion 10
-typedef uint8_t byte;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-typedef long long vlong;
-typedef unsigned long long uvlong;
-
typedef struct Srcloc Srcloc;
-typedef struct Bitset Bitset;
-typedef struct Optctx Optctx;
-typedef struct Strbuf Strbuf;
-typedef struct Htab Htab;
-typedef struct Str Str;
typedef struct Tysubst Tysubst;
typedef struct Tok Tok;
@@ -71,22 +54,11 @@ typedef enum {
#define Zloc ((Srcloc){-1, 0})
-struct Strbuf {
- char *buf;
- size_t sz;
- size_t len;
-};
-
struct Srcloc {
int line;
int file;
};
-struct Str {
- size_t len;
- char *buf;
-};
-
typedef enum {
Visintern,
Visexport,
@@ -99,22 +71,6 @@ typedef enum {
Dclextern = 1 << 1,
} Dclflags;
-struct Bitset {
- size_t nchunks;
- size_t *chunks;
-};
-
-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 Tok {
int type;
@@ -381,22 +337,6 @@ struct Node {
};
};
-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;
-};
-
/* globals */
extern Srcloc curloc;
extern char *filename;
@@ -451,24 +391,9 @@ static inline int bshas(Bitset *bs, size_t elt)
0;
}
-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);
/* useful key types */
int liteq(Node *a, Node *b);
int litvaleq(Node *a, Node *b);
-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);
ulong tyhash(void *t);
int tyeq(void *a, void *b);
ulong namehash(void *t);
@@ -476,26 +401,17 @@ int nameeq(void *a, void *b);
ulong nsnamehash(void *t);
int nsnameeq(void *a, void *b);
-/* util functions */
+/* parsing etc */
+void tokinit(char *file);
+int yylex(void);
+int yyparse(void);
+
+/* locations */
char *fname(Srcloc l);
int lnum(Srcloc l);
-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;
void fatal(Node *n, char *fmt, ...) FATAL;
void lfatal(Srcloc l, char *fmt, ...) FATAL;
void lfatalv(Srcloc l, char *fmt, va_list ap) FATAL;
-char *strdupn(char *s, size_t len);
-char *strjoin(char *u, char *v);
-void *memdup(void *mem, size_t len);
-size_t bprintf(char *buf, size_t len, char *fmt, ...);
-
-/* parsing etc */
-void tokinit(char *file);
-int yylex(void);
-int yyparse(void);
/* stab creation */
Stab *mkstab(int isfunc);
@@ -665,48 +581,9 @@ void *lpop(void *l, size_t *len);
void ldel(void *l, size_t *len, size_t idx);
void lfree(void *l, size_t *len);
-/* 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);
-
-/* string buffer */
-Strbuf *mksb();
-char *sbfin(Strbuf *sb);
-void sbputs(Strbuf *sb, char *s);
-void sbputb(Strbuf *sb, char b);
-
/* suffix replacement */
char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap);
-/* 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);
-
/* Options to control the compilation */
extern char debugopt[128];
extern int asmonly;
diff --git a/parse/specialize.c b/parse/specialize.c
index 72f922f..4df9729 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
static Node *specializenode(Node *g, Tysubst *tsmap);
diff --git a/parse/stab.c b/parse/stab.c
index 2d55f99..f23b1fd 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
/* Allows us to look up types/traits by name nodes */
diff --git a/parse/tok.c b/parse/tok.c
index 17fef0f..7ab2874 100644
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -11,6 +11,7 @@
#include <errno.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
#include "gram.h"
diff --git a/parse/type.c b/parse/type.c
index d711b6b..ea1c2ea 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -11,6 +11,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
typedef struct Typename Typename;
diff --git a/parse/use.c b/parse/use.c
index 3ab6ff5..f0c154c 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <unistd.h>
+#include "util.h"
#include "parse.h"
static void wrtype(FILE *fd, Type *val);
diff --git a/parse/util.c b/parse/util.c
deleted file mode 100644
index 33c2e0e..0000000
--- a/parse/util.c
+++ /dev/null
@@ -1,553 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <inttypes.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include "parse.h"
-
-/* malloc wrappers */
-void *zalloc(size_t sz)
-{
- void *mem;
-
- mem = calloc(1, sz);
- if (!mem && sz)
- die("Out of memory");
- return mem;
-}
-
-void *xalloc(size_t sz)
-{
- void *mem;
-
- mem = malloc(sz);
- if (!mem && sz)
- die("Out of memory");
- return mem;
-}
-
-void *zrealloc(void *mem, size_t oldsz, size_t sz)
-{
- char *p;
-
- p = xrealloc(mem, sz);
- if (sz > oldsz)
- memset(&p[oldsz], 0, sz - oldsz);
- return p;
-}
-
-void *xrealloc(void *mem, size_t sz)
-{
- mem = realloc(mem, sz);
- if (!mem && sz)
- die("Out of memory");
- return mem;
-}
-
-/* errors */
-void die(char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- va_end(ap);
- abort();
-}
-
-void fatal(Node *n, char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- lfatalv(n->loc, msg, ap);
- va_end(ap);
-}
-
-void lfatal(Srcloc l, char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- lfatalv(l, msg, ap);
- va_end(ap);
-}
-
-void lfatalv(Srcloc l, char *msg, va_list ap)
-{
- fprintf(stdout, "%s:%d: ", fname(l), lnum(l));
- vfprintf(stdout, msg, ap);
- fprintf(stdout, "\n");
- exit(1);
-}
-
-/* Some systems don't have strndup. */
-char *strdupn(char *s, size_t len)
-{
- char *ret;
-
- ret = xalloc(len + 1);
- memcpy(ret, s, len);
- ret[len] = '\0';
- return ret;
-}
-
-char *strjoin(char *u, char *v)
-{
- size_t n;
- char *s;
-
- n = strlen(u) + strlen(v) + 1;
- s = xalloc(n);
- bprintf(s, n + 1, "%s%s", u, v);
- return s;
-}
-
-void *memdup(void *mem, size_t len)
-{
- void *ret;
-
- if (!mem)
- return NULL;
- ret = xalloc(len);
- return memcpy(ret, mem, len);
-}
-
-/* lists */
-void lappend(void *l, size_t *len, void *n)
-{
- void ***pl;
-
- pl = l;
- *pl = xrealloc(*pl, (*len + 1) * sizeof(void *));
- (*pl)[*len] = n;
- (*len)++;
-}
-
-void *lpop(void *l, size_t *len)
-{
- void ***pl;
- void *v;
-
- pl = l;
- (*len)--;
- v = (*pl)[*len];
- *pl = xrealloc(*pl, *len * sizeof(void *));
- return v;
-}
-
-void linsert(void *p, size_t *len, size_t idx, void *v)
-{
- void ***pl, **l;
-
- pl = p;
- *pl = xrealloc(*pl, (*len + 1) * sizeof(void *));
- l = *pl;
-
- memmove(&l[idx + 1], &l[idx], (*len - idx) * sizeof(void *));
- l[idx] = v;
- (*len)++;
-}
-
-void ldel(void *p, size_t *len, size_t idx)
-{
- void ***pl, **l;
-
- assert(p != NULL);
- assert(idx < *len);
- pl = p;
- l = *pl;
- memmove(&l[idx], &l[idx + 1], (*len - idx - 1) * sizeof(void *));
- (*len)--;
- *pl = xrealloc(l, *len * sizeof(void *));
-}
-
-void lcat(void *dst, size_t *ndst, void *src, size_t nsrc)
-{
- size_t i;
- void ***d, **s;
-
- d = dst;
- s = src;
- for (i = 0; i < nsrc; i++)
- lappend(d, ndst, s[i]);
-}
-
-void lfree(void *l, size_t *len)
-{
- void ***pl;
-
- assert(l != NULL);
- pl = l;
- free(*pl);
- *pl = NULL;
- *len = 0;
-}
-
-/* endian packing */
-void be64(vlong v, byte buf[8])
-{
- buf[0] = (v >> 56) & 0xff;
- buf[1] = (v >> 48) & 0xff;
- buf[2] = (v >> 40) & 0xff;
- buf[3] = (v >> 32) & 0xff;
- buf[4] = (v >> 24) & 0xff;
- buf[5] = (v >> 16) & 0xff;
- buf[6] = (v >> 8) & 0xff;
- buf[7] = (v >> 0) & 0xff;
-}
-
-vlong host64(byte buf[8])
-{
- vlong v = 0;
-
- v |= ((vlong)buf[0] << 56LL);
- v |= ((vlong)buf[1] << 48LL);
- v |= ((vlong)buf[2] << 40LL);
- v |= ((vlong)buf[3] << 32LL);
- v |= ((vlong)buf[4] << 24LL);
- v |= ((vlong)buf[5] << 16LL);
- v |= ((vlong)buf[6] << 8LL);
- v |= ((vlong)buf[7] << 0LL);
- return v;
-}
-
-void be32(long v, byte buf[4])
-{
- buf[0] = (v >> 24) & 0xff;
- buf[1] = (v >> 16) & 0xff;
- buf[2] = (v >> 8) & 0xff;
- buf[3] = (v >> 0) & 0xff;
-}
-
-long host32(byte buf[4])
-{
- int32_t v = 0;
- v |= ((long)buf[0] << 24);
- v |= ((long)buf[1] << 16);
- v |= ((long)buf[2] << 8);
- v |= ((long)buf[3] << 0);
- return v;
-}
-
-void wrbuf(FILE *fd, void *p, size_t sz)
-{
- size_t n;
- char *buf;
-
- n = 0;
- buf = p;
- while (n < sz) {
- n += fwrite(buf + n, 1, sz - n, fd);
- if (feof(fd))
- die("Unexpected EOF");
- if (ferror(fd))
- die("Error writing");
- }
-}
-
-void rdbuf(FILE *fd, void *buf, size_t sz)
-{
- size_t n;
-
- n = sz;
- while (n > 0) {
- n -= fread(buf, 1, n, fd);
- if (feof(fd))
- die("Unexpected EOF");
- if (ferror(fd))
- die("Error writing");
- }
-}
-
-void wrbyte(FILE *fd, char val)
-{
- if (fputc(val, fd) == EOF)
- die("Unexpected EOF");
-}
-
-char rdbyte(FILE *fd)
-{
- int c;
- c = fgetc(fd);
- if (c == EOF)
- die("Unexpected EOF");
- return c;
-}
-
-void wrint(FILE *fd, long val)
-{
- byte buf[4];
- be32(val, buf);
- wrbuf(fd, buf, 4);
-}
-
-long rdint(FILE *fd)
-{
- byte buf[4];
- rdbuf(fd, buf, 4);
- return host32(buf);
-}
-
-void wrstr(FILE *fd, char *val)
-{
- size_t len;
-
- if (!val) {
- wrint(fd, -1);
- } else {
- wrint(fd, strlen(val));
- len = strlen(val);
- wrbuf(fd, val, len);
- }
-}
-
-char *rdstr(FILE *fd)
-{
- ssize_t len;
- char *s;
-
- len = rdint(fd);
- if (len == -1) {
- return NULL;
- } else {
- s = xalloc(len + 1);
- rdbuf(fd, s, len);
- s[len] = '\0';
- return s;
- }
-}
-
-void wrlenstr(FILE *fd, Str str)
-{
- wrint(fd, str.len);
- wrbuf(fd, str.buf, str.len);
-}
-
-void rdlenstr(FILE *fd, Str *str)
-{
- str->len = rdint(fd);
- str->buf = xalloc(str->len + 1);
- rdbuf(fd, str->buf, str->len);
- str->buf[str->len] = '\0';
-}
-
-void wrflt(FILE *fd, double val)
-{
- byte buf[8];
- /* Assumption: We have 'val' in 64 bit IEEE format */
- union {
- uvlong ival;
- double fval;
- } u;
-
- u.fval = val;
- be64(u.ival, buf);
- wrbuf(fd, buf, 8);
-}
-
-double rdflt(FILE *fd)
-{
- byte buf[8];
- union {
- uvlong ival;
- double fval;
- } u;
-
- if (fread(buf, 8, 1, fd) < 8)
- die("Unexpected EOF");
- u.ival = host64(buf);
- return u.fval;
-}
-
-size_t bprintf(char *buf, size_t sz, char *fmt, ...)
-{
- va_list ap;
- size_t n;
-
- va_start(ap, fmt);
- n = vsnprintf(buf, sz, fmt, ap);
- if (n >= sz)
- n = sz;
- va_end(ap);
-
- return n;
-}
-
-void wrbool(FILE *fd, int val) { wrbyte(fd, val); }
-
-int rdbool(FILE *fd) { return rdbyte(fd); }
-
-char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap)
-{
- size_t slen, suflen, swaplen;
-
- slen = strlen(s);
- suflen = strlen(suf);
- swaplen = strlen(swap);
-
- if (slen < suflen)
- return NULL;
- if (slen + swaplen >= sz)
- die("swapsuffix: buf too small");
-
- buf[0] = '\0';
- /* if we have matching suffixes */
- if (suflen < slen && !strcmp(suf, &s[slen - suflen])) {
- strncat(buf, s, slen - suflen);
- strncat(buf, swap, swaplen);
- } else {
- bprintf(buf, sz, "%s%s", s, swap);
- }
-
- return buf;
-}
-
-size_t max(size_t a, size_t b)
-{
- if (a > b)
- return a;
- else
- return b;
-}
-
-size_t min(size_t a, size_t b)
-{
- if (a < b)
- return a;
- else
- return b;
-}
-
-size_t align(size_t sz, size_t a)
-{
- /* align to 0 just returns sz */
- if (a == 0)
- return sz;
- return (sz + a - 1) & ~(a - 1);
-}
-
-void indentf(int depth, char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfindentf(stdout, depth, fmt, ap);
- va_end(ap);
-}
-
-void findentf(FILE *fd, int depth, char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfindentf(fd, depth, fmt, ap);
- va_end(ap);
-}
-
-void vfindentf(FILE *fd, int depth, char *fmt, va_list ap)
-{
- ssize_t i;
-
- for (i = 0; i < depth; i++)
- fprintf(fd, "\t");
- vfprintf(fd, fmt, ap);
-}
-
-static int optinfo(Optctx *ctx, char arg, int *take, int *mand)
-{
- char *s;
-
- for (s = ctx->optstr; *s != '\0'; s++) {
- if (*s == arg) {
- s++;
- if (*s == ':') {
- *take = 1;
- *mand = 1;
- return 1;
- } else if (*s == '?') {
- *take = 1;
- *mand = 0;
- return 1;
- } else {
- *take = 0;
- *mand = 0;
- return 1;
- }
- }
- }
- return 0;
-}
-
-static int findnextopt(Optctx *ctx)
-{
- size_t i;
-
- for (i = ctx->argidx + 1; i < ctx->noptargs; i++) {
- if (ctx->optargs[i][0] == '-')
- goto foundopt;
- else
- lappend(&ctx->args, &ctx->nargs, ctx->optargs[i]);
- }
- ctx->finished = 1;
- return 0;
-foundopt:
- ctx->argidx = i;
- ctx->curarg = ctx->optargs[i] + 1; /* skip initial '-' */
- return 1;
-}
-
-void optinit(Optctx *ctx, char *optstr, char **optargs, size_t noptargs)
-{
- ctx->args = NULL;
- ctx->nargs = 0;
-
- ctx->optstr = optstr;
- ctx->optargs = optargs;
- ctx->noptargs = noptargs;
- ctx->optdone = 0;
- ctx->finished = 0;
- ctx->argidx = 0;
- ctx->curarg = "";
- findnextopt(ctx);
-}
-
-int optnext(Optctx *ctx)
-{
- int take, mand;
- int c;
-
- c = *ctx->curarg;
- ctx->curarg++;
- if (!optinfo(ctx, c, &take, &mand)) {
- printf("Unexpected argument %c\n", *ctx->curarg);
- exit(1);
- }
-
- ctx->optarg = NULL;
- if (take) {
- if (*ctx->curarg) {
- ctx->optarg = ctx->curarg;
- ctx->curarg += strlen(ctx->optarg);
- } else if (ctx->argidx < ctx->noptargs - 1) {
- ctx->optarg = ctx->optargs[ctx->argidx + 1];
- ctx->argidx++;
- } else if (mand) {
- fprintf(stderr, "expected argument for %c\n", *ctx->curarg);
- }
- findnextopt(ctx);
- } else {
- if (*ctx->curarg == '\0')
- findnextopt(ctx);
- }
- return c;
-}
-
-int optdone(Optctx *ctx) { return *ctx->curarg == '\0' && ctx->finished; }