Annotation of os2sdk/startup/wild.c, revision 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.