static mcxstatus pars_realloc ( stream_state* iface , dim n_needed ) { dim n_alloc = MCX_MAX(n_needed+8, iface->pars_n_alloc * 1.2) ; mclpAR* p ; if (n_needed <= iface->pars_n_alloc) { if (n_needed > iface->pars_n_used) iface->pars_n_used = n_needed ; return STATUS_OK ; } p = mcxNRealloc ( iface->pars , n_alloc , iface->pars_n_alloc , sizeof p[0] , my_par_init_v , RETURN_ON_FAIL ) ;if(DEBUG3)fprintf(stderr, "realloc pars %lu (requested = %lu)\n", (ulong) n_alloc, (ulong) n_needed) ; if (!p) { mcxErr(module, "failure allocing p array (%lu units)", (ulong) n_alloc) ; return STATUS_FAIL ; } iface->pars = p ; iface->pars_n_used = n_needed ; iface->pars_n_alloc = n_alloc ; return STATUS_OK ; }
mcxstatus mclpARextend ( mclpAR* ar , long idx , double val ) { mclp* ivp = NULL ; if (ar->n_ivps >= ar->n_alloc) { long n_new_alloc = 4 + 1.22 * ar->n_alloc ; if (! ( ar->ivps = mcxNRealloc ( ar->ivps , n_new_alloc , ar->n_alloc , sizeof(mclp) , mclpInit_v , RETURN_ON_FAIL ) ) ) return STATUS_FAIL ; ar->n_alloc = n_new_alloc ; } ivp = ar->ivps + ar->n_ivps ; ivp->val = val ; ivp->idx = idx ; if (ar->n_ivps && ivp[-1].idx >= idx) { if (ivp[-1].idx > idx) BIT_OFF(ar->sorted, MCLPAR_SORTED | MCLPAR_UNIQUE) ; else BIT_OFF(ar->sorted, MCLPAR_UNIQUE) ; } ar->n_ivps++ ; return STATUS_OK ; }
mclpAR* mclpARensure ( mclpAR* mclpar , dim sz ) { if (!mclpar && !(mclpar = mclpARinit(NULL))) return NULL ; if (sz > mclpar->n_alloc) { if (!( mclpar->ivps = mcxNRealloc ( mclpar->ivps , sz , mclpar->n_alloc , sizeof(mclp) , mclpInit_v , RETURN_ON_FAIL ) ) ) return NULL ; mclpar->n_alloc = sz ; } return mclpar ; }
static dim do_a_file ( aggr** collectpp , const char* fname , dim collect_n ) { mcxIO* xf = mcxIOnew(fname, "r") ; mcxTing* buf = mcxTingEmpty(NULL, 100) ; mcxTing* lbl = mcxTingEmpty(NULL, 100) ; mcxstatus status = STATUS_OK ; aggr* collect = *collectpp ; dim ct = 0, collect_alloc = 0 ; if (!collect_n) collect_alloc = 100 , collect = mcxNAlloc(collect_alloc, sizeof collect[0], NULL, EXIT_ON_FAIL) ; mcxIOopen(xf, EXIT_ON_FAIL) ; while (STATUS_OK == (status = mcxIOreadLine(xf, buf, MCX_READLINE_CHOMP))) { double val ; const char* tabchar = NULL ; mcxbool get_header = collect_g != 'p' && !ct ? TRUE : FALSE ; mcxTingEnsure(lbl, buf->len) /* if header_g && !ct && !paste create/check label */ /* body of this while loop does too many things, refactor */ ; if (collect_g == 'p' || get_header) { if (!(tabchar = strchr(buf->str, '\t'))) mcxDie(1, me, "paste error at line %d file %s (no tab)", (int) xf->lc, fname) ; mcxTingNWrite(lbl, buf->str, tabchar - buf->str) ; } else { if (2 != sscanf(buf->str, "%s%lg", lbl->str, &val)) mcxDie(1, me, "parse error at line %d file %s", (int) xf->lc, fname) ; lbl->len = strlen(lbl->str) ; } if (!collect_n) { if (ct >= collect_alloc) { dim collect_realloc = collect_alloc * 1.44 ; collect = mcxNRealloc(collect, collect_realloc, collect_alloc, sizeof collect[0], NULL, EXIT_ON_FAIL) ; collect_alloc = collect_realloc ; } collect[ct].label = mcxTingStr(lbl) ; collect[ct].val = collect_g == 'p' || get_header ? 0.0 : val ; collect[ct].columns = collect_g == 'p' || get_header ? mcxTingNew(tabchar + (get_header ? 1 : 0)) : NULL ; } else { if (ct >= collect_n) mcxDie(1, me, "additional lines in file %s", fname) ; if (strcmp(collect[ct].label, lbl->str)) mcxDie ( 1 , me , "label conflict %s/%s at line %d in file %s" , collect[ct].label , lbl->str , (int) xf->lc, fname ) ; if (get_header) /* only need to check identity */ { if (strcmp(tabchar+1, collect[ct].columns->str)) mcxDie(1, me, "different columns <%s> and <%s>", collect[ct].columns->str, tabchar+1) ; } else if (collect_g == 'p') /* tack it on */ mcxTingNAppend(collect[ct].columns, tabchar, buf->len - lbl->len) ; else collect[ct].val += val ; } ct++ ; } if (collect_n) { if (ct != collect_n) mcxDie(1, me, "not enough lines in file %s", fname) ; } else { if (!ct) mcxDie(1, me, "empty file(s)") ; *collectpp = collect ; } mcxIOfree(&xf) ; return ct ; }