43#include "MagickCore/studio.h"
44#include "MagickCore/exception.h"
45#include "MagickCore/exception-private.h"
46#include "MagickCore/image.h"
47#include "MagickCore/image-private.h"
48#include "MagickCore/locale-private.h"
49#include "MagickCore/memory_.h"
50#include "MagickCore/memory-private.h"
51#include "MagickCore/string_.h"
52#include "MagickCore/string-private.h"
53#include "MagickCore/token.h"
54#include "MagickCore/token-private.h"
55#include "MagickCore/utility.h"
56#include "MagickCore/utility-private.h"
97MagickExport
TokenInfo *AcquireTokenInfo(
void)
102 token_info=(
TokenInfo *) AcquireCriticalMemory(
sizeof(*token_info));
103 token_info->signature=MagickCoreSignature;
132 assert(token_info != (
TokenInfo *) NULL);
133 assert(token_info->signature == MagickCoreSignature);
134 if (IsEventLogging() != MagickFalse)
135 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
136 token_info->signature=(~MagickCoreSignature);
137 token_info=(
TokenInfo *) RelinquishMagickMemory(token_info);
176MagickExport magick_hot_spot
size_t GetNextToken(
177 const char *magick_restrict start,
const char **magick_restrict end,
178 const size_t extent,
char *magick_restrict token)
192 assert(start != (
const char *) NULL);
193 assert(token != (
char *) NULL);
196 while ((isspace((
int) ((
unsigned char) *p)) != 0) && (*p !=
'\0'))
212 case '"': escape=
'"';
break;
213 case '\'': escape=
'\'';
break;
214 case '`': escape=
'\'';
break;
215 case '{': escape=
'}';
break;
216 default: escape=(*p);
break;
218 for (p++; *p !=
'\0'; p++)
220 if ((*p ==
'\\') && ((*(p+1) == escape) || (*(p+1) ==
'\\')))
228 if (i < (ssize_t) (extent-1))
230 if ((
size_t) (p-start) >= (extent-1))
237 if (i < (ssize_t) (extent-1))
240 if ((*p ==
'>') || (*p ==
'/'))
242 if (i < (ssize_t) (extent-1))
250 value=StringToDouble(p,&q);
252 if ((p != q) && (*p !=
','))
254 for ( ; (p < q) && (*p !=
','); p++)
256 if (i < (ssize_t) (extent-1))
258 if ((
size_t) (p-start) >= (extent-1))
263 if (i < (ssize_t) (extent-1))
269 if ((*p !=
'\0') && (isalpha((
int) ((
unsigned char) *p)) == 0) &&
270 (*p != *DirectorySeparator) && (*p !=
'#') && (*p !=
'<'))
272 if (i < (ssize_t) (extent-1))
277 for ( ; *p !=
'\0'; p++)
279 if (((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
'=') ||
280 (*p ==
',') || (*p ==
':') || (*p ==
';')) && (*(p-1) !=
'\\'))
282 if ((i > 0) && (*p ==
'<'))
284 if (i < (ssize_t) (extent-1))
290 for (p++; *p !=
'\0'; p++)
292 if (i < (ssize_t) (extent-1))
294 if ((*p ==
')') && (*(p-1) !=
'\\'))
296 if ((
size_t) (p-start) >= (extent-1))
302 if ((
size_t) (p-start) >= (extent-1))
309 if (LocaleNCompare(token,
"url(#",5) == 0)
311 q=strrchr(token,
')');
312 if (q != (
char *) NULL)
315 (void) memmove(token,token+5,(
size_t) (q-token-4));
318 while (isspace((
int) ((
unsigned char) *p)) != 0)
320 if (end != (
const char **) NULL)
321 *end=(
const char *) p;
322 return((
size_t) (p-start+1));
354MagickExport MagickBooleanType GlobExpression(
355 const char *magick_restrict expression,
const char *magick_restrict pattern,
356 const MagickBooleanType case_insensitive)
359 path[MagickPathExtent];
368 if (pattern == (
char *) NULL)
370 if (GetUTFCode(pattern) == 0)
372 if (LocaleCompare(pattern,
"*") == 0)
374 GetPathComponent(pattern,SubimagePath,path);
381 while ((GetUTFCode(pattern) != 0) && (done == MagickFalse))
383 if (GetUTFCode(expression) == 0)
384 if ((GetUTFCode(pattern) !=
'{') && (GetUTFCode(pattern) !=
'*'))
386 switch (GetUTFCode(pattern))
394 while (GetUTFCode(pattern) ==
'*')
395 pattern+=GetUTFOctets(pattern);
396 while ((GetUTFCode(expression) != 0) && (status == MagickFalse))
398 status=GlobExpression(expression,pattern,case_insensitive);
399 expression+=GetUTFOctets(expression);
401 if (status != MagickFalse)
403 while (GetUTFCode(expression) != 0)
404 expression+=GetUTFOctets(expression);
405 while (GetUTFCode(pattern) != 0)
406 pattern+=GetUTFOctets(pattern);
415 pattern+=GetUTFOctets(pattern);
418 if ((GetUTFCode(pattern) == 0) || (GetUTFCode(pattern) ==
']'))
423 if (GetUTFCode(pattern) ==
'\\')
425 pattern+=GetUTFOctets(pattern);
426 if (GetUTFCode(pattern) == 0)
432 if (GetUTFCode(pattern+GetUTFOctets(pattern)) ==
'-')
434 c=GetUTFCode(pattern);
435 pattern+=GetUTFOctets(pattern);
436 pattern+=GetUTFOctets(pattern);
437 if (GetUTFCode(pattern) ==
']')
442 if (GetUTFCode(pattern) ==
'\\')
444 pattern+=GetUTFOctets(pattern);
445 if (GetUTFCode(pattern) == 0)
451 if ((GetUTFCode(expression) < c) ||
452 (GetUTFCode(expression) > GetUTFCode(pattern)))
454 pattern+=GetUTFOctets(pattern);
459 if (GetUTFCode(pattern) != GetUTFCode(expression))
461 pattern+=GetUTFOctets(pattern);
464 pattern+=GetUTFOctets(pattern);
465 while ((GetUTFCode(pattern) !=
']') && (GetUTFCode(pattern) != 0))
467 if ((GetUTFCode(pattern) ==
'\\') &&
468 (GetUTFCode(pattern+GetUTFOctets(pattern)) > 0))
469 pattern+=GetUTFOctets(pattern);
470 pattern+=GetUTFOctets(pattern);
472 if (GetUTFCode(pattern) != 0)
474 pattern+=GetUTFOctets(pattern);
475 expression+=GetUTFOctets(expression);
483 pattern+=GetUTFOctets(pattern);
484 expression+=GetUTFOctets(expression);
495 target=AcquireString(pattern);
498 while ((GetUTFCode(pattern) !=
'}') && (GetUTFCode(pattern) != 0))
501 if ((GetUTFCode(pattern) ==
',') || (GetUTFCode(pattern) ==
'}'))
504 match=GlobExpression(expression,target,case_insensitive);
505 if (match != MagickFalse)
507 expression+=MagickMin(strlen(expression),strlen(target));
511 pattern+=GetUTFOctets(pattern);
514 while ((GetUTFCode(pattern) !=
'}') && (GetUTFCode(pattern) != 0))
515 pattern+=GetUTFOctets(pattern);
516 if (GetUTFCode(pattern) != 0)
517 pattern+=GetUTFOctets(pattern);
518 target=DestroyString(target);
521#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
524 pattern+=GetUTFOctets(pattern);
525 if (GetUTFCode(pattern) == 0)
532 if (case_insensitive != MagickFalse)
534 if (LocaleToLowercase((
int) GetUTFCode(expression)) != LocaleToLowercase((
int) GetUTFCode(pattern)))
541 if (GetUTFCode(expression) != GetUTFCode(pattern))
546 expression+=GetUTFOctets(expression);
547 pattern+=GetUTFOctets(pattern);
551 while (GetUTFCode(pattern) ==
'*')
552 pattern+=GetUTFOctets(pattern);
553 match=(GetUTFCode(expression) == 0) && (GetUTFCode(pattern) == 0) ?
554 MagickTrue : MagickFalse;
581MagickPrivate MagickBooleanType IsGlob(
const char *path)
584 status = MagickFalse;
589 if (IsPathAccessible(path) != MagickFalse)
591 for (p=path; *p !=
'\0'; p++)
779static ssize_t sindex(
int c,
const char *
string)
784 for (p=
string; *p !=
'\0'; p++)
786 return((ssize_t) (p-
string));
790static void StoreToken(
TokenInfo *token_info,
char *
string,
791 size_t max_token_length,
int c)
796 if ((token_info->offset < 0) ||
797 ((
size_t) token_info->offset >= (max_token_length-1)))
799 i=token_info->offset++;
801 if (token_info->state == IN_QUOTE)
803 switch (token_info->flag & 0x03)
807 string[i]=(char) LocaleToUppercase(c);
812 string[i]=(char) LocaleToLowercase(c);
820MagickExport
int Tokenizer(
TokenInfo *token_info,
const unsigned flag,
821 char *token,
const size_t max_token_length,
const char *line,
const char *white,
822 const char *break_set,
const char *quote,
const char escape,
char *breaker,
823 int *next,
char *quoted)
833 if (line[*next] ==
'\0')
835 token_info->state=IN_WHITE;
836 token_info->quote=(char) MagickFalse;
837 token_info->flag=flag;
838 for (token_info->offset=0; (int) line[*next] != 0; (*next)++)
841 i=sindex(c,break_set);
844 switch (token_info->state)
851 *breaker=break_set[i];
852 token[token_info->offset]=
'\0';
857 StoreToken(token_info,token,max_token_length,c);
866 switch (token_info->state)
870 token_info->state=IN_QUOTE;
871 token_info->quote=quote[i];
872 *quoted=(char) MagickTrue;
877 if (quote[i] != token_info->quote)
878 StoreToken(token_info,token,max_token_length,c);
881 token_info->state=IN_OZONE;
882 token_info->quote=
'\0';
890 token[token_info->offset]=
'\0';
899 switch (token_info->state)
906 token_info->state=IN_OZONE;
911 StoreToken(token_info,token,max_token_length,c);
917 if (c == (
int) escape)
919 if (line[(*next)+1] ==
'\0')
922 StoreToken(token_info,token,max_token_length,c);
924 token[token_info->offset]=
'\0';
927 switch (token_info->state)
932 token_info->state=IN_TOKEN;
940 StoreToken(token_info,token,max_token_length,c);
945 token[token_info->offset]=
'\0';
951 switch (token_info->state)
955 token_info->state=IN_TOKEN;
956 StoreToken(token_info,token,max_token_length,c);
962 StoreToken(token_info,token,max_token_length,c);
967 token[token_info->offset]=
'\0';
972 token[token_info->offset]=
'\0';