Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!drivax!frotz From: frotz@dri.com (Frotz) Newsgroups: comp.binaries.ibm.pc.d Subject: Re: Unix command globbing for MS-DOS Message-ID: <9972HZQ@dri.com> Date: 19 May 91 16:59:35 GMT References: <1991May16.144701.10301@magnus.acs.ohio-state.edu> Sender: frotz@dri.com Reply-To: frotz@dri.com Distribution: na Organization: Digital Research, Monterey CA/USA or none (see also My_Desk) Lines: 209 skesterk@magnus.acs.ohio-state.edu (Shane Kesterke) writes: ]After checking out all the archive sites I've managed to pick up MS-DOS ]equivalents of my favorite Unix commands. But the one thing I haven't ]found is like a TSR that will allow Unix wildcard usage in MS-DOS, ]particularly, command globbing (being able to type "file*" instead of ]"file*.*"). I use command globbing a lot on my Unix account here and ]I really miss it on MS-DOS. I tried WILDUNIX but it didn't seem to work. ]I still had to type *.* for a wildcard. Can anyone direct me to a handy ]program that will allow the freedom of command globbing and Unix wildcards? I know that you are looking for binaries, but I insist on building as many of my tools as I can (less chance of virii, and more opportunities to hack the code to my-way-of-thinking(tm)). Below is a code snippet that I include before Turbo C's c0$(MEMORY_MODEL).obj in the link line. This provides me with Un*x-like Wildcarding... The original author doesn't believe in copyrights for personally developed sources (I personally agree with him). His name is Mark G. Alexander currently of Borland (formerly of Digital Research, Inc.). alexander@borland.com (or possibly alexande@borland.com) Since this was written before the change in public domain status of files posted to networks, there is no public domain notice, nor any copyright notice. Therefore, it is hereby released to the public domain, with no rights reserved and no guarantee of merchantability... -- John "Frotz" Fa'atuai frotz@dri.com (email@domain) Digital Research, Inc. uunet!drivax!frotz (bang!email) c/o MIS Dept. 408/647-6570 or 408/646-6287 (vmail) 80 Garden Court, CompRm 408/649-3896 (phone) Monterey, CA 93940 408/646-6248 (fax) ---------------------------------------------------------------------- /*---------------------------------------------------------------------- * _wmatch - * * Match a wild card (w) string against a normal string (s). * Unix shell-style wildcards are supported, including '?', * multiple '*', and []. Recursion is used to handle multiple '*' * characters. One difference between this sort of wild card and the DOS * type is that "*" matches all files, even those that have an extension * (i.e. those with a '.'). Case is ignored because DOS filenames * may be passed in upper case. The parameters are far pointers because * the function is called by startup code in Turbo C's setargv.asm. * A space or tab character if found in the wildcard string is treated * as a NULL, because Turbo C sometimes passes us a trailing space * or tab, unfortunately. * * The function returns 0 if no match, 1 if match. */ #define IGNORECASE 1 #define DEBUG 0 #if 0 #include dos_string(s) char far *s; { while (*s) dos_putc(*s++); } dos_putc(c) int c; { bdos(2,c,0); } #endif int _wmatch(w,s) char far *w; /* the wild card string */ char far *s; /* the filename to match against the string */ { char wc,sc,wc1; int found, negate, trueval, falseval; #if 0 dos_string(w); dos_putc(','); dos_string(s); dos_putc('\r'); dos_putc('\n'); #endif /* Handle the FlexOS '^' character, which means negate the * result of the match. */ if (*w == '^') { w++; trueval = 0; falseval = 1; } else { trueval = 1; falseval = 0; } /* If the name starts with a '.', it must be explicitly matched * by a '.' in the wildcard. */ if (*s == '.') { if (*w != '.') return (falseval); s++; w++; } for (;;) { wc = *w++; sc = *s++; if (wc == ' ' || wc == '\t') /* whitespace terminates wildcard */ wc = 0; if (wc == 0 && sc == 0) /* at end of both strings? */ return (trueval); #if IGNORECASE if (wc >= 'A' && wc <= 'Z') wc = wc - 'A' + 'a'; if (sc >= 'A' && sc <= 'Z') sc = sc - 'A' + 'a'; #endif if (wc == sc) /* matched one character? */ continue; if (wc == '?') /* ? matches any single char */ continue; if (wc == '[') /* match any char within [] */ { found = 0; if ((negate = (*w == '!')) != 0) w++; while ((wc = *w++) != ']') { if (wc == 0) /* missing right bracket? */ return (0); if (found) /* already found a match? */ continue; #if IGNORECASE if (wc >= 'A' && wc <= 'Z') wc = wc - 'A' + 'a'; #endif if (*w == '-') /* range of characters? */ { wc1 = *++w; /* skip the '-' */ #if IGNORECASE if (wc1 >= 'A' && wc1 <= 'Z') wc1 = wc1 - 'A' + 'a'; #endif if (sc >= wc && sc <= wc1) found = 1; } else { if (wc == sc) found = 1; } } if (found == negate) return (falseval); continue; } if (wc == '*') { /* A trailing * always matches */ if (*w == 0 || *w == ' ' || *w == '\t') return (trueval); s--; /* back up string pointer */ for (;;) /* check all substrings */ { if (_wmatch(w,s)) /* does this substring match? */ return (trueval); if (*s == 0) /* reached end with no matches? */ return (falseval); s++; } } if (wc != sc) /* found a mismatch? */ return (falseval); } } #if DEBUG main(argc,argv) int argc; char *argv[]; { int i; if (argc < 3) { printf("usage: wmatch ...\n"); exit(1); } for (i = 2; i < argc; i++) printf("%s %s %s\n", argv[i],_wmatch(argv[1],argv[i]) ? "matches" : "doesn't match", argv[1]); } #endif