|
|
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.