1 | /* --redexp.vms--
|
---|
2 | This 'C' module may be included prior to the ``main'' programs on VMS in
|
---|
3 | order to allow 'C' arguments to contain redirection symbols (<,>,>>) and
|
---|
4 | VMS wild cards (*,%, ...], [-). By including this module, two programs
|
---|
5 | redirect() and expand() are run prior to turning control over to
|
---|
6 | your main() entry point.
|
---|
7 |
|
---|
8 | redirect-- Gregg Townsend circa 1983,
|
---|
9 | expand-- John Campbell circa 1987
|
---|
10 |
|
---|
11 | This code is public domain, others may use it freely. Credit, however, to
|
---|
12 | Gregg Townsend (who wrote ``redirect()'') and John Campbell (who followed
|
---|
13 | with ``expand()'') would be appreciated. If someone writes the next
|
---|
14 | logical successor ``pipe()'', please email a copy to
|
---|
15 | ...!arizona!naucse!jdc (John Campbell) (Gregg works on unix :-).
|
---|
16 |
|
---|
17 | HISTORY
|
---|
18 |
|
---|
19 | */
|
---|
20 |
|
---|
21 | #include <rms.h> /* No easy way to tell if this has already been included. */
|
---|
22 | #ifndef ERANGE
|
---|
23 | #include <stdlib.h> /* Include only if missing. */
|
---|
24 | #endif
|
---|
25 | #ifndef __FILE
|
---|
26 | #include <stdio.h> /* Include only if missing. */
|
---|
27 | #endif
|
---|
28 | #include <ctype.h> /* Added for conversion to lower case */
|
---|
29 | #ifndef __STRING_LOADED
|
---|
30 | #include <string.h>
|
---|
31 | #endif /* !__STRING_LOADED */
|
---|
32 |
|
---|
33 | /* Expansion of wild cards is done using RMS. */
|
---|
34 | struct NAMBLK { struct NAM nam; /* VMS nam block structure */
|
---|
35 | char es[NAM$C_MAXRSS], /* Extended string */
|
---|
36 | rs[NAM$C_MAXRSS]; /* Resultant string */
|
---|
37 | };
|
---|
38 |
|
---|
39 | #define ErrorExit 1
|
---|
40 |
|
---|
41 | /* Allow the user to override _N_FARGS or _E_FLAG if they wish. */
|
---|
42 | #ifndef _N_FARGS
|
---|
43 | #define _N_FARGS 0 /* no automatic redirection please */
|
---|
44 | #endif
|
---|
45 | #ifndef _E_FLAG
|
---|
46 | #define _E_FLAG 4 /* only include dev and dir if different from default */
|
---|
47 | #endif
|
---|
48 | /*
|
---|
49 | Since the following will possibly be included in a single module, try
|
---|
50 | hard to avoid name conflicts. (Just being static doesn't cut it if
|
---|
51 | compiled in the same module.)
|
---|
52 | */
|
---|
53 | #define redirect _r_edirect
|
---|
54 | #define filearg _f_ilearg
|
---|
55 | #define expand _e_xpand
|
---|
56 | #define wild_found _w_ild_found
|
---|
57 | #define wild_expand _w_ild_expand
|
---|
58 |
|
---|
59 | /* forward protypes */
|
---|
60 | static void redirect(int *argc, char *argv[], int nfargs);
|
---|
61 | char **expand (int *argc, const char *argv[], const int flag);
|
---|
62 |
|
---|
63 | main(int argc, char *argv[], char *envp[])
|
---|
64 | {
|
---|
65 | redirect (&argc, argv, _N_FARGS);
|
---|
66 | argv = expand (&argc, argv, _E_FLAG);
|
---|
67 |
|
---|
68 | /* Make the user's main entry point this routine's entry point. */
|
---|
69 | #define main _user_main
|
---|
70 | _user_main (argc, argv, envp);
|
---|
71 | }
|
---|
72 |
|
---|
73 | /* ------------------------ REDIRECT code ------------------------ */
|
---|
74 |
|
---|
75 | /*
|
---|
76 | * redirect(&argc,argv,nfargs) - redirect standard I/O
|
---|
77 | * int *argc number of command arguments (from call to main)
|
---|
78 | * char *argv[] command argument list (from call to main)
|
---|
79 | * int nfargs number of filename arguments to process
|
---|
80 | *
|
---|
81 | * argc and argv will be adjusted by redirect.
|
---|
82 | *
|
---|
83 | * redirect processes a program's command argument list and handles redirection
|
---|
84 | * of stdin, and stdout. Any arguments which redirect I/O are removed from the
|
---|
85 | * argument list, and argc is adjusted accordingly. redirect would typically be
|
---|
86 | * called as the first statement in the main program.
|
---|
87 | *
|
---|
88 | * Files are redirected based on syntax or position of command arguments.
|
---|
89 | * Arguments of the following forms always redirect a file:
|
---|
90 | *
|
---|
91 | * <file redirects standard input to read the given file
|
---|
92 | * >file redirects standard output to write to the given file
|
---|
93 | * >>file redirects standard output to append to the given file
|
---|
94 | *
|
---|
95 | * It is often useful to allow alternate input and output files as the
|
---|
96 | * first two command arguments without requiring the <file and >file
|
---|
97 | * syntax. If the nfargs argument to redirect is 2 or more then the
|
---|
98 | * first two command arguments, if supplied, will be interpreted in this
|
---|
99 | * manner: the first argument replaces stdin and the second stdout.
|
---|
100 | * A filename of "-" may be specified to occupy a position without
|
---|
101 | * performing any redirection.
|
---|
102 | *
|
---|
103 | * If nfargs is 1, only the first argument will be considered and will
|
---|
104 | * replace standard input if given. Any arguments processed by setting
|
---|
105 | * nfargs > 0 will be removed from the argument list, and again argc will
|
---|
106 | * be adjusted. Positional redirection follows syntax-specified
|
---|
107 | * redirection and therefore overrides it.
|
---|
108 | *
|
---|
109 | */
|
---|
110 |
|
---|
111 | /* forward prototype for local routine */
|
---|
112 | static void filearg(int *argc, char *argv[], int n, int i, FILE *fp, char mode[]);
|
---|
113 |
|
---|
114 | static void redirect(int *argc, char *argv[], int nfargs)
|
---|
115 | {
|
---|
116 | int i;
|
---|
117 |
|
---|
118 | i = 1;
|
---|
119 | while (i < *argc) { /* for every command argument... */
|
---|
120 | switch (argv[i][0]) { /* check first character */
|
---|
121 | case '<': /* <file redirects stdin */
|
---|
122 | filearg(argc,argv,i,1,stdin,"r");
|
---|
123 | break;
|
---|
124 | case '>': /* >file or >>file redirects stdout */
|
---|
125 | if (argv[i][1] == '>')
|
---|
126 | filearg(argc,argv,i,2,stdout,"a");
|
---|
127 | else
|
---|
128 | filearg(argc,argv,i,1,stdout,"w");
|
---|
129 | break;
|
---|
130 | default: /* not recognized, go on to next arg */
|
---|
131 | i++;
|
---|
132 | }
|
---|
133 | }
|
---|
134 | if (nfargs >= 1 && *argc > 1) /* if positional redirection & 1 arg */
|
---|
135 | filearg(argc,argv,1,0,stdin,"r"); /* then redirect stdin */
|
---|
136 | if (nfargs >= 2 && *argc > 1) /* likewise for 2nd arg if wanted */
|
---|
137 | filearg(argc,argv,1,0,stdout,"w");/* redirect stdout */
|
---|
138 | }
|
---|
139 |
|
---|
140 | /* local routine for redirect() */
|
---|
141 | /* filearg(&argc,argv,n,i,fp,mode) - redirect and remove file argument
|
---|
142 | * int *argc number of command arguments (from call to main)
|
---|
143 | * char *argv[] command argument list (from call to main)
|
---|
144 | * int n argv entry to use as file name and then delete
|
---|
145 | * int i first character of file name to use (skip '<' etc.)
|
---|
146 | * FILE *fp file pointer for file to reopen (typically stdin etc.)
|
---|
147 | * char mode[] file access mode (see freopen spec)
|
---|
148 | */
|
---|
149 |
|
---|
150 | static void filearg(int *argc, char *argv[], int n, int i, FILE *fp, char mode[])
|
---|
151 | {
|
---|
152 | if (strcmp(argv[n]+i,"-")) /* alter file if arg not "-" */
|
---|
153 | fp = freopen(argv[n]+i,mode,fp,"mbf=8","mbc=16");
|
---|
154 | if (fp == NULL) { /* abort on error */
|
---|
155 | fprintf(stderr,"%%can't open %s",argv[n]+i);
|
---|
156 | exit(ErrorExit);
|
---|
157 | }
|
---|
158 | for ( ; n < *argc; n++) /* move down following arguments */
|
---|
159 | argv[n] = argv[n+1];
|
---|
160 | *argc = *argc - 1; /* decrement argument count */
|
---|
161 | }
|
---|
162 |
|
---|
163 | /* ------------------------ EXPAND code ------------------------ */
|
---|
164 | /*-
|
---|
165 | ``expand()'' is a routine to expand wild-cards to file specifications.
|
---|
166 | This routine is often used in conjunction with ``redirect()'' to provide
|
---|
167 | both wild card expansion and standard file redirection prior to doing
|
---|
168 | any real work in a 'C' program.
|
---|
169 |
|
---|
170 | Normal usage is to include the following line prior to using argc or
|
---|
171 | argv in main():
|
---|
172 |
|
---|
173 | argv = expand (&argc, argv, 0);
|
---|
174 |
|
---|
175 | ``argc'' will be adjusted by ``expand()'', the return value from expand
|
---|
176 | will replace ``argv''.
|
---|
177 |
|
---|
178 | ``expand()'' processes a program's command argument list and expands any
|
---|
179 | wild cards into zero or more argv entries. Only arguments that posses VMS
|
---|
180 | wild-cards are expanded. Wild cards searched for are ``*'', ``%'',
|
---|
181 | ``...]'', and ``[-''. If the wild-card is found inside a single or double
|
---|
182 | quote ("*" or '%') then they are not counted as wild-cards. Be aware that
|
---|
183 | the expansion of a VMS wild card will match all VMS files, including
|
---|
184 | directory files (".DIR;1").
|
---|
185 |
|
---|
186 | NOTE: The use of quotes in VMS requires thinking about how the CLI expands
|
---|
187 | things before handing the argument line over to your program. Do not
|
---|
188 | expect "*" to avoid expansion, use """*""" instead. Likewise, expression
|
---|
189 | substitution precludes the use of (') to quote wild cards:
|
---|
190 | $ A := HELLO
|
---|
191 | $ ECHO 'a' ! 'C' program that calls ``expand()''
|
---|
192 | hello
|
---|
193 | The easiest way to escape a wild-card may be "'*'". The point is that
|
---|
194 | ``expand()'' will only recognize quotes passed into main().
|
---|
195 | Note: I have added '\' as an escape character -hdd.
|
---|
196 |
|
---|
197 | ``expand()'' references the VMS runtime routines, you will need to
|
---|
198 | link with the 'C' RTL whenever expand is used.
|
---|
199 |
|
---|
200 | Parameters:
|
---|
201 |
|
---|
202 | argc: Pointer to the number of command arguments (from main),
|
---|
203 | the contents of this parameter are modified.
|
---|
204 |
|
---|
205 | argv: Pointer to the initial command argument list (from main),
|
---|
206 | the contents are copied into a new array which is returned
|
---|
207 | from this routine.
|
---|
208 |
|
---|
209 | flag: Flag indicating how to expand wild-cards:
|
---|
210 | 0 - Complete file name expansion
|
---|
211 | 1 - only file name (no directory or version).
|
---|
212 | 2 - directory info and file name (no version).
|
---|
213 | 3 - file name and version info (no directory).
|
---|
214 | 4 - omit fields that are the same as RMS default.
|
---|
215 | -*/
|
---|
216 |
|
---|
217 | /* Local prototypes. */
|
---|
218 | int wild_found (char *string);
|
---|
219 | char **wild_expand (const char *string, char **argv, int *argc,
|
---|
220 | int extra, int flag);
|
---|
221 | /*
|
---|
222 | General note: removing the prototyping and const keywords should
|
---|
223 | allow this code to compile with VMS 'C' compilers prior to version
|
---|
224 | 2.3-024.
|
---|
225 | */
|
---|
226 |
|
---|
227 | char **expand (int *argc, const char *argv[], const int flag)
|
---|
228 | {
|
---|
229 | int i, nargc;
|
---|
230 | char **nargv;
|
---|
231 | char *s1;
|
---|
232 |
|
---|
233 | /* Get an initial amount of memory for the master nargv array. */
|
---|
234 | if ((nargv = (char **)malloc ((*argc+1) * sizeof (char *))) == NULL) {
|
---|
235 | fprintf (stderr, "Not enough memory to expand argument list\n");
|
---|
236 | exit (ErrorExit);
|
---|
237 | }
|
---|
238 | /* Copy the command name (0th argument), but only the name of the exe */
|
---|
239 | nargv[0] = strchr(argv[0],']');
|
---|
240 | if (nargv[0] != NULL) {
|
---|
241 | nargv[0]++;
|
---|
242 | if ((s1=strrchr(nargv[0],'.')) != NULL) *s1 = '\0';
|
---|
243 | } else {
|
---|
244 | nargv[0] = argv[0]; /* if nothing suitable take original */
|
---|
245 | }
|
---|
246 |
|
---|
247 | /* Copy all other arguments, expanding those that have wild characters. */
|
---|
248 | for (nargc = i = 1; i < *argc; i++) {
|
---|
249 | if (wild_found(argv[i]))
|
---|
250 | nargv = wild_expand(argv[i], nargv, &nargc, *argc-i, flag);
|
---|
251 | else
|
---|
252 | nargv[nargc++] = argv[i];
|
---|
253 | }
|
---|
254 | *argc = nargc;
|
---|
255 | nargv[nargc] = NULL; /* realloc always 0 fills, but... */
|
---|
256 |
|
---|
257 | return nargv;
|
---|
258 | }
|
---|
259 |
|
---|
260 | static int wild_found (char *string)
|
---|
261 | /*
|
---|
262 | Routine to search the given string for a VMS wild-card pattern.
|
---|
263 | Returns 1 if "*", "%", "[-", or "...]" is found. (This may not
|
---|
264 | be all VMS wild-cards but it is enough for now--anyone that wants
|
---|
265 | to recognize others can change this code.)
|
---|
266 |
|
---|
267 | Parameter:
|
---|
268 |
|
---|
269 | string: '\0' terminated character array.
|
---|
270 | */
|
---|
271 | {
|
---|
272 | int state = 0;
|
---|
273 |
|
---|
274 | /* State of 0 is "rest" state. State 1 on our way to [-, states 2-4
|
---|
275 | on our way to ...], negative states indicate the two quotes (' -10,
|
---|
276 | " -1).
|
---|
277 | */
|
---|
278 | for ( ;*string; string++) {
|
---|
279 | switch (*string) {
|
---|
280 | case '*':
|
---|
281 | case '%':
|
---|
282 | if (state >= 0)
|
---|
283 | return 1; /* Unquoted % or * found. */
|
---|
284 | break;
|
---|
285 | case '[':
|
---|
286 | if (state >= 0)
|
---|
287 | state = 1;
|
---|
288 | break;
|
---|
289 | case ']':
|
---|
290 | if (state == 4)
|
---|
291 | return 1; /* Unquoted ...] found. */
|
---|
292 | else if (state >= 0)
|
---|
293 | state = 0;
|
---|
294 | break;
|
---|
295 | case '-':
|
---|
296 | if (state == 1)
|
---|
297 | return 1; /* Unquoted [- found. */
|
---|
298 | else if (state >= 0)
|
---|
299 | state = 0;
|
---|
300 | break;
|
---|
301 | case '.':
|
---|
302 | if (state == 1 || state == 0)
|
---|
303 | state = 2; /* First '.' */
|
---|
304 | else if (state > 1 && state < 5)
|
---|
305 | state++; /* ... == states 2, 3, 4 */
|
---|
306 | else if (state >= 0)
|
---|
307 | state = 0;
|
---|
308 | break;
|
---|
309 | case '\'':
|
---|
310 | if (state <= -10)
|
---|
311 | state += 10; /* One ', possibly one " also */
|
---|
312 | else if (state < 0)
|
---|
313 | state -= 10; /* 0 ', possibly one " */
|
---|
314 | else
|
---|
315 | state = -10; /* No ' or " prior to this ' */
|
---|
316 | break;
|
---|
317 | case '"':
|
---|
318 | if (state == -11)
|
---|
319 | state = -10; /* Both " and ' prior to this. */
|
---|
320 | else if (state == -10)
|
---|
321 | state = -11; /* A ' prior to this. */
|
---|
322 | else if (state == -1)
|
---|
323 | state = 0; /* A " prior to this. */
|
---|
324 | else
|
---|
325 | state = -1; /* No ' or " prior to this " */
|
---|
326 | break;
|
---|
327 | case '\\':
|
---|
328 | string = strcpy(string, string+1);
|
---|
329 | state = 0;
|
---|
330 | break;
|
---|
331 | }
|
---|
332 | }
|
---|
333 | return 0;
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | static char **wild_expand(const char *wild, char **argv,
|
---|
338 | int *argc, int extra, int flag)
|
---|
339 | /*
|
---|
340 | Routine to expand wild into new arguments appended to the end
|
---|
341 | of argv[*argc]. This routine must realloc in order to make room
|
---|
342 | for the individual arguments and malloc for enough space for each
|
---|
343 | of the arguments. The return value is a new **argv.
|
---|
344 |
|
---|
345 | Parameters:
|
---|
346 |
|
---|
347 | wild: '\0' terminated string that needs to be expanded.
|
---|
348 |
|
---|
349 | argv: initial starting address of the argv array.
|
---|
350 |
|
---|
351 | argc: pointer to an integer that tells the current end of the
|
---|
352 | argument list.
|
---|
353 |
|
---|
354 | extra: The number of extra pointers that the returned argv
|
---|
355 | must have available for future assignments.
|
---|
356 |
|
---|
357 | flag: Flag indicating how to expand wild-card:
|
---|
358 | 0 - Complete file name expansion
|
---|
359 | 1 - only file name (no directory or version).
|
---|
360 | 2 - directory info and file name (no version)
|
---|
361 | 3 - file name and version info (no directory).
|
---|
362 | 4 - omit fields that are the same as RMS default.
|
---|
363 | */
|
---|
364 | {
|
---|
365 | int more_to_go = 1, err, length, status, len_wild, i, ddev_l, ddir_l;
|
---|
366 | char *namptr;
|
---|
367 | struct FAB fab_blk;
|
---|
368 | struct NAMBLK nam_blk;
|
---|
369 | char path[256];
|
---|
370 | char *ddevice = &path[0]; /* default device and directory */
|
---|
371 | char *ddirectory, *ppath;
|
---|
372 |
|
---|
373 | char *env = getenv("PATH");
|
---|
374 | ppath = &path[0];
|
---|
375 | while (*env) {
|
---|
376 | char *p = env++;
|
---|
377 | if ((*ppath++ = _toupper(*p)) == ':') {
|
---|
378 | ddev_l = ppath - &path[0];
|
---|
379 | *ppath++ = 0;
|
---|
380 | ddirectory = ppath;
|
---|
381 | }
|
---|
382 | }
|
---|
383 | *ppath++ = 0;
|
---|
384 | ddir_l = ppath - ddirectory - 1;
|
---|
385 | len_wild = strlen(wild);
|
---|
386 |
|
---|
387 | /* Initialize all the fab and nam fields needed for parse and search */
|
---|
388 |
|
---|
389 | fab_blk = cc$rms_fab; /* Initialize FAB structure */
|
---|
390 |
|
---|
391 | nam_blk.nam = cc$rms_nam; /* Initialize NAM structure */
|
---|
392 | fab_blk.fab$l_dna = ".*"; /* Default file specif. */
|
---|
393 | fab_blk.fab$b_dns = 2; /* Length of default spec. */
|
---|
394 | fab_blk.fab$l_nam = &nam_blk.nam; /* Set address of NAM in FAB*/
|
---|
395 | nam_blk.nam.nam$b_ess = NAM$C_MAXRSS; /* Set extended string size*/
|
---|
396 | nam_blk.nam.nam$l_esa = nam_blk.es; /* and address */
|
---|
397 | nam_blk.nam.nam$b_rss = NAM$C_MAXRSS; /* Set resultant string size*/
|
---|
398 | nam_blk.nam.nam$l_rsa = nam_blk.rs; /* and address */
|
---|
399 | nam_blk.nam.nam$l_rlf = NULL; /* No related file address */
|
---|
400 |
|
---|
401 | fab_blk.fab$l_fna = wild; /* Address of file name string */
|
---|
402 | fab_blk.fab$b_fns = len_wild; /* Length of file name string */
|
---|
403 |
|
---|
404 | /* Prepare to enter the search loop, parse fab. */
|
---|
405 | err = SYS$PARSE (&fab_blk);
|
---|
406 |
|
---|
407 | /* Catch the directory not found error and return no files found. */
|
---|
408 | if (err != RMS$_NORMAL)
|
---|
409 | exit(err);
|
---|
410 |
|
---|
411 | while (more_to_go) {
|
---|
412 | err = SYS$SEARCH (&fab_blk);
|
---|
413 | if (err == RMS$_NMF || err == RMS$_FNF)
|
---|
414 | more_to_go = 0; /* Done, no more files found */
|
---|
415 | else if (err != RMS$_NORMAL)
|
---|
416 | exit (err);
|
---|
417 | else {
|
---|
418 | /* Count that we now have this many arguments. */
|
---|
419 | (*argc)++;
|
---|
420 |
|
---|
421 | /* Make sure there is room for a new pointer. */
|
---|
422 | if ((argv = realloc (argv, (*argc + extra)*sizeof(char *))) == NULL) {
|
---|
423 | fprintf (stderr, "Not enough memory to expand argument list\n");
|
---|
424 | exit(ErrorExit);
|
---|
425 | }
|
---|
426 |
|
---|
427 | /* Move the right name into the list. */
|
---|
428 | switch (flag) {
|
---|
429 | case 0: /* Complete file name */
|
---|
430 | length = nam_blk.nam.nam$b_rsl;
|
---|
431 | namptr = nam_blk.rs;
|
---|
432 | break;
|
---|
433 | case 1: /* File name only (no directory or version). */
|
---|
434 | length = nam_blk.nam.nam$b_name + nam_blk.nam.nam$b_type;
|
---|
435 | namptr = nam_blk.nam.nam$l_name;
|
---|
436 | break;
|
---|
437 | case 2: /* directory and file name (no version) */
|
---|
438 | length = nam_blk.nam.nam$b_rsl - nam_blk.nam.nam$b_ver;
|
---|
439 | namptr = nam_blk.rs;
|
---|
440 | break;
|
---|
441 | case 3: /* File name and version (no directory). */
|
---|
442 | length = nam_blk.nam.nam$b_name +
|
---|
443 | nam_blk.nam.nam$b_type +
|
---|
444 | nam_blk.nam.nam$b_ver;
|
---|
445 | namptr = nam_blk.nam.nam$l_name;
|
---|
446 | break;
|
---|
447 | case 4: /* Remove redundant fields, no version */
|
---|
448 | length = nam_blk.nam.nam$b_rsl - nam_blk.nam.nam$b_ver;
|
---|
449 | namptr = nam_blk.rs;
|
---|
450 | if ((nam_blk.nam.nam$b_dev==ddev_l) &&
|
---|
451 | !strncmp(namptr, ddevice, nam_blk.nam.nam$b_dev)) {
|
---|
452 | length -= nam_blk.nam.nam$b_dev;
|
---|
453 | namptr += nam_blk.nam.nam$b_dev;
|
---|
454 | if ((nam_blk.nam.nam$b_dir==ddir_l) &&
|
---|
455 | !strncmp(namptr, ddirectory, nam_blk.nam.nam$b_dir)) {
|
---|
456 | length -= nam_blk.nam.nam$b_dir;
|
---|
457 | namptr += nam_blk.nam.nam$b_dir;
|
---|
458 | }
|
---|
459 | }
|
---|
460 | break;
|
---|
461 | default:
|
---|
462 | fprintf (stderr, "illegal flag used in VMS expand call\n");
|
---|
463 | exit (ErrorExit);
|
---|
464 | } /* end of switch */
|
---|
465 | /* Copy the requested string into the argument array. */
|
---|
466 | if ((argv[*argc-1] = malloc (length+1)) == NULL) {
|
---|
467 | fprintf (stderr, "Not enough memory to expand argument list\n");
|
---|
468 | exit (ErrorExit);
|
---|
469 | }
|
---|
470 | /* Copy the string, translate to lower case */
|
---|
471 | /* strncpy (argv[*argc-1], namptr, length); */
|
---|
472 | for (i=0; i<length; i++) {
|
---|
473 | argv[*argc-1][i] = _tolower(*namptr);
|
---|
474 | namptr++;
|
---|
475 | }
|
---|
476 | /* End of modification */
|
---|
477 | argv[*argc-1][length] = '\0';
|
---|
478 | }
|
---|
479 | } /* end while (more_to_go) */
|
---|
480 | return (argv);
|
---|
481 | }
|
---|
482 |
|
---|
483 | /* Remove all the defines that might affect the user's code. */
|
---|
484 |
|
---|
485 | #undef redirect
|
---|
486 | #undef filearg
|
---|
487 | #undef expand
|
---|
488 | #undef wild_found
|
---|
489 | #undef wild_expand
|
---|
490 |
|
---|
491 | #if 0
|
---|
492 | /* ------------------------ ECHO sample code ------------------------ */
|
---|
493 |
|
---|
494 | #include <stdio.h>
|
---|
495 | /* here come the 3 lines that make this Unix program into a VMS one: */
|
---|
496 | #ifdef VMS
|
---|
497 | #include <redexp.vms>
|
---|
498 | #endif
|
---|
499 |
|
---|
500 | /*
|
---|
501 | This main program allows you to run experiments with redexp.vms.
|
---|
502 | Try $ echo *.*, $ echo -f1 [-...]*.*, $ echo -f[0-3] *.*.
|
---|
503 | Questions about using "%", "\", etc. may be answered by testing
|
---|
504 | with this version of echo.
|
---|
505 |
|
---|
506 | To use this, cut from the "#if 0" above up to the last #endif,
|
---|
507 | and put the text in echo.c. Assuming you have defined VAXC$INCLUDE
|
---|
508 | to also look in the directory where you put redexp.VMS, you should
|
---|
509 | be able to compile and link echo. Define a symbol echo as
|
---|
510 | echo :== $sys$disk:[]echo
|
---|
511 | and you are ready to run.
|
---|
512 |
|
---|
513 | */
|
---|
514 | main(argc, argv)
|
---|
515 | int argc;
|
---|
516 | char *argv[];
|
---|
517 | {
|
---|
518 | int i = 0;
|
---|
519 |
|
---|
520 | while (i < argc) {
|
---|
521 | printf("argv[%d]: %s\n", i, argv[i]);
|
---|
522 | i++;
|
---|
523 | }
|
---|
524 | }
|
---|
525 | /* ------------------------ ECHO sample code end --------------------- */
|
---|
526 | #endif /* if 0 */
|
---|