This is glob.c in view mode; [Download] [Up]
#include <ctype.h> #include <dir.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dos.h> #include <io.h> #ifdef __GO32__ #include <sys/farptr.h> #else #include <alloc.h> #endif #define extern #include "glob.h" #undef extern int (*__glob_sense_expand_from_proxy)(int original_expand_wildcards) = 0; static int expand_wildcards = 0; static void parse_chars(void *ptr, int (*func)(void *ptr)); static int argv_max = 0; static int string_getc(void *ptr) { int c = *(*(char **)ptr)++; return c; } static int file_getc(void *ptr) { return fgetc((FILE *)ptr); } static char * get_proxy(int i) { int len; char *rv; int seg = __glob_proxy_vals[1]; int ofs = __glob_proxy_vals[2]; int c; #ifdef __GO32__ _farsetsel(_go32_conventional_mem_selector()); ofs = seg * 16 + _farnspeekw(seg*16+ofs+2*i); for (len=0; _farnspeekb(ofs+len); len++); rv = (char *)malloc(len+1); if (!rv) { fprintf(stderr, "Error: out of memory gathering arguments\n"); exit(1); } for (len=0; (c = _farnspeekb(ofs+len)) != 0; len++) rv[len] = c; rv[len] = 0; #else ofs = peek(seg, ofs+2*i); for (len=0; peekb(seg, ofs+len); len++); rv = (char *)malloc(len+1); if (!rv) { fprintf(stderr, "Error: out of memory gathering arguments\n"); exit(1); } for (len=0; (c = peekb(seg, ofs+len)) != 0; len++) rv[len] = c; rv[len] = 0; #endif return rv; } static void stash_arg_at(char *arg, int slot, int dup) { if (__glob_argv == 0) argv_max = 0; if (slot >= argv_max) { int newmax = (argv_max + 1)*2; if (__glob_argv) __glob_argv = (char **)realloc(__glob_argv, newmax * sizeof(char *)); else { __glob_argv = (char **)malloc(newmax * sizeof(char *)); __glob_argc = 0; argv_max = 0; } if (!__glob_argv) { fprintf(stderr, "Error: out of memory gathering arguments\n"); exit(1); } while (argv_max < newmax) __glob_argv[argv_max++] = 0; } __glob_argv[slot] = arg ? (dup ? strdup(arg) : arg) : 0; if (arg && !__glob_argv[slot]) { fprintf(stderr, "Error: out of memory gathering arguments\n"); exit(1); } if (arg && (slot >= __glob_argc)) __glob_argc = slot + 1; } static void stash_arg(char *arg) { stash_arg_at(arg, __glob_argc ? __glob_argc : 1, 1); } static void free_args(void) { int i; for (i=0; i<argv_max; i++) if (__glob_argv[i]) { free(__glob_argv[i]); __glob_argv[i] = 0; } __glob_argc = 0; } #define SINGLE_QUOTE '\'' #define DOUBLE_QUOTE '"' #define EOS '\0' #define isslash(c) ((c) == '\\' || (c) == '/') static char * rangematch(char *pattern, char test) { char c, c2; int negate, ok; if ((negate = (*pattern == '!')) != 0) ++pattern; /* * TO DO: quoting */ for (ok = 0; (c = *pattern++) != ']';) { if (c == EOS) return(NULL); /* illegal pattern */ if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']') { if (c <= test && test <= c2) ok = 1; else if (isalpha(test) && c <= (test^0x20) && (test^0x20) <= c2) ok = 1; pattern += 2; } else if (tolower(c) == tolower(test)) ok = 1; } return(ok == negate ? NULL : pattern); } static int hasdot; static int fnmatch(char *pattern, char *string) { register char c; char test, *rangematch(); for (;;) switch (c = *pattern++) { case EOS: return(*string == EOS); case '?': if ((test = *string++) == EOS || isslash(test)) return(0); break; case '*': c = *pattern; /* collapse multiple stars */ while (c == '*') c = *++pattern; /* optimize for pattern with * at end or before / */ if (c == EOS || (c == '.' && pattern[1] == EOS && !hasdot)) return(!strchr(string, '/')); else if (isslash(c)) { if ((string = strpbrk(string, "/\\")) == NULL) return(0); break; } /* general case, use recursion */ while ((test = *string) != EOS) { if (fnmatch(pattern, string)) return(1); if (isslash(test)) break; ++string; } return(0); case '[': if ((test = *string++) == EOS || isslash(test)) return(0); if ((pattern = rangematch(pattern, test)) == NULL) return(0); break; default: string++; if (tolower(c) != tolower(string[-1])) return(0); break; } } #define PATH_MAX 140 static int lowcase = 0; static int mustexist = 0; static void wildcard1(char *buf, char *bp, char *fp) { char *slpos = strpbrk(fp, "/\\"), slsave='-'; int done, i; struct ffblk ff; char *wildchars; if (slpos) { slsave = *slpos; *slpos = 0; } for (i=0; fp[i]; i++) { if (islower(fp[i])) lowcase = 1; if (isupper(fp[i])) lowcase = 0; } wildchars = strpbrk(fp, "*?[]"); if (!expand_wildcards || wildchars==0) { strcpy(bp, fp); if (slpos) { int bpl = strlen(bp); bp[bpl++] = slsave; bp[bpl] = 0; wildcard1(buf, bp+bpl, slpos+1); } else { if (wildchars == 0 && mustexist) { if (access(buf, 0) == 0) stash_arg(buf); } else stash_arg(buf); } } else { strcpy(bp, "*.*"); done = findfirst(buf, &ff, FA_RDONLY|FA_DIREC|FA_ARCH); while (!done) { if (ff.ff_name[0] != '.' || fp[0] == '.') { if (lowcase) strlwr(ff.ff_name); hasdot = strchr(ff.ff_name, '.')!=0; if (fnmatch(fp, ff.ff_name)) { strcpy(bp, ff.ff_name); if (slpos) { int bpl = strlen(bp); bp[bpl++] = slsave; bp[bpl] = 0; mustexist++; wildcard1(buf, bp+bpl, slpos+1); mustexist--; } else stash_arg(buf); } } done = findnext(&ff); } } if (slpos) *slpos = slsave; } static int argv_cmp(void *av, void *bv) { register char *a = *(char **)av; register char *b = *(char **)bv; return strcmp(a, b); } static void wildcard(char *arg) { char buf[140]; char *bp, *fp; int oarg; lowcase = 1; bp=buf; fp=arg; if (fp[1] == ':') { *bp++ = *fp++; *bp++ = *fp++; } if (*fp == '/' || *fp == '\\') *bp++ = *fp++; oarg = __glob_argc; if (oarg < 1) oarg = 1; wildcard1(buf, bp, fp); if (oarg >= __glob_argc) stash_arg(arg); else qsort(__glob_argv+oarg, __glob_argc - oarg, sizeof(char *), argv_cmp); } static void expand_arg(char *arg) { if (arg[0] == '@') { FILE *f = fopen(arg+1, "r"); if (f) { parse_chars(f, file_getc); fclose(f); return; } } else if (expand_wildcards && strspn("*?[]", arg)) wildcard(arg); else stash_arg(arg); } static void parse_chars(void *ptr, int (*func)(void *ptr)) { int quote = 0; int needs_expansion = 0; char argbuf[1000]; char *start = argbuf; int pending_arg = 0; int done = 0; int unc = -2; while (!done) { int c = (unc==-2) ? func(ptr) : unc; unc = -2; if (c <= 0) { if (pending_arg) { *start = 0; if (needs_expansion) expand_arg(argbuf); else stash_arg(argbuf); pending_arg = 0; start = argbuf; } done = 1; } else if (quote == SINGLE_QUOTE) { if (c == SINGLE_QUOTE) quote = 0; else *start++ = c; } else if (quote == DOUBLE_QUOTE) { if (c == DOUBLE_QUOTE) quote = 0; else if (c == '\\') { unc = func(ptr); if (strchr("\\'\"", unc)) { *start++ = unc; unc = -2; } else if (unc != '\n') { *start++ = c; } } else *start++ = c; } else if (isspace(c)) { if (pending_arg) { *start = 0; if (needs_expansion) expand_arg(argbuf); else stash_arg(argbuf); pending_arg = 0; start = argbuf; } } else { if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE) quote = c; else if (c == '\\') { unc = func(ptr); if (unc == '\n') unc = -2; else if (strchr("\\'\"", unc) || isspace(unc)) { *start++ = unc; unc = -2; } else *start++ = '\\'; } else { if (strchr("*?[]", c) || (c == '@' && start == argbuf)) needs_expansion = 1; *start++ = c; } pending_arg = 1; } } } static int getenvargs(void) { int i, ac; char aname[10]; char *a0 = getenv("_argc"); if (!a0) return 1; ac = atoi(a0); for (i=0; i<ac; i++) { sprintf(aname, "_argv%d", i); if (i == 0) stash_arg_at(getenv(aname), 0, 1); else expand_arg(getenv(aname)); } return 0; } void __glob_args(char *cmdline, char *dos_argv0, int _expand_wildcards) { expand_wildcards = _expand_wildcards; free_args(); __glob_argc = 0; __glob_proxy_count = 0; if (getenvargs()) { parse_chars(&cmdline, string_getc); if (__glob_argc > 4 && strcmp(__glob_argv[1], "!proxy") == 0) { int i; for (i=0; i+2 < __glob_argc; i++) { unsigned long pval = strtoul(__glob_argv[i+2], 0, 16); __glob_proxy_vals[i] = (unsigned) pval; } free_args(); __glob_proxy_count = i; if (__glob_sense_expand_from_proxy) expand_wildcards = __glob_sense_expand_from_proxy(expand_wildcards); stash_arg_at(get_proxy(0), 0, 1); for (i=1; i<__glob_proxy_vals[0]; i++) expand_arg(get_proxy(i)); } else stash_arg_at(dos_argv0, 0, 1); } stash_arg_at(0, __glob_argc, 0); } void __glob_env(char *app_name) { FILE *djgpp_env; char *djgpp_var = getenv("DJGPP"); char *copy; if (djgpp_var) { djgpp_env = fopen(djgpp_var, "rt"); if (djgpp_env) { char line[2000]; char base[12], *bp, *a0p, *tb = (char *)line; int this_prog = 1; base[0] = '['; bp = app_name; for (a0p = bp; *a0p; a0p++) if (strchr("\\/:", *a0p)) bp = a0p+1; for (a0p=base+1; *bp && *bp != '.';) *a0p++ = tolower(*bp++); *a0p++ = ']'; *a0p++ = 0; while (fgets(tb, 2000, djgpp_env)) { tb[strlen(tb)-1] = 0; if (tb[0] == 0) continue; if (tb[0] == '[') { if (strcmp(tb, base) == 0) this_prog = 1; else this_prog = 0; } else { if (this_prog) { char *tb2 = tb+strlen(tb)+1; char *sp=tb, *dp=tb2; while (*sp != '=') *dp++ = *sp++; if (*tb2 == '+') /* non-overriding */ { *dp = 0; tb2++; if (getenv(tb2)) continue; /* while fread */ } *dp++ = *sp++; /* copy the '=' */ while (*sp) { if (*sp == '%') { char *pp; if (sp[1] == '%') { *dp++ = '%'; sp += 2; } else { char ps, *e, *dirend; int dirpart=0, apsemi=0; int mapup=0, maplow=0, mapfs=0, mapbs=0; while (strchr(":;/\\<>", sp[1])) { switch (sp[1]) { case ':': dirpart=1; break; case ';': apsemi=1; break; case '/': mapfs=1; break; case '\\': mapbs=1; break; case '<': mapup=1; break; case '>': maplow=1; break; } sp++; } for (pp=sp+1; *pp && *pp != '%'; pp++); ps = *pp; *pp = 0; e = getenv(sp+1); dirend = dp; if (e) { while (*e) { char ec = *e++; if (strchr("\\/:", ec)) dirend=dp; if (mapup) ec = toupper(ec); if (maplow) ec = tolower(ec); if (mapfs && ec == '\\') ec = '/'; if (mapbs && ec == '/') ec = '\\'; *dp++ = ec; } } if (dirpart) dp = dirend; if (apsemi && e) *dp++ = ';'; if (ps == 0) break; sp = pp+1; } } else *dp++ = *sp++; } *dp++ = 0; copy = strdup(tb2); if (!copy) { fprintf(stderr, "Error: out of memory gathering environment\n"); exit(1); } putenv(copy); } } } fclose(djgpp_env); } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.