Adding for loop capability
authorJim Fox <fox@washington.edu>
Fri, 6 Mar 2009 23:33:43 +0000 (23:33 +0000)
committerJim Fox <fox@washington.edu>
Fri, 6 Mar 2009 23:33:43 +0000 (23:33 +0000)
doxygen.m4
xmltooling/util/TemplateEngine.cpp
xmltooling/util/TemplateEngine.h

index e4688de..e9c56c2 100644 (file)
@@ -78,7 +78,7 @@ AC_DEFUN([DX_REQUIRE_PROG], [
 AC_PATH_TOOL([$1], [$2])
 if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
     AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
-    AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+    AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
 fi
 ])
 
@@ -101,7 +101,7 @@ test "$DX_FLAG_$1" = "$2" \
 # ----------------------------------------------------------
 # Turn off the DX_CURRENT_FEATURE if the required feature is off.
 AC_DEFUN([DX_CLEAR_DEPEND], [
-test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
 ])
 
 # DX_FEATURE_ARG(FEATURE, DESCRIPTION,
index 7d3e7d8..22881e3 100644 (file)
@@ -33,6 +33,8 @@ void TemplateEngine::setTagPrefix(const char* tagPrefix)
     ifnottag = string("<") + tagPrefix + "ifnot ";
     ifendtag = string("</") + tagPrefix + "if>";
     ifnotendtag = string("</") + tagPrefix + "ifnot>";
+    fortag = string("<") + tagPrefix + "for ";
+    forendtag = string("</") + tagPrefix + "for>";
 }
 
 string TemplateEngine::unsafe_chars = "#%&():[]\\`{}";
@@ -186,6 +188,53 @@ void TemplateEngine::process(
             lastpos = thispos + ifnotendtag.length();
             return;
         }
+
+#ifdef HAVE_STRCASECMP
+        else if (!strncasecmp(thispos, fortag.c_str(), fortag.length()))
+#else
+        else if (!_strnicmp(thispos, fortag.c_str(), fortag.length()))
+#endif
+        {
+            // Save this position off.
+            lastpos = thispos + iftag.length();
+            string key;
+            bool cond = visible;
+
+            // search for the end of this tag
+            if ((thispos = strchr(lastpos, '>')) != NULL) {
+                key = buf.substr(lastpos-line, thispos-lastpos);
+                trimspace(key);
+                lastpos = thispos + 1; // strlen(">")
+            }
+            const vector<xmltooling::TemplateEngine::TemplateParameters> forParams = parameters.getParameterCollection(key.c_str());
+
+            unsigned int forend = forParams.size();
+            if (forend==0) {  // have to go through at least once to match end tags
+               cond = false;
+               forend = 1;
+            }
+
+            const char *savlastpos = lastpos;
+            for (unsigned int i=0; i<forend; i++ ) {
+                const TemplateParameters nullp;
+                const TemplateParameters* tp = forParams.size()>0? static_cast<const TemplateParameters*>(&forParams[i]): &nullp;
+                lastpos = savlastpos;
+                process(cond, buf, lastpos, os, *tp, e);
+            }
+
+        }
+
+#ifdef HAVE_STRCASECMP
+        else if (!strncasecmp(thispos, forendtag.c_str(), forendtag.length()))
+#else
+        else if (!_strnicmp(thispos, forendtag.c_str(), forendtag.length()))
+#endif
+        {
+            // Save this position off and pop the stack.
+            lastpos = thispos + forendtag.length();
+            return;
+        }
+
         else {
             // Skip it.
             if (visible)
index 08db6e4..ad4027b 100644 (file)
@@ -28,6 +28,7 @@
 #include <map>
 #include <string>
 #include <iostream>
+#include <vector>
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -42,6 +43,7 @@ namespace xmltooling {
      *  <li> &lt;mlp key/&gt; </li>
      *  <li> &lt;mlpif key&gt; stuff &lt;/mlpif&gt;</li>
      *  <li> &lt;mlpifnot key&gt; stuff &lt;/mlpifnot&gt;</li>
+     *  <li> &lt;mlpfor key&gt; stuff &lt;/mlpfor&gt;</li>
      * </ul>
      * 
      * The default tag prefix is "mlp". This can be overridden for
@@ -69,13 +71,14 @@ namespace xmltooling {
          * Allows callers to supply a more dynamic lookup mechanism to supplement a basic map.
          */
         class XMLTOOL_API TemplateParameters {
-            MAKE_NONCOPYABLE(TemplateParameters);
+            // MAKE_NONCOPYABLE(TemplateParameters);
         public:
             TemplateParameters() : m_request(NULL) {}
             virtual ~TemplateParameters() {}
             
             /** Map of known parameters to supply to template. */
             std::map<std::string,std::string> m_map;
+            std::map<std::string,std::vector<TemplateParameters> > m_collectionMap;
             
             /** Request from client that resulted in template being processed. */
             const GenericRequest* m_request;
@@ -90,6 +93,17 @@ namespace xmltooling {
                 std::map<std::string,std::string>::const_iterator i=m_map.find(name);
                 return (i!=m_map.end() ? i->second.c_str() : (m_request ? m_request->getParameter(name) : NULL));
             }
+
+            /**
+             * Returns the collection of parameters to plug into the template.
+             * 
+             * @param name  name of parameter collection
+             * @return vector of parameters
+             */
+            virtual const std::vector<TemplateParameters> getParameterCollection(const char* name) const {
+                std::map<std::string,std::vector<TemplateParameters> >::const_iterator i=m_collectionMap.find(name);
+                return (i->second);
+            }
         };
         
         /**
@@ -126,7 +140,7 @@ namespace xmltooling {
             const XMLToolingException* e
             ) const;
             
-        std::string keytag,iftag,ifendtag,ifnottag,ifnotendtag;
+        std::string keytag,iftag,ifendtag,ifnottag,ifnotendtag,fortag,forendtag;
     };
 };