|
WizardsToolkit
1.0.7
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % TTTTT OOO K K EEEEE N N % 00007 % T O O K K E NN N % 00008 % T O O KKK EEE N N N % 00009 % T O O K K E N NN % 00010 % T OOO K K EEEEE N N % 00011 % % 00012 % % 00013 % Wizard's Toolkit Token Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % March 2003 % 00018 % % 00019 % % 00020 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.wizards-toolkit.org/script/license.php % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 % 00038 */ 00039 00040 /* 00041 Include declarations. 00042 */ 00043 #include "wizard/studio.h" 00044 #include "wizard/exception.h" 00045 #include "wizard/exception-private.h" 00046 #include "wizard/locale_.h" 00047 #include "wizard/string_.h" 00048 #include "wizard/string-private.h" 00049 #include "wizard/token.h" 00050 #include "wizard/utility.h" 00051 00052 /* 00053 Typedef declarations. 00054 */ 00055 struct _TokenInfo 00056 { 00057 int 00058 state; 00059 00060 WizardStatusType 00061 flag; 00062 00063 ssize_t 00064 offset; 00065 00066 char 00067 quote; 00068 }; 00069 00070 /* 00071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00072 % % 00073 % % 00074 % % 00075 + G e t W i z a r d T o k e n % 00076 % % 00077 % % 00078 % % 00079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00080 % 00081 % GetWizardToken() gets a token from the token stream. A token is defined as a 00082 % sequence of characters delimited by whitespace (e.g. clip-path), a sequence 00083 % delimited with quotes (.e.g "Quote me"), or a sequence enclosed in 00084 % parenthesis (e.g. rgb(0,0,0)). 00085 % 00086 % The format of the GetWizardToken method is: 00087 % 00088 % void GetWizardToken(const char *start,const char **end,char *token) 00089 % 00090 % A description of each parameter follows: 00091 % 00092 % o start: the start of the token sequence. 00093 % 00094 % o end: point to the end of the token sequence. 00095 % 00096 % o token: copy the token to this buffer. 00097 % 00098 */ 00099 WizardExport void GetWizardToken(const char *start,const char **end,char *token) 00100 { 00101 register const char 00102 *p; 00103 00104 register ssize_t 00105 i; 00106 00107 assert(start != (const char *) NULL); 00108 assert(token != (char *) NULL); 00109 i=0; 00110 for (p=start; *p != '\0'; ) 00111 { 00112 while ((isspace((int) ((unsigned char) *p)) != 0) && (*p != '\0')) 00113 p++; 00114 if (*p == '\0') 00115 break; 00116 switch (*p) 00117 { 00118 case '"': 00119 case '\'': 00120 case '`': 00121 case '{': 00122 { 00123 register char 00124 escape; 00125 00126 switch (*p) 00127 { 00128 case '"': escape='"'; break; 00129 case '\'': escape='\''; break; 00130 case '`': escape='\''; break; 00131 case '{': escape='}'; break; 00132 default: escape=(*p); break; 00133 } 00134 for (p++; *p != '\0'; p++) 00135 { 00136 if ((*p == '\\') && ((*(p+1) == escape) || (*(p+1) == '\\'))) 00137 p++; 00138 else 00139 if (*p == escape) 00140 { 00141 p++; 00142 break; 00143 } 00144 token[i++]=(*p); 00145 } 00146 break; 00147 } 00148 case '/': 00149 { 00150 token[i++]=(*p++); 00151 if ((*p == '>') || (*p == '/')) 00152 token[i++]=(*p++); 00153 break; 00154 } 00155 default: 00156 { 00157 char 00158 *q; 00159 00160 double 00161 value; 00162 00163 value=StringToDouble(p,&q); 00164 (void) value; 00165 if ((p != q) && (*p != ',')) 00166 { 00167 for ( ; (p < q) && (*p != ','); p++) 00168 token[i++]=(*p); 00169 if (*p == '%') 00170 token[i++]=(*p++); 00171 break; 00172 } 00173 if ((*p != '\0') && (isalpha((int) ((unsigned char) *p)) == 0) && 00174 (*p != *DirectorySeparator) && (*p != '#') && (*p != '<')) 00175 { 00176 token[i++]=(*p++); 00177 break; 00178 } 00179 for ( ; *p != '\0'; p++) 00180 { 00181 if (((isspace((int) ((unsigned char) *p)) != 0) || (*p == '=') || 00182 (*p == ',') || (*p == ':')) && (*(p-1) != '\\')) 00183 break; 00184 if ((i > 0) && (*p == '<')) 00185 break; 00186 token[i++]=(*p); 00187 if (*p == '>') 00188 break; 00189 if (*p == '(') 00190 for (p++; *p != '\0'; p++) 00191 { 00192 token[i++]=(*p); 00193 if ((*p == ')') && (*(p-1) != '\\')) 00194 break; 00195 } 00196 } 00197 break; 00198 } 00199 } 00200 break; 00201 } 00202 token[i]='\0'; 00203 if (LocaleNCompare(token,"url(#",5) == 0) 00204 { 00205 i=(ssize_t) strlen(token); 00206 (void) CopyWizardString(token,token+5,MaxTextExtent); 00207 token[i-6]='\0'; 00208 } 00209 if (LocaleNCompare(token,"url(",4) == 0) 00210 { 00211 i=(ssize_t) strlen(token); 00212 (void) CopyWizardString(token,token+4,MaxTextExtent); 00213 token[i-5]='\0'; 00214 } 00215 while (isspace((int) ((unsigned char) *p)) != 0) 00216 p++; 00217 if (end != (const char **) NULL) 00218 *end=(const char *) p; 00219 } 00220 00221 /* 00222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00223 % % 00224 % % 00225 % % 00226 % G l o b E x p r e s s i o n % 00227 % % 00228 % % 00229 % % 00230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00231 % 00232 % GlobExpression() returns WizardTrue if the expression matches the pattern. 00233 % 00234 % The format of the GlobExpression function is: 00235 % 00236 % WizardBooleanType GlobExpression(const char *expression, 00237 % const char *pattern,const WizardBooleanType case_insensitive) 00238 % 00239 % A description of each parameter follows: 00240 % 00241 % o expression: Specifies a pointer to a text string containing a file name. 00242 % 00243 % o pattern: Specifies a pointer to a text string containing a pattern. 00244 % 00245 % o case_insensitive: set to WizardTrue to ignore the case when matching 00246 % an expression. 00247 % 00248 */ 00249 WizardExport WizardBooleanType GlobExpression(const char *expression, 00250 const char *pattern,const WizardBooleanType case_insensitive) 00251 { 00252 WizardBooleanType 00253 done, 00254 match; 00255 00256 /* 00257 Return on empty pattern or '*'. 00258 */ 00259 if (pattern == (char *) NULL) 00260 return(WizardTrue); 00261 if (*pattern == '\0') 00262 return(WizardTrue); 00263 if (LocaleCompare(pattern,"*") == 0) 00264 return(WizardTrue); 00265 /* 00266 Evaluate glob expression. 00267 */ 00268 done=WizardFalse; 00269 while ((*pattern != '\0') && (done == WizardFalse)) 00270 { 00271 if (*expression == '\0') 00272 if ((*pattern != '{') && (*pattern != '*')) 00273 break; 00274 switch (*pattern) 00275 { 00276 case '*': 00277 { 00278 WizardBooleanType 00279 status; 00280 00281 pattern++; 00282 status=WizardFalse; 00283 while ((*expression != '\0') && (status == WizardFalse)) 00284 status=GlobExpression(expression++,pattern,case_insensitive); 00285 if (status != WizardFalse) 00286 { 00287 while (*expression != '\0') 00288 expression++; 00289 while (*pattern != '\0') 00290 pattern++; 00291 } 00292 break; 00293 } 00294 case '[': 00295 { 00296 char 00297 c; 00298 00299 pattern++; 00300 for ( ; ; ) 00301 { 00302 if ((*pattern == '\0') || (*pattern == ']')) 00303 { 00304 done=WizardTrue; 00305 break; 00306 } 00307 if (*pattern == '\\') 00308 { 00309 pattern++; 00310 if (*pattern == '\0') 00311 { 00312 done=WizardTrue; 00313 break; 00314 } 00315 } 00316 if (*(pattern+1) == '-') 00317 { 00318 c=(*pattern); 00319 pattern+=2; 00320 if (*pattern == ']') 00321 { 00322 done=WizardTrue; 00323 break; 00324 } 00325 if (*pattern == '\\') 00326 { 00327 pattern++; 00328 if (*pattern == '\0') 00329 { 00330 done=WizardTrue; 00331 break; 00332 } 00333 } 00334 if ((*expression < c) || (*expression > *pattern)) 00335 { 00336 pattern++; 00337 continue; 00338 } 00339 } 00340 else 00341 if (*pattern != *expression) 00342 { 00343 pattern++; 00344 continue; 00345 } 00346 pattern++; 00347 while ((*pattern != ']') && (*pattern != '\0')) 00348 { 00349 if ((*pattern == '\\') && (*(pattern+1) != '\0')) 00350 pattern++; 00351 pattern++; 00352 } 00353 if (*pattern != '\0') 00354 { 00355 pattern++; 00356 expression++; 00357 } 00358 break; 00359 } 00360 break; 00361 } 00362 case '?': 00363 { 00364 pattern++; 00365 expression++; 00366 break; 00367 } 00368 case '{': 00369 { 00370 register const char 00371 *p; 00372 00373 pattern++; 00374 while ((*pattern != '}') && (*pattern != '\0')) 00375 { 00376 p=expression; 00377 match=WizardTrue; 00378 while ((*p != '\0') && (*pattern != '\0') && 00379 (*pattern != ',') && (*pattern != '}') && 00380 (match != WizardFalse)) 00381 { 00382 if (*pattern == '\\') 00383 pattern++; 00384 match=(*pattern == *p) ? WizardTrue : WizardFalse; 00385 p++; 00386 pattern++; 00387 } 00388 if (*pattern == '\0') 00389 { 00390 match=WizardFalse; 00391 done=WizardTrue; 00392 break; 00393 } 00394 else 00395 if (match != WizardFalse) 00396 { 00397 expression=p; 00398 while ((*pattern != '}') && (*pattern != '\0')) 00399 { 00400 pattern++; 00401 if (*pattern == '\\') 00402 { 00403 pattern++; 00404 if (*pattern == '}') 00405 pattern++; 00406 } 00407 } 00408 } 00409 else 00410 { 00411 while ((*pattern != '}') && (*pattern != ',') && 00412 (*pattern != '\0')) 00413 { 00414 pattern++; 00415 if (*pattern == '\\') 00416 { 00417 pattern++; 00418 if ((*pattern == '}') || (*pattern == ',')) 00419 pattern++; 00420 } 00421 } 00422 } 00423 if (*pattern != '\0') 00424 pattern++; 00425 } 00426 break; 00427 } 00428 case '\\': 00429 { 00430 pattern++; 00431 if (*pattern == '\0') 00432 break; 00433 } 00434 default: 00435 { 00436 if (case_insensitive != WizardFalse) 00437 { 00438 if (tolower((int) ((unsigned char) *expression)) != 00439 tolower((int) ((unsigned char) *pattern))) 00440 { 00441 done=WizardTrue; 00442 break; 00443 } 00444 } 00445 else 00446 if (*expression != *pattern) 00447 { 00448 done=WizardTrue; 00449 break; 00450 } 00451 expression++; 00452 pattern++; 00453 } 00454 } 00455 } 00456 while (*pattern == '*') 00457 pattern++; 00458 match=(*expression == '\0') && (*pattern == '\0') ? WizardTrue : WizardFalse; 00459 return(match); 00460 } 00461 00462 /* 00463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00464 % % 00465 % % 00466 + I s G l o b % 00467 % % 00468 % % 00469 % % 00470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00471 % 00472 % IsGlob() returns WizardTrue if the path specification contains a globbing 00473 % pattern. 00474 % 00475 % The format of the IsGlob method is: 00476 % 00477 % WizardBooleanType IsGlob(const char *geometry) 00478 % 00479 % A description of each parameter follows: 00480 % 00481 % o status: IsGlob() returns WizardTrue if the path specification contains 00482 % a globbing patten. 00483 % 00484 % o path: The path. 00485 % 00486 */ 00487 WizardExport WizardBooleanType IsGlob(const char *path) 00488 { 00489 WizardBooleanType 00490 status; 00491 00492 if (IsAccessible(path) != WizardFalse) 00493 return(WizardFalse); 00494 status=(strchr(path,'*') != (char *) NULL) || 00495 (strchr(path,'?') != (char *) NULL) || 00496 (strchr(path,'{') != (char *) NULL) || 00497 (strchr(path,'}') != (char *) NULL) || 00498 (strchr(path,'[') != (char *) NULL) || 00499 (strchr(path,']') != (char *) NULL) ? WizardTrue : WizardFalse; 00500 return(status); 00501 }