home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / e / elv17src.zip / AMIWILD.C < prev    next >
C/C++ Source or Header  |  1992-12-30  |  7KB  |  319 lines

  1. /* amiwild.c */
  2.  
  3. /*-
  4.  *    Mike Rieser                 Dale Rahn
  5.  *    2410 Happy Hollow Rd. Apt D-10        540 Vine St.
  6.  *    West Lafayette, IN 47906         West Lafayette, IN 47906
  7.  *    riesermc@mentor.cc.purdue.edu        rahn@sage.cc.purdue.edu
  8.  */
  9.  
  10. /* The following macros were defined in "vi.h". I'm undefining them so they
  11.  * don't conflict with the versions in exec/io.h.
  12.  */
  13. #ifdef CMD_READ
  14. #undef CMD_READ
  15. #undef CMD_WRITE
  16. #undef CMD_STOP
  17. #endif
  18.  
  19. /* #include <string.h> */
  20. #include <stdio.h>
  21. #include <stddef.h>
  22. #include <exec/memory.h>
  23. #include <dos/dosextens.h>
  24. #include <clib/dos_protos.h>
  25.  
  26. /* Some needed prototypes from clib/exec_protos.h */
  27. extern APTR  AllocMem(unsigned long byteSize, unsigned long requirements);
  28. extern void  FreeMem(APTR memoryBlock, unsigned long byteSize);
  29. extern struct Library *OpenLibrary(UBYTE * libName, unsigned long version);
  30. extern void  CloseLibrary(struct Library *library);
  31.  
  32. #if AZTEC_C
  33. #include <pragmas/exec_lib.h>
  34. #include <pragmas/dos_lib.h>
  35. #else
  36. #include <pragmas/exec.h>
  37. #include <pragmas/dos.h>
  38. #endif
  39.  
  40. #define    DOS_LIBRARY    ((UBYTE *) "dos.library")
  41.  
  42. #ifdef AZTEC_C
  43. /* Some needed prototypes from string.h and stdlib.h */
  44. extern char *strdup(char *);
  45. extern char *strpbrk(char *, char *);
  46. extern void *realloc(void *, size_t);
  47. extern void  free(void *);
  48. #endif
  49.  
  50. /* Dynamic Stack Routines by Mike Rieser */
  51. void         push(void *object);
  52. void        *pop(void);
  53.  
  54. #define STACK_SIZE    20
  55.  
  56. static struct stack
  57. {
  58.     void       **top, **bottom;
  59. } stack = { (void **) 0, (void **) 0 };
  60.  
  61. /* Functions */
  62.  
  63. /*-
  64.  * Only push() a pointer to the object to be stacked!
  65.  *
  66.  * The first call to push() allocates the stack's memory,
  67.  * and a push() to a full stack increases its size.
  68.  *
  69.  * WARNING:  Modification to an object after a push()
  70.  * will effect the stacked value!
  71.  */
  72. void push(void   *object)
  73. {
  74.     size_t       stack_size = stack.top - stack.bottom;
  75.  
  76.     if (0 == stack_size % STACK_SIZE)
  77.     {
  78.     stack.bottom = (void **) realloc(stack.bottom, sizeof(stack.top)
  79.                      * (stack_size + STACK_SIZE));
  80.     if ((void **) 0 == stack.bottom)
  81.     {
  82.         free(stack.bottom);
  83.         puts("Memory exhausted.");
  84.         clean_exit(10);
  85.     }
  86.     stack.top = stack.bottom + stack_size;
  87.     }
  88.     *stack.top++ = object;        /* increment the top of the stack */
  89.     return;
  90. }
  91.  
  92.  
  93. /*-
  94.  * pop() returns a pointer to the top object on the stack.
  95.  *
  96.  * pop() on the last elment frees the stack's memory.
  97.  *
  98.  * pop() on an empty stack is permitted and returns 0.
  99.  *
  100.  * NOTE: As long as you aren't trying to save NULL pointers,
  101.  * you can use pop() to tell when the stack is empty.
  102.  */
  103. void *pop(void)
  104. {
  105.     void        *object;
  106.  
  107.     if (!stack.bottom)
  108.     return (void *) 0;
  109.  
  110.     object = *--stack.top;
  111.  
  112.     if (stack.top == stack.bottom)
  113.     {
  114.     free(stack.bottom);
  115.     stack.top = stack.bottom = (void **) 0;
  116.     }
  117.     return object;
  118. }
  119.  
  120.  
  121. /*
  122.  * isOldDos - this function checks if the dos version is pre 2.x.
  123.  */
  124. int isOldDOS()
  125. {
  126.     static BOOL  OldDOS = -1;
  127.  
  128.     switch (OldDOS)
  129.     {
  130.     case 0:
  131.     break;
  132.     case 1:
  133.     break;
  134.     default:
  135.     {
  136.         struct Library *DosBase;
  137.  
  138.         if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
  139.         {
  140.         CloseLibrary(DosBase);
  141.         OldDOS = 0;
  142.         } else
  143.         {
  144.         OldDOS = 1;
  145.         }
  146.     }
  147.     }
  148.  
  149.     return OldDOS;
  150. }
  151.  
  152.  
  153. /*
  154.  * matchwild - pushes filenames which match the given pattern.
  155.  * it also returns a count of the matches found.
  156. */
  157. int matchwild(char *pattern)
  158. {
  159.     static char *special = "#?*%([|";    /* )] */
  160.     struct AnchorPath *APath;
  161.     int          matches = 0;
  162.     LONG         error;
  163.  
  164.     /* Check if correct OS */
  165.     if (isOldDOS())
  166.     return;
  167.  
  168.     /* Check if pattern is special */
  169.     if (!(strpbrk(pattern, special)))
  170.     return;
  171.  
  172.     APath = AllocMem(sizeof(struct AnchorPath) + BLKSIZE, MEMF_CLEAR);
  173.  
  174.     if (!(APath))
  175.     return;
  176.  
  177.     APath->ap_Strlen = BLKSIZE;
  178.     APath->ap_BreakBits = SIGBREAKF_CTRL_C;
  179.  
  180.     if ((error = MatchFirst((UBYTE *) pattern, APath)) == 0)
  181.     {
  182.     do
  183.     {
  184.         ++matches;
  185.         push(strdup((char *) APath->ap_Buf));
  186.     }
  187.     while ((error = MatchNext(APath)) == 0);
  188.     }
  189.     MatchEnd(APath);
  190.  
  191.     if (error != ERROR_NO_MORE_ENTRIES)
  192.     {
  193.     PrintFault(error, NULL);
  194.     }
  195.     FreeMem(APath, sizeof(struct AnchorPath) + BLKSIZE);
  196.  
  197.     return matches;
  198. }
  199.  
  200.  
  201. /*
  202.  * expand -- returns new char **argv to replace previous one. It also adjusts
  203.  * argc.
  204.  * 
  205.  * NOTE: The calling function really needs to free each element.
  206.  */
  207. char **expand(int  *argc, char **argv)
  208. {
  209.     int          i;
  210.     static char *special = "#?*%([|";    /* )] */
  211.  
  212.     for (i = 0; i < *argc; ++i)
  213.     {
  214.     if (strpbrk(argv[i], special))
  215.     {
  216.         matchwild(argv[i]);        /* expands the wildcard pattern */
  217.     } else
  218.     {
  219.         push(strdup(argv[i]));    /* Make sure nobody frees memory twice */
  220.     }
  221.     }
  222.  
  223.     *argc = stack.top - stack.bottom;
  224.     return stack.bottom;
  225. }
  226.  
  227.  
  228. /*
  229.  * This is something I wish I didn't have to participate in.
  230.  *
  231.  * wildcard - returns filename arguments in one string 
  232.  * separated by spaces.
  233.  */
  234. char *wildcard(char *names)
  235. {
  236.     int          i, count;
  237.     char        *pc, *buf;
  238.  
  239.     buf = strdup(names);
  240.     if (0 == (count = matchwild(names)))
  241.     {
  242.     strcpy(names, buf);
  243.     free(buf);
  244.     return names;
  245.     }
  246.     free(buf);
  247.  
  248.     buf = tmpblk.c;
  249.     for (i = 0; i < count; ++i)
  250.     {
  251.     buf += sprintf(buf, "%s ", pc = pop());
  252.     free(pc);
  253.     }
  254.  
  255.     return tmpblk.c;
  256. }
  257.  
  258.  
  259. #ifndef AZTEC_C
  260.  
  261. /*
  262.  * strdup -- copies a string into a safe place.
  263.  */
  264. char *strdup(char *str)
  265. {
  266.     char        *dup = (char *) malloc(strlen(str) + 1);
  267.  
  268.     return (dup) ? strcpy(dup, str) : (char *) 0;    /* returns dup */
  269. }
  270.  
  271. #endif
  272.  
  273.  
  274. /*
  275.  * Replace main by one that will expand the arg list.
  276.  */
  277. void main(int argc, char **argv)
  278. {
  279.     char       **nargv;
  280.  
  281.     if (argc == 0)
  282.         if (Output() == 0)
  283.         exit(2);    /* ran from WorkBench with no window */
  284.  
  285.     nargv = expand(&argc, argv);
  286.  
  287.     (void) _user_main(argc, nargv);
  288.     (void) clean_exit(0);
  289. }
  290.  
  291.  
  292. clean_exit(int val)
  293. {
  294.     void        *pc;
  295.  
  296.     while (pc = pop())
  297.     free(pc);
  298.     exit(val);
  299. }
  300.  
  301. #define main    _user_main
  302. #define exit    clean_exit
  303.  
  304. /* The following macros were defined in <exec/io.h>. I'm undefining them so they
  305.  * don't conflict with the versions in vi.h. If they're used in main.c after
  306.  * this point, you need to redefine the way amiwild.c works.
  307.  */
  308. #ifdef CMD_READ
  309. #undef CMD_READ
  310. #endif
  311.  
  312. #ifdef CMD_WRITE
  313. #undef CMD_WRITE
  314. #endif
  315.  
  316. #ifdef CMD_STOP
  317. #undef CMD_STOP
  318. #endif
  319.