[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