home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / program / c / WILD.ZIP / WILD.C
Encoding:
C/C++ Source or Header  |  1986-06-27  |  4.0 KB  |  208 lines

  1. /*
  2. ** wild.c
  3. ** wildcard expander
  4. **
  5. ** handles '*' (none or more of any char), '?' (exactly one char), and
  6. ** '[string]' (chars which match string chars or between n1 and n2 if 'n1-n2'
  7. ** in string inclusive)
  8. **
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <register.h>
  13. #include <ctype.h>
  14.  
  15. /*
  16. ** these are the data structures
  17. **
  18. ** [_psp]:81
  19. **    Raw command line.
  20. **
  21. **    __argv
  22. **     -------       ------
  23. **     |     |---->|    |---->"arg0"
  24. **     -------       ------
  25. **           |    |---->"arg1"
  26. **           ------
  27. **            ....
  28. **           ------
  29. **           |    |---->"argn"
  30. **           ------
  31. **           |NULL|
  32. **           ------
  33. */
  34.  
  35. #define SLASHCHAR    '\\'
  36. #define FWDSLASHCHAR '/'
  37. #define SLASH        "\\"
  38. #define FWDSLASH    "/"
  39.  
  40.  
  41. char *_hfind();
  42.  
  43. extern int __argc;
  44. extern int __argl;
  45. extern char **__argv;
  46.  
  47. static int _add(int, char ***, char far *, char far *, int );
  48. static int _match(char far *, char ***, char far *, int );
  49. static _sort (char **);
  50.  
  51. static _hmmcpy( a, b, n )
  52.   char *a, far *b;
  53.   int n;
  54. { REG1 int i;
  55.   for ( i = 0; i < n; i++ )
  56.     *( a + i ) = *( b + i );
  57. }
  58.  
  59. char **
  60. _cwild ( argv, pass, arg )
  61.  
  62. char **argv;
  63. int pass;
  64. char far *arg;
  65.  
  66.     {
  67.     char savechar;
  68.     char far *wchar;
  69.     char far *arghead = arg;
  70.     int  ptr, sptr, arglen;
  71.  
  72.     _setdta();
  73.     while ( *arg && ( *arg != ' ' ) && ( *arg != '\t' ) 
  74.              && ( *arg != '\15' ))
  75.           arg++;
  76.     savechar = *arg;        /* save this character, since it is in psp */
  77.     *arg = '\0';
  78.           
  79.     for ( wchar = arghead; wchar && ( *wchar != '*' ) && ( *wchar != '?' );
  80.         wchar++ );
  81.     _match( wchar, &argv, arghead, pass );
  82.     *arg = savechar;        /* restore this character */
  83.     return( argv );
  84.     }
  85.  
  86.  
  87.  
  88.  
  89.  static int
  90. _match ( ptr, argv, arg, pass)
  91.     char far *ptr;
  92.     char ***argv;
  93.     char far *arg;
  94.     int pass;
  95.     {
  96.     char *new;
  97.     int length;
  98.     char **oldargv = *argv;
  99.     int gotone = 0;
  100.     if ( pass == 1 )
  101.          --__argc;
  102.  
  103.     while (ptr != arg && *ptr != SLASHCHAR && *ptr != FWDSLASHCHAR
  104.            && *ptr != ':')
  105.         /* find first slash or ':' before wildcard */
  106.         ptr--;
  107.  
  108.     if (*ptr == ':' && ptr != arg+1) /* weird name, just add it as is */
  109.         return( _add( 0, argv, arg, (char far *)NULL, pass ) );
  110.  
  111.     if (*ptr == SLASHCHAR || *ptr == FWDSLASHCHAR 
  112.         || *ptr == ':') /* pathname */
  113.         length = ptr - arg + 1; /* length of dir prefix */
  114.  
  115.     if (new = _hfind(arg)) {    /* get the first file name */
  116.  
  117.         do    { /* got a file name */
  118.             if (strcmp(new, ".") 
  119.                && strcmp(new, "..")) {
  120.                 if (*ptr != SLASHCHAR && *ptr != ':'
  121.                     && *ptr != FWDSLASHCHAR ) {
  122.                     /* current directory; don't need path */
  123.                     if ( _add( 0, argv, (char far *)new,
  124.                            (char far *)NULL, pass ) )
  125.                         return(-1);
  126.                     }
  127.                 else    /* add full pathname */
  128.                     if ( _add( length, argv, 
  129.                          (char far *)new, arg, pass) )
  130.                         return(-1);
  131.                 gotone++;
  132.                 }
  133.  
  134.             } while (new = _hfind(NULL));  /* get following files */
  135.  
  136.         if (gotone) {
  137.             if ( pass == 2 )
  138.                {
  139.                 new = **argv;
  140.                 **argv = NULL;
  141.                 _sort(oldargv);
  142.                 **argv = new;
  143.                }
  144.             return(0);
  145.             }
  146.         }
  147.  
  148.     return( _add( 0, argv, arg, (char far *)NULL, pass) ); /* no match */
  149.     }
  150.  
  151.  
  152. static int
  153. _add(length, argv, arg, prfxstr, pass )
  154.     int length;
  155.     char ***argv;
  156.     char far *arg;
  157.     char far *prfxstr;
  158.     {
  159.     int argln = 1, prfln = 0;
  160.     char far *argcnt = arg, far *prfcnt = prfxstr;
  161.     while ( *argcnt )
  162.         {
  163.           argln++;
  164.           argcnt++;
  165.         }
  166.     while ( *prfcnt )
  167.         {
  168.           prfln++;
  169.           prfcnt++;
  170.         }
  171.     if ( pass == 1 )
  172.           {
  173.             __argc++;
  174.             __argl += argln + length;
  175.           }
  176.        else        /* pass 2 actually build the arg */
  177.           {
  178.             if ( length )
  179.                _hmmcpy( (char *)**argv, (char far *)prfxstr, prfln );
  180.             _hmmcpy( (char *)**argv + length, arg, argln );
  181.             (*argv)++;
  182.             **argv = (char *)(*(*argv - 1) + argln + length);
  183.           }
  184.  
  185.     return(0);
  186.     }
  187.  
  188.  
  189. static
  190. _sort (first)
  191.     char **first;
  192.     {
  193.     char *temp, **last;
  194.     if (!*first)
  195.         return;
  196.     while (*first) {
  197.         last = first;
  198.          while (*++last)    {
  199.             if (strcmp(*last, *first) < 0) {
  200.                 temp = *first;
  201.                 *first = *last;
  202.                 *last = temp;
  203.                 }
  204.             }
  205.          ++first;
  206.     }
  207. }
  208.