Code

LPE: fix undo bug for applying/removing effect
[inkscape.git] / buildtool.cpp
index 39ae5be6ef87214665a371ed77809106453d419a..94a430da38fcfb06f2f44c389d0e07a985ae5e3b 100644 (file)
@@ -38,7 +38,7 @@
  *     
  */  
 
-#define BUILDTOOL_VERSION  "BuildTool v0.6.13, 2007 Bob Jamison"
+#define BUILDTOOL_VERSION  "BuildTool v0.7.1, 2007 Bob Jamison"
 
 #include <stdio.h>
 #include <fcntl.h>
@@ -1150,7 +1150,7 @@ private:
 
     void getLineAndColumn(int pos, int *lineNr, int *colNr);
 
-    void error(char *fmt, ...);
+    void error(const char *fmt, ...);
 
     int peek(int pos);
 
@@ -1325,7 +1325,7 @@ void Element::print()
 
 typedef struct
     {
-    char *escaped;
+    const char *escaped;
     char value;
     } EntityEntry;
 
@@ -1405,7 +1405,7 @@ void Parser::getLineAndColumn(int pos, int *lineNr, int *colNr)
 }
 
 
-void Parser::error(char *fmt, ...)
+void Parser::error(const char *fmt, ...)
 {
     int lineNr;
     int colNr;
@@ -1643,7 +1643,7 @@ int Parser::parseElement(int p0, Element *par,int lineNr)
     if (ch!='<')
         return p0;
 
-    int line, col;
+    //int line, col;
     //getLineAndColumn(p, &line, &col);
 
     p++;
@@ -2149,7 +2149,7 @@ private:
 
     int peek(int p);
 
-    int match(int p, char *key);
+    int match(int p, const char *key);
 
     int parseScheme(int p);
 
@@ -2171,9 +2171,9 @@ private:
 
 typedef struct
 {
-    int  ival;
-    char *sval;
-    int  port;
+    int         ival;
+    const char *sval;
+    int         port;
 } LookupEntry;
 
 LookupEntry schemes[] =
@@ -2501,7 +2501,7 @@ int URI::peek(int p)
 
 
 
-int URI::match(int p0, char *key)
+int URI::match(int p0, const char *key)
 {
     int p = p0;
     while (p < parselen)
@@ -2918,6 +2918,39 @@ public:
     int getLine()
         { return line; }
 
+
+    /**
+     * Set a property to a given value
+     */
+    virtual void setProperty(const String &name, const String &val)
+        {
+        properties[name] = val;
+        }
+
+    /**
+     * Return a named property is found, else a null string
+     */
+    virtual String getProperty(const String &name)
+        {
+        String val;
+        std::map<String, String>::iterator iter = properties.find(name);
+        if (iter != properties.end())
+            val = iter->second;
+        return val;
+        }
+
+    /**
+     * Return true if a named property is found, else false
+     */
+    virtual bool hasProperty(const String &name)
+        {
+        std::map<String, String>::iterator iter = properties.find(name);
+        if (iter == properties.end())
+            return false;
+        return true;
+        }
+
+
 protected:
 
     /**
@@ -2929,17 +2962,17 @@ protected:
     /**
      *  Print a printf()-like formatted error message
      */
-    void error(char *fmt, ...);
+    void error(const char *fmt, ...);
 
     /**
      *  Print a printf()-like formatted trace message
      */
-    void status(char *fmt, ...);
+    void status(const char *fmt, ...);
 
     /**
      *  Print a printf()-like formatted trace message
      */
-    void trace(char *fmt, ...);
+    void trace(const char *fmt, ...);
 
     /**
      *  Check if a given string matches a given regex pattern
@@ -2973,6 +3006,11 @@ protected:
      */
     String trim(const String &s);
 
+    /**
+     *  Return a lower case version of the given string
+     */
+    String toLower(const String &s);
+
     /**
      * Return the native format of the canonical
      * path which we store
@@ -3030,19 +3068,6 @@ protected:
     virtual std::map<String, String> &getProperties()
         { return properties; }
 
-    /**
-     * Return a named property if found, else a null string
-     */
-    virtual String getProperty(const String &name)
-        {
-        String val;
-        std::map<String, String>::iterator iter;
-        iter = properties.find(name);
-        if (iter != properties.end())
-            val = iter->second;
-        return val;
-        }
-
 
     std::map<String, String> properties;
 
@@ -3100,7 +3125,7 @@ private:
 /**
  *  Print a printf()-like formatted error message
  */
-void MakeBase::error(char *fmt, ...)
+void MakeBase::error(const char *fmt, ...)
 {
     va_list args;
     va_start(args,fmt);
@@ -3115,7 +3140,7 @@ void MakeBase::error(char *fmt, ...)
 /**
  *  Print a printf()-like formatted trace message
  */
-void MakeBase::status(char *fmt, ...)
+void MakeBase::status(const char *fmt, ...)
 {
     va_list args;
     va_start(args,fmt);
@@ -3142,7 +3167,7 @@ String MakeBase::resolve(const String &otherPath)
 /**
  *  Print a printf()-like formatted trace message
  */
-void MakeBase::trace(char *fmt, ...)
+void MakeBase::trace(const char *fmt, ...)
 {
     va_list args;
     va_start(args,fmt);
@@ -3349,6 +3374,24 @@ String MakeBase::trim(const String &s)
     return res;
 }
 
+
+/**
+ *  Return a lower case version of the given string
+ */
+String MakeBase::toLower(const String &s)
+{
+    if (s.size()==0)
+        return s;
+
+    String ret;
+    for(unsigned int i=0; i<s.size() ; i++)
+        {
+        ret.push_back(tolower(s[i]));
+        }
+    return ret;
+}
+
+
 /**
  * Return the native format of the canonical
  * path which we store
@@ -4312,13 +4355,7 @@ public:
      *
      */
     PkgConfig()
-        { init(); }
-
-    /**
-     *
-     */
-    PkgConfig(const String &namearg)
-        { init(); name = namearg; }
+        { path="."; init(); }
 
     /**
      *
@@ -4344,6 +4381,30 @@ public:
     virtual String getName()
         { return name; }
 
+    /**
+     *
+     */
+    virtual String getPath()
+        { return path; }
+
+    /**
+     *
+     */
+    virtual void setPath(const String &val)
+        { path = val; }
+
+    /**
+     *
+     */
+    virtual String getPrefix()
+        { return prefix; }
+
+    /**
+     *  Allow the user to override the prefix in the file
+     */
+    virtual void setPrefix(const String &val)
+        { prefix = val; }
+
     /**
      *
      */
@@ -4362,6 +4423,17 @@ public:
     virtual String getLibs()
         { return libs; }
 
+    /**
+     *
+     */
+    virtual String getAll()
+        {
+         String ret = cflags;
+         ret.append(" ");
+         ret.append(libs);
+         return ret;
+        }
+
     /**
      *
      */
@@ -4398,12 +4470,21 @@ public:
     virtual std::vector<String> &getRequireList()
         { return requireList; }
 
+    /**
+     *  Read a file for its details
+     */         
     virtual bool readFile(const String &fileName);
 
+    /**
+     *  Read a file for its details
+     */         
+    virtual bool query(const String &name);
+
 private:
 
     void init()
         {
+        //do not set path or prefix here
         name         = "";
         description  = "";
         cflags       = "";
@@ -4421,6 +4502,8 @@ private:
     void assign(const PkgConfig &other)
         {
         name         = other.name;
+        path         = other.path;
+        prefix       = other.prefix;
         description  = other.description;
         cflags       = other.cflags;
         libs         = other.libs;
@@ -4446,12 +4529,18 @@ private:
 
     void parseVersion();
 
+    bool parseLine(const String &lineBuf);
+
     bool parse(const String &buf);
 
     void dumpAttrs();
 
     String name;
 
+    String path;
+
+    String prefix;
+
     String description;
 
     String cflags;
@@ -4495,6 +4584,7 @@ int PkgConfig::get(int pos)
 /**
  *  Skip over all whitespace characters beginning at pos.  Return
  *  the position of the first non-whitespace character.
+ *  Pkg-config is line-oriented, so check for newline
  */
 int PkgConfig::skipwhite(int pos)
 {
@@ -4604,15 +4694,12 @@ void PkgConfig::parseVersion()
 }
 
 
-bool PkgConfig::parse(const String &buf)
+bool PkgConfig::parseLine(const String &lineBuf)
 {
-    init();
-
-    parsebuf = (char *)buf.c_str();
-    parselen = buf.size();
+    parsebuf = (char *)lineBuf.c_str();
+    parselen = lineBuf.size();
     int pos = 0;
-
-
+    
     while (pos < parselen)
         {
         String attrName;
@@ -4633,6 +4720,7 @@ bool PkgConfig::parse(const String &buf)
         pos = getword(pos, attrName);
         if (attrName.size() == 0)
             continue;
+        
         pos = skipwhite(pos);
         ch = get(pos);
         if (ch != ':' && ch != '=')
@@ -4667,10 +4755,18 @@ bool PkgConfig::parse(const String &buf)
                         subName.push_back((char)ch);
                     pos++;
                     }
-                //trace("subName:%s", subName.c_str());
-                String subVal = attrs[subName];
-                //trace("subVal:%s", subVal.c_str());
-                attrVal.append(subVal);
+                //trace("subName:%s %s", subName.c_str(), prefix.c_str());
+                if (subName == "prefix" && prefix.size()>0)
+                    {
+                    attrVal.append(prefix);
+                    //trace("prefix override:%s", prefix.c_str());
+                    }
+                else
+                    {
+                    String subVal = attrs[subName];
+                    //trace("subVal:%s", subVal.c_str());
+                    attrVal.append(subVal);
+                    }
                 }
             else
                 attrVal.push_back((char)ch);
@@ -4680,23 +4776,55 @@ bool PkgConfig::parse(const String &buf)
         attrVal = trim(attrVal);
         attrs[attrName] = attrVal;
 
-        if (attrName == "Name")
+        String attrNameL = toLower(attrName);
+
+        if (attrNameL == "name")
             name = attrVal;
-        else if (attrName == "Description")
+        else if (attrNameL == "description")
             description = attrVal;
-        else if (attrName == "Cflags")
+        else if (attrNameL == "cflags")
             cflags = attrVal;
-        else if (attrName == "Libs")
+        else if (attrNameL == "libs")
             libs = attrVal;
-        else if (attrName == "Requires")
+        else if (attrNameL == "requires")
             requires = attrVal;
-        else if (attrName == "Version")
+        else if (attrNameL == "version")
             version = attrVal;
 
         //trace("name:'%s'  value:'%s'",
         //      attrName.c_str(), attrVal.c_str());
         }
 
+    return true;
+}
+
+
+bool PkgConfig::parse(const String &buf)
+{
+    init();
+
+    String line;
+    int lineNr = 0;
+    for (unsigned int p=0 ; p<buf.size() ; p++)
+        {
+        int ch = buf[p];
+        if (ch == '\n' || ch == '\r')
+            {
+            if (!parseLine(line))
+                return false;
+            line.clear();
+            lineNr++;
+            }
+        else
+            {
+            line.push_back(ch);
+            }
+        }
+    if (line.size()>0)
+        {
+        if (!parseLine(line))
+            return false;
+        }
 
     parseRequires();
     parseVersion();
@@ -4704,6 +4832,9 @@ bool PkgConfig::parse(const String &buf)
     return true;
 }
 
+
+
+
 void PkgConfig::dumpAttrs()
 {
     //trace("### PkgConfig attributes for %s", fileName.c_str());
@@ -4715,9 +4846,9 @@ void PkgConfig::dumpAttrs()
 }
 
 
-bool PkgConfig::readFile(const String &fileNameArg)
+bool PkgConfig::readFile(const String &fname)
 {
-    fileName = fileNameArg;
+    fileName = getNativePath(fname);
 
     FILE *f = fopen(fileName.c_str(), "r");
     if (!f)
@@ -4741,8 +4872,25 @@ bool PkgConfig::readFile(const String &fileNameArg)
         return false;
         }
 
-    dumpAttrs();
+    //dumpAttrs();
+
+    return true;
+}
+
+
+
+bool PkgConfig::query(const String &pkgName)
+{
+    name = pkgName;
 
+    String fname = path;
+    fname.append("/");
+    fname.append(name);
+    fname.append(".pc");
+
+    if (!readFile(fname))
+        return false;
+    
     return true;
 }
 
@@ -5045,7 +5193,7 @@ private:
     /**
      *
      */
-    bool sequ(int pos, char *key);
+    bool sequ(int pos, const char *key);
 
     /**
      *
@@ -5265,7 +5413,7 @@ int DepTool::getword(int pos, String &ret)
  * Return whether the sequence of characters in the buffer
  * beginning at pos match the key,  for the length of the key
  */
-bool DepTool::sequ(int pos, char *key)
+bool DepTool::sequ(int pos, const char *key)
 {
     while (*key)
         {
@@ -5711,6 +5859,7 @@ public:
         TASK_MAKEFILE,
         TASK_MKDIR,
         TASK_MSGFMT,
+        TASK_PKG_CONFIG,
         TASK_RANLIB,
         TASK_RC,
         TASK_SHAREDLIB,
@@ -6015,7 +6164,7 @@ public:
                              srcFullName.c_str());
                 fprintf(f, "#### COMMAND ###\n");
                 int col = 0;
-                for (int i = 0 ; i < cmd.size() ; i++)
+                for (unsigned int i = 0 ; i < cmd.size() ; i++)
                     {
                     char ch = cmd[i];
                     if (isspace(ch)  && col > 63)
@@ -6703,8 +6852,9 @@ public:
             //trace("skipped <makefile>");
             return true;
             }
+        String fullNative = getNativePath(fullName);
         //trace("fullName:%s", fullName.c_str());
-        FILE *f = fopen(fullName.c_str(), "w");
+        FILE *f = fopen(fullNative.c_str(), "w");
         if (!f)
             {
             error("<makefile> could not open %s for writing : %s",
@@ -6927,6 +7077,145 @@ private:
 
 
 
+/**
+ *  Perform a Package-Config query similar to pkg-config
+ */
+class TaskPkgConfig : public Task
+{
+public:
+
+    typedef enum
+        {
+        PKG_CONFIG_QUERY_CFLAGS,
+        PKG_CONFIG_QUERY_LIBS,
+        PKG_CONFIG_QUERY_ALL
+        } QueryTypes;
+
+    TaskPkgConfig(MakeBase &par) : Task(par)
+        {
+        type = TASK_PKG_CONFIG;
+        name = "pkg-config";
+        }
+
+    virtual ~TaskPkgConfig()
+        {}
+
+    virtual bool execute()
+        {
+        String path = parent.resolve(pkg_config_path);
+        PkgConfig pkgconfig;
+        pkgconfig.setPath(path);
+        pkgconfig.setPrefix(prefix);
+        if (!pkgconfig.query(pkgName))
+            {
+            error("<pkg-config> query failed for '%s", name.c_str());
+            return false;
+            }
+        String ret;
+        switch (query)
+            {
+            case PKG_CONFIG_QUERY_CFLAGS:
+                {
+                ret = pkgconfig.getCflags();
+                break;
+                }
+            case PKG_CONFIG_QUERY_LIBS:
+                {
+                ret = pkgconfig.getLibs();
+                break;
+                }
+            case PKG_CONFIG_QUERY_ALL:
+                {
+                ret = pkgconfig.getAll();
+                break;
+                }
+            default:
+                {
+                error("<pkg-config> unhandled query : %d", query);
+                return false;
+                }
+            
+            }
+        status("          : %s", ret.c_str());
+        parent.setProperty(propName, ret);
+        return true;
+        }
+
+    virtual bool parse(Element *elem)
+        {
+        String s;
+        //# NAME
+        if (!parent.getAttribute(elem, "name", s))
+            return false;
+        if (s.size()>0)
+           pkgName = s;
+        else
+            {
+            error("<pkg-config> requires 'name=\"package\"' attribute");
+            return false;
+            }
+
+        //# PROPERTY
+        if (!parent.getAttribute(elem, "property", s))
+            return false;
+        if (s.size()>0)
+           propName = s;
+        else
+            {
+            error("<pkg-config> requires 'property=\"name\"' attribute");
+            return false;
+            }
+        if (parent.hasProperty(propName))
+            {
+            error("<pkg-config> property '%s' is already defined",
+                          propName.c_str());
+            return false;
+            }
+        parent.setProperty(propName, "undefined");
+
+        //# PATH
+        if (!parent.getAttribute(elem, "path", s))
+            return false;
+        if (s.size()>0)
+           pkg_config_path = s;
+
+        //# PREFIX
+        if (!parent.getAttribute(elem, "prefix", s))
+            return false;
+        if (s.size()>0)
+           prefix = s;
+
+        //# QUERY
+        if (!parent.getAttribute(elem, "query", s))
+            return false;
+        if (s == "cflags")
+            query = PKG_CONFIG_QUERY_CFLAGS;
+        else if (s == "libs")
+            query = PKG_CONFIG_QUERY_LIBS;
+        else if (s == "both")
+            query = PKG_CONFIG_QUERY_ALL;
+        else
+            {
+            error("<pkg-config> requires 'query=\"type\"' attribute");
+            error("where type = cflags, libs, or both");
+            return false;
+            }
+        return true;
+        }
+
+private:
+
+    String pkgName;
+    String prefix;
+    String propName;
+    String pkg_config_path;
+    int query;
+
+};
+
+
+
+
 
 
 /**
@@ -7473,6 +7762,8 @@ Task *Task::createTask(Element *elem, int lineNr)
         task = new TaskMkDir(parent);
     else if (tagName == "msgfmt")
         task = new TaskMsgFmt(parent);
+    else if (tagName == "pkg-config")
+        task = new TaskPkgConfig(parent);
     else if (tagName == "ranlib")
         task = new TaskRanlib(parent);
     else if (tagName == "rc")
@@ -7940,7 +8231,8 @@ bool Make::executeTarget(Target &target,
             }
         }
 
-    status("## Target : %s", name.c_str());
+    status("## Target : %s : %s", name.c_str(),
+            target.getDescription().c_str());
 
     //Now let's do the tasks
     std::vector<Task *> &tasks = target.getTasks();
@@ -8469,7 +8761,7 @@ typedef buildtool::String String;
 /**
  *  Format an error message in printf() style
  */
-static void error(char *fmt, ...)
+static void error(const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
@@ -8509,7 +8801,7 @@ static bool parseProperty(const String &s, String &name, String &val)
 /**
  * Compare a buffer with a key, for the length of the key
  */
-static bool sequ(const String &buf, char *key)
+static bool sequ(const String &buf, const char *key)
 {
     int len = buf.size();
     for (int i=0 ; key[i] && i<len ; i++)