/** \file * Wildcard expansion for WIN32 version * * Copyright (c) 2000 John Bridges. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission.
* * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 3 * of the License, or (at your option) any later version. * * This file is subject to the terms of the GNU General Public License as * published by the Free Software Foundation. A copy of this license is * included with this software distribution in the file COPYING. If you * do not have a copy, you may obtain a copy by writing to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * Please send bug reports about this file to indent@peekpoke.com */ #if defined (_WIN32) && !defined (__CYGWIN__) #include #include #include #include #include #include #include "sys.h" #include "code_io.h" #include "indent.h" #define MAX_PATH 1024 struct arginfo { int nargc; int argpos; char *argbuf; int bufsize; }; /** * */ static void myabort ( char *str) { puts (""); puts (str); exit (1); } static void fparms (struct arginfo *arg, char *fname); static void chkparm (struct arginfo *arg, char *str); /** * */ static void addarg ( struct arginfo *arg, char *str) { int cnt; if (*str == '@') { fparms (arg, str + 1); } else { cnt = strlen (str) + 1; if (arg->argpos + cnt >= arg->bufsize) { arg->bufsize += 8192; arg->argbuf = realloc (arg->argbuf, arg->bufsize); } strcpy (arg->argbuf + arg->argpos, str); arg->argpos += cnt; ++arg->nargc; } } /** * */ static void fparms ( struct arginfo *arg, char *fname) { char * buf = NULL; char * cp = NULL; char * ecp = NULL; unsigned int cnt; short quoted = 0; FILE * fs = fopen (fname, "rb"); if (!fs) { myabort (_("CANNOT FIND '@' FILE!")); } fseek (fs, 0l, 2); cnt = ftell (fs); fseek (fs, 0l, 0); buf = malloc (cnt + 1); fread (buf, 1, cnt, fs); fclose (fs); *(ecp = buf + cnt) = 0; cp = buf; while (cp < ecp) { if (*cp == ';') { while (cp < ecp && *cp != '\r' && *cp != '\n') { *cp++ = 0; } } if (*cp < ' ') { *cp = 0; } if (*cp == '"') { *cp = 0; quoted = !quoted; } if (!quoted) { if (*cp == ' ') { *cp = 0; /* set spaces to null */ } if (*cp >= 'A' && *cp <= 'Z') { *cp += 32; } } ++cp; } cp = buf; while (cp < ecp) { if (*cp) { chkparm (arg, cp); cp += strlen (cp); } ++cp; } free (buf); } /** * */ static int wildmatch( const char *s1, const char *s2) { if (s1 == NULL) { s1 = ""; } if (s2 == NULL) { s2 = ""; } while (*s1 && (*s2 || *s1 == '*')) { if (tolower (*s1) != tolower (*s2) && *s1 != '?' && *s1 != '*') { return 0; } if (*s2) { if (*s1 == '*') { ++s1; if (!*s1) { return 1; } while (*s2) { if (wildmatch (s1, s2)) { return 1; } ++s2; } return 0; } ++s2; } ++s1; } if (*s1 || *s2) { return 0; } else { return 1; } } /** * */ static short removearg ( struct arginfo *arg, char *str) { char *cp = NULL; int i; int cnt; i = arg->nargc; cp = arg->argbuf; while (i-- > 0) { cnt = strlen (cp) + 1; if (wildmatch (str, cp)) { arg->argpos -= cnt; memcpy (cp, cp + cnt, arg->argpos - (cp - arg->argbuf)); --arg->nargc; } else { cp += cnt; } } return 0; } /** * */ static void chkparm ( struct arginfo *arg, char *str) { char tmpstr[MAX_PATH + 1]; char * cp = NULL; char * pnt2 = NULL; short remarg = 0; long hFile; struct _finddata_t c_file; if (*str == '!') { remarg = 1; ++str; } if (strchr (str, '?') || strchr (str, '*')) { if (remarg) { removearg (arg, str); } else { strcpy (tmpstr, str); if (!(cp = strrchr (tmpstr, '\\'))) { if (!(cp = strrchr (tmpstr, '/'))) { if (!(cp = strrchr (tmpstr, ':'))) { cp = tmpstr - 1; } } } pnt2 = cp + 1; hFile = _findfirst (str, &c_file); while (hFile > 0) { if (!(c_file.attrib & _A_SUBDIR)) { cp = pnt2; strcpy (pnt2, c_file.name); while (*cp) { if (islower (*cp)) { strcpy (pnt2, c_file.name); break; } *cp = tolower (*cp); ++cp; } addarg (arg, tmpstr); } if (_findnext (hFile, &c_file)) { _findclose (hFile); hFile = 0; } } } } else { if (remarg) { removearg (arg, str); } else { addarg (arg, str); } } } /** * */ extern void wildexp ( int *argc, char ***argv) { char * cp = NULL; char ** pnt; char ** nargv; struct arginfo arg; int i; arg.bufsize = 8192; arg.argpos = 0; arg.argbuf = malloc (arg.bufsize); arg.nargc = 0; i = *argc; pnt = *argv; while (i--) { chkparm (&arg, *pnt++); } arg.argbuf = realloc (arg.argbuf, arg.argpos); cp = arg.argbuf; i = *argc = arg.nargc; if (arg.nargc < 32) { arg.nargc = 32; } *argv = nargv = malloc (arg.nargc * sizeof (nargv[0])); while (i--) { *nargv++ = cp; cp += strlen (cp) + 1; } } #endif /* defined (_WIN32) && !defined (__CYGWIN__) */