|
|
1.1 ! root 1: /*** ! 2: *wild.c - wildcard expander ! 3: * ! 4: * Copyright (c) 1985-1987, Microsoft Corporation. All rights reserved. ! 5: * ! 6: *Purpose: ! 7: * expands wildcards in argv ! 8: * ! 9: * handles '*' (none or more of any char), '?' (exactly one char), and ! 10: * '[string]' (chars which match string chars or between n1 and n2 if ! 11: * 'n1-n2'in string inclusive) ! 12: * ! 13: *******************************************************************************/ ! 14: ! 15: #include <stdio.h> ! 16: #include <register.h> ! 17: #include <ctype.h> ! 18: #include <msdos.h> ! 19: ! 20: ! 21: /* ! 22: ** these are the data structures ! 23: ** ! 24: ** __argv ! 25: ** ------- ------ ! 26: ** | |---->| |---->"arg0" ! 27: ** ------- ------ ! 28: ** | |---->"arg1" ! 29: ** ------ ! 30: ** .... ! 31: ** ------ ! 32: ** | |---->"argn" ! 33: ** ------ ! 34: ** |NULL| ! 35: ** ------ ! 36: ** argend ! 37: ** ------- ! 38: ** ------- | | ! 39: ** | | __argc ------- ! 40: ** ------- | ! 41: ** | ! 42: ** arghead V ! 43: ** ------ --------- ---------- ! 44: ** | |---->| | |----> .... ---->| |NULL| ! 45: ** ------ --------- ---------- ! 46: ** | | ! 47: ** V V ! 48: ** "narg0" "nargn" ! 49: */ ! 50: ! 51: #define SLASHCHAR '\\' ! 52: #define FWDSLASHCHAR '/' ! 53: #define SLASH "\\" ! 54: #define FWDSLASH "/" ! 55: #define STAR "*.*" ! 56: ! 57: #define WILDSTRING "*?" ! 58: ! 59: char *strdup(); ! 60: char *strpbrk(); ! 61: char *strcpy(); ! 62: char *strncpy(); ! 63: char *strcat(); ! 64: char *malloc(); ! 65: char *_find(); ! 66: ! 67: static int match (); ! 68: static int add (); ! 69: static sort (); ! 70: ! 71: extern int __argc; ! 72: extern char **__argv; ! 73: ! 74: struct argnode { ! 75: char *argptr; ! 76: struct argnode *nextnode; ! 77: }; ! 78: ! 79: static struct argnode *arghead; ! 80: static struct argnode *argend; ! 81: ! 82: /*** ! 83: *int _cwild() - wildcard expander ! 84: * ! 85: *Purpose: ! 86: * expands wildcard in file specs in argv ! 87: * ! 88: * handles '*' (none or more of any char), '?' (exactly one char), and ! 89: * '[string]' (chars which match string chars or between n1 and n2 ! 90: * if 'n1-n2' in string inclusive) ! 91: * ! 92: *Entry: ! 93: * ! 94: *Exit: ! 95: * returns 0 if successful, -1 if any malloc() calls fail ! 96: * if problems with malloc, the old argc and argv are not touched ! 97: * ! 98: *Exceptions: ! 99: * ! 100: *******************************************************************************/ ! 101: ! 102: int ! 103: _cwild () ! 104: { ! 105: REG1 char **argv = __argv; ! 106: REG2 struct argnode *nodeptr; ! 107: REG3 int argc; ! 108: REG4 char **tmp; ! 109: char *wchar; ! 110: int ptr, sptr, arglen; ! 111: ! 112: arghead = argend = NULL; ! 113: ! 114: for (argv = __argv; *argv; argv++) /* for each arg... */ ! 115: if ( *(*argv)++ == '"' ) ! 116: /* strip leading quote from quoted arg */ ! 117: { ! 118: if (add(*argv)) ! 119: return(-1); ! 120: } ! 121: else if (wchar = strpbrk( *argv, WILDSTRING )) { ! 122: /* attempt to expand arg with wildcard */ ! 123: if (match( *argv, wchar )) ! 124: return(-1); ! 125: } ! 126: else if (add( *argv )) /* normal arg, just add */ ! 127: return(-1); ! 128: ! 129: /* count the args */ ! 130: for (argc = 0, nodeptr = arghead; nodeptr; ! 131: nodeptr = nodeptr->nextnode, argc++) ! 132: ; ! 133: ! 134: /* try to get new arg vector */ ! 135: if (!(tmp = (char **)malloc(sizeof(char *)*(argc+1)))) ! 136: return(-1); ! 137: ! 138: /* the new arg vector... */ ! 139: __argv = tmp; ! 140: ! 141: /* the new arg count... */ ! 142: __argc = argc; ! 143: ! 144: /* install the new args */ ! 145: for (nodeptr = arghead; nodeptr; nodeptr = nodeptr->nextnode) ! 146: *tmp++ = nodeptr->argptr; ! 147: ! 148: /* the terminal NULL */ ! 149: *tmp = NULL; ! 150: ! 151: /* free up local data */ ! 152: for (nodeptr = arghead; nodeptr; nodeptr = arghead) { ! 153: arghead = arghead->nextnode; ! 154: free(nodeptr); ! 155: } ! 156: ! 157: /* return success */ ! 158: return(0); ! 159: } ! 160: ! 161: ! 162: /*** ! 163: *match(arg, ptr) - [STATIC] ! 164: * ! 165: *Purpose: ! 166: * ! 167: *Entry: ! 168: * ! 169: *Exit: ! 170: * ! 171: *Exceptions: ! 172: * ! 173: *******************************************************************************/ ! 174: ! 175: static int ! 176: match (arg, ptr) ! 177: REG4 char *arg; ! 178: REG1 char *ptr; ! 179: { ! 180: REG2 char *new; ! 181: REG3 int length; ! 182: char *all; ! 183: REG5 struct argnode *first; ! 184: REG6 int gotone = 0; ! 185: ! 186: while (ptr != arg && *ptr != SLASHCHAR && *ptr != FWDSLASHCHAR ! 187: && *ptr != ':') { ! 188: /* find first slash or ':' before wildcard */ ! 189: ptr--; ! 190: } ! 191: ! 192: if (*ptr == ':' && ptr != arg+1) /* weird name, just add it as is */ ! 193: return(add(arg)); ! 194: ! 195: if (*ptr == SLASHCHAR || *ptr == FWDSLASHCHAR ! 196: || *ptr == ':') /* pathname */ ! 197: length = ptr - arg + 1; /* length of dir prefix */ ! 198: ! 199: if (new = _find(arg)) { /* get the first file name */ ! 200: first = argend; ! 201: ! 202: do { /* got a file name */ ! 203: if (strcmp(new, ".") && strcmp(new, "..")) { ! 204: if (*ptr != SLASHCHAR && *ptr != ':' ! 205: && *ptr != FWDSLASHCHAR ) { ! 206: /* current directory; don't need path */ ! 207: if (!(arg = strdup(new)) || add(arg)) ! 208: return(-1); ! 209: } ! 210: else /* add full pathname */ ! 211: if (!(all=malloc(length+strlen(new)+1)) ! 212: || add(strcpy(strncpy(all,arg,length)+length,new) ! 213: - length)) ! 214: return(-1); ! 215: ! 216: gotone++; ! 217: } ! 218: ! 219: } ! 220: while (new = _find(NULL)); /* get following files */ ! 221: ! 222: if (gotone) { ! 223: sort(first ? first->nextnode : arghead); ! 224: return(0); ! 225: } ! 226: } ! 227: ! 228: return(add(arg)); /* no match */ ! 229: } ! 230: ! 231: /*** ! 232: *add(arg) - [STATIC] ! 233: * ! 234: *Purpose: ! 235: * ! 236: *Entry: ! 237: * ! 238: *Exit: ! 239: * ! 240: *Exceptions: ! 241: * ! 242: *******************************************************************************/ ! 243: ! 244: static int ! 245: add (arg) ! 246: char *arg; ! 247: { ! 248: REG1 struct argnode *nodeptr; ! 249: ! 250: if (!(nodeptr = (struct argnode *)malloc(sizeof(struct argnode)))) ! 251: return(-1); ! 252: ! 253: nodeptr->argptr = arg; ! 254: nodeptr->nextnode = NULL; ! 255: ! 256: if (arghead) ! 257: argend->nextnode = nodeptr; ! 258: else ! 259: arghead = nodeptr; ! 260: ! 261: argend = nodeptr; ! 262: return(0); ! 263: } ! 264: ! 265: ! 266: /*** ! 267: *sort(first) - [STATIC] ! 268: * ! 269: *Purpose: ! 270: * ! 271: *Entry: ! 272: * ! 273: *Exit: ! 274: * ! 275: *Exceptions: ! 276: * ! 277: *******************************************************************************/ ! 278: ! 279: static ! 280: sort (first) ! 281: REG2 struct argnode *first; ! 282: { ! 283: REG1 struct argnode *nodeptr; ! 284: REG3 char *temp; ! 285: ! 286: if (first) /* something to sort */ ! 287: while (nodeptr = first->nextnode) { ! 288: do { ! 289: if (strcmp(nodeptr->argptr, first->argptr) < 0) { ! 290: temp = first->argptr; ! 291: first->argptr = nodeptr->argptr; ! 292: nodeptr->argptr = temp; ! 293: } ! 294: } ! 295: while (nodeptr = nodeptr->nextnode); ! 296: ! 297: first = first->nextnode; ! 298: } ! 299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.