[mapserver-commits] r8268 - trunk/mapserver

svn at osgeo.org svn at osgeo.org
Mon Dec 22 09:48:10 EST 2008


Author: aboudreault
Date: 2008-12-22 09:48:10 -0500 (Mon, 22 Dec 2008)
New Revision: 8268

Modified:
   trunk/mapserver/HISTORY.TXT
   trunk/mapserver/mapserver.h
   trunk/mapserver/mapstring.c
   trunk/mapserver/maptemplate.c
Log:
Improved Tag parsing in template code. (#2781)


Modified: trunk/mapserver/HISTORY.TXT
===================================================================
--- trunk/mapserver/HISTORY.TXT	2008-12-19 15:46:13 UTC (rev 8267)
+++ trunk/mapserver/HISTORY.TXT	2008-12-22 14:48:10 UTC (rev 8268)
@@ -12,6 +12,8 @@
 Current Version (5.3-dev, SVN trunk):
 ------------------------------------
 
+- Improved Tag parsing in template code. (#2781)
+
 - Added hashtable object and metadata methods for php-mapscript (#2773)
 
 - mappostgis.c: Fix trailing spaces in fixed varchar fields (#2817)

Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h	2008-12-19 15:46:13 UTC (rev 8267)
+++ trunk/mapserver/mapserver.h	2008-12-22 14:48:10 UTC (rev 8268)
@@ -1631,6 +1631,7 @@
 MS_DLL_EXPORT char *msTryBuildPath(char *szReturnPath, const char *abs_path, const char *path);
 MS_DLL_EXPORT char *msTryBuildPath3(char *szReturnPath, const char *abs_path, const char *path1, const char *path2);
 MS_DLL_EXPORT char **msStringSplit(const char *string, char cd, int *num_tokens);
+MS_DLL_EXPORT char **msStringTokenize( const char *pszLine, const char *pszDelim, int *num_tokens, int preserve_quote);
 MS_DLL_EXPORT int msCountChars(char *str, char ch);
 MS_DLL_EXPORT char *msLongToString(long value);
 MS_DLL_EXPORT char *msDoubleToString(double value, int force_f);

Modified: trunk/mapserver/mapstring.c
===================================================================
--- trunk/mapserver/mapstring.c	2008-12-19 15:46:13 UTC (rev 8267)
+++ trunk/mapserver/mapstring.c	2008-12-22 14:48:10 UTC (rev 8268)
@@ -755,6 +755,74 @@
   return(token);
 }
 
+/* This method is similar to msStringSplit but support quoted strings. 
+   It also support multi-characters delimiter and allows to preserve quotes */
+char **msStringTokenize( const char *pszLine, const char *pszDelim, 
+                         int *num_tokens, int preserve_quote )
+{
+    char **papszResult = NULL;
+    int n = 1, iChar, nLength = strlen(pszLine), iTokenChar = 0, bInQuotes = MS_FALSE;
+    char *pszToken = (char *) malloc(sizeof(char*)*(nLength+1));
+    int nDelimLen = strlen(pszDelim);
+
+    /* Compute the number of tokens */
+    for( iChar = 0; pszLine[iChar] != '\0'; iChar++ )
+    {
+        if( bInQuotes && pszLine[iChar] == '"' && pszLine[iChar+1] == '"' )
+        {
+            iChar++;
+        }
+        else if( pszLine[iChar] == '"' )
+        {
+            bInQuotes = !bInQuotes;
+        }
+        else if ( !bInQuotes && strncmp(pszLine+iChar,pszDelim,nDelimLen) == 0 )
+        {
+            iChar += nDelimLen - 1;
+            n++;
+        }
+    }
+
+    papszResult = (char **) malloc(sizeof(char *)*n);
+    n = iTokenChar = bInQuotes = 0;
+    for( iChar = 0; pszLine[iChar] != '\0'; iChar++ )
+    {
+        if( bInQuotes && pszLine[iChar] == '"' && pszLine[iChar+1] == '"' )
+        {
+           if (preserve_quote == MS_TRUE)
+              pszToken[iTokenChar++] = '"';
+           pszToken[iTokenChar++] = '"';
+           iChar++;
+        }
+        else if( pszLine[iChar] == '"' )
+        {
+           if (preserve_quote == MS_TRUE)
+              pszToken[iTokenChar++] = '"';
+            bInQuotes = !bInQuotes;
+        }
+        else if( !bInQuotes && strncmp(pszLine+iChar,pszDelim,nDelimLen) == 0 )
+        {
+            pszToken[iTokenChar++] = '\0';
+            papszResult[n] = pszToken;
+            pszToken = (char *) malloc(sizeof(char*)*(nLength+1));
+            iChar += nDelimLen - 1;
+            iTokenChar = 0;
+            n++;
+        }
+        else
+        {
+            pszToken[iTokenChar++] = pszLine[iChar];
+        }
+    }
+
+    pszToken[iTokenChar++] = '\0';
+    papszResult[n] = pszToken;
+    
+    *num_tokens = n+1;
+
+    return papszResult;
+}
+
 /**********************************************************************
  *                       msEncodeChar()
  *

Modified: trunk/mapserver/maptemplate.c
===================================================================
--- trunk/mapserver/maptemplate.c	2008-12-19 15:46:13 UTC (rev 8267)
+++ trunk/mapserver/maptemplate.c	2008-12-22 14:48:10 UTC (rev 8268)
@@ -424,6 +424,33 @@
    return pszStart;
 }
 
+/* 
+** This function return a pointer 
+** to the end of the tag in pszTag
+** 
+** The end of a tag is the next
+** non-quoted ']' character. 
+** Return NULL if not found.
+*/ 
+
+char *findTagEnd(const char *pszTag)
+{
+   char *pszEnd = NULL, 
+        *pszTmp = (char*)pszTag;
+
+   while (pszTmp != NULL) {
+      if (*pszTmp == '"')
+         pszTmp = strchr(pszTmp+1,'"');
+      if ((pszTmp == NULL) || (*pszTmp == ']')) { 
+         pszEnd = pszTmp;
+         pszTmp = NULL;
+      } else
+         pszTmp++;
+   }
+   
+   return pszEnd;
+}
+
 /*
 ** Return a hashtableobj from instr of all
 ** arguments. hashtable must be freed by caller.
@@ -435,7 +462,6 @@
    char **papszArgs, **papszVarVal;
    int nArgs, nDummy;
    int i;
-   char *pszQuoteStr, *pszQuoteStart, *pszQuoteEnd;
    
    if(!pszTag || !pszInstr) {
      msSetError(MS_WEBERR, "Invalid pointer.", "getTagArgs()");
@@ -446,8 +472,8 @@
    pszStart = findTag(pszInstr, pszTag);
 
    if(pszStart) {
-      /* find ending position */
-      pszEnd = strchr(pszStart, ']');
+       /* find ending position */
+       pszEnd = findTagEnd(pszStart);
    
       if(pszEnd) {
          /* skip the tag name */
@@ -464,63 +490,14 @@
             if(!(*ppoHashTable))
               *ppoHashTable = msCreateHashTable();
             
-            /* Enable the use of "" in args */
-            /* To do so, extract all "" values */
-            /* and replace the " in it by spaces */
-            if(strchr(pszArgs, '"'))
-            {
-                pszQuoteEnd = pszArgs;
-                while((pszQuoteStart = strchr(pszQuoteEnd, '"')))
-                {
-                    pszQuoteEnd = strchr(pszQuoteStart+1, '"');
-                    if(pszQuoteEnd)
-                    {
-                        pszQuoteEnd[0] = '\0';
-                        while((pszQuoteStr = strchr(pszQuoteStart, ' ')))
-                            pszQuoteStr[0] = '"';
-
-                        /* Replace also the '=' to be able to use it in the */
-                        /* quoted argument. The '=' is replaced by ']' which */
-                        /* is illegal before here since this is the closing */
-                        /* character of the whole tag. */
-                        while((pszQuoteStr = strchr(pszQuoteStart, '=')))
-                            pszQuoteStr[0] = ']';
-
-                        /* Then remove the starting and ending quote */
-                        pszQuoteEnd[0] = '"';
-                        for(i=(pszQuoteStart-pszArgs); i<nLength; i++)
-                        {
-                            if(i+1 >= pszQuoteEnd-pszArgs)
-                                if(i+2 >= nLength)
-                                    pszArgs[i] = '\0';
-                                else
-                                    pszArgs[i] = pszArgs[i+2];
-                            else
-                                pszArgs[i] = pszArgs[i+1];
-                        }
-                    }
-                }
-            }
-
             /* put all arguments seperate by space in a hash table */
-            papszArgs = msStringSplit(pszArgs, ' ', &nArgs);
+            papszArgs = msStringTokenize(pszArgs, " ", &nArgs, MS_TRUE);
 
             /* msReturnTemplateQuerycheck all argument if they have values */
             for (i=0; i<nArgs; i++) {
-               /* Quotes are in fact spaces */
-               if(strchr(papszArgs[i],'"'))
-                   while((pszQuoteStr = strchr(papszArgs[i],'"')))
-                       pszQuoteStr[0] = ' ';
-
                if(strchr(papszArgs[i], '='))
                {
-                  papszVarVal = msStringSplit(papszArgs[i], '=', &nDummy);
-               
-                  /* ']' are in fact '=' (See above). */
-                  if(strchr(papszVarVal[1],']'))
-                      while((pszQuoteStr = strchr(papszVarVal[1],']')))
-                          pszQuoteStr[0] = '=';
-
+                  papszVarVal = msStringTokenize(papszArgs[i], "=", &nDummy, MS_FALSE);               
                   msInsertHashTable(*ppoHashTable, papszVarVal[0], 
                                     papszVarVal[1]);
                   free(papszVarVal[0]);
@@ -1618,7 +1595,7 @@
     msFreeShape(&tShape);
     
     /* find the end of the tag */
-    tagEnd = strchr(tagStart, ']');
+    tagEnd = findTagEnd(tagStart);
     tagEnd++;
 
     /* build the complete tag so we can do substitution */



More information about the mapserver-commits mailing list