int main(int argc, char *argv[]) { char *s, *ct, *last, *ret; if (3 != argc) { /* 0 1 2 (3) */ printf("usage: %s <s> <ct>\n", argv[0]); exit(1); } s = argv[1]; ct = argv[2]; printf("s = |%s|\n", s); printf("ct = |%s|\n", ct); ret = airStrtok(s, ct, &last); while (ret) { printf("|%s|\n", ret); ret = airStrtok(NULL, ct, &last); } printf("--------------\n"); printf("hey, why doesn't this work?!?!?\n"); printf("s = |%s|\n", s); ret = strtok(s, ct); while (ret) { printf("ret = |%s|\n", ret); ret = strtok(NULL, ct); } exit(0); }
int _nrrdReadNrrdParse_kinds (FILE *file, Nrrd *nrrd, NrrdIoState *nio, int useBiff) { char me[]="_nrrdReadNrrdParse_kinds", err[BIFF_STRLEN]; unsigned int ai; char *info, *tok, *last; airArray *mop; AIR_UNUSED(file); mop = airMopNew(); info = airStrdup(nio->line + nio->pos); airMopAdd(mop, info, airFree, airMopAlways); _CHECK_HAVE_DIM; for (ai=0; ai<nrrd->dim; ai++) { tok = airStrtok(!ai ? info : NULL, _nrrdFieldSep, &last); if (!tok) { sprintf(err, "%s: couldn't extract string for kind %d of %d", me, ai+1, nrrd->dim); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } if (!strcmp(tok, NRRD_UNKNOWN)) { nrrd->axis[ai].kind = nrrdKindUnknown; continue; } if (!strcmp(tok, NRRD_NONE)) { nrrd->axis[ai].center = nrrdKindUnknown; continue; } if (!(nrrd->axis[ai].kind = airEnumVal(nrrdKind, tok))) { sprintf(err, "%s: couldn't parse \"%s\" kind %d of %d", me, tok, ai+1, nrrd->dim); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } } if (airStrtok(!ai ? info : NULL, _nrrdFieldSep, &last)) { sprintf(err, "%s: seem to have more than expected %d kinds", me, nrrd->dim); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } /* can't run this now because kinds can come before sizes, in which case the kind/size check in _nrrdFieldCheck_kinds will incorrectly flag an error ... if (_nrrdFieldCheck[nrrdField_kinds](nrrd, useBiff)) { sprintf(err, "%s: trouble", me); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } */ airMopOkay(mop); return 0; }
/* ******** airStrntok() ** ** returns the number of tokens parsable by airStrtok(), but does ** NOT alter the given string */ unsigned int airStrntok(const char *_s, const char *ct) { char *s, *t, *l=NULL; unsigned int n = 0; if (_s && ct) { s = airStrdup(_s); t = airStrtok(s, ct, &l); while (t) { n++; t = airStrtok(NULL, ct, &l); } airFree(s); /* no NULL assignment to s, else compile warnings */ } return n; }
unsigned int airParseStrE(int *out, const char *_s, const char *ct, unsigned int n, ...) { unsigned int i; char *tmp, *s, *last; airArray *mop; va_list ap; airEnum *enm; /* grab the enum every time, prior to error checking */ va_start(ap, n); enm = va_arg(ap, airEnum *); va_end(ap); /* if we got NULL, there's nothing to do */ if (!(out && _s && ct)) { return 0; } mop = airMopNew(); /* copy the input so that we don't change it */ s = airStrdup(_s); airMopMem(mop, &s, airMopAlways); if (1 == n) { /* Because it should be permissible to have spaces in what is intended to be only a single string from an airEnum, we treat 1==n differently, and do NOT use airStrtok to tokenize the input string s into spaces. We check the whole s string */ out[0] = airEnumVal(enm, s); if (airEnumUnknown(enm) == out[0]) { airMopError(mop); return 0; } } else { /* keep calling airStrtok() until we have everything */ for (i=0; i<n; i++) { tmp = airStrtok(i ? NULL : s, ct, &last); if (!tmp) { airMopError(mop); return i; } out[i] = airEnumVal(enm, tmp); if (airEnumUnknown(enm) == out[i]) { airMopError(mop); return i; } } } airMopOkay(mop); return n; }
unsigned int airParseStrC(char *out, const char *_s, const char *ct, unsigned int n, ...) { unsigned int i; char *tmp, *s, *last; /* if we got NULL, there's nothing to do */ if (!(out && _s && ct)) return 0; /* copy the input so that we don't change it */ s = airStrdup(_s); /* keep calling airStrtok() until we have everything */ for (i=0; i<n; i++) { tmp = airStrtok(i ? NULL : s, ct, &last); if (!tmp) { free(s); return i; } out[i] = tmp[0]; } free(s); return n; }
int _nrrdReadNrrdParse_centers (FILE *file, Nrrd *nrrd, NrrdIoState *nio, int useBiff) { char me[]="_nrrdReadNrrdParse_centers", err[BIFF_STRLEN]; unsigned int ai; char *tok, *info, *last; airArray *mop; AIR_UNUSED(file); mop = airMopNew(); info = airStrdup(nio->line + nio->pos); airMopAdd(mop, info, airFree, airMopAlways); _CHECK_HAVE_DIM; for (ai=0; ai<nrrd->dim; ai++) { tok = airStrtok(!ai ? info : NULL, _nrrdFieldSep, &last); if (!tok) { sprintf(err, "%s: couldn't extract string for center %d of %d", me, ai+1, nrrd->dim); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } if (!strcmp(tok, NRRD_UNKNOWN)) { nrrd->axis[ai].center = nrrdCenterUnknown; continue; } if (!strcmp(tok, NRRD_NONE)) { nrrd->axis[ai].center = nrrdCenterUnknown; continue; } if (!(nrrd->axis[ai].center = airEnumVal(nrrdCenter, tok))) { sprintf(err, "%s: couldn't parse center \"%s\" for axis %d", me, tok, ai); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } } if (airStrtok(!ai ? info : NULL, _nrrdFieldSep, &last)) { sprintf(err, "%s: seem to have more than expected %d centers", me, nrrd->dim); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } if (_nrrdFieldCheck[nrrdField_centers](nrrd, useBiff)) { sprintf(err, "%s: trouble", me); biffMaybeAdd(NRRD, err, useBiff); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
unsigned int airParseStrS(char **out, const char *_s, const char *ct, unsigned int n, ...) { unsigned int i; int greedy; char *tmp, *s, *last; airArray *mop; va_list ap; /* grab "greedy" every time, prior to error checking */ va_start(ap, n); greedy = va_arg(ap, int); va_end(ap); /* if we got NULL, there's nothing to do */ if (!(out && _s && ct)) return 0; mop = airMopNew(); /* copy the input so that we don't change it */ s = airStrdup(_s); airMopMem(mop, &s, airMopAlways); /* keep calling airStrtok() until we have everything */ for (i=0; i<n; i++) { /* if n == 1, then with greediness, the whole string is used, and without greediness, we use airStrtok() to get only the first part of it */ if (n > 1 || !greedy) { tmp = airStrtok(i ? NULL : s, ct, &last); } else { tmp = s; } if (!tmp) { airMopError(mop); return i; } out[i] = airStrdup(tmp); if (!out[i]) { airMopError(mop); return i; } airMopMem(mop, out+i, airMopOnError); } airMopOkay(mop); return n; }
/* ** _hestPrintStr() ** ** not a useful function. Do not use. */ void _hestPrintStr(FILE *f, int indent, int already, int width, const char *_str, int bslash) { char *str, *ws, *last; int nwrd, wrd, pos, s, newed=AIR_FALSE; str = airStrdup(_str); nwrd = airStrntok(str, " "); pos = already; for (wrd=0; wrd<nwrd; wrd++) { /* we used airStrtok() to delimit words on spaces ... */ ws = airStrtok(!wrd ? str : NULL, " ", &last); /* ... but then convert tabs to spaces */ airStrtrans(ws, '\t', ' '); if ((int)(pos + 1 + strlen(ws)) <= width - !!bslash) { /* if this word would still fit on the current line */ if (wrd && !newed) fprintf(f, " "); fprintf(f, "%s", ws); pos += 1 + strlen(ws); newed = AIR_FALSE; } else { /* else we start a new line and print the indent */ if (bslash) { fprintf(f, " \\"); } fprintf(f, "\n"); for (s=0; s<indent; s++) { fprintf(f, " "); } fprintf(f, "%s", ws); pos = indent + strlen(ws); } /* if the last character of the word was a newline, then indent */ if ('\n' == ws[strlen(ws)-1]) { for (s=0; s<indent; s++) { fprintf(f, " "); } pos = indent; newed = AIR_TRUE; } else { newed = AIR_FALSE; } } fprintf(f, "\n"); free(str); }
/* ******** meetPullVolParse ** ** parses a string to extract all the information necessary to create ** the pullVolume (this function originated in Deft/src/main-pull.c) */ int meetPullVolParse(meetPullVol *mpv, const char *_str) { static const char me[]="meetPullVolParse"; #define VFMT_SHRT "<fileName>:<kind>:<volName>" #define SFMT "<minScl>-<#smp>-<maxScl>[-no|u]" #define VFMT_LONG "<fileName>:<kind>:" SFMT ":<volName>" char *str, *ctok, *clast=NULL, *dtok, *dlast=NULL; airArray *mop; int wantSS; if (!(mpv && _str)) { biffAddf(MEET, "%s: got NULL pointer", me); return 1; } if (!( str = airStrdup(_str) )) { biffAddf(MEET, "%s: couldn't strdup input", me); return 1; } mop = airMopNew(); airMopAdd(mop, str, airFree, airMopAlways); if (!( 3 == airStrntok(str, ":") || 4 == airStrntok(str, ":") )) { biffAddf(MEET, "%s: didn't get 3 or 4 \":\"-separated tokens in \"%s\"; " "not of form " VFMT_SHRT " or " VFMT_LONG , me, _str); airMopError(mop); return 1; } /* mpv->nin is set elsewhere */ wantSS = (4 == airStrntok(str, ":")); ctok = airStrtok(str, ":", &clast); if (!(mpv->fileName = airStrdup(ctok))) { biffAddf(MEET, "%s: couldn't strdup fileName", me); airMopError(mop); return 1; } airMopAdd(mop, &(mpv->fileName), (airMopper)airSetNull, airMopOnError); airMopAdd(mop, mpv->fileName, airFree, airMopOnError); ctok = airStrtok(NULL, ":", &clast); if (!(mpv->kind = meetConstGageKindParse(ctok))) { biffAddf(MEET, "%s: couldn't parse \"%s\" as kind", me, ctok); airMopError(mop); return 1; } if (wantSS) { int haveFlags; ctok = airStrtok(NULL, ":", &clast); if (!( 3 == airStrntok(ctok, "-") || 4 == airStrntok(ctok, "-") )) { biffAddf(MEET, "%s: didn't get 3 or 4 \"-\"-separated tokens in \"%s\"; " "not of form SFMT" , me, ctok); airMopError(mop); return 1; } haveFlags = (4 == airStrntok(ctok, "-")); dtok = airStrtok(ctok, "-", &dlast); if (1 != sscanf(dtok, "%lg", &(mpv->rangeSS[0]))) { biffAddf(MEET, "%s: couldn't parse \"%s\" as min scale", me, dtok); airMopError(mop); return 1; } dtok = airStrtok(NULL, "-", &dlast); if (1 != sscanf(dtok, "%u", &(mpv->numSS))) { biffAddf(MEET, "%s: couldn't parse \"%s\" as # scale samples", me, dtok); airMopError(mop); return 1; } if (!( mpv->numSS >= 2 )) { biffAddf(MEET, "%s: need # scale samples >= 2 (not %u)", me, mpv->numSS); airMopError(mop); return 1; } dtok = airStrtok(NULL, "-", &dlast); if (1 != sscanf(dtok, "%lg", &(mpv->rangeSS[1]))) { biffAddf(MEET, "%s: couldn't parse \"%s\" as max scale", me, dtok); airMopError(mop); return 1; } /* initialize things as if there were no flags */ mpv->derivNormSS = AIR_FALSE; mpv->uniformSS = AIR_FALSE; mpv->optimSS = AIR_FALSE; mpv->derivNormBiasSS = 0.0; if (haveFlags) { char *flags, *bias; /* look for various things in flags */ flags = airToLower(airStrdup(airStrtok(NULL, "-", &dlast))); airMopAdd(mop, flags, airFree, airMopAlways); if (strchr(flags, 'n')) { mpv->derivNormSS = AIR_TRUE; } if (strchr(flags, 'u')) { mpv->uniformSS = AIR_TRUE; } if (strchr(flags, 'o')) { mpv->optimSS = AIR_TRUE; } if (mpv->optimSS && mpv->uniformSS) { biffAddf(MEET, "%s: can't have both optimal ('o') and uniform ('u') " "flags set in \"%s\"", me, flags); airMopError(mop); return 1; } if ((bias = strchr(flags, '+'))) { /* indicating a bias, unfortunately only a positive one is possible here, because of the way that other fields are tokenized by '-' */ bias++; if (1 != sscanf(bias, "%lf", &(mpv->derivNormBiasSS))) { biffAddf(MEET, "%s: couldn't parse bias \"%s\"", me, bias); airMopError(mop); return 1; } } } /* mpv->ninSS and mpv->posSS are allocated and filled elsewhere */ mpv->ninSS = NULL; mpv->posSS = NULL; /* we don't actually create nrrds nor load the volumes here, because we don't know cachePath, and because we might want different pullVolumes to share the same underlying Nrrds */ } else { /* no scale-space stuff wanted */ mpv->numSS = 0; mpv->rangeSS[0] = mpv->rangeSS[1] = AIR_NAN; mpv->ninSS = NULL; mpv->posSS = NULL; } ctok = airStrtok(NULL, ":", &clast); if (!(mpv->volName = airStrdup(ctok))) { biffAddf(MEET, "%s: couldn't strdup volName", me); airMopError(mop); return 1; } airMopAdd(mop, &(mpv->volName), (airMopper)airSetNull, airMopOnError); airMopAdd(mop, mpv->volName, airFree, airMopOnError); if (strchr(ctok, '-')) { biffAddf(MEET, "%s: you probably don't want \"-\" in volume name \"%s\"; " "forgot last \":\" in scale sampling specification?", me, ctok); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
/* ******** miteShadeSpecParse ** ** set up a miteShadeSpec based on a string. Valid forms are: ** ** none ** phong:<vector> ** litten:<vector>,<vector>,<scalar>,<scalar> ** ** where <vector> and <scalar> are specifications of 3-vector and scalar ** parsable by miteVariableParse */ int miteShadeSpecParse(miteShadeSpec *shpec, char *shadeStr) { static const char me[]="miteShadeSpecParse"; char *buff, *qstr, *tok, *state; airArray *mop; int ansLength; mop = airMopNew(); if (!( shpec && airStrlen(shadeStr) )) { biffAddf(MITE, "%s: got NULL pointer and/or empty string", me); airMopError(mop); return 1; } buff = airToLower(airStrdup(shadeStr)); if (!buff) { biffAddf(MITE, "%s: couldn't strdup shading spec", me); airMopError(mop); return 1; } airMopAdd(mop, buff, airFree, airMopAlways); shpec->method = miteShadeMethodUnknown; if (!strcmp("none", buff)) { shpec->method = miteShadeMethodNone; } else if (buff == strstr(buff, "phong:")) { shpec->method = miteShadeMethodPhong; qstr = buff + strlen("phong:"); if (miteVariableParse(shpec->vec0, qstr)) { biffAddf(MITE, "%s: couldn't parse \"%s\" as shading vector", me, qstr); airMopError(mop); return 1; } ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength; if (3 != ansLength) { biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", me, qstr, ansLength); airMopError(mop); return 1; } shpec->method = miteShadeMethodPhong; } else if (buff == strstr(buff, "litten:")) { qstr = buff + strlen("litten:"); /* ---- first vector */ tok = airStrtok(qstr, ",", &state); if (miteVariableParse(shpec->vec0, tok)) { biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor vector", me, tok); airMopError(mop); return 1; } ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength; if (3 != ansLength) { biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", me, qstr, ansLength); airMopError(mop); return 1; } /* ---- second vector */ tok = airStrtok(qstr, ",", &state); if (miteVariableParse(shpec->vec1, tok)) { biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor vector", me, tok); airMopError(mop); return 1; } ansLength = shpec->vec1->kind->table[shpec->vec1->item].answerLength; if (3 != ansLength) { biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)", me, qstr, ansLength); airMopError(mop); return 1; } /* ---- first scalar */ tok = airStrtok(qstr, ",", &state); if (miteVariableParse(shpec->scl0, tok)) { biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor scalar", me, tok); airMopError(mop); return 1; } ansLength = shpec->scl0->kind->table[shpec->scl0->item].answerLength; if (1 != ansLength) { biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)", me, qstr, ansLength); airMopError(mop); return 1; } /* ---- second scalar */ tok = airStrtok(qstr, ",", &state); if (miteVariableParse(shpec->scl1, tok)) { biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor scalar", me, tok); airMopError(mop); return 1; } ansLength = shpec->scl1->kind->table[shpec->scl1->item].answerLength; if (1 != ansLength) { biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)", me, qstr, ansLength); airMopError(mop); return 1; } shpec->method = miteShadeMethodLitTen; } else { biffAddf(MITE, "%s: shading specification \"%s\" not understood", me, shadeStr); airMopError(mop); return 1; } airMopOkay(mop); return 0; }