|
|
1.1 ! root 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: * [email protected] [email protected] ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.