Return to stack.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / sntp / libopts |
1.1 ! misho 1: ! 2: /** ! 3: * \file stack.c ! 4: * ! 5: * Time-stamp: "2010-07-17 10:42:27 bkorb" ! 6: * ! 7: * This is a special option processing routine that will save the ! 8: * argument to an option in a FIFO queue. ! 9: * ! 10: * This file is part of AutoOpts, a companion to AutoGen. ! 11: * AutoOpts is free software. ! 12: * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved ! 13: * ! 14: * AutoOpts is available under any one of two licenses. The license ! 15: * in use must be one of these two and the choice is under the control ! 16: * of the user of the license. ! 17: * ! 18: * The GNU Lesser General Public License, version 3 or later ! 19: * See the files "COPYING.lgplv3" and "COPYING.gplv3" ! 20: * ! 21: * The Modified Berkeley Software Distribution License ! 22: * See the file "COPYING.mbsd" ! 23: * ! 24: * These files have the following md5sums: ! 25: * ! 26: * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 ! 27: * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 ! 28: * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd ! 29: */ ! 30: ! 31: #ifdef WITH_LIBREGEX ! 32: # include REGEX_HEADER ! 33: #endif ! 34: ! 35: /*=export_func optionUnstackArg ! 36: * private: ! 37: * ! 38: * what: Remove option args from a stack ! 39: * arg: + tOptions* + pOpts + program options descriptor + ! 40: * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + ! 41: * ! 42: * doc: ! 43: * Invoked for options that are equivalenced to stacked options. ! 44: =*/ ! 45: void ! 46: optionUnstackArg( ! 47: tOptions* pOpts, ! 48: tOptDesc* pOptDesc ) ! 49: { ! 50: int res; ! 51: ! 52: tArgList* pAL; ! 53: ! 54: if ((pOptDesc->fOptState & OPTST_RESET) != 0) ! 55: return; ! 56: pAL = (tArgList*)pOptDesc->optCookie; ! 57: ! 58: /* ! 59: * IF we don't have any stacked options, ! 60: * THEN indicate that we don't have any of these options ! 61: */ ! 62: if (pAL == NULL) { ! 63: pOptDesc->fOptState &= OPTST_PERSISTENT_MASK; ! 64: if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0) ! 65: pOptDesc->fOptState |= OPTST_DISABLED; ! 66: return; ! 67: } ! 68: ! 69: #ifdef WITH_LIBREGEX ! 70: { ! 71: regex_t re; ! 72: int i, ct, dIdx; ! 73: ! 74: if (regcomp(&re, pOptDesc->optArg.argString, REG_NOSUB) != 0) ! 75: return; ! 76: ! 77: /* ! 78: * search the list for the entry(s) to remove. Entries that ! 79: * are removed are *not* copied into the result. The source ! 80: * index is incremented every time. The destination only when ! 81: * we are keeping a define. ! 82: */ ! 83: for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) { ! 84: tCC* pzSrc = pAL->apzArgs[ i ]; ! 85: char* pzEq = strchr(pzSrc, '='); ! 86: ! 87: if (pzEq != NULL) ! 88: *pzEq = NUL; ! 89: ! 90: res = regexec(&re, pzSrc, (size_t)0, NULL, 0); ! 91: switch (res) { ! 92: case 0: ! 93: /* ! 94: * Remove this entry by reducing the in-use count ! 95: * and *not* putting the string pointer back into ! 96: * the list. ! 97: */ ! 98: AGFREE(pzSrc); ! 99: pAL->useCt--; ! 100: break; ! 101: ! 102: default: ! 103: case REG_NOMATCH: ! 104: if (pzEq != NULL) ! 105: *pzEq = '='; ! 106: ! 107: /* ! 108: * IF we have dropped an entry ! 109: * THEN we have to move the current one. ! 110: */ ! 111: if (dIdx != i) ! 112: pAL->apzArgs[ dIdx ] = pzSrc; ! 113: dIdx++; ! 114: } ! 115: } ! 116: ! 117: regfree(&re); ! 118: } ! 119: #else /* not WITH_LIBREGEX */ ! 120: { ! 121: int i, ct, dIdx; ! 122: ! 123: /* ! 124: * search the list for the entry(s) to remove. Entries that ! 125: * are removed are *not* copied into the result. The source ! 126: * index is incremented every time. The destination only when ! 127: * we are keeping a define. ! 128: */ ! 129: for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) { ! 130: tCC* pzSrc = pAL->apzArgs[ i ]; ! 131: char* pzEq = strchr(pzSrc, '='); ! 132: ! 133: if (pzEq != NULL) ! 134: *pzEq = NUL; ! 135: ! 136: if (strcmp(pzSrc, pOptDesc->optArg.argString) == 0) { ! 137: /* ! 138: * Remove this entry by reducing the in-use count ! 139: * and *not* putting the string pointer back into ! 140: * the list. ! 141: */ ! 142: AGFREE(pzSrc); ! 143: pAL->useCt--; ! 144: } else { ! 145: if (pzEq != NULL) ! 146: *pzEq = '='; ! 147: ! 148: /* ! 149: * IF we have dropped an entry ! 150: * THEN we have to move the current one. ! 151: */ ! 152: if (dIdx != i) ! 153: pAL->apzArgs[ dIdx ] = pzSrc; ! 154: dIdx++; ! 155: } ! 156: } ! 157: } ! 158: #endif /* WITH_LIBREGEX */ ! 159: /* ! 160: * IF we have unstacked everything, ! 161: * THEN indicate that we don't have any of these options ! 162: */ ! 163: if (pAL->useCt == 0) { ! 164: pOptDesc->fOptState &= OPTST_PERSISTENT_MASK; ! 165: if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0) ! 166: pOptDesc->fOptState |= OPTST_DISABLED; ! 167: AGFREE((void*)pAL); ! 168: pOptDesc->optCookie = NULL; ! 169: } ! 170: } ! 171: ! 172: ! 173: /* ! 174: * Put an entry into an argument list. The first argument points to ! 175: * a pointer to the argument list structure. It gets passed around ! 176: * as an opaque address. ! 177: */ ! 178: LOCAL void ! 179: addArgListEntry(void** ppAL, void* entry) ! 180: { ! 181: tArgList* pAL = *(void**)ppAL; ! 182: ! 183: /* ! 184: * IF we have never allocated one of these, ! 185: * THEN allocate one now ! 186: */ ! 187: if (pAL == NULL) { ! 188: pAL = (tArgList*)AGALOC(sizeof(*pAL), "new option arg stack"); ! 189: if (pAL == NULL) ! 190: return; ! 191: pAL->useCt = 0; ! 192: pAL->allocCt = MIN_ARG_ALLOC_CT; ! 193: *ppAL = (void*)pAL; ! 194: } ! 195: ! 196: /* ! 197: * ELSE if we are out of room ! 198: * THEN make it bigger ! 199: */ ! 200: else if (pAL->useCt >= pAL->allocCt) { ! 201: size_t sz = sizeof(*pAL); ! 202: pAL->allocCt += INCR_ARG_ALLOC_CT; ! 203: ! 204: /* ! 205: * The base structure contains space for MIN_ARG_ALLOC_CT ! 206: * pointers. We subtract it off to find our augment size. ! 207: */ ! 208: sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT); ! 209: pAL = (tArgList*)AGREALOC((void*)pAL, sz, "expanded opt arg stack"); ! 210: if (pAL == NULL) ! 211: return; ! 212: *ppAL = (void*)pAL; ! 213: } ! 214: ! 215: /* ! 216: * Insert the new argument into the list ! 217: */ ! 218: pAL->apzArgs[ (pAL->useCt)++ ] = entry; ! 219: } ! 220: ! 221: ! 222: /*=export_func optionStackArg ! 223: * private: ! 224: * ! 225: * what: put option args on a stack ! 226: * arg: + tOptions* + pOpts + program options descriptor + ! 227: * arg: + tOptDesc* + pOptDesc + the descriptor for this arg + ! 228: * ! 229: * doc: ! 230: * Keep an entry-ordered list of option arguments. ! 231: =*/ ! 232: void ! 233: optionStackArg( ! 234: tOptions* pOpts, ! 235: tOptDesc* pOD ) ! 236: { ! 237: char * pz; ! 238: ! 239: if ((pOD->fOptState & OPTST_RESET) != 0) { ! 240: tArgList* pAL = (void*)pOD->optCookie; ! 241: int ix; ! 242: if (pAL == NULL) ! 243: return; ! 244: ! 245: ix = pAL->useCt; ! 246: while (--ix >= 0) ! 247: AGFREE(pAL->apzArgs[ix]); ! 248: AGFREE(pAL); ! 249: ! 250: } else { ! 251: if (pOD->optArg.argString == NULL) ! 252: return; ! 253: ! 254: AGDUPSTR(pz, pOD->optArg.argString, "stack arg"); ! 255: addArgListEntry(&(pOD->optCookie), (void*)pz); ! 256: } ! 257: } ! 258: /* ! 259: * Local Variables: ! 260: * mode: C ! 261: * c-file-style: "stroustrup" ! 262: * indent-tabs-mode: nil ! 263: * End: ! 264: * end of autoopts/stack.c */