/* * Copyright (C) 1996, 1997, 1998, 1999, 2000 Florian Schintke * * This 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 2, or (at your option) any later version. * * This is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License with the * c2html, java2html, pas2html or perl2html source package as the file * COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Documenttitle and purpose: */ /* Implementation of the UN*X wildcards in C. So they are */ /* available in a portable way and can be used whereever */ /* needed. */ /* */ /* Version: */ /* 1.2 */ /* */ /* Test cases: */ /* Please look into the Shellscript testwildcards.main */ /* */ /* Author(s): */ /* Florian Schintke (schintke@gmx.de) */ /* */ /* Tester: */ /* Florian Schintke (schintke@gmx.de) */ /* */ /* Testing state: */ /* tested with the atac tool */ /* Latest test state is documented in testwildcards.report */ /* The program that tested this functions is available as */ /* testwildcards.c */ /* */ /* Dates: */ /* First editing: unknown, but before 04/02/1997 */ /* Last Change : 04/07/2000 */ /* */ /* Known Bugs: */ /* */ #include #include "wildcard.h" int set (char **wildcard, char **test); /* Scans a set of characters and returns 0 if the set mismatches at this */ /* position in the teststring and 1 if it is matching */ /* wildcard is set to the closing ] and test is unmodified if mismatched */ /* and otherwise the char pointer is pointing to the next character */ int asterisk (char **wildcard, char **test); /* scans an asterisk */ int wildcardfit(char *wildcard, char *test) { int fit = 1; for (; ('\000' != *wildcard) && (1 == fit) && ('\000' != *test); wildcard++) { switch (*wildcard) { case '[': wildcard++; /* leave out the opening square * bracket */ fit = set(&wildcard, &test); /* we don't need to decrement the wildcard as in case */ /* of asterisk because the closing ] is still there */ break; case '?': test++; break; case '*': fit = asterisk(&wildcard, &test); /* * the asterisk was skipped by asterisk() but the * loop will */ /* increment by itself. So we have to decrement */ wildcard--; break; default: fit = (int)(*wildcard == *test); test++; } } while ((*wildcard == '*') && (1 == fit)) /* here the teststring is empty otherwise you cannot */ /* leave the previous loop */ wildcard++; return (int)((1 == fit) && ('\0' == *test) && ('\0' == *wildcard)); } int set(char **wildcard, char **test) { int fit = 0; int negation = 0; int at_beginning = 1; if ('!' == **wildcard) { negation = 1; (*wildcard)++; } while ((']' != **wildcard) || (1 == at_beginning)) { if (0 == fit) { if (('-' == **wildcard) && ((*(*wildcard - 1)) < (*(*wildcard + 1))) && (']' != *(*wildcard + 1)) && (0 == at_beginning)) { if (((**test) >= (*(*wildcard - 1))) && ((**test) <= (*(*wildcard + 1)))) { fit = 1; (*wildcard)++; } } else if ((**wildcard) == (**test)) { fit = 1; } } (*wildcard)++; at_beginning = 0; } if (1 == negation) /* change from zero to one and vice versa */ fit = 1 - fit; if (1 == fit) (*test)++; return (fit); } int asterisk(char **wildcard, char **test) { /* Warning: uses multiple returns */ int fit = 1; /* erase the leading asterisk */ (*wildcard)++; while (('\000' != (**test)) && (('?' == **wildcard) || ('*' == **wildcard))) { if ('?' == **wildcard) (*test)++; (*wildcard)++; } /* Now it could be that test is empty and wildcard contains */ /* aterisks. Then we delete them to get a proper state */ while ('*' == (**wildcard)) (*wildcard)++; if (('\0' == (**test)) && ('\0' != (**wildcard))) return (fit = 0); if (('\0' == (**test)) && ('\0' == (**wildcard))) return (fit = 1); else { /* Neither test nor wildcard are empty! */ /* the first character of wildcard isn't in [*?] */ if (0 == wildcardfit(*wildcard, (*test))) { do { (*test)++; /* * skip as much characters as possible in the * teststring */ /* stop if a character match occurs */ while (((**wildcard) != (**test)) && ('[' != (**wildcard)) && ('\0' != (**test))) (*test)++; } while ((('\0' != **test)) ? (0 == wildcardfit(*wildcard, (*test))) : (0 != (fit = 0))); } if (('\0' == **test) && ('\0' == **wildcard)) fit = 1; return (fit); } }