/* 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); }
static void strlabel(Cfg *cfg, char *lbl, Bb *bb) { if (htget(cfg->lblmap, lbl) != bb) { htput(cfg->lblmap, lbl, bb); lappend(&bb->lbls, &bb->nlbls, lbl); } }
static void fixtypemappings(Stab *st) { size_t i; Type *t, *old; /* * merge duplicate definitions. * This allows us to compare named types by id, instead * of doing a deep walk through the type. This ability is * depended on when we do type inference. */ for (i = 0; i < ntypefixdest; i++) { t = htget(tidmap, itop(typefixid[i])); if (!t) die("Unable to find type for id %zd\n", typefixid[i]); *typefixdest[i] = t; } for (i = 0; i < ntypefixdest; i++) { old = *typefixdest[i]; if (old->type == Tyname || old->type == Tygeneric) { t = htget(tydedup, old); if (!t) { t = old; htput(tydedup, old, old); } *typefixdest[i] = t; } } /* check for duplicate type definitions */ for (i = 0; i < ntypefixdest; i++) { t = htget(tidmap, itop(typefixid[i])); if ((t->type != Tyname && t->type != Tygeneric) || t->issynth) continue; old = htget(tydedup, t); if (old && !tyeq(t, old) && !isspecialization(t, old)) lfatal(t->loc, "Duplicate definition of type %s on %s:%d", tystr(old), file->file.files[old->loc.file], old->loc.line); } for (i = 0; i < ntypefixdest; i++) lfree(&typefixdest, &ntypefixdest); lfree(&typefixid, &ntypefixid); }
static Node *simpblob(Simp *s, Node *blob, Node ***l, size_t *nl) { Node *n, *d, *r; char lbl[128]; n = mkname(blob->line, genlblstr(lbl, 128)); d = mkdecl(blob->line, n, blob->expr.type); r = mkexpr(blob->line, Ovar, n, NULL); d->decl.init = blob; d->decl.type = blob->expr.type; d->decl.isconst = 1; htput(s->globls, d, strdup(lbl)); r->expr.did = d->decl.did; r->expr.type = blob->expr.type; r->expr.isconst = 1; lappend(l, nl, d); return r; }
Trait *traitunpickle(FILE *fd) { Trait *tr; size_t i, n; intptr_t uid; /* create an empty trait */ tr = mktrait(Zloc, NULL, NULL, NULL, 0, NULL, 0, 0); uid = rdint(fd); tr->ishidden = rdbool(fd); tr->name = unpickle(fd); tr->param = tyunpickle(fd); n = rdint(fd); for (i = 0; i < n; i++) lappend(&tr->memb, &tr->nmemb, rdsym(fd, tr)); n = rdint(fd); for (i = 0; i < n; i++) lappend(&tr->funcs, &tr->nfuncs, rdsym(fd, tr)); htput(trmap, itop(uid), tr); return tr; }
static void initconsts(Htab *globls) { Type *ty; Node *name; Node *dcl; tyintptr = mktype(Zloc, Tyuint64); tyword = mktype(Zloc, Tyuint); tyvoid = mktype(Zloc, Tyvoid); ty = mktyfunc(Zloc, NULL, 0, mktype(Zloc, Tyvoid)); ty->type = Tycode; name = mknsname(Zloc, "_rt", "abort_oob"); dcl = mkdecl(Zloc, name, ty); dcl->decl.isconst = 1; dcl->decl.isextern = 1; htput(globls, dcl, asmname(dcl)); abortoob = mkexpr(Zloc, Ovar, name, NULL); abortoob->expr.type = ty; abortoob->expr.did = dcl->decl.did; abortoob->expr.isconst = 1; }
/* Usefile format: * U<pkgname> * T<pickled-type> * R<picled-trait> * I<pickled-impl> * D<picled-decl> * G<pickled-decl><pickled-initializer> */ int loaduse(char *path, FILE *f, Stab *st, Vis vis) { intptr_t tid; size_t i; int v; char *pkg; Node *dcl, *impl, *init; Stab *s; Type *ty; Trait *tr; char *lib; int c; pushstab(file->file.globls); if (!tydedup) tydedup = mkht(tyhash, tyeq); if (fgetc(f) != 'U') return 0; v = rdint(f); if (v != Abiversion) { fprintf(stderr, "%s: abi version %d, expected %d\n", path, v, Abiversion); return 0; } pkg = rdstr(f); /* if the package names match up, or the usefile has no declared * package, then we simply add to the current stab. Otherwise, * we add a new stab under the current one */ if (st->name) { if (pkg && !strcmp(pkg, st->name)) { s = st; } else { s = findstab(st, pkg); } } else { if (pkg) { s = findstab(st, pkg); } else { s = st; } } if (!streq(st->name, pkg)) vis = Visintern; if (!s) { printf("could not find matching package for merge: %s in %s\n", st->name, path); exit(1); } tidmap = mkht(ptrhash, ptreq); trmap = mkht(ptrhash, ptreq); if (!initmap) initmap = mkht(namehash, nameeq); /* builtin traits */ for (i = 0; i < Ntraits; i++) htput(trmap, itop(i), traittab[i]); while ((c = fgetc(f)) != EOF) { switch(c) { case 'L': lib = rdstr(f); for (i = 0; i < file->file.nlibdeps; i++) if (!strcmp(file->file.libdeps[i], lib)) /* break out of both loop and switch */ goto foundlib; lappend(&file->file.libdeps, &file->file.nlibdeps, lib); foundlib: break; case 'X': lib = rdstr(f); for (i = 0; i < file->file.nextlibs; i++) if (!strcmp(file->file.extlibs[i], lib)) /* break out of both loop and switch */ goto foundextlib; lappend(&file->file.extlibs, &file->file.nextlibs, lib); foundextlib: break; case 'F': lappend(&file->file.files, &file->file.nfiles, rdstr(f)); break; case 'G': case 'D': dcl = rdsym(f, NULL); dcl->decl.vis = vis; dcl->decl.isglobl = 1; putdcl(s, dcl); break; case 'S': init = unpickle(f); if (!hthas(initmap, init)) { htput(initmap, init, init); lappend(&file->file.init, &file->file.ninit, init); } break; case 'R': tr = traitunpickle(f); tr->vis = vis; puttrait(s, tr->name, tr); for (i = 0; i < tr->nfuncs; i++) putdcl(s, tr->funcs[i]); break; case 'T': tid = rdint(f); ty = tyunpickle(f); if(!ty->ishidden) ty->vis = vis; htput(tidmap, itop(tid), ty); /* fix up types */ if (ty->type == Tyname || ty->type == Tygeneric) { if (ty->issynth) break; if (!streq(s->name, ty->name->name.ns)) ty->ishidden = 1; if (!gettype(s, ty->name) && !ty->ishidden) puttype(s, ty->name, ty); } else if (ty->type == Tyunion) { for (i = 0; i < ty->nmemb; i++) if (!getucon(s, ty->udecls[i]->name) && !ty->udecls[i]->synth) putucon(s, ty->udecls[i]); } break; case 'I': impl = unpickle(f); putimpl(s, impl); /* specialized declarations always go into the global stab */ for (i = 0; i < impl->impl.ndecls; i++) putdcl(file->file.globls, impl->impl.decls[i]); break; case EOF: break; } } fixtypemappings(s); fixtraitmappings(s); htfree(tidmap); popstab(); return 1; }
int main(int argc, char *argv[]) { printf("%s", banner); char line[8000]; char k[8000]; int i, h, vlen, offt, len; if (argc < 3) { puts("Usage: run [foo.idx] [foo.sql]"); exit(-1); } CFP = fopen(argv[1], "r"); for (i=0; i < BUCKETS; i++) { HT[i].n = NULL; HT[i].len = 0; } int c = 0; while ((len=fgetln(line)) != -1) { parse(line, k, &vlen, &offt); //printf("%s:%d@%d\n", k, vlen, offt); htput(k, vlen, offt); c++; } printf("Loaded \t%d words\n", c); int fd = open(argv[2], O_RDONLY); struct stat sb; fstat(fd, &sb); int sz; sz = sb.st_size; void *ad; ad = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd, 0); #define HISTORY_FILE ".lookups" linenoiseHistoryLoad(HISTORY_FILE); /* Load the history at startup */ linenoiseSetCompletionCallback(completion); char *str; while((str = linenoise(">>> ")) != NULL) { if (strcmp(str, "/exit") == 0) break; if (str[0] != '\0') { len = strlen(str); if (len < 1) continue; h = hash(str); if (HT[h].len) { NODE *n = lookup(str, HT[h].n); if (n) { int offt, vlen; offt = n->idx->offt; vlen = n->idx->vlen; char *p = ad + offt; while (--vlen) printf("%c", *p++); } else { puts("Not found in tree"); int j; for (j=0,i=0; i < cc_len; i++) { if (complet(str, CC[i].key) == 0) { printf("%d) %s\n", ++j, CC[i].key); } } //TODO also do levenshtein search if no found } } else puts("Not found in table"); linenoiseHistoryAdd(str); linenoiseHistorySave(HISTORY_FILE); /* Save every new entry */ printf("\n"); } if (str) free(str); } printf("\n"); if (str) free(str); close(fd); for (i=0; i < BUCKETS; i++) { if (HT[i].len) { //printf("bucket %d: %d keys\n", i, HT[i].len); freetree(HT[i].n); } } for (i=0; i < cc_len; i++) { free(CC[i].key); } return 0; }