home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-1 / WILDEX20.C < prev    next >
Text File  |  2000-06-30  |  7KB  |  296 lines

  1.  
  2. /*
  3.     WILDEXP.C     v2.0    5/10/84
  4.     BDS C Command-line Wild-card expansion utility.
  5.  
  6.     Written by Leor Zolman. Various sections of the code were
  7.     added/fixed by:
  8.         W. Earnest, Dave Hardy, Gary P. Novosielski,
  9.         Bob Mathias and others (thanks, y'all!)
  10.  
  11.     New for v2.0:
  12.         User area prefixes on wildcards are now permitted;
  13.         '*' or '?' as user number searches ALL user areas (0-15).
  14.         As usual by BDS C convention: if both a drive spec and a
  15.         user area prefix are used with the same file spec, then
  16.         the user area prefix must be first.
  17.  
  18.     General Description:
  19.  
  20.     WILDEXP lets ambiguous file names appear on the command line to C
  21.     programs, automatically expanding the parameter list to contain
  22.     all files that fit the afn's.
  23.  
  24.     An afn preceded by a "!" causes all names matching the given afn to
  25.     be EXCLUDED from the resulting expansion list. Thus, to yield a
  26.     command line containing all files except "COM" files, you'd say:
  27.  
  28.         A>progname !*.com <cr>
  29.  
  30.     (If a single "!" spec is the only parameter on the command line,
  31.     then an implicit "*.*" is assumed to have preceded it.)
  32.  
  33.     Another example: to get all files on B: except .C files, say:
  34.  
  35.         A>prognam b:*.* !b:*.c <cr>
  36.  
  37.     When giving a "!" afn, "*" chars in the string matches to the end of
  38.     either the filename or extension, just like CP/M, but "?" chars match
  39.     ONE and ONLY ONE character in either the filename or extension.
  40.  
  41.  
  42.     To use WILDEXP, begin your "main" function as follows:
  43.  
  44.     ---------------------------------------------
  45.     main(argc,argv)
  46.     char **argv;
  47.     {
  48.         ...                 /* local declarations  */
  49.         wildexp(&argc,&argv, sys);   /* perform wildexp expansions */
  50.         dioinit(&argc,argv);         /* if using DIO, put this here */
  51.          .
  52.         .
  53.         .
  54.     ---------------------------------------------
  55.  
  56.     "sys" tells WILDEXP whether or not to recognize "system" (invisible)
  57.     files during ambiguous file name expansions. If true (non-zero), then
  58.     system files are seen, otherwise not. See the "CP.C" program for an
  59.     example of how a command line option can be used to control this
  60.     feature  of WILDEXP.
  61.  
  62.     Link WILDEXP.CRL in with your program by including it on the CLINK
  63.     command line. That's all there is to it.
  64.  
  65.     Note that "wildexp" uses the "sbrk" function to obtain storage,
  66.     so don't go playing around with memory that is outside of the
  67.     external or stack areas unless you obtain the memory through "sbrk"
  68.     or "alloc" calls.
  69. */
  70.  
  71. #include    <bdscio.h>
  72. #define        MAXITEMS    512    /* max no. of items after expansion */
  73. #define        SEARCH_FIRST    17    /* BDOS calls */
  74. #define        SEARCH_NEXT    18
  75. #define        SET_DMA        26
  76.  
  77. wildexp(oargcp, oargvp, sysflag)
  78. int    *oargcp;        /* pointer to old argc */
  79. char    ***oargvp;        /* pointer to old argv */
  80. int    sysflag;        /* TRUE to include system (invisible) files */
  81. {
  82.     int    nargc;        /* new argc */
  83.     char    **nargv;    /* new argv */
  84.     char    **oargv;    /* old argv */
  85.     int    oargc;        /* old argc */
  86.     char    fcb[36];    /* fcb used for search for first/next calls */
  87.     char    dmapos;        /* value returned by search calls */
  88.     char    first_time;    /* used in search routine */
  89.     char    tmpfn[20],    /* temp filename buffer */
  90.         *tmpfnp;
  91.     char     tmpfn2[25];
  92.     char    *notfns[20];    /* list of !<afn> entries */
  93.     int    notcount;    /* count of entries in notfns */
  94.  
  95.     char    cur_drive;    /* currently logged drive */
  96.     char     cur_usr;    /* currently logged user area */
  97.     int    first_usr;    /* range of user areas in which to search */
  98.     int    last_usr;    /* for a given wild-card filename */
  99.     int    exp_usr;    /* explicit user area prefix given? */
  100.  
  101.     char    *str;
  102.     int    i,j,k;
  103.  
  104.     bdos(SET_DMA, 0x80);        /* set default DMA address */
  105.  
  106.     cur_drive = bdos(25);        /* get current drive    */
  107.     cur_usr = bdos(32, 0xff);    /* and user area    */
  108.  
  109.     oargv = *oargvp;
  110.     oargc = *oargcp;
  111.     nargc = 1;
  112.     notcount = 0;
  113.  
  114.     if ((nargv = sbrk(MAXITEMS * 2 + 4)) == ERROR)
  115.         return ERROR;
  116.  
  117.     for (i = 1;(nargc <= (MAXITEMS+1)) && i < oargc; i++)
  118.     {
  119.         first_usr = last_usr = cur_usr;
  120.         tmpfnp = tmpfn;
  121.         str = oargv[i];
  122.         if (*str == '!') {
  123.             if (i == 1) {
  124.                 oargv[oargc] = "*.*";
  125.                 oargc++;
  126.             }                
  127.             notfns[notcount++] = &oargv[i][1];
  128.         }
  129.         else if (!haswild(str))
  130.             nargv[nargc++] = str;
  131.         else {
  132.            exp_usr = hasuno(str);
  133.  
  134.            if (exp_usr) {        /* explicit user area spec? */
  135.             if (*str == '*' || *str == '?')
  136.                 { first_usr = 0; last_usr = 15; }
  137.             else
  138.                 first_usr = last_usr = atoi(str);
  139.             while (*str++ != '/')
  140.                 ;
  141.            }
  142.  
  143.            setfcb(fcb,str);    /* set up fcb for searching */
  144.            if ((tmpfn[1] = str[1]) == ':')
  145.            {
  146.             tmpfn[0] = str[0];
  147.             tmpfnp = tmpfn + 2;
  148.             bdos(14,tmpfn[0] - 'A');
  149.            }
  150.  
  151.            for (j = first_usr; j <= last_usr; j++)
  152.            {
  153.              bdos(32, j);
  154.              first_time = TRUE;
  155.              while (nargc <= (MAXITEMS+1))  /* find matching files */
  156.              {
  157.             dmapos = bdos(first_time ? SEARCH_FIRST : SEARCH_NEXT,
  158.                                     fcb);
  159.             if (dmapos == 255) break;
  160.             first_time = FALSE;
  161.  
  162.             if (sysflag || peek((BASE + 0x8A) + dmapos * 32) < 128)
  163.             {
  164.             
  165.               hackname(tmpfnp,(BASE + 0x80 + dmapos * 32));
  166.               tmpfn2[0] = '\0';
  167.               if (exp_usr)
  168.                 sprintf(tmpfn2, "%d/", j);
  169.               strcat(tmpfn2,tmpfn);
  170.  
  171.               if ((nargv[nargc] = sbrk(strlen(tmpfn2) + 1))==ERROR)
  172.                   return ERROR;
  173.               strcpy(nargv[nargc++], tmpfn2);
  174.             }
  175.              }
  176.            }
  177.            bdos(14,cur_drive);        /* restore to current drive */
  178.            bdos(32,cur_usr);        /* and use area */
  179.         }
  180.  
  181.     }
  182.     for (i = 0; i < notcount; i++)
  183.         for (j = 1; j < nargc; j++)
  184.             while (match(notfns[i],nargv[j],cur_drive))
  185.             {
  186.                 if(j == --nargc)
  187.                     break;
  188.                 for (k = j; k < nargc; k++)
  189.                     nargv[k] = nargv[k+1];
  190.             }
  191.     *oargcp = nargc;
  192.     *oargvp = nargv;
  193.     return 0;
  194. }
  195.  
  196. hackname(dest,source)
  197. char *dest, *source;
  198. {
  199.     int i,j;
  200.  
  201.     j = 0;
  202.  
  203. /* Remove attributes first so compares will work */
  204.     for (i = 1; i < 12; i++) source[i] &= 0x7F;
  205.  
  206.     for (i = 1; i < 9; i++)
  207.     {
  208.         if (source[i] == ' ') break;
  209.         dest[j++] = source[i];
  210.     }
  211.     if (source[9] != ' ')
  212.         dest[j++] = '.';
  213.  
  214.     for (i = 9; i < 12; i++)
  215.     {
  216.         if (source[i] == ' ') break;
  217.         dest[j++] = source[i];
  218.     }
  219.     dest[j] = '\0';
  220.     return dest;
  221. }
  222.  
  223. int haswild(fname)
  224. char *fname;
  225. {
  226.     char c;
  227.  
  228.     while (c = *fname++)
  229.         if (c == '*' || c == '?') 
  230.             return TRUE;
  231.     return FALSE;
  232. }
  233.  
  234. int match(wildnam, filnam, cur_drive)
  235. char *wildnam, *filnam, cur_drive;
  236. {
  237.    char c;
  238.  
  239.    if (wildnam[1] != ':')
  240.    {
  241.     if (filnam[1] == ':')
  242.         if (filnam[0] - 'A' == cur_drive)
  243.             filnam += 2;
  244.         else
  245.             return FALSE;
  246.    }
  247.    else
  248.    {
  249.     if (filnam[1] != ':')
  250.         if (wildnam[0] - 'A' == cur_drive)
  251.             wildnam += 2;
  252.         else
  253.             return FALSE;
  254.    }
  255.  
  256.    while (c = *wildnam++)
  257.     if (c == '?')
  258.         if ((c = *filnam++) && c != '.')
  259.             continue;
  260.         else
  261.             return FALSE;
  262.     else if (c == '*')
  263.     {
  264.         while (c = *wildnam)
  265.         {     wildnam++;
  266.             if (c == '.') break;
  267.         }
  268.         while (c = *filnam)
  269.         {    filnam++;
  270.             if (c == '.') break;
  271.         }
  272.     }
  273.     else if (c == *filnam++)
  274.          continue;
  275.     else return FALSE;
  276.  
  277.    if (!*filnam)
  278.     return TRUE;
  279.    else
  280.     return FALSE;
  281. }
  282.  
  283.  
  284. int hasuno(str)       /* return true if filename string has user num. prefix */
  285. char *str;
  286. {
  287.     if (str[1] == '/' && (*str == '*' || *str == '?'))
  288.         return TRUE;
  289.  
  290.     if (isdigit(*str++))
  291.         return (*str == '/' || isdigit(*str++) && *str == '/');
  292.     else
  293.         return FALSE;
  294. }
  295.  
  296.