Annotation of os2sdk/startup/wild.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.