diff --git a/buildtool.cpp b/buildtool.cpp
index 23d265f02a6ebbfa5a81ecb39e1939008736d508..2b4307ab0f0e2ca6026a7eabc2a4a874d0d32a8b 100644 (file)
--- a/buildtool.cpp
+++ b/buildtool.cpp
*
*/
-#define BUILDTOOL_VERSION "BuildTool v0.9.6"
+#define BUILDTOOL_VERSION "BuildTool v0.9.9"
#include <stdio.h>
#include <fcntl.h>
/**
* 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;
+
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
+
+};
+
+
+
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;
FILE *destf = fopen(destNative.c_str(), "wb");
if (!destf)
{
+ fclose(srcf);
error("copyFile cannot open %s for writing", srcNative.c_str());
return false;
}
}
-
-
-
//########################################################################
//# D E P T O O L
//########################################################################
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);
{
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");
private:
String fileNameOpt;
+ String forceOpt;
String textOpt;
};
pcPrefix = "pc.";
pccPrefix = "pcc.";
pclPrefix = "pcl.";
+ bzrPrefix = "bzr.";
properties.clear();
for (unsigned int i = 0 ; i < allTasks.size() ; i++)
delete allTasks[i];
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;