13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                    TTTTT   OOO   K   K  EEEEE  N   N                        %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                      T    O   O  K  K   E      NN  N                        %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                      T    O   O  KKK    EEE    N N N                        %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                      T    O   O  K  K   E      N  NN                        %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                      T     OOO   K   K  EEEEE  N   N                        %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                         MagickCore Token Methods                            %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             Software Design                                 %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                  Cristy                                     %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              January 1993                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string-private.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token-private.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
53d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h"
543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Typedef declaractions.
573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystruct _TokenInfo
593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    state;
623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickStatusType
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    flag;
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  ssize_t
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    offset;
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    quote;
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
72bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    signature;
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy};
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   A c q u i r e T o k e n I n f o                                           %
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  AcquireTokenInfo() allocates the TokenInfo structure.
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the AcquireTokenInfo method is:
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      TokenInfo *AcquireTokenInfo()
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport TokenInfo *AcquireTokenInfo(void)
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  TokenInfo
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *token_info;
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9973bd4a51b419e914565bdf204bf1540dc4c8ee26cristy  token_info=(TokenInfo *) AcquireMagickMemory(sizeof(*token_info));
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (token_info == (TokenInfo *) NULL)
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
102e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  token_info->signature=MagickCoreSignature;
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(token_info);
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   D e s t r o y T o k e n I n f o                                           %
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DestroyTokenInfo() deallocates memory associated with an TokenInfo
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  structure.
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the DestroyTokenInfo method is:
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      TokenInfo *DestroyTokenInfo(TokenInfo *token_info)
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o token_info: Specifies a pointer to an TokenInfo structure.
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport TokenInfo *DestroyTokenInfo(TokenInfo *token_info)
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(token_info != (TokenInfo *) NULL);
133e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(token_info->signature == MagickCoreSignature);
134e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  token_info->signature=(~MagickCoreSignature);
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token_info=(TokenInfo *) RelinquishMagickMemory(token_info);
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(token_info);
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1448bedb4edca01599dfd0612cb0daa35b09c67d736Cristy+   G e t N e x t T o k e n                                                   %
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
150ce9583ca242465aa34760f6be20dde3644fdf0e3dirk%  GetNextToken() gets a token from the token stream.  A token is defined as
151df11e55f50d0a8dc1aee2f31377433a1d467c42bcristy%  a sequence of characters delimited by whitespace (e.g. clip-path), a
152df11e55f50d0a8dc1aee2f31377433a1d467c42bcristy%  sequence delimited with quotes (.e.g "Quote me"), or a sequence enclosed in
1538bedb4edca01599dfd0612cb0daa35b09c67d736Cristy%  parenthesis (e.g. rgb(0,0,0)).  GetNextToken() also recognizes these
154dd8327f9d17d538c11ec1bed595da7b6b96dcc68cristy%  separator characters: ':', '=', ',', and ';'.
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1568bedb4edca01599dfd0612cb0daa35b09c67d736Cristy%  The format of the GetNextToken method is:
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1588bedb4edca01599dfd0612cb0daa35b09c67d736Cristy%      void GetNextToken(const char *start,const char **end,
1590f9ed5ef8d6249099c5fd5720046d770daab0e9fCristy%        const size_t extent,char *token)
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o start: the start of the token sequence.
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o end: point to the end of the token sequence.
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
167a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy%    o extent: maximum extent of the token.
168a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy%
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o token: copy the token to this buffer.
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1728bedb4edca01599dfd0612cb0daa35b09c67d736CristyMagickExport void GetNextToken(const char *start,const char **end,
173a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy  const size_t extent,char *token)
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  double
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value;
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
181bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
18432f691292dd8d0ff10a6b03c3861ab65e2fc35c1cristy  assert(start != (const char *) NULL);
18532f691292dd8d0ff10a6b03c3861ab65e2fc35c1cristy  assert(token != (char *) NULL);
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=0;
187708e3c690939d1c675af263860990d054aa014b2cristy  p=start;
188708e3c690939d1c675af263860990d054aa014b2cristy  while ((isspace((int) ((unsigned char) *p)) != 0) && (*p != '\0'))
189708e3c690939d1c675af263860990d054aa014b2cristy    p++;
190708e3c690939d1c675af263860990d054aa014b2cristy  switch (*p)
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
19204861e2ceaa512a2668756169f4fba5507c47c28cristy    case '\0':
19304861e2ceaa512a2668756169f4fba5507c47c28cristy      break;
194708e3c690939d1c675af263860990d054aa014b2cristy    case '"':
195708e3c690939d1c675af263860990d054aa014b2cristy    case '\'':
196708e3c690939d1c675af263860990d054aa014b2cristy    case '`':
197708e3c690939d1c675af263860990d054aa014b2cristy    case '{':
1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
199708e3c690939d1c675af263860990d054aa014b2cristy      register char
200708e3c690939d1c675af263860990d054aa014b2cristy        escape;
201708e3c690939d1c675af263860990d054aa014b2cristy
202708e3c690939d1c675af263860990d054aa014b2cristy      switch (*p)
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
204708e3c690939d1c675af263860990d054aa014b2cristy        case '"': escape='"'; break;
205708e3c690939d1c675af263860990d054aa014b2cristy        case '\'': escape='\''; break;
206708e3c690939d1c675af263860990d054aa014b2cristy        case '`': escape='\''; break;
207708e3c690939d1c675af263860990d054aa014b2cristy        case '{': escape='}'; break;
208708e3c690939d1c675af263860990d054aa014b2cristy        default: escape=(*p); break;
209708e3c690939d1c675af263860990d054aa014b2cristy      }
210708e3c690939d1c675af263860990d054aa014b2cristy      for (p++; *p != '\0'; p++)
211708e3c690939d1c675af263860990d054aa014b2cristy      {
212708e3c690939d1c675af263860990d054aa014b2cristy        if ((*p == '\\') && ((*(p+1) == escape) || (*(p+1) == '\\')))
213708e3c690939d1c675af263860990d054aa014b2cristy          p++;
214708e3c690939d1c675af263860990d054aa014b2cristy        else
215708e3c690939d1c675af263860990d054aa014b2cristy          if (*p == escape)
216708e3c690939d1c675af263860990d054aa014b2cristy            {
217708e3c690939d1c675af263860990d054aa014b2cristy              p++;
218708e3c690939d1c675af263860990d054aa014b2cristy              break;
219708e3c690939d1c675af263860990d054aa014b2cristy            }
22078a72f5f18f55030dfb8dbc5b2b935827651970aCristy        if (i < (ssize_t) (extent-1))
221a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy          token[i++]=(*p);
222708e3c690939d1c675af263860990d054aa014b2cristy      }
223708e3c690939d1c675af263860990d054aa014b2cristy      break;
224708e3c690939d1c675af263860990d054aa014b2cristy    }
225708e3c690939d1c675af263860990d054aa014b2cristy    case '/':
226708e3c690939d1c675af263860990d054aa014b2cristy    {
22778a72f5f18f55030dfb8dbc5b2b935827651970aCristy      if (i < (ssize_t) (extent-1))
228708e3c690939d1c675af263860990d054aa014b2cristy        token[i++]=(*p++);
229a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy      if ((*p == '>') || (*p == '/'))
23078a72f5f18f55030dfb8dbc5b2b935827651970aCristy        if (i < (ssize_t) (extent-1))
231a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy          token[i++]=(*p++);
232708e3c690939d1c675af263860990d054aa014b2cristy      break;
233708e3c690939d1c675af263860990d054aa014b2cristy    }
234708e3c690939d1c675af263860990d054aa014b2cristy    default:
235708e3c690939d1c675af263860990d054aa014b2cristy    {
236708e3c690939d1c675af263860990d054aa014b2cristy      char
237708e3c690939d1c675af263860990d054aa014b2cristy        *q;
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
239708e3c690939d1c675af263860990d054aa014b2cristy      value=StringToDouble(p,&q);
240708e3c690939d1c675af263860990d054aa014b2cristy      (void) value;
241708e3c690939d1c675af263860990d054aa014b2cristy      if ((p != q) && (*p != ','))
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
243708e3c690939d1c675af263860990d054aa014b2cristy          for ( ; (p < q) && (*p != ','); p++)
24478a72f5f18f55030dfb8dbc5b2b935827651970aCristy            if (i < (ssize_t) (extent-1))
245a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy              token[i++]=(*p);
246708e3c690939d1c675af263860990d054aa014b2cristy          if (*p == '%')
24778a72f5f18f55030dfb8dbc5b2b935827651970aCristy            if (i < (ssize_t) (extent-1))
248a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy              token[i++]=(*p++);
249708e3c690939d1c675af263860990d054aa014b2cristy          break;
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
251708e3c690939d1c675af263860990d054aa014b2cristy      if ((*p != '\0') && (isalpha((int) ((unsigned char) *p)) == 0) &&
252708e3c690939d1c675af263860990d054aa014b2cristy          (*p != *DirectorySeparator) && (*p != '#') && (*p != '<'))
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
25478a72f5f18f55030dfb8dbc5b2b935827651970aCristy          if (i < (ssize_t) (extent-1))
255a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy            token[i++]=(*p++);
256708e3c690939d1c675af263860990d054aa014b2cristy          break;
257708e3c690939d1c675af263860990d054aa014b2cristy        }
258708e3c690939d1c675af263860990d054aa014b2cristy      for ( ; *p != '\0'; p++)
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
260708e3c690939d1c675af263860990d054aa014b2cristy        if (((isspace((int) ((unsigned char) *p)) != 0) || (*p == '=') ||
261a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy            (*p == ',') || (*p == ':') || (*p == ';')) && (*(p-1) != '\\'))
262708e3c690939d1c675af263860990d054aa014b2cristy          break;
263708e3c690939d1c675af263860990d054aa014b2cristy        if ((i > 0) && (*p == '<'))
264708e3c690939d1c675af263860990d054aa014b2cristy          break;
26578a72f5f18f55030dfb8dbc5b2b935827651970aCristy        if (i < (ssize_t) (extent-1))
266a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy          token[i++]=(*p);
267708e3c690939d1c675af263860990d054aa014b2cristy        if (*p == '>')
268708e3c690939d1c675af263860990d054aa014b2cristy          break;
269708e3c690939d1c675af263860990d054aa014b2cristy        if (*p == '(')
270708e3c690939d1c675af263860990d054aa014b2cristy          for (p++; *p != '\0'; p++)
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
27278a72f5f18f55030dfb8dbc5b2b935827651970aCristy            if (i < (ssize_t) (extent-1))
273a8b2bb29cfc3909ff5772673d568ac2add6a5083Cristy              token[i++]=(*p);
274708e3c690939d1c675af263860990d054aa014b2cristy            if ((*p == ')') && (*(p-1) != '\\'))
275708e3c690939d1c675af263860990d054aa014b2cristy              break;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
278708e3c690939d1c675af263860990d054aa014b2cristy      break;
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token[i]='\0';
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleNCompare(token,"url(",4) == 0)
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ssize_t
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        offset;
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      offset=4;
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (token[offset] == '#')
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        offset++;
290bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      i=(ssize_t) strlen(token);
291151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(token,token+offset,MagickPathExtent);
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      token[i-offset-1]='\0';
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (isspace((int) ((unsigned char) *p)) != 0)
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p++;
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (end != (const char **) NULL)
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *end=(const char *) p;
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G l o b E x p r e s s i o n                                               %
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GlobExpression() returns MagickTrue if the expression matches the pattern.
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GlobExpression function is:
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType GlobExpression(const char *expression,
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const char *pattern,const MagickBooleanType case_insensitive)
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o expression: Specifies a pointer to a text string containing a file name.
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pattern: Specifies a pointer to a text string containing a pattern.
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o case_insensitive: set to MagickTrue to ignore the case when matching
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      an expression.
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GlobExpression(const char *expression,
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char *pattern,const MagickBooleanType case_insensitive)
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    done,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    match;
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Return on empty pattern or '*'.
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pattern == (char *) NULL)
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (GetUTFCode(pattern) == 0)
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare(pattern,"*") == 0)
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pattern+strlen(pattern)-1;
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((GetUTFCode(p) == ']') && (strchr(pattern,'[') != (char *) NULL))
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ExceptionInfo
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *exception;
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ImageInfo
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *image_info;
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Determine if pattern is a scene, i.e. img0001.pcd[2].
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info=AcquireImageInfo();
360151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      (void) CopyMagickString(image_info->filename,pattern,MagickPathExtent);
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=AcquireExceptionInfo();
362d965a420485ec04d44aa15ccf4adcfc55811a2e9cristy      (void) SetImageInfo(image_info,0,exception);
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      exception=DestroyExceptionInfo(exception);
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (LocaleCompare(image_info->filename,pattern) != 0)
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          image_info=DestroyImageInfo(image_info);
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return(MagickFalse);
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info=DestroyImageInfo(image_info);
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Evaluate glob expression.
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  done=MagickFalse;
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while ((GetUTFCode(pattern) != 0) && (done == MagickFalse))
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (GetUTFCode(expression) == 0)
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((GetUTFCode(pattern) != '{') && (GetUTFCode(pattern) != '*'))
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    switch (GetUTFCode(pattern))
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case '*':
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        MagickBooleanType
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status;
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        status=MagickFalse;
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pattern+=GetUTFOctets(pattern);
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((GetUTFCode(expression) != 0) && (status == MagickFalse))
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          status=GlobExpression(expression,pattern,case_insensitive);
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          expression+=GetUTFOctets(expression);
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status != MagickFalse)
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            while (GetUTFCode(expression) != 0)
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              expression+=GetUTFOctets(expression);
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            while (GetUTFCode(pattern) != 0)
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case '[':
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
40555a91cddcdea3aa002893186a773e1704884a9dfcristy        int
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          c;
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pattern+=GetUTFOctets(pattern);
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for ( ; ; )
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if ((GetUTFCode(pattern) == 0) || (GetUTFCode(pattern) == ']'))
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              done=MagickTrue;
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetUTFCode(pattern) == '\\')
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetUTFCode(pattern) == 0)
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  done=MagickTrue;
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy             }
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetUTFCode(pattern+GetUTFOctets(pattern)) == '-')
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              c=GetUTFCode(pattern);
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetUTFCode(pattern) == ']')
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  done=MagickTrue;
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  break;
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (GetUTFCode(pattern) == '\\')
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pattern+=GetUTFOctets(pattern);
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (GetUTFCode(pattern) == 0)
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      done=MagickTrue;
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      break;
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if ((GetUTFCode(expression) < c) ||
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (GetUTFCode(expression) > GetUTFCode(pattern)))
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pattern+=GetUTFOctets(pattern);
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  continue;
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetUTFCode(pattern) != GetUTFCode(expression))
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                pattern+=GetUTFOctets(pattern);
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                continue;
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          pattern+=GetUTFOctets(pattern);
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while ((GetUTFCode(pattern) != ']') && (GetUTFCode(pattern) != 0))
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if ((GetUTFCode(pattern) == '\\') &&
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (GetUTFCode(pattern+GetUTFOctets(pattern)) > 0))
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pattern+=GetUTFOctets(pattern);
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetUTFCode(pattern) != 0)
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              expression+=GetUTFOctets(expression);
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case '?':
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pattern+=GetUTFOctets(pattern);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        expression+=GetUTFOctets(expression);
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case '{':
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pattern+=GetUTFOctets(pattern);
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((GetUTFCode(pattern) != '}') && (GetUTFCode(pattern) != 0))
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p=expression;
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          match=MagickTrue;
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while ((GetUTFCode(p) != 0) && (GetUTFCode(pattern) != 0) &&
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (GetUTFCode(pattern) != ',') && (GetUTFCode(pattern) != '}') &&
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                 (match != MagickFalse))
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetUTFCode(pattern) == '\\')
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            match=(GetUTFCode(pattern) == GetUTFCode(p)) ? MagickTrue :
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MagickFalse;
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p+=GetUTFOctets(p);
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            pattern+=GetUTFOctets(pattern);
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetUTFCode(pattern) == 0)
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              match=MagickFalse;
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              done=MagickTrue;
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (match != MagickFalse)
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                expression=p;
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while ((GetUTFCode(pattern) != '}') &&
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (GetUTFCode(pattern) != 0))
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pattern+=GetUTFOctets(pattern);
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (GetUTFCode(pattern) == '\\')
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pattern+=GetUTFOctets(pattern);
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if (GetUTFCode(pattern) == '}')
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        pattern+=GetUTFOctets(pattern);
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                while ((GetUTFCode(pattern) != '}') &&
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (GetUTFCode(pattern) != ',') &&
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                       (GetUTFCode(pattern) != 0))
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  pattern+=GetUTFOctets(pattern);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (GetUTFCode(pattern) == '\\')
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      pattern+=GetUTFOctets(pattern);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      if ((GetUTFCode(pattern) == '}') ||
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          (GetUTFCode(pattern) == ','))
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        pattern+=GetUTFOctets(pattern);
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (GetUTFCode(pattern) != 0)
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              pattern+=GetUTFOctets(pattern);
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
541ecbe37f4ebcb73a6eb7c3797ce4184206dbd9881cristy      case '\\':
542ecbe37f4ebcb73a6eb7c3797ce4184206dbd9881cristy      {
543ecbe37f4ebcb73a6eb7c3797ce4184206dbd9881cristy        pattern+=GetUTFOctets(pattern);
5444705fe8c5f70cfc58abe38367b414452b96b8c54cristy        if (GetUTFCode(pattern) == 0)
5454705fe8c5f70cfc58abe38367b414452b96b8c54cristy          break;
546ecbe37f4ebcb73a6eb7c3797ce4184206dbd9881cristy      }
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      default:
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (case_insensitive != MagickFalse)
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (tolower((int) GetUTFCode(expression)) !=
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                tolower((int) GetUTFCode(pattern)))
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                done=MagickTrue;
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (GetUTFCode(expression) != GetUTFCode(pattern))
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              done=MagickTrue;
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        expression+=GetUTFOctets(expression);
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        pattern+=GetUTFOctets(pattern);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (GetUTFCode(pattern) == '*')
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pattern+=GetUTFOctets(pattern);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  match=(GetUTFCode(expression) == 0) && (GetUTFCode(pattern) == 0) ?
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MagickTrue : MagickFalse;
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(match);
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+     I s G l o b                                                             %
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsGlob() returns MagickTrue if the path specification contains a globbing
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pattern.
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsGlob method is:
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsGlob(const char *geometry)
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o path: the path.
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5997832dc2d904c471770087cce18a9a2d76c2216a3cristyMagickPrivate MagickBooleanType IsGlob(const char *path)
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
602a21ae824483761f2db9b1905258689a66ea74a5bcristy    status = MagickFalse;
603a21ae824483761f2db9b1905258689a66ea74a5bcristy
604a21ae824483761f2db9b1905258689a66ea74a5bcristy  register const char
605a21ae824483761f2db9b1905258689a66ea74a5bcristy    *p;
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (IsPathAccessible(path) != MagickFalse)
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
609a21ae824483761f2db9b1905258689a66ea74a5bcristy  for (p=path; *p != '\0'; p++)
610a21ae824483761f2db9b1905258689a66ea74a5bcristy  {
611a21ae824483761f2db9b1905258689a66ea74a5bcristy    switch (*p)
612a21ae824483761f2db9b1905258689a66ea74a5bcristy    {
613a21ae824483761f2db9b1905258689a66ea74a5bcristy      case '*':
614a21ae824483761f2db9b1905258689a66ea74a5bcristy      case '?':
615a21ae824483761f2db9b1905258689a66ea74a5bcristy      case '{':
616a21ae824483761f2db9b1905258689a66ea74a5bcristy      case '}':
617a21ae824483761f2db9b1905258689a66ea74a5bcristy      case '[':
618a21ae824483761f2db9b1905258689a66ea74a5bcristy      case ']':
619a21ae824483761f2db9b1905258689a66ea74a5bcristy      {
620a21ae824483761f2db9b1905258689a66ea74a5bcristy        status=MagickTrue;
621a21ae824483761f2db9b1905258689a66ea74a5bcristy        break;
622a21ae824483761f2db9b1905258689a66ea74a5bcristy      }
623a21ae824483761f2db9b1905258689a66ea74a5bcristy      default:
624a21ae824483761f2db9b1905258689a66ea74a5bcristy        break;
625a21ae824483761f2db9b1905258689a66ea74a5bcristy    }
626a21ae824483761f2db9b1905258689a66ea74a5bcristy  }
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(status);
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   T o k e n i z e r                                                         %
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Tokenizer() is a generalized, finite state token parser.  It extracts tokens
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  one at a time from a string of characters.  The characters used for white
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  space, for break characters, and for quotes can be specified.  Also,
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  characters in the string can be preceded by a specifiable escape character
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  which removes any special meaning the character may have.
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Here is some terminology:
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o token: A single unit of information in the form of a group of
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      characters.
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o white space: Apace that gets ignored (except within quotes or when
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      escaped), like blanks and tabs. in addition, white space terminates a
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      non-quoted token.
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o break set: One or more characters that separates non-quoted tokens.
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Commas are a common break character. The usage of break characters to
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      signal the end of a token is the same as that of white space, except
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      multiple break characters with nothing or only white space between
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      generate a null token for each two break characters together.
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      For example, if blank is set to be the white space and comma is set to
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      be the break character, the line
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        A, B, C ,  , DEF
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ... consists of 5 tokens:
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        1)  "A"
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        2)  "B"
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        3)  "C"
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        4)  "" (the null string)
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        5)  "DEF"
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o Quote character: A character that, when surrounding a group of other
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      characters, causes the group of characters to be treated as a single
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      token, no matter how many white spaces or break characters exist in
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the group. Also, a token always terminates after the closing quote.
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      For example, if ' is the quote character, blank is white space, and
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      comma is the break character, the following string
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        A, ' B, CD'EF GHI
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ... consists of 4 tokens:
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        1)  "A"
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        2)  " B, CD" (note the blanks & comma)
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        3)  "EF"
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        4)  "GHI"
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      The quote characters themselves do not appear in the resultant
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      tokens.  The double quotes are delimiters i use here for
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      documentation purposes only.
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o Escape character: A character which itself is ignored but which
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      causes the next character to be used as is.  ^ and \ are often used
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      as escape characters. An escape in the last position of the string
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      gets treated as a "normal" (i.e., non-quote, non-white, non-break,
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      and non-escape) character. For example, assume white space, break
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      character, and quote are the same as in the above examples, and
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      further, assume that ^ is the escape character. Then, in the string
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ABC, ' DEF ^' GH' I ^ J K^ L ^
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ... there are 7 tokens:
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        1)  "ABC"
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        2)  " DEF ' GH"
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        3)  "I"
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        4)  " "     (a lone blank)
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        5)  "J"
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        6)  "K L"
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        7)  "^"     (passed as is at end of line)
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the Tokenizer method is:
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      int Tokenizer(TokenInfo *token_info,const unsigned flag,char *token,
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const size_t max_token_length,const char *line,const char *white,
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const char *break_set,const char *quote,const char escape,
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char *breaker,int *next,char *quoted)
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o flag: right now, only the low order 3 bits are used.
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        1 => convert non-quoted tokens to upper case
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        2 => convert non-quoted tokens to lower case
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        0 => do not convert non-quoted tokens
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o token: a character string containing the returned next token
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o max_token_length: the maximum size of "token".  Characters beyond
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      "max_token_length" are truncated.
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o string: the string to be parsed.
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o white: a string of the valid white spaces.  example:
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char whitesp[]={" \t"};
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      blank and tab will be valid white space.
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o break: a string of the valid break characters. example:
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char breakch[]={";,"};
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      semicolon and comma will be valid break characters.
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o quote: a string of the valid quote characters. An example would be
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        char whitesp[]={"'\"");
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      (this causes single and double quotes to be valid) Note that a
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      token starting with one of these characters needs the same quote
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      character to terminate it.
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      for example:
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "ABC '
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      is unterminated, but
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        "DEF" and 'GHI'
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      are properly terminated.  Note that different quote characters
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      can appear on the same line; only for a given token do the quote
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      characters have to be the same.
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o escape: the escape character (NOT a string ... only one
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      allowed). Use zero if none is desired.
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o breaker: the break character used to terminate the current
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      token.  If the token was quoted, this will be the quote used.  If
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the token is the last one on the line, this will be zero.
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o next: this variable points to the first character of the
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      next token.  it gets reset by "tokenizer" as it steps through the
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      string.  Set it to 0 upon initialization, and leave it alone
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      after that.  You can change it if you want to jump around in the
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      string or re-parse from the beginning, but be careful.
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o quoted: set to True if the token was quoted and MagickFalse
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      if not.  You may need this information (for example:  in C, a
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      string with quotes around it is a character string, while one
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      without is an identifier).
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o result: 0 if we haven't reached EOS (end of string), and 1
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      if we have.
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IN_WHITE 0
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IN_TOKEN 1
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IN_QUOTE 2
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define IN_OZONE 3
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
797bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic ssize_t sindex(int c,const char *string)
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const char
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (p=string; *p != '\0'; p++)
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (c == (int) (*p))
804cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy      return((ssize_t) (p-string));
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(-1);
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void StoreToken(TokenInfo *token_info,char *string,
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t max_token_length,int c)
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
811bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((token_info->offset < 0) ||
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ((size_t) token_info->offset >= (max_token_length-1)))
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  i=token_info->offset++;
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  string[i]=(char) c;
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (token_info->state == IN_QUOTE)
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (token_info->flag & 0x03)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      string[i]=(char) toupper(c);
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      string[i]=(char) tolower(c);
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport int Tokenizer(TokenInfo *token_info,const unsigned flag,
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char *token,const size_t max_token_length,const char *line,const char *white,
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char *break_set,const char *quote,const char escape,char *breaker,
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int *next,char *quoted)
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    c;
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *breaker='\0';
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *quoted='\0';
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (line[*next] == '\0')
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(1);
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token_info->state=IN_WHITE;
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token_info->quote=(char) MagickFalse;
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token_info->flag=flag;
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (token_info->offset=0; (int) line[*next] != 0; (*next)++)
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    c=(int) line[*next];
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i=sindex(c,break_set);
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i >= 0)
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (token_info->state)
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_WHITE:
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_TOKEN:
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_OZONE:
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (*next)++;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *breaker=break_set[i];
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token[token_info->offset]='\0';
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return(0);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_QUOTE:
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            StoreToken(token_info,token,max_token_length,c);
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i=sindex(c,quote);
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i >= 0)
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (token_info->state)
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_WHITE:
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token_info->state=IN_QUOTE;
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token_info->quote=quote[i];
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *quoted=(char) MagickTrue;
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_QUOTE:
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (quote[i] != token_info->quote)
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              StoreToken(token_info,token,max_token_length,c);
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            else
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              {
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                token_info->state=IN_OZONE;
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                token_info->quote='\0';
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              }
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_TOKEN:
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_OZONE:
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *breaker=(char) c;
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token[token_info->offset]='\0';
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return(0);
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i=sindex(c,white);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (i >= 0)
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (token_info->state)
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_WHITE:
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_OZONE:
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_TOKEN:
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token_info->state=IN_OZONE;
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_QUOTE:
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            StoreToken(token_info,token,max_token_length,c);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (c == (int) escape)
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (line[(*next)+1] == '\0')
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *breaker='\0';
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            StoreToken(token_info,token,max_token_length,c);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (*next)++;
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token[token_info->offset]='\0';
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return(0);
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        switch (token_info->state)
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_WHITE:
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (*next)--;
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token_info->state=IN_TOKEN;
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_TOKEN:
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_QUOTE:
9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (*next)++;
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            c=(int) line[*next];
9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            StoreToken(token_info,token,max_token_length,c);
9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            break;
9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          case IN_OZONE:
9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            token[token_info->offset]='\0';
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return(0);
9653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
9683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    switch (token_info->state)
9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case IN_WHITE:
972326182d587fc1b1a8c934dafbf412d05615a540acristy      {
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        token_info->state=IN_TOKEN;
974326182d587fc1b1a8c934dafbf412d05615a540acristy        StoreToken(token_info,token,max_token_length,c);
975326182d587fc1b1a8c934dafbf412d05615a540acristy        break;
976326182d587fc1b1a8c934dafbf412d05615a540acristy      }
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case IN_TOKEN:
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case IN_QUOTE:
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        StoreToken(token_info,token,max_token_length,c);
9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      case IN_OZONE:
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        token[token_info->offset]='\0';
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return(0);
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token[token_info->offset]='\0';
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(0);
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
993