1 /* 2 3 * Copyright (c) 1984, 1985, 1986 AT&T 4 * All Rights Reserved 5 6 * THIS IS UNPUBLISHED PROPRIETARY SOURCE 7 * CODE OF AT&T. 8 * The copyright notice above does not 9 * evidence any actual or intended 10 * publication of such source code. 11 12 */ 13 /* @(#)gmatch.c 1.1 */ 14 15 /* 16 * gmatch - match Shell expression patterns 17 * 18 * David Korn 19 * AT&T Bell Laboratories 20 * Room 5D-112 21 * Murray Hill, N. J. 07974 22 * Tel. x7975 23 * 24 * Derived from Bourne Shell 25 */ 26 27 /* 28 * gmatch compares the string s with the shell pattern p. 29 * returns 1 for match, 0 otherwise. 30 * The ESCAPE character is used to remove special meaning in pattern only. 31 */ 32 33 #define ESCAPE '\\' 34 35 #ifdef MULTIBYTE 36 # include "national.h" 37 # define C_MASK (3<<(7*ESS_MAXCHAR)) /* character classes */ 38 # define peekchar(x) (_save=x,_c=getchar(x),x=_save,_c) 39 # define getchar(x) ja_getchar((unsigned char**)(&(x))) 40 int ja_getchar(); 41 static char *_save; 42 static int _c; 43 #else 44 # define getchar(x) (*x++) 45 # define peekchar(x) (*x) 46 #endif /* MULTIBYTE */ 47 48 gmatch(s, p) 49 #ifdef MULTIBYTE 50 char *p; 51 #else 52 register char *p; 53 #endif /* MULTIBYTE */ 54 char *s; 55 { 56 register int scc,c; 57 register int d; 58 char *olds; 59 while((olds=s,scc = getchar(s))) 60 { 61 switch(c = getchar(p)) 62 { 63 case '[': 64 { 65 char ok = 0; 66 int lc = -1; 67 int notflag=0; 68 if(*p == '!' ) 69 { 70 notflag=1; 71 p++; 72 } 73 while(c = getchar(p)) 74 { 75 if(c==']' && lc>=0) 76 return(ok?gmatch(s,p):0); 77 else if(c=='-' && lc>=0 && *p!=']') 78 /*character range */ 79 { 80 c = getchar(p); 81 #ifdef MULTIBYTE 82 /* must be in same char set */ 83 if((c&C_MASK) != (lc&C_MASK)) 84 { 85 int match; 86 match = (scc==c||scc==lc); 87 if(notflag) 88 { 89 if(!match) 90 ok++; 91 else 92 return(0); 93 } 94 else 95 { 96 if(match) 97 ok++; 98 } 99 lc = c; 100 } 101 #endif /* MULTIBYTE */ 102 if(notflag) 103 { 104 if(lc>scc || scc>c) 105 ok++; 106 else 107 return(0); 108 } 109 else 110 if(lc<scc && scc<=c) 111 ok++; 112 } 113 else 114 { 115 if(c == ESCAPE) 116 c = *p++; 117 if(notflag) 118 { 119 if(scc!=c) 120 ok++; 121 else 122 return(0); 123 } 124 else 125 { 126 if(scc==c) 127 ok++; 128 } 129 lc = c; 130 } 131 } 132 return(0); 133 } 134 case '\\': 135 c = getchar(p); /* need exact match */ 136 default: 137 if(c != scc) 138 return(0); 139 case '?': 140 break; 141 case '*': 142 /* several asterisks are the same as one */ 143 while(*p=='*' ) 144 p++; 145 if(*p==0) 146 return(1); 147 d = scc; 148 c = peekchar(p); 149 scc = (c!='?' && c !='['); 150 if(c==ESCAPE) 151 c = *(p+1); 152 while(d) 153 { 154 if(scc && c != d) 155 ; 156 else if(gmatch(olds,p)) 157 return(1); 158 olds = s; 159 d = getchar(s); 160 161 } 162 return(0); 163 164 case 0: 165 return(scc==0); 166 } 167 } 168 while(*p == '*') 169 p++; 170 return(*p==0); 171 } 172 173 #ifdef MULTIBYTE 174 175 /* 176 * This character read from one to three bytes and returns a character 177 * The character set designation is in the bits defined by C_MASK 178 */ 179 180 int ja_getchar(address) 181 unsigned char **address; 182 { 183 register unsigned char *cp = *(unsigned char**)address; 184 register int c = *cp++; 185 register int size; 186 int d; 187 if(size = echarset(c)) 188 { 189 d = (size==1?c:0); 190 c = size; 191 size = in_csize(c); 192 c <<= 7*(ESS_MAXCHAR-size); 193 if(d) 194 { 195 size--; 196 c = (c<<7) | (d&~HIGHBIT); 197 } 198 while(size-- >0) 199 c = (c<<7) | ((*cp++)&~HIGHBIT); 200 } 201 *address = cp; 202 return(c); 203 } 204 #endif /*MULTIBYTE*/ 205