Code

Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
[inkscape.git] / buildtool.cpp
index a7d0876909b658e185fb7f07e483fa97aba3532e..538a6faa51c92a1619081bace877a7bc92082552 100644 (file)
@@ -39,7 +39,7 @@
  *
  */
 
-#define BUILDTOOL_VERSION  "BuildTool v0.9.6"
+#define BUILDTOOL_VERSION  "BuildTool v0.9.9"
 
 #include <stdio.h>
 #include <fcntl.h>
@@ -3189,11 +3189,19 @@ protected:
     /**
      *    If this prefix is seen in a substitution, use as a
      *    pkg-config 'libs' query
-     *             example:  <property pkg-config="pcl"/>
+     *             example:  <property pkg-config-libs="pcl"/>
      *             ${pcl.gtkmm}
      */
     String pclPrefix;
 
+    /**
+     *    If this prefix is seen in a substitution, use as a
+     *    Subversion "svn info" query
+     *             example:  <property subversion="svn"/>
+     *             ${svn.Revision}
+     */
+    String svnPrefix;
+
 
 
 
@@ -3634,6 +3642,112 @@ private:
 
 
 
+/**
+ * Execute the "svn info" command and parse the result.
+ * This is a simple, small class. Define here, because it
+ * is used by MakeBase implementation methods. 
+ */
+class SvnInfo : public MakeBase
+{
+public:
+
+#if 0
+    /**
+     * Safe way. Execute "svn info --xml" and parse the result.  Search for
+     * elements/attributes.  Safe from changes in format.
+     */
+    bool query(const String &name, String &res)
+    {
+        String cmd = "svn info --xml";
+    
+        String outString, errString;
+        bool ret = executeCommand(cmd.c_str(), "", outString, errString);
+        if (!ret)
+            {
+            error("error executing '%s': %s", cmd.c_str(), errString.c_str());
+            return false;
+            }
+        Parser parser;
+        Element *elem = parser.parse(outString); 
+        if (!elem)
+            {
+            error("error parsing 'svn info' xml result: %s", outString.c_str());
+            return false;
+            }
+        
+        res = elem->getTagValue(name);
+        if (res.size()==0)
+            {
+            res = elem->getTagAttribute("entry", name);
+            }
+        return true;
+    } 
+#else
+
+
+    /**
+     * Universal way.  Parse the file directly.  Not so safe from
+     * changes in format.
+     */
+    bool query(const String &name, String &res)
+    {
+        String fileName = resolve(".svn/entries");
+        String nFileName = getNativePath(fileName);
+        
+        std::map<String, String> properties;
+        
+        FILE *f = fopen(nFileName.c_str(), "r");
+        if (!f)
+            {
+            error("could not open SVN 'entries' file");
+            return false;
+            }
+
+        const char *fieldNames[] =
+            {
+            "format-nbr",
+            "name",
+            "kind",
+            "revision",
+            "url",
+            "repos",
+            "schedule",
+            "text-time",
+            "checksum",
+            "committed-date",
+            "committed-rev",
+            "last-author",
+            "has-props",
+            "has-prop-mods",
+            "cachable-props",
+            };
+
+        for (int i=0 ; i<15 ; i++)
+            {
+            inbuf[0] = '\0';
+            if (feof(f) || !fgets(inbuf, 255, f))
+                break;
+            properties[fieldNames[i]] = trim(inbuf);
+            }
+        fclose(f);
+        
+        res = properties[name];
+        
+        return true;
+    } 
+    
+private:
+
+    char inbuf[256];
+
+#endif
+
+};
+
+
+
+
+
 
 /**
  *  Print a printf()-like formatted error message
@@ -4584,6 +4698,22 @@ bool MakeBase::lookupProperty(const String &propertyName, String &result)
             return false;
         result = val;
         }
+    else if (svnPrefix.size() > 0 &&
+        varname.compare(0, svnPrefix.size(), svnPrefix) == 0)
+        {
+        varname = varname.substr(svnPrefix.size());
+        String val;
+        SvnInfo svnInfo;
+        if (varname == "revision")
+           {
+            if (!svnInfo.query(varname, val))
+                return "";
+            result = "r"+val;
+            }
+        if (!svnInfo.query(varname, val))
+            return false;
+        result = val;
+        }
     else
         {
         std::map<String, String>::iterator iter;
@@ -5607,9 +5737,6 @@ bool PkgConfig::query(const String &pkgName)
 }
 
 
-
-
-
 //########################################################################
 //# D E P T O O L
 //########################################################################
@@ -7600,7 +7727,6 @@ public:
         bool verbose     = parent.evalBool(verboseOpt, false);
         bool quiet       = parent.evalBool(quietOpt, false);
         bool failOnError = parent.evalBool(failOnErrorOpt, true);
-        struct stat finfo;
         switch (delType)
             {
             case DEL_FILE:
@@ -7610,7 +7736,7 @@ public:
                 char *fname = (char *)fullName.c_str();
                 if (!quiet && verbose)
                     taskstatus("path: %s", fname);
-                if (!removeFile(fullName))
+                if (failOnError && !removeFile(fullName))
                     {
                     //error("Could not delete file '%s'", fullName.c_str());
                     return false;
@@ -7623,7 +7749,7 @@ public:
                 String fullDir = parent.resolve(dirName);
                 if (!quiet && verbose)
                     taskstatus("path: %s", fullDir.c_str());
-                if (!removeDirectory(fullDir))
+                if (failOnError && !removeDirectory(fullDir))
                     {
                     //error("Could not delete directory '%s'", fullDir.c_str());
                     return false;
@@ -8087,13 +8213,14 @@ public:
     virtual bool execute()
         {
         String fileName = parent.eval(fileNameOpt, "");
+        bool force      = parent.evalBool(forceOpt, false);
         String text     = parent.eval(textOpt, "");
 
         taskstatus("%s", fileName.c_str());
         String fullName = parent.resolve(fileName);
-        if (!isNewerThan(parent.getURI().getPath(), fullName))
+        if (!force && !isNewerThan(parent.getURI().getPath(), fullName))
             {
-            //trace("skipped <makefile>");
+            taskstatus("skipped");
             return true;
             }
         String fullNative = getNativePath(fullName);
@@ -8117,6 +8244,8 @@ public:
         {
         if (!parent.getAttribute(elem, "file", fileNameOpt))
             return false;
+        if (!parent.getAttribute(elem, "force", forceOpt))
+            return false;
         if (fileNameOpt.size() == 0)
             {
             error("<makefile> requires 'file=\"filename\"' attribute");
@@ -8132,6 +8261,7 @@ public:
 private:
 
     String fileNameOpt;
+    String forceOpt;
     String textOpt;
 };
 
@@ -9372,6 +9502,7 @@ void Make::init()
     pcPrefix        = "pc.";
     pccPrefix       = "pcc.";
     pclPrefix       = "pcl.";
+    svnPrefix       = "svn.";
     properties.clear();
     for (unsigned int i = 0 ; i < allTasks.size() ; i++)
         delete allTasks[i];
@@ -9790,6 +9921,16 @@ bool Make::parseProperty(Element *elem)
             pclPrefix = attrVal;
             pclPrefix.push_back('.');
             }
+        else if (attrName == "subversion")
+            {
+            if (attrVal.find('.') != attrVal.npos)
+                {
+                error("subversion prefix cannot have a '.' in it");
+                return false;
+                }
+            svnPrefix = attrVal;
+            svnPrefix.push_back('.');
+            }
         }
 
     return true;