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; }
int nrrdGetenvBool(int *val, char **envStr, const char *envVar) { char *env; int tmp; if (!(val && envVar)) { return -1; } env = getenv(envVar); if (envStr) { *envStr = env; } if (!env) { return -1; } if (!strlen(env)) { /* for bools, being merely set (but not to any string) means "true" */ *val = AIR_TRUE; return AIR_TRUE; } tmp = airEnumVal(airBool, env); if (airEnumUnknown(airBool) == tmp) { return AIR_FALSE; } else { *val = tmp; return AIR_TRUE; } }
unsigned int airParseStrB(int *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] = airEnumVal(airBool, tmp); if (airEnumUnknown(airBool) == out[i]) { free(s); return i; } } free(s); return n; }
int airEnumVal(const airEnum *enm, const char *str) { char *strCpy, test[AIR_STRLEN_SMALL]; unsigned int ii; if (!str) { return airEnumUnknown(enm); } strCpy = airStrdup(str); if (!enm->sense) { airToLower(strCpy); } if (enm->strEqv) { /* want strlen and not airStrlen here because the strEqv array should be terminated by a non-null empty string */ for (ii=0; strlen(enm->strEqv[ii]); ii++) { strncpy(test, enm->strEqv[ii], AIR_STRLEN_SMALL); test[AIR_STRLEN_SMALL-1] = '\0'; if (!enm->sense) { airToLower(test); } if (!strcmp(test, strCpy)) { free(strCpy); return enm->valEqv[ii]; } } } else { /* enm->strEqv NULL */ for (ii=1; ii<=enm->M; ii++) { strncpy(test, enm->str[ii], AIR_STRLEN_SMALL); test[AIR_STRLEN_SMALL-1] = '\0'; if (!enm->sense) { airToLower(test); } if (!strcmp(test, strCpy)) { free(strCpy); return enm->val ? enm->val[ii] : (int)ii; /* HEY scrutinize cast */ } } } /* else we never matched a string */ free(strCpy); return airEnumUnknown(enm); }
/* ******** airEnumFmtDesc() ** ** Formats a description line for one element "val" of airEnum "enm", ** and puts the result in a NEWLY ALLOCATED string which is the return ** of this function. The formatting is done via sprintf(), as governed ** by "fmt", which should contain to "%s" conversion sequences, the ** first for the string version "val", and the second for the ** description If "canon", then the canonical string representation ** will be used (the one in enm->str[]), otherwise the shortest string ** representation will be used (which differs from the canonical one ** when there is a strEqv[]/valEqv[] pair defining a shorter string) */ char * airEnumFmtDesc(const airEnum *enm, int val, int canon, const char *fmt) { const char *desc; char *buff, ident[AIR_STRLEN_SMALL]; const char *_ident; int i; size_t len; if (!(enm && enm->desc && fmt)) { return airStrdup("(airEnumDesc: invalid args)"); } if (airEnumValCheck(enm, val)) { val = airEnumUnknown(enm); } _ident = airEnumStr(enm, val); if (!canon && enm->strEqv) { len = airStrlen(_ident); for (i=0; airStrlen(enm->strEqv[i]); i++) { if (val != enm->valEqv[i]) { /* this isn't a string representing the value we care about */ continue; } if (airStrlen(enm->strEqv[i]) < len) { /* this one is shorter */ len = airStrlen(enm->strEqv[i]); _ident = enm->strEqv[i]; } } } strncpy(ident, _ident, AIR_STRLEN_SMALL); ident[AIR_STRLEN_SMALL-1] = '\0'; if (!enm->sense) { airToLower(ident); } desc = enm->desc[_airEnumIndex(enm, val)]; buff = AIR_CALLOC(airStrlen(fmt) + airStrlen(ident) + airStrlen(desc) + 1, char); if (buff) { sprintf(buff, fmt, ident, desc); } return buff; }
int nrrdGetenvEnum(int *val, char **envStr, const airEnum *enm, const char *envVar) { char *env; int tmp; if (!(val && envVar)) { return -1; } env = getenv(envVar); if (envStr) { *envStr = env; } if (!env) { return -1; } tmp = airEnumVal(enm, env); if (airEnumUnknown(enm) == tmp) { return AIR_FALSE; } else { *val = tmp; return AIR_TRUE; } }