/* ** wild.c ** wildcard expander ** ** handles '*' (none or more of any char), '?' (exactly one char), and ** '[string]' (chars which match string chars or between n1 and n2 if 'n1-n2' ** in string inclusive) ** */ #include #include #include /* ** these are the data structures ** ** [_psp]:81 ** Raw command line. ** ** __argv ** ------- ------ ** | |---->| |---->"arg0" ** ------- ------ ** | |---->"arg1" ** ------ ** .... ** ------ ** | |---->"argn" ** ------ ** |NULL| ** ------ */ #define SLASHCHAR '\\' #define FWDSLASHCHAR '/' #define SLASH "\\" #define FWDSLASH "/" char *_hfind(); extern int __argc; extern int __argl; extern char **__argv; static int _add(int, char ***, char far *, char far *, int ); static int _match(char far *, char ***, char far *, int ); static _sort (char **); static _hmmcpy( a, b, n ) char *a, far *b; int n; { REG1 int i; for ( i = 0; i < n; i++ ) *( a + i ) = *( b + i ); } char ** _cwild ( argv, pass, arg ) char **argv; int pass; char far *arg; { char savechar; char far *wchar; char far *arghead = arg; int ptr, sptr, arglen; _setdta(); while ( *arg && ( *arg != ' ' ) && ( *arg != '\t' ) && ( *arg != '\15' )) arg++; savechar = *arg; /* save this character, since it is in psp */ *arg = '\0'; for ( wchar = arghead; wchar && ( *wchar != '*' ) && ( *wchar != '?' ); wchar++ ); _match( wchar, &argv, arghead, pass ); *arg = savechar; /* restore this character */ return( argv ); } static int _match ( ptr, argv, arg, pass) char far *ptr; char ***argv; char far *arg; int pass; { char *new; int length; char **oldargv = *argv; int gotone = 0; if ( pass == 1 ) --__argc; while (ptr != arg && *ptr != SLASHCHAR && *ptr != FWDSLASHCHAR && *ptr != ':') /* find first slash or ':' before wildcard */ ptr--; if (*ptr == ':' && ptr != arg+1) /* weird name, just add it as is */ return( _add( 0, argv, arg, (char far *)NULL, pass ) ); if (*ptr == SLASHCHAR || *ptr == FWDSLASHCHAR || *ptr == ':') /* pathname */ length = ptr - arg + 1; /* length of dir prefix */ if (new = _hfind(arg)) { /* get the first file name */ do { /* got a file name */ if (strcmp(new, ".") && strcmp(new, "..")) { if (*ptr != SLASHCHAR && *ptr != ':' && *ptr != FWDSLASHCHAR ) { /* current directory; don't need path */ if ( _add( 0, argv, (char far *)new, (char far *)NULL, pass ) ) return(-1); } else /* add full pathname */ if ( _add( length, argv, (char far *)new, arg, pass) ) return(-1); gotone++; } } while (new = _hfind(NULL)); /* get following files */ if (gotone) { if ( pass == 2 ) { new = **argv; **argv = NULL; _sort(oldargv); **argv = new; } return(0); } } return( _add( 0, argv, arg, (char far *)NULL, pass) ); /* no match */ } static int _add(length, argv, arg, prfxstr, pass ) int length; char ***argv; char far *arg; char far *prfxstr; { int argln = 1, prfln = 0; char far *argcnt = arg, far *prfcnt = prfxstr; while ( *argcnt ) { argln++; argcnt++; } while ( *prfcnt ) { prfln++; prfcnt++; } if ( pass == 1 ) { __argc++; __argl += argln + length; } else /* pass 2 actually build the arg */ { if ( length ) _hmmcpy( (char *)**argv, (char far *)prfxstr, prfln ); _hmmcpy( (char *)**argv + length, arg, argln ); (*argv)++; **argv = (char *)(*(*argv - 1) + argln + length); } return(0); } static _sort (first) char **first; { char *temp, **last; if (!*first) return; while (*first) { last = first; while (*++last) { if (strcmp(*last, *first) < 0) { temp = *first; *first = *last; *last = temp; } } ++first; } }