Code

Indent support for XSLT extensions output.
[inkscape.git] / buildtool.cpp
index a7d0876909b658e185fb7f07e483fa97aba3532e..2b4307ab0f0e2ca6026a7eabc2a4a874d0d32a8b 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
+     *    Bazaar "bzr revno" query
+     *             example:  <property subversion="svn"/> ???
+     *             ${bzr.Revision}
+     */
+    String bzrPrefix;
+
 
 
 
@@ -3632,6 +3640,138 @@ private:
     int parselen;
 };
 
+/**
+ * Execute the "bzr revno" command and return the result.
+ * This is a simple, small class.
+ */
+class BzrRevno : public MakeBase
+{
+public:
+
+    /**
+     * Safe way. Execute "bzr revno" and return the result.
+     * Safe from changes in format.
+     */
+    bool query(String &res)
+    {
+        String cmd = "bzr revno";
+
+        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;
+            }
+        res = outString;
+        return true;
+    } 
+};
+
+/**
+ * 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
+
+};
+
+
+
 
 
 
@@ -4584,6 +4724,23 @@ bool MakeBase::lookupProperty(const String &propertyName, String &result)
             return false;
         result = val;
         }
+    else if (bzrPrefix.size() > 0 &&
+        varname.compare(0, bzrPrefix.size(), bzrPrefix) == 0)
+        {
+        varname = varname.substr(bzrPrefix.size());
+        String val;
+        //SvnInfo svnInfo;
+        BzrRevno bzrRevno;
+        if (varname == "revision")
+           {
+            if (!bzrRevno.query(val))
+                return "";
+            result = "r"+val;
+        }
+        /*if (!svnInfo.query(varname, val))
+            return false;
+        result = val;*/
+        }
     else
         {
         std::map<String, String>::iterator iter;
@@ -5083,6 +5240,7 @@ bool MakeBase::copyFile(const String &srcFile, const String &destFile)
     FILE *destf = fopen(destNative.c_str(), "wb");
     if (!destf)
         {
+        fclose(srcf);
         error("copyFile cannot open %s for writing", srcNative.c_str());
         return false;
         }
@@ -5607,9 +5765,6 @@ bool PkgConfig::query(const String &pkgName)
 }
 
 
-
-
-
 //########################################################################
 //# D E P T O O L
 //########################################################################
@@ -7600,7 +7755,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 +7764,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 +7777,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 +8241,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 +8272,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 +8289,7 @@ public:
 private:
 
     String fileNameOpt;
+    String forceOpt;
     String textOpt;
 };
 
@@ -9372,6 +9530,7 @@ void Make::init()
     pcPrefix        = "pc.";
     pccPrefix       = "pcc.";
     pclPrefix       = "pcl.";
+    bzrPrefix       = "bzr.";
     properties.clear();
     for (unsigned int i = 0 ; i < allTasks.size() ; i++)
         delete allTasks[i];
@@ -9790,6 +9949,16 @@ bool Make::parseProperty(Element *elem)
             pclPrefix = attrVal;
             pclPrefix.push_back('.');
             }
+        else if (attrName == "subversion")
+            {
+            if (attrVal.find('.') != attrVal.npos)
+                {
+                error("bzr prefix cannot have a '.' in it");
+                return false;
+                }
+            bzrPrefix = attrVal;
+            bzrPrefix.push_back('.');
+            }
         }
 
     return true;