|
|
1.1 root 1: /***
2: *wild.c - wildcard expander
3: *
4: * Copyright (c) 1985-1987, Microsoft Corporation. All rights reserved.
5: *
6: *Purpose:
7: * expands wildcards in argv
8: *
9: * handles '*' (none or more of any char), '?' (exactly one char), and
10: * '[string]' (chars which match string chars or between n1 and n2 if
11: * 'n1-n2'in string inclusive)
12: *
13: *******************************************************************************/
14:
15: #include <stdio.h>
16: #include <register.h>
17: #include <ctype.h>
18: #include <msdos.h>
19:
20:
21: /*
22: ** these are the data structures
23: **
24: ** __argv
25: ** ------- ------
26: ** | |---->| |---->"arg0"
27: ** ------- ------
28: ** | |---->"arg1"
29: ** ------
30: ** ....
31: ** ------
32: ** | |---->"argn"
33: ** ------
34: ** |NULL|
35: ** ------
36: ** argend
37: ** -------
38: ** ------- | |
39: ** | | __argc -------
40: ** ------- |
41: ** |
42: ** arghead V
43: ** ------ --------- ----------
44: ** | |---->| | |----> .... ---->| |NULL|
45: ** ------ --------- ----------
46: ** | |
47: ** V V
48: ** "narg0" "nargn"
49: */
50:
51: #define SLASHCHAR '\\'
52: #define FWDSLASHCHAR '/'
53: #define SLASH "\\"
54: #define FWDSLASH "/"
55: #define STAR "*.*"
56:
57: #define WILDSTRING "*?"
58:
59: char *strdup();
60: char *strpbrk();
61: char *strcpy();
62: char *strncpy();
63: char *strcat();
64: char *malloc();
65: char *_find();
66:
67: static int match ();
68: static int add ();
69: static sort ();
70:
71: extern int __argc;
72: extern char **__argv;
73:
74: struct argnode {
75: char *argptr;
76: struct argnode *nextnode;
77: };
78:
79: static struct argnode *arghead;
80: static struct argnode *argend;
81:
82: /***
83: *int _cwild() - wildcard expander
84: *
85: *Purpose:
86: * expands wildcard in file specs in argv
87: *
88: * handles '*' (none or more of any char), '?' (exactly one char), and
89: * '[string]' (chars which match string chars or between n1 and n2
90: * if 'n1-n2' in string inclusive)
91: *
92: *Entry:
93: *
94: *Exit:
95: * returns 0 if successful, -1 if any malloc() calls fail
96: * if problems with malloc, the old argc and argv are not touched
97: *
98: *Exceptions:
99: *
100: *******************************************************************************/
101:
102: int
103: _cwild ()
104: {
105: REG1 char **argv = __argv;
106: REG2 struct argnode *nodeptr;
107: REG3 int argc;
108: REG4 char **tmp;
109: char *wchar;
110: int ptr, sptr, arglen;
111:
112: arghead = argend = NULL;
113:
114: for (argv = __argv; *argv; argv++) /* for each arg... */
115: if ( *(*argv)++ == '"' )
116: /* strip leading quote from quoted arg */
117: {
118: if (add(*argv))
119: return(-1);
120: }
121: else if (wchar = strpbrk( *argv, WILDSTRING )) {
122: /* attempt to expand arg with wildcard */
123: if (match( *argv, wchar ))
124: return(-1);
125: }
126: else if (add( *argv )) /* normal arg, just add */
127: return(-1);
128:
129: /* count the args */
130: for (argc = 0, nodeptr = arghead; nodeptr;
131: nodeptr = nodeptr->nextnode, argc++)
132: ;
133:
134: /* try to get new arg vector */
135: if (!(tmp = (char **)malloc(sizeof(char *)*(argc+1))))
136: return(-1);
137:
138: /* the new arg vector... */
139: __argv = tmp;
140:
141: /* the new arg count... */
142: __argc = argc;
143:
144: /* install the new args */
145: for (nodeptr = arghead; nodeptr; nodeptr = nodeptr->nextnode)
146: *tmp++ = nodeptr->argptr;
147:
148: /* the terminal NULL */
149: *tmp = NULL;
150:
151: /* free up local data */
152: for (nodeptr = arghead; nodeptr; nodeptr = arghead) {
153: arghead = arghead->nextnode;
154: free(nodeptr);
155: }
156:
157: /* return success */
158: return(0);
159: }
160:
161:
162: /***
163: *match(arg, ptr) - [STATIC]
164: *
165: *Purpose:
166: *
167: *Entry:
168: *
169: *Exit:
170: *
171: *Exceptions:
172: *
173: *******************************************************************************/
174:
175: static int
176: match (arg, ptr)
177: REG4 char *arg;
178: REG1 char *ptr;
179: {
180: REG2 char *new;
181: REG3 int length;
182: char *all;
183: REG5 struct argnode *first;
184: REG6 int gotone = 0;
185:
186: while (ptr != arg && *ptr != SLASHCHAR && *ptr != FWDSLASHCHAR
187: && *ptr != ':') {
188: /* find first slash or ':' before wildcard */
189: ptr--;
190: }
191:
192: if (*ptr == ':' && ptr != arg+1) /* weird name, just add it as is */
193: return(add(arg));
194:
195: if (*ptr == SLASHCHAR || *ptr == FWDSLASHCHAR
196: || *ptr == ':') /* pathname */
197: length = ptr - arg + 1; /* length of dir prefix */
198:
199: if (new = _find(arg)) { /* get the first file name */
200: first = argend;
201:
202: do { /* got a file name */
203: if (strcmp(new, ".") && strcmp(new, "..")) {
204: if (*ptr != SLASHCHAR && *ptr != ':'
205: && *ptr != FWDSLASHCHAR ) {
206: /* current directory; don't need path */
207: if (!(arg = strdup(new)) || add(arg))
208: return(-1);
209: }
210: else /* add full pathname */
211: if (!(all=malloc(length+strlen(new)+1))
212: || add(strcpy(strncpy(all,arg,length)+length,new)
213: - length))
214: return(-1);
215:
216: gotone++;
217: }
218:
219: }
220: while (new = _find(NULL)); /* get following files */
221:
222: if (gotone) {
223: sort(first ? first->nextnode : arghead);
224: return(0);
225: }
226: }
227:
228: return(add(arg)); /* no match */
229: }
230:
231: /***
232: *add(arg) - [STATIC]
233: *
234: *Purpose:
235: *
236: *Entry:
237: *
238: *Exit:
239: *
240: *Exceptions:
241: *
242: *******************************************************************************/
243:
244: static int
245: add (arg)
246: char *arg;
247: {
248: REG1 struct argnode *nodeptr;
249:
250: if (!(nodeptr = (struct argnode *)malloc(sizeof(struct argnode))))
251: return(-1);
252:
253: nodeptr->argptr = arg;
254: nodeptr->nextnode = NULL;
255:
256: if (arghead)
257: argend->nextnode = nodeptr;
258: else
259: arghead = nodeptr;
260:
261: argend = nodeptr;
262: return(0);
263: }
264:
265:
266: /***
267: *sort(first) - [STATIC]
268: *
269: *Purpose:
270: *
271: *Entry:
272: *
273: *Exit:
274: *
275: *Exceptions:
276: *
277: *******************************************************************************/
278:
279: static
280: sort (first)
281: REG2 struct argnode *first;
282: {
283: REG1 struct argnode *nodeptr;
284: REG3 char *temp;
285:
286: if (first) /* something to sort */
287: while (nodeptr = first->nextnode) {
288: do {
289: if (strcmp(nodeptr->argptr, first->argptr) < 0) {
290: temp = first->argptr;
291: first->argptr = nodeptr->argptr;
292: nodeptr->argptr = temp;
293: }
294: }
295: while (nodeptr = nodeptr->nextnode);
296:
297: first = first->nextnode;
298: }
299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.