home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / directry / ztwildc / zglob.c
Encoding:
C/C++ Source or Header  |  1992-09-21  |  6.6 KB  |  179 lines

  1. /*-------------------------------- ZGLOB.C (version 1.0) ----------------------*
  2. *
  3. * NAME:
  4. *
  5. *      zglob - Zortech C++ v3.0 command line filename wildcard expansion.
  6. *
  7. * SYNOPSIS:
  8. *
  9. *      int zglob(argc, argv, attr) 
  10. *      int *argc;           <- pointer to argument.
  11. *      char **argv[];       <- pointer to argument array pointer.
  12. *      int attr;            <- file type search attributes.
  13. *
  14. * DESCRIPTION:
  15. *
  16. *      Zglob() expands command line arguments containing '*' and/or '?' into
  17. *      existing file names. The wildcards can be in the file name or extension,
  18. *      but not the path. The function arguments 'argc' and 'argv' are replaced 
  19. *      with the expanded argument count and list. Individual wildcard file name
  20. *      arguments are sorted alphabetically in the expanded argument list. The 
  21. *      attribute argument is the file attribute of the files to be found. An 
  22. *      attribute value of 0 will find all normal files. The attribute bits are
  23. *      defined in <dos.h>.
  24. *      Errors encountered during the expansion process (no match, no memory) are
  25. *      written to ERROR. Zglob() returns a 1 on success, or a 0 on failure.
  26. *      
  27. *      Zglob() uses the Zortech C++ v3.0 library functions findfirst() and 
  28. *      findnext(). All other function calls are ANSI compliant. A singly linked
  29. *      list is first built containing pointers to the expanded file names. When
  30. *      the original argument list is exhausted, an array of pointers (argv) to 
  31. *      character strings is allocated. The argument pointers in the linked list
  32. *      are then copied to the new argv. A vector of integers, which point to 
  33. *      where to old arguments start in the new argv, is also built. The integer
  34. *      vector is used with qsort() to alphabetize individual wildcard arguments.
  35. *
  36. * USAGE:
  37. *
  38. *      main(int argc, char *argv[])
  39. *      {
  40. *         int i;
  41. *         if( !zglob(&argc,&argv,0))            <-- call with 0 attr.
  42. *             return EXIT_FAILURE;              <-- an errror occured, bye!
  43. *         for( i=0; i<argc, i++) { ... }        <-- as before, but expanded.
  44. *         
  45. * AUTHOR:
  46. *
  47. *      Version 1.0 - Jeff Dragovich (09/21/92).
  48. *
  49. * ACKNOWLEDGEMENTS:
  50. *
  51. *      This routine is modeled after, and very similar to GLOB.C, v1.06, written
  52. *      by Bob Kamins (11/28/87).
  53. *
  54. * BUGS:
  55. *
  56. *      Allocated memory is not free()'d when an error occurs. 
  57. *      File name expansion is attempted on all arguments containing a wildcard.
  58. *      Old argv and argc are lost forever.
  59. *
  60. *-----------------------------------------------------------------------------*/
  61. #include <stdio.h>  
  62. #include <dos.h>
  63. #include <string.h>
  64. #include <stdlib.h>
  65. #include <io.h>
  66.  
  67. int glob(int *, char ***, int);                 
  68. static int insert(char *);                          
  69. static int expand(char *, int);
  70. static int fcmp( char **, char **);
  71.  
  72. typedef struct node Node;         /* linked list node */
  73. struct node {
  74.     char *s;
  75.     Node *pn;
  76. };
  77.  
  78. #define ERROR stdout              /* predefined error output stream */
  79.  
  80. static struct node *phead;        /* pointer to list head */
  81. static struct node *ptail;        /* pointer to list tail */
  82. static int newc;                  /* new number of arguments */
  83. static int *srtz;                 /* integer array of pointers to elements of */
  84.                                   /* old arguments start location in new argv */
  85.  
  86. /*------------------------------------------------------------------- zglob() */
  87. int zglob(int *argc, char **argv[], int attr)
  88. {
  89.     int i;
  90.     char **pnew;
  91.     char err[] = "memory allocation error in zglob() : %s\n";
  92.     struct node *pcurr,*pnext;
  93.  
  94.     newc = 0;       /* just to make sure */
  95.     phead = NULL;
  96.  
  97.     srtz = (int *)malloc( (*argc+1)*sizeof(int) );    /* integer vector */
  98.     if( srtz == NULL )    {
  99.         fprintf(ERROR,err,"srtz");
  100.         return(0);
  101.     }
  102.  
  103.     for( i=0; i<*argc; i++) {               /* expand all arguments */
  104.         srtz[i] = newc;
  105.         if( !expand( (*argv)[i], attr ) ) return(0);
  106.     }
  107.     srtz[*argc] = newc;
  108.  
  109.     pnew = (char **)malloc( newc*sizeof(char *) );   /* new argv */
  110.     if( pnew == NULL ) {
  111.         fprintf(ERROR,err,"pnew");
  112.         return(0);
  113.     }
  114.     for( i=0, pcurr=phead; i<newc; i++) {     /* write over to new argv */
  115.         pnew[i] = pcurr->s;
  116.         pnext = pcurr->pn;
  117.         free(pcurr);                          /* free up node */
  118.         pcurr = pnext;
  119.     }
  120.     *argv = pnew;
  121.  
  122.     /* sort new argv by reference to old argv elements location */
  123.  
  124.     for( i=1; i<*argc; i++) 
  125.         qsort( &((*argv)[srtz[i]]), srtz[i+1]-srtz[i], sizeof(char**), fcmp);
  126.     *argc = newc;
  127.     free(srtz);
  128.     return(1);
  129. }
  130. /*------------------------------------------------------------------ expand() */
  131. static int expand( char *argv, int attr)
  132. {
  133.     int ret;
  134.     struct FIND *pfind;
  135.  
  136.     if( strpbrk(argv,"*?") == NULL )            /* is there a wildcard */
  137.         return( insert(argv) );                 /* no, but add to list */
  138.  
  139.     pfind = findfirst(argv,attr);               /* attempt to expand */
  140.     if( pfind == NULL ) {
  141.         fprintf(ERROR,"%s : No Match\n",argv);  /* must be a "no match" */
  142.         return(0);                              /* go back with error */
  143.     }
  144.     while( pfind != NULL ) {                    /* loop until no more matches */
  145.         ret = insert(pfind->name);      /* put expanded name in list */
  146.         if ( !ret ) return(ret);        /* must be a malloc error in insert() */
  147.         pfind = findnext();             /* get next match */
  148.     }     
  149.     return(1);                          /* everything ok */
  150. }
  151. /*------------------------------------------------------------------ insert() */
  152. static int insert(char *str)
  153. {
  154.     char *p;
  155.     struct node *nptr;
  156.  
  157.     p = (char *) malloc( strlen(str) + 1 );                /* new argv[i] */
  158.     nptr = (struct node *)malloc( sizeof(struct node) );   /* get node */
  159.     if( (p==NULL) || (nptr==NULL) ) {                      /* no memory */
  160.         fprintf(ERROR,"memory allocation failure in glob()->insert()\n");
  161.         return(0);
  162.     }
  163.     strcpy(p,str);                                     /* copy over to heap */
  164.     newc++;                                            /* another argument */
  165.  
  166.     if( phead == NULL ) phead = nptr;                  /* update linked list */
  167.     else ptail->pn = nptr;
  168.     ptail = nptr;
  169.     ptail->pn = NULL;
  170.     ptail->s = p;
  171.     return(1);
  172. }
  173. /*-------------------------------------------------------------------- fcmp() */
  174. static int fcmp( char **a, char **b )                  /* used by qsort */
  175. {
  176.     return( strcmp(*a,*b) );
  177. }
  178.