home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 264_01 / globargs.c < prev    next >
Text File  |  1979-12-31  |  3KB  |  135 lines

  1. /*
  2.  * globargs.c
  3.  * Link with getdir.asm to form a command line argument wildcard expander
  4.  * for Manx Aztec C86.
  5.  * Rename the real main() to _main().
  6.  *
  7.  * David MacKenzie
  8.  * Latest revision: 05/08/88
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include "getdir.h"
  13.  
  14. /* Arbitrary internal limit on filename path length. */
  15. #define MAXPATH 125
  16.  
  17. /* Granularity with which space for argv is allocated. */
  18. #define ARG_INCR 10
  19.  
  20. char   *
  21. malloc(), *realloc();
  22.  
  23. /*
  24.  * Return a pointer to the last element of the given path.
  25.  */
  26. char   *
  27. basename(p)
  28.     char   *p;
  29. {
  30.     char   *tail;
  31.  
  32.     for (tail = p; *p; ++p)
  33.     if (*p == ':' || *p == '\\')
  34.         tail = p + 1;
  35.     return tail;
  36. }
  37.  
  38. static void
  39. overflow()
  40. {
  41.     fprintf(stderr, "Too many arguments.\n");
  42.     exit(1);
  43. }
  44.  
  45. static char **
  46. initargv()
  47. {
  48.     char  **argv;
  49.  
  50.     argv = (char **) malloc(ARG_INCR * sizeof(char **));
  51.     if (!argv)
  52.     overflow();
  53.     return argv;
  54. }
  55.  
  56. /*
  57.  * Return ptr to a copy of s in newly allocated memory.
  58.  */
  59. static char *
  60. savestr(s)
  61.     char   *s;
  62. {
  63.     char   *t;
  64.  
  65.     t = malloc(strlen(s) + 1);
  66.     if (!t)
  67.     overflow();
  68.     (void) strcpy(t, s);
  69.     return t;
  70. }
  71.  
  72. /*
  73.  * Save arg at position argc in array argv.
  74.  */
  75. static char **
  76. savearg(arg, argv, argc, alloc)
  77.     char   *arg;
  78.     char  **argv;
  79.     int     argc;
  80.     int     alloc;        /* If true, allocate mem, otherwise copy ptr. */
  81. {
  82.     if (argc > 0 && argc % ARG_INCR == 0) {
  83.     argv = (char **) realloc(argv, (argc + ARG_INCR) * sizeof(char **));
  84.     if (!argv)
  85.         overflow();
  86.     }
  87.     argv[argc] = alloc ? savestr(arg) : arg;
  88.     return argv;
  89. }
  90.  
  91. main(argc, argv, envp)
  92.     int     argc;
  93.     char  **argv;
  94.     char  **envp;
  95. {
  96.     char    dirbuf[512];    /* Buffer for disk input. */
  97.     struct ffblk *dir = (struct ffblk *) dirbuf;
  98.     char    pathbuf[MAXPATH];    /* Path of globbed arguments. */
  99.     char   *tail;        /* Tail component of pathbuf. */
  100.     int     nargc;
  101.     char  **nargv;
  102.     int     optind;
  103.  
  104.     setdta(dirbuf);        /* Set disk transfer area. */
  105.  
  106.     nargc = 0;
  107.     nargv = initargv();
  108.     for (optind = 0; optind < argc; ++optind) {
  109.     if (!index(argv[optind], '*') && !index(argv[optind], '?'))
  110.         nargv = savearg(argv[optind], nargv, nargc++, 0);
  111.     else if (!getfirst(argv[optind], FA_NORMAL | FA_DIREC)) {
  112.         /*
  113.          * Copy any leading drive and/or path into pathbuf because the
  114.          * MS-DOS globbing routines return only the base of the
  115.          * filenames. 
  116.          */
  117.         (void) strcpy(pathbuf, argv[optind]);
  118.         tail = basename(pathbuf);
  119.  
  120.         do {
  121.         if (dir->ff_fname[0] != '.') {
  122.             (void) strcpy(tail, dir->ff_fname);
  123.             nargv = savearg(pathbuf, nargv, nargc++, 1);
  124.         }
  125.         } while (!getnext(argv[optind], FA_NORMAL | FA_DIREC));
  126.     } else {
  127.         fprintf(stderr, "No match.\n");
  128.         exit(1);
  129.     }
  130.     }
  131.     /* Some programs expect that argv[argc] is NULL. */
  132.     nargv = savearg(NULL, nargv, nargc, 0);
  133.     _main(nargc, nargv, envp);
  134. }
  135.