43#include "magick/studio.h"
44#include "magick/exception.h"
45#include "magick/exception-private.h"
46#include "magick/image.h"
47#include "magick/image-private.h"
48#include "magick/locale-private.h"
49#include "magick/memory_.h"
50#include "magick/string_.h"
51#include "magick/string-private.h"
52#include "magick/token.h"
53#include "magick/token-private.h"
54#include "magick/utility.h"
95MagickExport TokenInfo *AcquireTokenInfo(
void)
100 token_info=(TokenInfo *) AcquireMagickMemory(
sizeof(*token_info));
101 if (token_info == (TokenInfo *) NULL)
102 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
103 token_info->signature=MagickCoreSignature;
130MagickExport TokenInfo *DestroyTokenInfo(TokenInfo *token_info)
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))
253 value=StringToDouble(p,&q);
255 if ((p != q) && (*p !=
','))
257 for ( ; (p < q) && (*p !=
','); p++)
259 if (i < (ssize_t) (extent-1))
261 if ((
size_t) (p-start) >= (extent-1))
266 if (i < (ssize_t) (extent-1))
272 if ((*p !=
'\0') && (isalpha((
int) ((
unsigned char) *p)) == 0) &&
273 (*p != *DirectorySeparator) && (*p !=
'#') && (*p !=
'<'))
275 if (i < (ssize_t) (extent-1))
280 for ( ; *p !=
'\0'; p++)
282 if (((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
'=') ||
283 (*p ==
',') || (*p ==
':') || (*p ==
';')) && (*(p-1) !=
'\\'))
285 if ((i > 0) && (*p ==
'<'))
287 if (i < (ssize_t) (extent-1))
293 for (p++; *p !=
'\0'; p++)
295 if (i < (ssize_t) (extent-1))
297 if ((*p ==
')') && (*(p-1) !=
'\\'))
299 if ((
size_t) (p-start) >= (extent-1))
305 if ((
size_t) (p-start) >= (extent-1))
312 if (LocaleNCompare(token,
"url(#",5) == 0)
314 q=strrchr(token,
')');
315 if (q != (
char *) NULL)
318 (void) memmove(token,token+5,(
size_t) (q-token-4));
321 while (isspace((
int) ((
unsigned char) *p)) != 0)
323 if (end != (
const char **) NULL)
324 *end=(
const char *) p;
358static MagickBooleanType GlobExpression_(
const char *magick_restrict expression,
359 const char *magick_restrict pattern,
const MagickBooleanType case_insensitive,
362 if (depth > MagickMaxRecursionDepth)
370 if (pattern == (
const char *) NULL)
372 if (GetUTFCode(pattern) == 0)
374 if ((GetUTFCode(pattern) ==
'*') &&
375 (GetUTFCode(pattern+GetUTFOctets(pattern)) == 0))
377 if ((strchr(pattern,
'{') == NULL) &&
378 (strchr(pattern,
'*') == NULL) &&
379 (strchr(pattern,
'?') == NULL))
382 path[MagickPathExtent]= { 0 };
387 GetPathComponent(pattern,SubimagePath,path);
391 while (GetUTFCode(pattern) != 0)
394 ecode = GetUTFCode(expression),
395 pcode = GetUTFCode(pattern);
397 if ((ecode == 0) && (pcode !=
'*') && (pcode !=
'{'))
408 pattern+=GetUTFOctets(pattern);
410 while (GetUTFCode(pattern) ==
'*');
416 if (GlobExpression_(expression,pattern,case_insensitive,depth+1) != MagickFalse)
421 while (GetUTFCode(expression) != 0)
422 expression+=GetUTFOctets(expression);
423 while (GetUTFCode(pattern) != 0)
424 pattern+=GetUTFOctets(pattern);
427 if (GetUTFCode(expression) == 0)
429 expression+=GetUTFOctets(expression);
437 pattern+=GetUTFOctets(pattern);
438 expression+=GetUTFOctets(expression);
444 *p = pattern+GetUTFOctets(pattern),
445 *q = pattern+GetUTFOctets(pattern);
448 matched = MagickFalse;
452 while ((GetUTFCode(q) != 0) && (GetUTFCode(q) !=
']'))
454 if (GetUTFCode(q) == 0)
462 code = GetUTFCode(p);
465 octets = GetUTFOctets(p);
471 octets=GetUTFOctets(p);
474 if ((next < q) && (GetUTFCode(next) ==
'-'))
479 next+=GetUTFOctets(next);
480 ncode=GetUTFCode(next);
483 next+=GetUTFOctets(next);
484 ncode=GetUTFCode(next);
486 if ((ecode >= code) && (ecode <= ncode))
488 p=next+GetUTFOctets(next);
500 if (matched == MagickFalse)
502 pattern=q+GetUTFOctets(q);
503 expression+=GetUTFOctets(expression);
517 remaining = MagickPathExtent;
519 pattern+=GetUTFOctets(pattern);
520 if (GetUTFCode(pattern) == 0)
526 while ((GetUTFCode(p) != 0) && (GetUTFCode(p) !=
'}'))
528#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
529 if (GetUTFCode(p) ==
'\\')
532 if (GetUTFCode(p) == 0)
538 if (GetUTFCode(p) !=
'}')
541 alternative=AcquireString(pattern);
546 code = GetUTFCode(pattern);
551 if ((code == 0) || (code ==
',') || (code ==
'}'))
563 subpattern=AcquireString(alternative);
564 if (ConcatenateString(&subpattern,q) == MagickFalse)
566 subpattern=DestroyString(subpattern);
567 alternative=DestroyString(alternative);
570 match=GlobExpression_(expression,subpattern,case_insensitive,
572 subpattern=DestroyString(subpattern);
573 if (match != MagickFalse)
578 while (GetUTFCode(expression) != 0)
579 expression+=GetUTFOctets(expression);
581 while (GetUTFCode(pattern) != 0)
582 pattern+=GetUTFOctets(pattern);
583 alternative=DestroyString(alternative);
590 remaining=MagickPathExtent;
593 pattern+=GetUTFOctets(pattern);
601 octets=GetUTFOctets(pattern);
602 if ((octets == 0) || (octets >= remaining))
604 (void) memcpy(a,pattern,octets);
609 alternative=DestroyString(alternative);
612#if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
615 pattern+=GetUTFOctets(pattern);
616 if (GetUTFCode(pattern) == 0)
629 if (case_insensitive != MagickFalse)
631 pc=LocaleToLowercase(pc);
632 ec=LocaleToLowercase(ec);
636 pattern+=GetUTFOctets(pattern);
637 expression+=GetUTFOctets(expression);
642 while (GetUTFCode(pattern) ==
'*')
643 pattern+=GetUTFOctets(pattern);
644 return(((GetUTFCode(expression) == 0) &&
645 (GetUTFCode(pattern) == 0)) ? MagickTrue : MagickFalse);
648MagickExport MagickBooleanType GlobExpression(
649 const char *magick_restrict expression,
const char *magick_restrict pattern,
650 const MagickBooleanType case_insensitive)
652 return(GlobExpression_(expression,pattern,case_insensitive,0));
678MagickExport MagickBooleanType IsGlob(
const char *path)
681 status = MagickFalse;
686 if (IsPathAccessible(path) != MagickFalse)
688 for (p=path; *p !=
'\0'; p++)
735MagickExport MagickBooleanType IsMagickTrue(
const char *value)
737 if (value == (
const char *) NULL)
739 if (LocaleCompare(value,
"true") == 0)
741 if (LocaleCompare(value,
"on") == 0)
743 if (LocaleCompare(value,
"yes") == 0)
745 if (LocaleCompare(value,
"1") == 0)
917static ssize_t sindex(
int c,
const char *
string)
922 for (p=
string; *p !=
'\0'; p++)
924 return((ssize_t) (p-
string));
928static void StoreToken(TokenInfo *token_info,
char *
string,
929 size_t max_token_length,
int c)
934 if ((token_info->offset < 0) ||
935 ((
size_t) token_info->offset >= (max_token_length-1)))
937 i=token_info->offset++;
939 if (token_info->state == IN_QUOTE)
941 switch (token_info->flag & 0x03)
945 string[i]=(char) LocaleToUppercase(c);
950 string[i]=(char) LocaleToLowercase(c);
958MagickExport
int Tokenizer(TokenInfo *token_info,
const unsigned flag,
959 char *token,
const size_t max_token_length,
const char *line,
const char *white,
960 const char *break_set,
const char *quote,
const char escape,
char *breaker,
961 int *next,
char *quoted)
971 if (line[*next] ==
'\0')
973 token_info->state=IN_WHITE;
974 token_info->quote=(char) MagickFalse;
975 token_info->flag=flag;
976 for (token_info->offset=0; (
int) line[*next] != 0; (*next)++)
979 i=sindex(c,break_set);
982 switch (token_info->state)
989 *breaker=break_set[i];
990 token[token_info->offset]=
'\0';
995 StoreToken(token_info,token,max_token_length,c);
1004 switch (token_info->state)
1008 token_info->state=IN_QUOTE;
1009 token_info->quote=quote[i];
1010 *quoted=(char) MagickTrue;
1015 if (quote[i] != token_info->quote)
1016 StoreToken(token_info,token,max_token_length,c);
1019 token_info->state=IN_OZONE;
1020 token_info->quote=
'\0';
1028 token[token_info->offset]=
'\0';
1037 switch (token_info->state)
1044 token_info->state=IN_OZONE;
1049 StoreToken(token_info,token,max_token_length,c);
1055 if (c == (
int) escape)
1057 if (line[(*next)+1] ==
'\0')
1060 StoreToken(token_info,token,max_token_length,c);
1062 token[token_info->offset]=
'\0';
1065 switch (token_info->state)
1070 token_info->state=IN_TOKEN;
1077 c=(int) line[*next];
1078 StoreToken(token_info,token,max_token_length,c);
1083 token[token_info->offset]=
'\0';
1089 switch (token_info->state)
1093 token_info->state=IN_TOKEN;
1094 StoreToken(token_info,token,max_token_length,c);
1100 StoreToken(token_info,token,max_token_length,c);
1105 token[token_info->offset]=
'\0';
1110 token[token_info->offset]=
'\0';