/***********************************************************************/ /* */ /* Objective Caml */ /* */ /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */ /* */ /* Copyright 1996 Institut National de Recherche en Informatique et */ /* en Automatique. All rights reserved. This file is distributed */ /* under the terms of the GNU Library General Public License. */ /* */ /***********************************************************************/ /* $Id$ */ /* Expansion of @responsefile and *? file patterns in the command line */ #include #include #include #include #include #include #include #include static int argc; static char ** argv; static int argvsize; static void store_argument(char * arg); static void expand_argument(char * arg); static void expand_pattern(char * arg); static void expand_diversion(char * filename); static void out_of_memory(void) { fprintf(stderr, "Out of memory while expanding command line\n"); exit(2); } static void store_argument(char * arg) { if (argc + 1 >= argvsize) { argvsize *= 2; argv = (char **) realloc(argv, argvsize * sizeof(char *)); if (argv == NULL) out_of_memory(); } argv[argc++] = arg; } static void expand_argument(char * arg) { char * p; if (arg[0] == '@') { expand_diversion(arg + 1); return; } for (p = arg; *p != 0; p++) { if (*p == '*' || *p == '?') { expand_pattern(arg); return; } } store_argument(arg); } static void expand_pattern(char * pat) { int handle; struct _finddata_t ffblk; handle = _findfirst(pat, &ffblk); if (handle == -1) { store_argument(pat); /* a la Bourne shell */ return; } do { store_argument(strdup(ffblk.name)); } while (_findnext(handle, &ffblk) != -1); _findclose(handle); } static void expand_diversion(char * filename) { struct _stat stat; int fd; char * buf, * endbuf, * p, * s; if (_stat(filename, &stat) == -1 || (fd = _open(filename, O_RDONLY | O_BINARY, 0)) == -1) { fprintf(stderr, "Cannot open file %s\n", filename); exit(2); } buf = (char *) malloc(stat.st_size + 1); if (buf == NULL) out_of_memory(); _read(fd, buf, stat.st_size); endbuf = buf + stat.st_size; _close(fd); for (p = buf; p < endbuf; /*nothing*/) { /* Skip leading blanks */ while (p < endbuf && isspace(*p)) p++; if (p >= endbuf) break; s = p; /* Skip to next blank or end of buffer */ while (p < endbuf && !isspace(*p)) p++; /* Delimit argument and expand it */ *p++ = 0; expand_argument(s); } } void expand_command_line(int * argcp, char *** argvp) { int i; argc = 0; argvsize = 16; argv = (char **) malloc(argvsize * sizeof(char *)); if (argv == NULL) out_of_memory(); for (i = 0; i < *argcp; i++) expand_argument((*argvp)[i]); argv[argc] = NULL; *argcp = argc; *argvp = argv; }