int CfgQueryStringExamples(int verbose, struct cfg *cfg, char *args[]) { unsigned char buf[1024], *row[10]; FILE *in; int ret; if ((in = fopen(args[0], "r")) == NULL) { PMNO(errno); return -1; } while ((ret = csv_row_fread(in, buf, 1024, row, 10, ',', CSV_QUOTES | CSV_TRIM)) > 0) { int success = atoi(row[0]); tcase_printf(verbose, "%s:\n", row[1]); cfg_clear(cfg); if (cfg_load_cgi_query_string(cfg, row[1], row[1] + tcslen(row[1])) == -1) { if (success) { ret = -1; AMSG(""); goto out; } } else if (!success) { ret = -1; AMSG("Supposed to fail"); goto out; } if (verbose) { iter_t iter; const tchar *name; tchar dst[512]; cfg_iterate(cfg, &iter); while ((name = cfg_next(cfg, &iter))) { if (cfg_get_str(cfg, dst, 512, NULL, name) == -1) { errno = ENOENT; PMNO(errno); return -1; } tcase_printf(verbose, "\t%s=%s\n", name, dst); } } } out: fclose(in); return ret; }
struct allocator * suba_init(void *mem, size_t size, int rst, size_t mincell) { struct allocator *suba = mem; size_t hdrsiz; hdrsiz = ALIGN(sizeof *suba); if (mem == NULL || size <= (hdrsiz + POFF) || (!rst && memcmp(SUBA_MAGIC, suba->magic, 8)) != 0) { PMNO(errno = EINVAL); return NULL; } if (rst) { struct cell *c; memset(suba, 0, hdrsiz); memcpy(suba->magic, SUBA_MAGIC, 8); suba->tail = hdrsiz; /* cell data must be large enough for next ref_t */ suba->mincell = ALIGN(sizeof(size_t)); if (mincell > suba->mincell) { suba->mincell = ALIGN(mincell); } suba->size = suba->max_free = size; c = suba_addr(suba, hdrsiz); c->size = size - (hdrsiz + POFF); c->next = suba->tail; } return suba; }
struct eval * eval_new(symlook_fn symlook, void *context) { struct eval *eval; struct tok *em; if ((eval = malloc(sizeof *eval)) == NULL) { PMNO(errno); return NULL; } memset(eval, 0, sizeof *eval); if ((eval->toks = varray_new(sizeof(struct tok), NULL)) == NULL || (eval->opstk = stack_new(4096, NULL)) == NULL || (eval->stk = stack_new(4096, NULL)) == NULL || (em = varray_get(eval->toks, eval->toki++)) == NULL) { AMSG(""); eval_del(eval); return NULL; } eval->context = context; eval->symlook = symlook; em->type = TOK_TYPE_EMPTY; stack_push(eval->opstk, em); return eval; }
static int error(struct eval *eval, struct tok *tok) { PMNO(errno = EILSEQ); (void)eval; (void)tok; return -1; }
int PoolExercise(int verbose, struct cfg *cfg, char *args[]) { void *data; int rate, i; struct linkedlist *l; struct pool *p; cfg = NULL; args[0] = NULL; if ((p = pool_new(EXERCISE_SM_COUNT, (new_fn)allocator_alloc, allocator_free, NULL, NULL, BUFFER_SIZE_SM, 0, NULL)) == NULL || (l = linkedlist_new(0, NULL)) == NULL) { PMNO(errno); return 1; } rate = EXERCISE_R0; for (i = 0; i < EXERCISE_SM_COUNT; i++) { if (i == EXERCISE_SM_P1) { rate = EXERCISE_R1; } else if (i == EXERCISE_SM_P2) { rate = EXERCISE_R2; } else if (i == EXERCISE_SM_P3) { rate = EXERCISE_R3; } if (rand() % 10 < rate) { if (pool_size(p) == EXERCISE_SM_COUNT && pool_unused(p) == 0) { continue; } else if ((data = pool_get(p)) == NULL) { AMSG(""); return -1; } else if (linkedlist_add(l, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d get %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else if ((data = linkedlist_remove(l, 0))) { if (data == NULL || pool_release(p, data) == -1) { AMSG("%04d %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); return -1; } tcase_printf(verbose, "%04d rel %p s=%d,u=%d\n", i, data, pool_size(p), pool_unused(p)); } else { tcase_printf(verbose, "%04d nothing to release\n", i); } } linkedlist_del(l, NULL, NULL); pool_del(p); return 0; }
void * stdlib_realloc(struct allocator *al, void *obj, size_t size) { void *p; if ((p = realloc(obj, size)) == NULL && size) { PMNO(errno); } (void)al; return p; }
void * open_mmap(const char *name, int flags, int mode, size_t size) { char *fname, buf[32] = "/tmp/"; int i, fd, prot = PROT_READ; void *ret; fname = buf + 5; for (i = 0; i < 22 && name[i]; i++) { if (name[i] == '.' || name[i] == '/') { errno = EINVAL; PMNO(errno); return NULL; } fname[i] = name[i]; } strcpy(fname + i, ".shm"); if ((fd = open(buf, flags, mode)) == -1 || (mode && fchmod(fd, mode) == -1)) { PMNF(errno, ": %s", buf); return NULL; } if (ftruncate(fd, size) == -1) { close(i); PMNO(errno); return NULL; } if ((flags & O_RDWR)) { prot |= PROT_WRITE; } if ((ret = mmap(NULL, size, prot, MAP_SHARED, fd, 0)) == MAP_FAILED) { PMNO(errno); return NULL; } close(fd); return ret; }
int svcond_create(svcond_t *cond, struct pool *sempool) { struct _svs_data *sd; if (cond == NULL || sempool == NULL || (sd = sempool->context) == NULL || sd->val != 1) { PMNO(errno = EINVAL); return -1; } memset(cond, sizeof *cond, 0); cond->sempool = sempool; if ((cond->blocked_lock = pool_get(sempool)) == NULL || (cond->block_queue = pool_get(sempool)) == NULL || (cond->unblock_lock = pool_get(sempool)) == NULL) { PMNO(errno = EAGAIN); svcond_destroy(cond); return -1; } /* MMSG("%d: %d %d %d", cond->blocked_lock->id, cond->blocked_lock->num, cond->block_queue->num, cond->unblock_lock->num); */ cond->unblock_lock->flags |= SEM_UNDO; if (svsem_setvalue(cond->block_queue, 0) == -1) { PMNO(errno); svcond_destroy(cond); return -1; } return 0; }
int OpenCre(int verbose, struct cfg *cfg, char *args[]) { int nprocs = atoi(args[0]), n = atoi(args[1]), i, j, status; pid_t *pids; svsem_t sem; if (svsem_create(&sem, 0, 1) == -1) { AMSG(""); return -1; } if ((pids = malloc(nprocs * sizeof *pids)) == NULL) { PMNO(errno); return -1; } for (i = 0; i < nprocs; i++) { if ((pids[i] = fork()) == 0) { run(&sem, n, verbose); exit(0); } } for (j = 0; j < n; j++) { usleep(200); if (verbose) { printf("%d\n", j); } svsem_post_multiple(&sem, nprocs); } do { waitpid(pids[--i], &status, 0); if ((errno = WEXITSTATUS(status))) { perror(""); } tcase_printf(verbose, "process complete\n"); } while(i); free(pids); svsem_destroy(&sem); tcase_printf(verbose, "done"); cfg = NULL; return 0; }
void * stdlib_alloc(struct allocator *al, size_t size, int zero) { void *p; if (zero) { p = calloc(1, size); } else { p = malloc(size); } if (p == NULL) { PMNO(errno); return NULL; } (void)al; return p; }
TOKFILE * tok_fopen(const char *filename) { TOKFILE *tf; if ((tf = calloc(1, sizeof *tf)) == NULL) { PMNO(errno); return NULL; } if ((tf->in = fopen(filename, "r")) == NULL) { PMNF(errno, ": %s", filename); free(tf); return NULL; } tf->line = 1; return tf; }
int eval_expression(struct eval *eval, const tchar *expr, const tchar *elim, unsigned long *result) { struct tok *tok, *op; trans_fn fn; int n; if (eval == NULL || expr == NULL || expr > elim || result == NULL) { PMNO(errno = EINVAL); return -1; } if (expr == elim) { *result = 0; return 0; } do { if ((n = next_tok(eval, expr, elim, &tok)) == -1) { AMSG(""); return -1; } do { op = stack_peek(eval->opstk); fn = trans_matrix[tok->type - 1][op->type - 1]; if (fn && fn(eval, tok) == -1) { AMSG(""); return -1; } } while (fn == pop); expr += n; } while (n); if ((tok = stack_pop(eval->stk))) { *result = tok->val; } else { *result = 0; } return 0; }
static int pop(struct eval *eval, struct tok *tok) { struct tok *op = stack_pop(eval->opstk); struct tok *p2 = stack_pop(eval->stk); struct tok *p1 = stack_peek(eval->stk); switch (op->type) { case TOK_TYPE_BITOR: p1->val |= p2->val; break; case TOK_TYPE_BITAND: p1->val &= p2->val; break; case TOK_TYPE_BITXOR: p1->val ^= p2->val; break; case TOK_TYPE_ADD: p1->val += p2->val; break; case TOK_TYPE_SUB: p1->val -= p2->val; break; case TOK_TYPE_MUL: p1->val *= p2->val; break; case TOK_TYPE_DIV: p1->val /= p2->val; break; default: PMNO(errno = EINVAL); return -1; } (void)tok; return 0; }
struct sym * symadd(struct idl *idl, const char *idl_type, const char *out_type, const char *ndr_type, size_t ndr_size) { struct sym *sym; if (idl == NULL || idl_type == NULL || *idl_type == '\0') { PMNO(EINVAL); return NULL; } if ((sym = symnew(idl->al)) == NULL) { AMSG(""); return NULL; } sym->idl_type = dupstr(idl_type, idl->al); if (out_type) { sym->out_type = dupstr(out_type, idl->al); } if (ndr_type) { sym->ndr_type = dupstr(ndr_type, idl->al); } sym->ndr_size = ndr_size; if (hashmap_put(idl->syms, (void *)sym->idl_type, sym) == -1) { AMSG(""); return NULL; } return sym; }
static int snextch(struct sinput *in) { int ch; if (in->in) { if ((ch = fgetc(in->in)) == EOF) { if (ferror(in->in)) { PMNO(errno); return -1; } return 0; } } else { if (in->sn == 0) { return 0; } ch = *(in->src)++; in->sn--; } in->count++; return ch; }
int LinkedlistExercise(int verbose, struct cfg *cfg, char *args[]) { int rate, i, n = 0, idx; char *str; struct linkedlist *l = linkedlist_new(EXERCISE_MED_COUNT, NULL); cfg = NULL; args[0] = NULL; if (l == NULL) { AMSG(""); return -1; } rate = EXERCISE_R0; for (i = 0; i < EXERCISE_MED_COUNT; i++) { if (i == EXERCISE_MED_P1) { rate = EXERCISE_R1; } else if (i == EXERCISE_MED_P2) { rate = EXERCISE_R2; } else if (i == EXERCISE_MED_P3) { rate = EXERCISE_R3; } if (rand() % 10 < rate) { idx = 0; str = malloc(8); sprintf(str, "%07d", n++); if (rand() % 5) { idx = linkedlist_size(l); if (idx) { idx = rand() % idx; } } if (linkedlist_insert(l, idx, str) == -1) { PMNO(errno); return -1; } tcase_printf(verbose, "INSERT: %s size now %d\n", str, linkedlist_size(l)); } else { if (linkedlist_is_empty(l)) { tcase_printf(verbose, "EMPTY\n"); } else { idx = rand() % linkedlist_size(l); str = linkedlist_get(l, idx); if (linkedlist_remove_data(l, str) == NULL) { PMNO(errno); return -1; } if ((idx % 10) == 0) { unsigned int count = 0; iter_t iter; linkedlist_iterate(l, &iter); while (linkedlist_next(l, &iter)) { count++; } if (count != linkedlist_size(l)) { PMSG("count=%u,linkedlist_size=%u\n", count, linkedlist_size(l)); return -1; } } if (str) { tcase_printf(verbose, "REMOVE: %s %d\n", str, linkedlist_size(l)); free(str); } else { PMSG("remove failure"); return -1; } } } } linkedlist_del(l, allocator_free, NULL); return 0; }
int path_canon(const unsigned char *src, const unsigned char *slim, unsigned char *dst, unsigned char *dlim, int srcsep, int dstsep) { unsigned char *start = dst, *prev; int state = ST_START; while (src < slim && dst < dlim) { switch (state) { case ST_START: state = ST_SEPARATOR; if (*src == srcsep) { *dst++ = dstsep; src++; break; } case ST_SEPARATOR: if (*src == '\0') { *dst = '\0'; return dst - start; } else if (*src == srcsep) { src++; break; } else if (*src == '.') { state = ST_DOT1; } else { state = ST_NORMAL; } *dst++ = *src++; break; case ST_NORMAL: if (*src == '\0') { *dst = '\0'; return dst - start; } else if (*src == srcsep) { state = ST_SEPARATOR; *dst++ = dstsep; src++; break; } *dst++ = *src++; break; case ST_DOT1: if (*src == '\0') { dst--; *dst = '\0'; return dst - start; } else if (*src == srcsep) { state = ST_SEPARATOR; dst--; break; } else if (*src == '.') { state = ST_DOT2; *dst++ = *src++; break; } state = ST_NORMAL; *dst++ = *src++; break; case ST_DOT2: if (*src == '\0' || *src == srcsep) { /* note src is not advanced in this case */ state = ST_SEPARATOR; dst -= 2; prev = dst - 1; if (dst == start || prev == start) { break; } do { dst--; prev = dst - 1; } while (dst > start && *prev != dstsep); break; } state = ST_NORMAL; *dst++ = *src++; break; } } PMNO(errno = ERANGE); return -1; }
int tokget(TOKFILE *in, char *dst, char *dlim) { char *start = dst; int ch; if (in->state == -1) { *dst = '\0'; return 0; } while (dst < dlim) { ch = fgetc(in->in); if (ch == '#') { while ((ch = fgetc(in->in)) != '\n') { if (ch == EOF) { *dst = '\0'; return 0; } } } else if (ch == '\n') { in->line++; } switch (in->state) { case 0: if (ch == EOF) { in->state = -1; *dst = '\0'; return 0; } else if (isspace(ch)) { break; } in->state = 1; case 1: if (ch == EOF) { in->state = -1; *dst = '\0'; return 0; } else if (istokchar(ch)) { *dst++ = ch; *dst = '\0'; in->state = 0; return 1; } in->state = 2; case 2: if (isspace(ch) || istokchar(ch) || ch == EOF) { if (ch == EOF) { in->state = -1; } else if (ch == '*' && (dst - start) == 1 && *start == '/') { in->state = 3; /* comment */ dst = start; break; } else { ungetc(ch, in->in); in->state = 0; } *dst = '\0'; return dst - start; } *dst++ = ch; break; case 3: if (ch == '*') { in->state = 4; } break; case 4: if (ch != '*') { in->state = ch != '/' ? 3 : 0; } break; default: errno = EINVAL; PMNF(errno, ": invalid TOKFILE state: %d", in->state); in->state = -1; return -1; } } if (dst == dlim) { errno = ERANGE; PMNO(errno); return -1; } return 0; }
pid_t daemonize(mode_t mask, const char *rundir, const char *pidpath, const char *lockpath, const char *logpath) { pid_t pid; int fd; if (getppid() == 1) { /* already a daemon */ return 0; } if ((pid = fork())) { return pid; } /* child (daemon) continues */ setsid(); /* obtain a new process group */ umask(mask); /* set newly created file permissions */ /* close all descriptors */ for (fd = getdtablesize(); fd >= 0; fd--) { close(fd); } /* but stdin, stdout, and stderr are redirected to /dev/null */ if ((fd = open("/dev/null", O_RDWR)) != 0 || dup(fd) != 1 || dup(fd) != 2) { return -1; } if (logpath) { /* open the logfile */ time_t start = time(NULL); if ((logfp = fopen(logpath, "a")) == NULL) { PMNF(errno, ": %s", logpath); return -1; } msgno_hdlr = daemonlog; daemonlog("log started: %s", ctime(&start)); } if (lockpath) { if ((fd = open(lockpath, O_RDWR | O_CREAT, 0640)) == -1) { PMNF(errno, ": %s", lockpath); return -1; } if (lockf(fd, F_TLOCK, 0) == -1) { /* can not lock */ PMNF(errno, ": %s: Server already running.", lockpath); return -1; } } /* first instance continues */ if (pidpath) { char str[10]; if ((fd = open(pidpath, O_RDWR | O_CREAT, 0640)) == -1) { PMNO(errno); return -1; } sprintf(str, "%d\n", getpid()); if (write(fd, str, strlen(str)) == -1) { /* write pid to lockfile */ PMNO(errno); return -1; } close(fd); } if (rundir && chdir(rundir) == -1) { /* change running directory */ PMNF(errno, ": %s", rundir); return -1; } signal(SIGTSTP,SIG_IGN); /* ignore tty signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); return 0; }
void * suba_alloc(struct allocator *suba, size_t size, int zero) { struct cell *c1, *c2, *c3; size_t s = size; int reclaim = 0; size = size < suba->mincell ? suba->mincell : ALIGN(size); again: if (reclaim) { int progress = 0; //if (suba->reclaim && suba->reclaim_depth <= RECLAIM_DEPTH_MAX) { // suba->reclaim_depth++; // progress = suba->reclaim(suba, suba->reclaim_arg, reclaim); // suba->reclaim_depth--; //} if (!progress) { PMNO(errno = ENOMEM); return NULL; } } c2 = SADR(suba, suba->tail); for ( ;; ) { c1 = c2; if ((c2 = suba_addr(suba, c1->next)) == NULL) { PMNF(errno = EFAULT, ": 0x%08x", c1->next); return NULL; } if (c2->size >= size) { break; /* found a cell large enough */ } if (c1->next == suba->tail) { reclaim++; goto again; } } if (c2->size > (POFF + size + suba->mincell)) { /* split new cell */ c3 = (struct cell *)(C2P(c2) + size); c3->size = c2->size - (size + POFF); if (c1 == c2) { c1 = c3; } else { c3->next = c2->next; } c1->next = SREF(suba, c3); c2->size = size; if (c2 == SADR(suba, suba->tail)) { suba->tail = SREF(suba, c3); } } else if (c1->next == suba->tail) { /* never use the last cell! */ reclaim++; goto again; } else { /* use the entire cell */ c1->next = c2->next; } // CHDK counters suba->allocated_size += POFF + c2->size; suba->allocated_count++; if(suba->allocated_size > suba->allocated_peak) { suba->allocated_peak = suba->allocated_size; } // old suba counters /* suba->alloc_total += POFF + c2->size; suba->size_total += s; */ return zero ? memset(C2P(c2), 0, size) : C2P(c2); }
static int csv_parse_str(struct sinput *in, unsigned char *buf, size_t bn, unsigned char *row[], int rn, int sep, int flags) { int trim, quotes, ch, state, r, j, t, inquotes; trim = flags & CSV_TRIM; quotes = flags & CSV_QUOTES; state = ST_START; inquotes = 0; ch = r = j = t = 0; memset(row, 0, sizeof(unsigned char *) * rn); while (rn && bn && (ch = snextch(in)) > 0) { switch (state) { case ST_START: if (ch != '\n' && ch != sep && isspace(ch)) { if (!trim) { buf[j++] = ch; bn--; t = j; } break; } else if (quotes && ch == '"') { j = t = 0; state = ST_COLLECT; inquotes = 1; break; } state = ST_COLLECT; case ST_COLLECT: if (inquotes) { if (ch == '"') { state = ST_END_QUOTE; break; } } else if (ch == sep || ch == '\n') { row[r++] = buf; rn--; if (ch == '\n' && t && buf[t - 1] == '\r') { t--; bn++; /* crlf -> lf */ } buf[t] = '\0'; bn--; buf += t + 1; j = t = 0; state = ST_START; inquotes = 0; if (ch == '\n') { rn = 0; } break; } else if (quotes && ch == '"') { PMNF(errno = EILSEQ, ": unexpected quote in element %d", (r + 1)); return -1; } buf[j++] = ch; bn--; if (!trim || isspace(ch) == 0) { t = j; } break; case ST_TAILSPACE: case ST_END_QUOTE: if (ch == sep || ch == '\n') { row[r++] = buf; rn--; buf[j] = '\0'; bn--; buf += j + 1; j = t = 0; state = ST_START; inquotes = 0; if (ch == '\n') { rn = 0; } break; } else if (quotes && ch == '"' && state != ST_TAILSPACE) { buf[j++] = '"'; bn--; /* nope, just an escaped quote */ t = j; state = ST_COLLECT; break; } else if (isspace(ch)) { state = ST_TAILSPACE; break; } errno = EILSEQ; PMNF(errno, ": bad end quote in element %d", (r + 1)); return -1; } } if (ch == -1) { AMSG(""); return -1; } if (bn == 0) { PMNO(errno = E2BIG); return -1; } if (rn) { if (inquotes && state != ST_END_QUOTE) { PMNO(errno = EILSEQ); return -1; } row[r] = buf; buf[t] = '\0'; } return in->count; }
int suba_free(void *suba0, void *ptr) { struct allocator *suba = suba0; struct cell *c1, *c2, *c3; ref_t ref; int j1, j2; if (!ptr) return 0; if (!suba_ref(suba, ptr)) { PMNO(errno = EFAULT); return -1; } /* splice the cell back into the list */ c1 = SADR(suba, suba->tail); c2 = P2C(ptr); if (c2->size > suba->max_free || (ref = suba_ref(suba, c2)) == 0) { PMNF(errno = EINVAL, ": %p: %d", ptr, c2->size); return -1; } // CHDK counters suba->allocated_size -= POFF + c2->size; suba->allocated_count--; // old suba counter // suba->free_total += POFF + c2->size; /* c2->stk[0] = NULL; suba_print_cell(suba, " FREE", c2); */ if (c2 > c1) { /* append to end of list */ if (ISADJ(c1,c2)) { /* join with last cell */ c1->size += POFF + c2->size; return 0; } c2->next = c1->next; suba->tail = c1->next = ref; return 0; } while (c1->next < ref) { /* find insertion point */ if (c1->next < POFF) { PMNF(errno = EINVAL, ": next ref corrupted: %d", c1->next); return -1; } c1 = SADR(suba, c1->next); } c3 = SADR(suba, c1->next); j1 = ISADJ(c1,c2); /* c1 and c2 need to be joined */ j2 = ISADJ(c2,c3); /* c2 and c3 need to be joined */ if (j1) { if (j2) { /* splice all three cells together */ if (SREF(suba, c3) == suba->tail) { suba->tail = SREF(suba, c1); } c1->next = c3->next; c1->size += POFF + c3->size; } c1->size += POFF + c2->size; } else { if (j2) { if (SREF(suba, c3) == suba->tail) { suba->tail = ref; } c2->next = c3->next == SREF(suba, c3) ? ref : c3->next; c2->size += POFF + c3->size; } else { c2->next = c1->next; } c1->next = ref; } return 0; }
int HashmapExercise0(int verbose, struct cfg *cfg, char *args[]) { struct hashmap0 *h; int rate = 0, i, n = 0; int count = atoi(args[0]); int interval = atoi(args[1]); iter_t riter; char *str; clock_t t0; void *mem; struct allocator *al; iter_t iter; int chkpnt = 0; if ((mem = malloc(0xFFFFFFF)) == NULL || (al = suba_init(mem, 0xFFFFFFF, 1, 0)) == NULL || (h = hashmap0_new(HASHMAP_LARGE, hash_str, (compare_fn)strcmp, NULL, allocator_free, NULL, al)) == NULL) { AMSG(""); return -1; } srand(1); fputc('\n', stderr); t0 = clock(); fprintf(stderr, " time count size mem\n"); hashmap0_iterate(h, &iter); rate_iterate(&riter); for (i = 0; i < count; i++) { if ((i % interval) == 0) { fprintf(stderr, "%2d %8ld %8d %8d %8d %d\n", chkpnt++, (clock() - t0) / 1000, hashmap0_size(h), HASHMAP_LARGE, h->al->size_total - h->al->free_total, rate); rate = rate_next(&riter); } if (rand() % 10 < rate) { str = allocator_alloc(NULL, 16, 0); sprintf(str, "%015d", n++); if (hashmap0_put(h, str, str) == -1) { AMSG(""); return -1; } else { /*fputc('+', stderr); */ tcase_printf(verbose, "put %s %d\n", str, hashmap0_size(h)); } } else { if (hashmap0_is_empty(h)) { tcase_printf(verbose, "hashmap0 empty\n"); } else { str = hashmap0_next(h, &iter); if (str) { tcase_printf(verbose, "get %s %d\n", str, hashmap0_size(h)); if ((str = hashmap0_remove(h, str)) == NULL) { errno = EFAULT; PMNO(errno); return -1; } /*fputc('-', stderr); */ tcase_printf(verbose, "remove %s %d\n", str, hashmap0_size(h)); allocator_free(NULL, str); } else { /*fputc('x', stderr); */ tcase_printf(verbose, "nothing left to iterate over\r"); hashmap0_iterate(h, &iter); } } } } fprintf(stderr, "%2d %8ld %8d %8d %8d\n", chkpnt++, (clock() - t0) / 1000, hashmap0_size(h), HASHMAP_LARGE, h->al->size_total); hashmap0_del(h); tcase_printf(verbose, "hashmap0 done\n"); cfg = NULL; return 0; }