static void setlen(struct naStr* s, int sz) { if(s->data) naFree(s->data); s->len = sz; s->data = naAlloc(sz+1); s->data[sz] = 0; // nul terminate }
// Handles multiple EOL conventions by using stdio's ungetc. Will not // work for other IO types without converting them to FILE* with // fdopen() or whatnot... static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args) { naRef result; struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0; int i=0, c, sz = 128; char *buf; if(!g || g->type != &naStdIOType) naRuntimeError(ctx, "bad argument to readln()"); buf = naAlloc(sz); while(1) { c = getcguard(ctx, g->handle, buf); if(c == EOF || c == '\n') break; if(c == '\r') { int c2 = getcguard(ctx, g->handle, buf); if(c2 != EOF && c2 != '\n') if(EOF == ungetc(c2, g->handle)) break; break; } buf[i++] = c; if(i >= sz) buf = naRealloc(buf, sz *= 2); } result = c == EOF ? naNil() : naStr_fromdata(naNewString(ctx), buf, i); naFree(buf); return result; }
naRef naIOGhost(naContext c, FILE* f) { struct naIOGhost* ghost = naAlloc(sizeof(struct naIOGhost)); ghost->type = &naStdIOType; ghost->handle = f; return naNewGhost(c, &naIOGhostType, ghost); }
static void setlen(struct naStr* s, int sz) { if(s->emblen == -1 && DATA(s)) naFree(s->data.ref.ptr); if(sz > MAX_STR_EMBLEN) { s->emblen = -1; s->data.ref.len = sz; s->data.ref.ptr = naAlloc(sz+1); } else { s->emblen = sz; } DATA(s)[sz] = 0; // nul terminate }
static HashRec* resize(struct naHash* hash) { HashRec *hr = hash->rec, *hr2; int i, lgsz = 0; if(hr) { int oldsz = hr->size; while(oldsz) { oldsz >>= 1; lgsz++; } } hr2 = naAlloc(recsize(lgsz)); hr2->size = hr2->next = 0; hr2->lgsz = lgsz; for(i=0; i<(2*(1<<lgsz)); i++) TAB(hr2)[i] = ENT_EMPTY; for(i=0; hr && i < POW2(hr->lgsz+1); i++) if(TAB(hr)[i] >= 0) hashset(hr2, ENTS(hr)[TAB(hr)[i]].key, ENTS(hr)[TAB(hr)[i]].val); naGC_swapfree((void*)&hash->rec, hr2); return hr2; }
static naRef f_newthread(naContext c, naRef me, int argc, naRef* args) { ThreadData *td; if(argc < 1 || !naIsFunc(args[0])) naRuntimeError(c, "bad/missing argument to newthread"); td = naAlloc(sizeof(*td)); td->ctx = naNewContext(); td->func = args[0]; naTempSave(td->ctx, td->func); #ifdef _WIN32 CreateThread(0, 0, threadtop, td, 0, 0); #else { pthread_t t; int err; if((err = pthread_create(&t, 0, threadtop, td))) naRuntimeError(c, "newthread failed: %s", strerror(err)); pthread_detach(t); } #endif return naNil(); }