gmatch.c (3676B)
1 /* 2 * Derived from /usr/src/cmd/sh/expand.c, Unix 7th Edition: 3 * 4 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * Redistributions of source code and documentation must retain the 10 * above copyright notice, this list of conditions and the following 11 * disclaimer. 12 * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed or owned by Caldera 18 * International, Inc. 19 * Neither the name of Caldera International, Inc. nor the names of 20 * other contributors may be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA 24 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE 28 * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 33 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 34 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 #if __GNUC__ >= 3 && __GNUC_MINOR__ >= 4 || __GNUC__ >= 4 38 #define USED __attribute__ ((used)) 39 #elif defined __GNUC__ 40 #define USED __attribute__ ((unused)) 41 #else 42 #define USED 43 #endif 44 static const char sccsid[] USED = "@(#)gmatch.sl 1.5 (gritter) 5/29/05"; 45 46 #include <stdlib.h> 47 #include <wchar.h> 48 #include <limits.h> 49 50 #include "mbtowi.h" 51 52 #define fetch(wc, s, n) ((mb_cur_max > 1 && *(s) & 0200 ? \ 53 ((n) = mbtowi(&(wc), (s), mb_cur_max), \ 54 (n) = ((n) > 0 ? (n) : (n) < 0 ? (wc = WEOF, 1) : 1)) :\ 55 ((wc) = *(s) & 0377, (n) = 1)), (s) += (n), (wc)) 56 57 int 58 gmatch(const char *s, const char *p) 59 { 60 const char *bs = s; 61 int mb_cur_max = MB_CUR_MAX; 62 wint_t c, scc; 63 int n; 64 65 if (fetch(scc, s, n) == WEOF) 66 return (0); 67 switch (fetch(c, p, n)) { 68 69 case '[': { 70 int ok = 0, excl; 71 unsigned long lc = ULONG_MAX; 72 const char *bp; 73 74 if (*p == '!') { 75 p++; 76 excl = 1; 77 } else 78 excl = 0; 79 fetch(c, p, n); 80 bp = p; 81 while (c != '\0') { 82 if (c == ']' && p > bp) 83 return (ok ^ excl ? gmatch(s, p) : 0); 84 else if (c == '-' && p > bp && *p != ']') { 85 if (*p == '\\') 86 p++; 87 if (fetch(c, p, n) == '\0') 88 break; 89 if (lc <= scc && scc <= c) 90 ok = 1; 91 } else { 92 if (c == '\\') { 93 if (fetch(c, p, n) == '\0') 94 break; 95 } 96 if (scc == (lc = c)) 97 ok = 1; 98 } 99 fetch(c, p, n); 100 } 101 return (0); 102 } 103 104 case '\\': 105 fetch(c, p, n); 106 if (c == '\0') 107 return (0); 108 /*FALLTHRU*/ 109 110 default: 111 if (c != scc) 112 return (0); 113 /*FALLTHRU*/ 114 115 case '?': 116 return (scc ? gmatch(s, p) : 0); 117 118 case '*': 119 if (*p == '\0') 120 return (1); 121 s = bs; 122 while (*s) { 123 if (gmatch(s, p)) 124 return (1); 125 fetch(scc, s, n); 126 } 127 return (0); 128 129 case '\0': 130 return (scc == '\0'); 131 132 case WEOF: 133 return (0); 134 135 } 136 }