--- /dev/null
+G++ = g++
+CPPFLAGS = -O2 -Wall#-D_DEBUG_
+PREFIX = /usr/local
+DESTDIR =
+LDFLAGS =
+
+CPPSRCS = XMLAttrs.cpp XMLChangelog.cpp XMLFiles.cpp XMLMacro.cpp \
+ XMLMirror.cpp XMLParser.cpp XMLPackage.cpp XMLRequires.cpp \
+ XMLScript.cpp XMLSource.cpp XMLSpec.cpp xml2spec.cpp
+CPPOBJS = $(CPPSRCS:.cpp=.o)
+INCS = -I. -I.. -I../build -I../lib -I../rpmio
+LIBDIR = #-L../build/.libs
+LIBS = -lexpat -lrpm -lrpmbuild -lrpmdb -lrpmio -lpopt
+
+all: xml2spec
+
+.SUFFIXES: .cpp .o
+
+.cpp.o:
+ $(G++) $(CPPFLAGS) $(INCS) -c $<
+
+xml2spec: $(CPPOBJS)
+ $(G++) $(CPPFLAGS) $(LDFLAGS) -o xml2spec $(CPPOBJS) $(LIBDIR) $(LIBS)
+
+test: xml2spec
+ @./xml2spec example.spec.xml example.out.spec
+
+clean: clean-xml2spec
+
+clean-xml2spec:
+ @rm -rf xml2spec *.o
+ @rm -rf example.out.spec
+ @rm -rf example.out.xml
+
+install:
+ @mkdir -p $(DESTDIR)$(PREFIX)/bin
+ @cp xml2spec $(DESTDIR)$(PREFIX)/bin
--- /dev/null
+// standard C++ includes
+#include <string>
+
+// standard includes
+#include <string.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+XMLAttr::XMLAttr(const char* szName,
+ const char* szValue)
+ : XMLBase()
+{
+ if (szName)
+ m_sName.assign(szName);
+ if (szValue)
+ m_sValue.assign(szValue);
+}
+
+XMLAttr::XMLAttr(const XMLAttr& rAttr)
+ : XMLBase()
+{
+ m_sName.assign(rAttr.m_sName);
+ m_sValue.assign(rAttr.m_sValue);
+}
+
+XMLAttr::~XMLAttr()
+{
+}
+
+XMLAttr XMLAttr::operator=(XMLAttr attr)
+{
+ m_sName.assign(attr.m_sName);
+ m_sValue.assign(attr.m_sValue);
+}
+
+XMLAttrs::XMLAttrs(const char** szAttrs)
+ : XMLBase()
+{
+ for (int i = 0; szAttrs && szAttrs[i]; i += 2) {
+ XMLAttr attr(szAttrs[i],
+ szAttrs[i+1]);
+ m_vAttrs.push_back(attr);
+ }
+}
+
+XMLAttrs::XMLAttrs(const XMLAttrs& rAttrs)
+ : XMLBase()
+{
+ m_vAttrs = rAttrs.m_vAttrs;
+}
+
+XMLAttrs::~XMLAttrs()
+{
+}
+
+bool XMLAttrs::validate(structValidAttrs* paValids,
+ XMLBase* pError)
+{
+ // nothing found at present
+ for (unsigned int i = 0; paValids[i].m_nValue != XATTR_END; i++)
+ paValids[i].m_bFound = false;
+
+ // test everything we have
+ for (unsigned int i = 0; i < num(); i++) {
+ bool bInvalid = true;
+ for (unsigned int j = 0; paValids[j].m_nValue != XATTR_END; j++) {
+ if (strcasecmp(paValids[j].m_szName, get(i).getName()) == 0) {
+ paValids[i].m_bFound = true;
+ bInvalid = false;
+ break;
+ }
+ }
+ if (bInvalid) {
+ char szTmp[1024];
+ sprintf(szTmp, "Unknown attribute '%s'", get(i).getName());
+ pError->setWarning(szTmp);
+ }
+ }
+
+ // see if we have mandator tags that are not there
+ for (unsigned int i = 0; paValids[i].m_nValue != XATTR_END; i++) {
+ if (paValids[i].m_bMandatory && !paValids[i].m_bFound) {
+ char szTmp[1024];
+ sprintf(szTmp, "Mandatory attribute '%s' not found",
+ paValids[i].m_szName);
+ pError->setError(szTmp);
+ return false;
+ }
+ }
+
+ // if we got this far, everything is ok
+ return true;
+}
+
+const char* XMLAttrs::get(const char* szName)
+{
+ if (szName)
+ {
+ for (unsigned int i = 0; i < num(); i++) {
+ if (strcasecmp(szName, get(i).getName()) == 0)
+ return get(i).getValue();
+ }
+ }
+ return NULL;
+}
--- /dev/null
+#ifndef _H_XMLATTRS_
+#define _H_XMLATTRS_
+
+// standard C++ includes
+#include <string>
+#include <vector>
+
+// our includes
+#include "XMLBase.h"
+
+using namespace std;
+
+// definition for the end of the attributes
+#define XATTR_END 0xFFFF
+
+struct structValidAttrs
+{
+ unsigned int m_nValue;
+ bool m_bMandatory;
+ bool m_bFound;
+ char* m_szName;
+};
+
+// forward class definitions
+class XMLSpec;
+
+class XMLAttr : public XMLBase
+{
+//
+// contructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName The name of the attribute
+ * @param szValue The attribute value
+ * @return none
+ **/
+ XMLAttr(const char* szName,
+ const char* szValue);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rAttr Reference to the attribute to copy
+ * @return none
+ **/
+ XMLAttr(const XMLAttr& rAttr);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLAttr();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param attr The attribute to copy
+ * @return the assigned obkect
+ **/
+ XMLAttr operator=(XMLAttr attr);
+
+//
+// get/set functions
+//
+public:
+ /**
+ * Returns the attribute name
+ * .
+ * @param none
+ * @return string containing the attribute name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Returns the attribute value
+ * .
+ * @param none
+ * @return string containing the attribute value
+ **/
+ const char* getValue()
+ {
+ return m_sValue.c_str();
+ }
+
+//
+// member variables
+//
+public:
+ string m_sName;
+ string m_sValue;
+};
+
+class XMLAttrs : public XMLBase
+{
+//
+// constructors/destructor
+//
+public:
+ /**
+ * The default attribute constructor
+ * .
+ * @param szAttrs Pointer to an array of attributes, terminated by NULL
+ * @return none
+ **/
+ XMLAttrs(const char** szAttrs);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rAttrs The attribute object to copy
+ * @return none
+ **/
+ XMLAttrs(const XMLAttrs& rAttrs);
+
+ /**
+ * The default destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLAttrs();
+
+//
+// member functions
+//
+public:
+ /**
+ * Validates an attribute object against the valid attributes. This
+ * checks for mandatory attributes (error) as well as unexpected
+ * attributes. (warnings)
+ * .
+ * @param paValids Pointer to the array of valid attributes
+ * @param pError The class in which we will set the errors
+ * and/or warnings.
+ * @return true on valid attributes, false otherwise
+ **/
+ bool validate(structValidAttrs* paValids,
+ XMLBase* pError);
+
+ /**
+ * Returns the value of an attribute as specified by the name
+ * .
+ * @param szName The name of the attribute whose value we are
+ * to return
+ * @return The value or NULL if the attribute was not found
+ **/
+ const char* get(const char* szName);
+
+//
+// member variables get/set functions
+//
+public:
+ /**
+ * Gets the number of attributes contained in this object
+ * .
+ * @param none
+ * @returns The number of attributes
+ **/
+ unsigned int num()
+ {
+ return m_vAttrs.size();
+ }
+
+ /**
+ * Returns a specific attribute by number
+ * .
+ * @param nNum The number of the attribute to return
+ * @return The attribute or NULL if it doesn't exist
+ **/
+ XMLAttr& get(unsigned int nNum)
+ {
+ return m_vAttrs[nNum];
+ }
+
+//
+// protected data members
+//
+protected:
+ vector<XMLAttr> m_vAttrs;
+};
+
+#endif
--- /dev/null
+#ifndef _H_XMLBASE_
+#define _H_XMLBASE_
+
+// standard C++ includes
+#include <string>
+
+// standard include
+#include <stdio.h>
+
+using namespace std;
+
+class XMLBase
+{
+//
+// constructors/destructor methods
+//
+public:
+ /**
+ * Default class constructor
+ * .
+ * param none
+ * @return none
+ **/
+ XMLBase()
+ {
+ m_bHasError = false;
+ m_bHasWarning = false;
+ }
+
+ /**
+ * Default class destructor
+ * .
+ * param none
+ * @return none
+ **/
+ ~XMLBase()
+ {
+ }
+
+//
+// member variable get and set functions
+//
+public:
+ /**
+ * Tests if the object has an error set.
+ * .
+ * @param none
+ * @return true if we have an error, false otherwise
+ **/
+ bool hasError()
+ {
+ return m_bHasError;
+ }
+
+ /**
+ * Sets the error message that can be retrieved from this
+ * object instance
+ * .
+ * @param szError The error string
+ * @return none
+ **/
+ void setError(const char* szError = NULL)
+ {
+ if (szError) {
+ m_bHasError = true;
+ m_sError.assign(szError);
+ }
+ else
+ m_bHasError = false;
+ }
+
+ /**
+ * Returns the currently set error value
+ * .
+ * @param none
+ * @return pointer to the error string
+ **/
+ const char* getError()
+ {
+ m_bHasError = false;
+ return m_sError.c_str();
+ }
+
+ /**
+ * Tests if the object has a warning set.
+ * .
+ * @param none
+ * @return true if we have a warning, false otherwise
+ **/
+ bool hasWarning()
+ {
+ return m_bHasWarning;
+ }
+
+ /**
+ * Sets the warning message that can be retrieved from this
+ * object instance
+ * .
+ * @param szWarning The warning string
+ * @return none
+ **/
+ void setWarning(const char* szWarning = NULL)
+ {
+ if (szWarning) {
+ m_bHasWarning = true;
+ m_sWarning.assign(szWarning);
+ }
+ else
+ m_bHasWarning = false;
+ }
+
+ /**
+ * Returns the currently set warning value
+ * .
+ * @param none
+ * @return pointer to the warning string
+ **/
+ const char* getWarning()
+ {
+ m_bHasWarning = false;
+ return m_sWarning.c_str();
+ }
+
+//
+// protected internal variables
+//
+protected:
+ bool m_bHasError;
+ string m_sError;
+ bool m_bHasWarning;
+ string m_sWarning;
+};
+
+#endif
--- /dev/null
+// standard C++ includes
+#include <string>
+
+// our includes
+#include "XMLChangelog.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+bool XMLChangelogEntry::parseCreate(XMLAttrs* pAttrs,
+ const char* szChange,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+
+ XMLChangelogEntry change(szChange);
+ pSpec->getChangelog().lastDate().addEntry(change);
+ return true;
+}
+
+XMLChangelogEntry::XMLChangelogEntry(const char* szChange)
+ : XMLBase()
+{
+ m_sChange.assign(szChange);
+}
+
+XMLChangelogEntry::XMLChangelogEntry(const XMLChangelogEntry& rEntry)
+ : XMLBase()
+{
+ m_sChange.assign(rEntry.m_sChange);
+}
+
+XMLChangelogEntry::~XMLChangelogEntry()
+{
+}
+
+void XMLChangelogEntry::toSpecFile(ostream& rOut)
+{
+ rOut << endl << "- " << getChange();
+}
+
+void XMLChangelogEntry::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t\t\t<change>" << getChange() << "</change>";
+}
+
+// attribute structure for XMLChangelogDate
+structValidAttrs g_paChangelogDateAttrs[] =
+{
+ {0x0000, true, false, "date"},
+ {0x0001, true, false, "author"},
+ {0x0002, false, false, "author-email"},
+ {0x0003, false, false, "version"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLChangelogDate::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate our attributes
+ if (!pAttrs->validate(g_paChangelogDateAttrs, (XMLBase*)pSpec))
+ return false;
+
+ XMLChangelogDate date(pAttrs->get("date"),
+ pAttrs->get("author"),
+ pAttrs->get("author-email"),
+ pAttrs->get("version"));
+ pSpec->getChangelog().addDate(date);
+ return true;
+}
+
+XMLChangelogDate::XMLChangelogDate(const char* szDate,
+ const char* szAuthor,
+ const char* szEmail,
+ const char* szVersion)
+ : XMLBase()
+{
+ if (szDate)
+ m_sDate.assign(szDate);
+ if (szAuthor)
+ m_sAuthor.assign(szAuthor);
+ if (szEmail)
+ m_sEmail.assign(szEmail);
+ if (szVersion)
+ m_sVersion.assign(szVersion);
+}
+
+XMLChangelogDate::XMLChangelogDate(const XMLChangelogDate& rDate)
+ : XMLBase()
+{
+ m_sDate.assign(rDate.m_sDate);
+ m_sAuthor.assign(rDate.m_sAuthor);
+ m_sEmail.assign(rDate.m_sEmail);
+ m_sVersion.assign(rDate.m_sVersion);
+ m_vEntries = rDate.m_vEntries;
+}
+
+XMLChangelogDate::~XMLChangelogDate()
+{
+}
+
+void XMLChangelogDate::toSpecFile(ostream& rOut)
+{
+ if (numEntries()) {
+ rOut << endl << "* " << getDate() << " " << getAuthor();
+ if (hasEmail())
+ rOut << " <" << getEmail() << ">";
+ if (hasVersion())
+ rOut << " " << getVersion();
+ for (unsigned int i = 0; i < numEntries(); i++)
+ getEntry(i).toSpecFile(rOut);
+ rOut << endl;
+ }
+}
+
+void XMLChangelogDate::toXMLFile(ostream& rOut)
+{
+ if (numEntries()) {
+ rOut << endl << "\t\t<changes date=\"" << getDate() << "\"";
+ rOut << endl << "\t\t author=\"" << getAuthor() << "\"";
+ if (hasEmail())
+ rOut << endl << "\t\t author-email=\"" << getEmail() << "\"";
+ if (hasVersion())
+ rOut << endl << "\t\t version=\"" << getVersion() << "\"";
+ rOut << ">";
+ for (unsigned int i = 0; i < numEntries(); i++)
+ getEntry(i).toXMLFile(rOut);
+ rOut << endl << "\t\t</changes>";
+ }
+}
+
+XMLChangelog::XMLChangelog()
+ : XMLBase()
+{
+}
+
+XMLChangelog::XMLChangelog(const XMLChangelog& rChangelog)
+ : XMLBase()
+{
+ m_vDates = rChangelog.m_vDates;
+}
+
+XMLChangelog::~XMLChangelog()
+{
+}
+
+void XMLChangelog::toSpecFile(ostream& rOut)
+{
+ if (numDates()) {
+ rOut << endl << "%changelog";
+ for (unsigned int i = 0; i < numDates(); i++)
+ getDate(i).toSpecFile(rOut);
+ rOut << endl;
+ }
+}
+
+void XMLChangelog::toXMLFile(ostream& rOut)
+{
+ if (numDates()) {
+ rOut << endl << "\t<changelog>";
+ for (unsigned int i = 0; i < numDates(); i++)
+ getDate(i).toXMLFile(rOut);
+ rOut << endl << "\t<changelog>";
+ }
+}
+
+void XMLChangelog::toRPMStruct(Spec spec)
+{
+}
--- /dev/null
+#ifndef _H_XMLCHANGELOG_
+#define _H_XMLCHANGELOG_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+
+// rpm includes
+#include <rpmbuild.h>
+
+// forward class definitions
+class XMLSpec;
+class XMLChangelog;
+
+using namespace std;
+
+class XMLChangelogEntry : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Adds a changelog entry
+ * .
+ * @param pAttrs The XML attributes
+ * @param szEntry The entry to create
+ * @param pSpec Pointer to our spec
+ * @return true on success, false othersise
+ */
+ static bool parseCreate(XMLAttrs* pAttrs,
+ const char* szEntry,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default contructor
+ * .
+ * @param szChange The change entry
+ * @return none
+ **/
+ XMLChangelogEntry(const char* szChange);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rEntry Reference to the entry to copy
+ * @return none
+ **/
+ XMLChangelogEntry(const XMLChangelogEntry& rEntry);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLChangelogEntry();
+
+//
+// member functions
+//
+public:
+ /**
+ * Outputs the object into a spec file
+ * .
+ * @param rOut Reference to our output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Outputs the object into an XML spec file
+ * .
+ * @param rOut Reference to our output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Returns the enrty
+ * .
+ * @param none
+ * @return string containing the entry
+ **/
+ const char* getChange()
+ {
+ return m_sChange.c_str();
+ }
+
+//
+// member variables
+//
+public:
+ string m_sChange;
+};
+
+class XMLChangelogDate : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Creates a XMLChangelogDate object
+ * .
+ * @param pAttrs The XML attributes
+ * @param pSpec The spec to add this object to
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default contructor
+ * .
+ * @param szDate The date
+ * @param szAuthor The author
+ * @param szEmail The author's email
+ * @param szVersion The version in which this change was made
+ * @return none
+ **/
+ XMLChangelogDate(const char* szDate,
+ const char* szAuthor,
+ const char* szEmail,
+ const char* szVersion);
+
+ /**
+ * Copy contructor
+ * .
+ * @param rDate Reference to the date object to copy
+ * @return none
+ **/
+ XMLChangelogDate(const XMLChangelogDate& rDate);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLChangelogDate();
+
+//
+// public member functions
+//
+public:
+ /**
+ * Outputs the object into a spec file
+ * .
+ * @param rOut Reference to our output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Outputs the object into an XML spec file
+ * .
+ * @param rOut Reference to our output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member variables get/set functions
+//
+public:
+ /**
+ * Returns the date for the group of entries
+ * .
+ * @param none
+ * @return string representation of the date
+ **/
+ const char* getDate()
+ {
+ return m_sDate.c_str();
+ }
+
+ /**
+ * Checks for an author
+ * .
+ * @param none
+ * @return true if we have an author, false otherwise
+ **/
+ bool hasAuthor()
+ {
+ return m_sAuthor.length() ? true : false;
+ }
+
+ /**
+ * Returns the author's name
+ * .
+ * @param none
+ * @return string containing the author's name
+ **/
+ const char* getAuthor()
+ {
+ return m_sAuthor.c_str();
+ }
+
+ /**
+ * Checks if we have an email address for the author
+ * .
+ * @param none
+ * @return true if we hava an email, false otherwise
+ **/
+ bool hasEmail()
+ {
+ return m_sEmail.length() ? true : false;
+ }
+
+ /**
+ * Returns the author's email addresse
+ * .
+ * @param none
+ * @return a string containing the author's email address
+ **/
+ const char* getEmail()
+ {
+ return m_sEmail.c_str();
+ }
+
+ /**
+ * Checks if we have a change version
+ * .
+ * @param none
+ * @return true if we have a version, false otherwise
+ **/
+ bool hasVersion()
+ {
+ return m_sVersion.length() ? true : false;
+ }
+
+ /**
+ * Gets the change version
+ * .
+ * @param none
+ * @return string containing the version
+ **/
+ const char* getVersion()
+ {
+ return m_sVersion.c_str();
+ }
+
+ /**
+ * Returns the number of entries for this date
+ * .
+ * @param none
+ * @return the number of entries
+ **/
+ unsigned int numEntries()
+ {
+ return m_vEntries.size();
+ }
+
+ /**
+ * Returns a specific entry
+ * .
+ * @param nNum The number of the entry to return
+ * @return the enrty
+ **/
+ XMLChangelogEntry& getEntry(unsigned int nNum)
+ {
+ return m_vEntries[nNum];
+ }
+
+ /**
+ * Adds an entry for this date
+ * .
+ * @param szEntry The entry to add
+ * @return none
+ **/
+ void addEntry(XMLChangelogEntry& rEntry)
+ {
+ m_vEntries.push_back(rEntry);
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sDate;
+ string m_sAuthor;
+ string m_sEmail;
+ string m_sVersion;
+ vector<XMLChangelogEntry> m_vEntries;
+};
+
+class XMLChangelog : public XMLBase
+{
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param none
+ * @return none
+ **/
+ XMLChangelog();
+
+ /**
+ * Copy constructor
+ * .
+ * @param rChangelog The object to copy
+ * @return none
+ **/
+ XMLChangelog(const XMLChangelog& rChangelog);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLChangelog();
+
+//
+// public member functions
+//
+public:
+ /**
+ * Converts the object into a spec file
+ * .
+ * @param rOut Reference to the output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an xML spec
+ * .
+ * @param rOut Reference to the output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the object into an RPM structure
+ * .
+ * @param spec RPM structure
+ * @return none
+ **/
+ void toRPMStruct(Spec spec);
+//
+// variable get/set functions
+//
+public:
+ /**
+ * Adds a date to the changelog
+ * .
+ * @param rDate The date to add
+ * @return none
+ **/
+ void addDate(XMLChangelogDate& rDate)
+ {
+ m_vDates.push_back(rDate);
+ }
+
+ /**
+ * Returns the number of dates in the changelog
+ * .
+ * @param none
+ * @return the number of dates
+ **/
+ unsigned int numDates()
+ {
+ return m_vDates.size();
+ }
+
+ /**
+ * Gets a specific date
+ * .
+ * @param nNum The entry number
+ * @return The requated date
+ **/
+ XMLChangelogDate& getDate(unsigned int nNum)
+ {
+ return m_vDates[nNum];
+ }
+
+ /**
+ * Gets the last date we have added
+ * .
+ * @param none
+ * @return the last date
+ **/
+ XMLChangelogDate& lastDate()
+ {
+ return m_vDates[numDates()-1];
+ }
+
+//
+// member variables
+//
+protected:
+ vector<XMLChangelogDate> m_vDates;
+};
+
+#endif
--- /dev/null
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLFiles.h"
+#include "XMLPackage.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+// attribute structure for XMLFile
+structValidAttrs g_paFileAttrs[] =
+{
+ {0x0000, false, false, "attr"},
+ {0x0001, false, false, "gid"},
+ {0x0002, false, false, "uid"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLFile::parseCreate(XMLAttrs* pAttrs,
+ const char* szPath,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pSpec || !pAttrs->validate(g_paFileAttrs, (XMLBase*)pSpec))
+ return false;
+
+ // create and return
+ XMLFile file(pAttrs->get("attr"),
+ pAttrs->get("uid"),
+ pAttrs->get("gid"),
+ szPath);
+ pSpec->lastPackage().getFiles().addFile(file);
+ return true;
+}
+
+XMLFile::XMLFile(const char* szAttr,
+ const char* szOwner,
+ const char* szGroup,
+ const char* szPath)
+ : XMLBase()
+{
+ if (szAttr)
+ m_sAttr.assign(szAttr);
+ if (szOwner)
+ m_sOwner.assign(szOwner);
+ if (szGroup)
+ m_sGroup.assign(szGroup);
+ if (szPath)
+ m_sPath.assign(szPath);
+}
+
+XMLFile::XMLFile(const XMLFile& rFile)
+ : XMLBase()
+{
+ m_sAttr.assign(rFile.m_sAttr);
+ m_sOwner.assign(rFile.m_sOwner);
+ m_sGroup.assign(rFile.m_sGroup);
+ m_sPath.assign(rFile.m_sPath);
+}
+
+XMLFile::~XMLFile()
+{
+}
+
+XMLFile XMLFile::operator=(XMLFile file)
+{
+ m_sAttr.assign(file.m_sAttr);
+ m_sOwner.assign(file.m_sOwner);
+ m_sGroup.assign(file.m_sGroup);
+ m_sPath.assign(file.m_sPath);
+}
+
+void XMLFile::toSpecFile(ostream& rOut)
+{
+ if (hasAttr() || hasOwner() || hasGroup()) {
+ rOut << "%attr(";
+ rOut << (hasAttr() ? getAttr() : "-");
+ rOut << "," << (hasOwner() ? getOwner() : "-");
+ rOut << "," << (hasGroup() ? getGroup() : "-");
+ rOut << ") ";
+ }
+ rOut << getPath() << endl;
+}
+
+void XMLFile::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t\t\t<file";
+ if (hasAttr())
+ rOut << " attr=\"" << getAttr() << "\"";
+ if (hasOwner())
+ rOut << " uid=\"" << getOwner() << "\"";
+ if (hasGroup())
+ rOut << " gid=\"" << getAttr() << "\"";
+ rOut << ">";
+ rOut << getPath() << "</file>";
+}
+
+// attribute structure for XMLFiles
+structValidAttrs g_paFilesAttrs[] =
+{
+ {0x0000, false, false, "attr"},
+ {0x0001, false, false, "gid"},
+ {0x0002, false, false, "uid"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLFiles::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pSpec || !pAttrs->validate(g_paFilesAttrs, (XMLBase*)pSpec))
+ return false;
+
+ pSpec->lastPackage().getFiles().setDefAttr(pAttrs->get("attr"));
+ pSpec->lastPackage().getFiles().setDefOwner(pAttrs->get("uid"));
+ pSpec->lastPackage().getFiles().setDefGroup(pAttrs->get("gid"));
+ return true;
+}
+
+XMLFiles::XMLFiles()
+ : XMLBase()
+{
+}
+
+XMLFiles::XMLFiles(const XMLFiles& rFiles)
+ : XMLBase()
+{
+ m_sAttr.assign(rFiles.m_sAttr);
+ m_sOwner.assign(rFiles.m_sOwner);
+ m_sGroup.assign(rFiles.m_sGroup);
+ m_vFiles = rFiles.m_vFiles;
+}
+
+XMLFiles::~XMLFiles()
+{
+}
+
+XMLFiles XMLFiles::operator=(XMLFiles files)
+{
+ m_sAttr.assign(files.m_sAttr);
+ m_sOwner.assign(files.m_sOwner);
+ m_sGroup.assign(files.m_sGroup);
+ m_vFiles = files.m_vFiles;
+ return *this;
+}
+
+void XMLFiles::toSpecFile(ostream& rOut)
+{
+ if (numFiles()) {
+ if (hasDefAttr() || hasDefOwner() || hasDefGroup()) {
+ rOut << "%defattr(";
+ rOut << (hasDefAttr() ? getDefAttr() : "-");
+ rOut << "," << (hasDefOwner() ? getDefOwner() : "-");
+ rOut << "," << (hasDefGroup() ? getDefGroup() : "-");
+ rOut << ")" << endl;
+ }
+ for (unsigned int i = 0; i < numFiles(); i++)
+ getFile(i).toSpecFile(rOut);
+ }
+}
+
+void XMLFiles::toXMLFile(ostream& rOut)
+{
+ if (numFiles()) {
+ rOut << endl << "\t\t<files";
+ if (hasDefAttr())
+ rOut << " attr=\"" << getDefAttr() << "\"";
+ if (hasDefOwner())
+ rOut << " uid=\"" << getDefOwner() << "\"";
+ if (hasDefGroup())
+ rOut << " gid=\"" << getDefGroup() << "\"";
+ rOut << ">";
+ for (unsigned int i = 0; i < numFiles(); i++)
+ getFile(i).toXMLFile(rOut);
+ rOut << endl << "\t\t</files>";
+ }
+}
--- /dev/null
+#ifndef _H_XMLFILES_
+#define _H_XMLFILES_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+
+// forward class definitions
+class XMLPackage;
+class XMLFiles;
+class XMLSpec;
+
+using namespace std;
+
+// <file ...>
+class XMLFile : public XMLBase
+{
+//
+// object creation static functions
+//
+public:
+ /**
+ * Creates a file object and add it to the correct XMLFiles
+ * container.
+ * .
+ * @param pAttrs The attributes in the XML tag
+ * @param szPath The file path
+ * @param pSpec The spec to which these files belong
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ const char* szPath,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default contructor
+ * .
+ * @param szAttr The file's attribute (NULL if default)
+ * @param szOwner The file's owner (NULL if default)
+ * @param szGroup The file's group (NULL if default)
+ * @param szPath The file path
+ * @return none
+ **/
+ XMLFile(const char* szAttr,
+ const char* szOwner,
+ const char* szGroup,
+ const char* szPath);
+
+ /**
+ * Copy constructire
+ * .
+ * @param rFile Reference to the object to copy
+ * @return none
+ **/
+ XMLFile(const XMLFile& rFile);
+
+ /**
+ * Default destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLFile();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param file The file that we wish to copy
+ * @return a copy of the original
+ **/
+ XMLFile operator=(XMLFile file);
+
+//
+// member functions
+//
+public:
+ /**
+ * Outputs the obkect to an RPM spec file
+ * .
+ * @param rOut Reference to the output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Outputs the object to an XML spec file
+ * .
+ * @param rOut Reference to the output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Returns the file path
+ * .
+ * @param none
+ * @return string containing the path
+ **/
+ const char* getPath()
+ {
+ return m_sPath.c_str();
+ }
+
+ /**
+ * Checks for a file attribute
+ * .
+ * @param none
+ * @return true if we have one, false otherwise
+ **/
+ bool hasAttr()
+ {
+ return m_sAttr.length() ? true : false;
+ }
+
+ /**
+ * Returns the file attribute
+ * .
+ * @param none
+ * @return the sttribute string
+ **/
+ const char* getAttr()
+ {
+ return m_sAttr.c_str();
+ }
+
+ /**
+ * Checks if we have a file owner
+ * .
+ * @param none
+ * @return true if we have an owner, false otherwise
+ **/
+ bool hasOwner()
+ {
+ return m_sOwner.length() ? true : false;
+ }
+
+ /**
+ * Returns the file owner
+ * .
+ * @param no0ne
+ * @return the owner as a string
+ **/
+ const char* getOwner()
+ {
+ return m_sOwner.c_str();
+ }
+
+ /**
+ * Checks for a file group
+ * .
+ * @param none
+ * @return true if we have a group, false otherwise
+ **/
+ bool hasGroup()
+ {
+ return m_sGroup.length() ? true : false;
+ }
+
+ /**
+ * Returns the file group
+ * .
+ * @param none
+ * @return string containing the group
+ **/
+ const char* getGroup()
+ {
+ return m_sGroup.c_str();
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sPath;
+ string m_sAttr;
+ string m_sOwner;
+ string m_sGroup;
+};
+
+// <files ...>
+class XMLFiles : public XMLBase
+{
+//
+// object creation static functions
+//
+public:
+ /**
+ * Creates an object as parsed from an XML spec
+ * .
+ * @param pAttrs XML atrtributes to use
+ * @param pSpec The spec to which we are adding this object to
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param none
+ * @return none
+ **/
+ XMLFiles();
+
+ /**
+ * Copy constructor
+ * .
+ * @param rFiles Reference to the object to copy
+ * @return none
+ **/
+ XMLFiles(const XMLFiles& rFiles);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLFiles();
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param files XMLFiles object to copy
+ * @return copied object
+ **/
+ XMLFiles operator=(XMLFiles files);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Adds a file to our file list
+ * .
+ * @param rFile File to add
+ * @return none
+ **/
+ void addFile(XMLFile& rFile)
+ {
+ m_vFiles.push_back(rFile);
+ }
+
+ /**
+ * Returns the number of files in our list
+ * .
+ * @param none
+ * @return none
+ **/
+ unsigned int numFiles()
+ {
+ return m_vFiles.size();
+ }
+
+ /**
+ * Returns a specific file
+ * .
+ * @param nNum Number of the file to return
+ * @return the file object
+ **/
+ XMLFile& getFile(unsigned int nNum)
+ {
+ return m_vFiles[nNum];
+ }
+
+ /**
+ * Checks for a default attribute
+ * .
+ * @param none
+ * @return true if we have a default attribute, false otherwise
+ **/
+ bool hasDefAttr()
+ {
+ return m_sAttr.length() ? true : false;
+ }
+
+ /**
+ * Sets the default attribute
+ * .
+ * @param szAttr The attribute value
+ * @return none
+ **/
+ void setDefAttr(const char* szAttr)
+ {
+ if (szAttr)
+ m_sAttr.assign(szAttr);
+ }
+
+ /**
+ * Returns the default attribute
+ * .
+ * @param none
+ * @return string contating the attribute
+ **/
+ const char* getDefAttr()
+ {
+ return m_sAttr.c_str();
+ }
+
+ /**
+ * Check if we have a default owner
+ * .
+ * @param none
+ * @return true if we have an owner, false otherwise
+ **/
+ bool hasDefOwner()
+ {
+ return m_sOwner.length() ? true : false;
+ }
+
+ /**
+ * Sets the default owner
+ * .
+ * @param szOwner The owner
+ * @return none
+ **/
+ void setDefOwner(const char* szOwner)
+ {
+ if (szOwner)
+ m_sOwner.assign(szOwner);
+ }
+
+ /**
+ * Returns the default owner
+ * .
+ * @param none
+ * @return the owner string
+ **/
+ const char* getDefOwner()
+ {
+ return m_sOwner.c_str();
+ }
+
+ /**
+ * Checks if we have a default group
+ * .
+ * @param none
+ * @return true if we have an owner, false otherwise
+ **/
+ bool hasDefGroup()
+ {
+ return m_sGroup.length() ? true : false;
+ }
+
+ /**
+ * Sets the default group
+ * .
+ * @param szGroup The group to set
+ * @return none
+ **/
+ void setDefGroup(const char* szGroup)
+ {
+ if (szGroup)
+ m_sGroup.assign(szGroup);
+ }
+
+ /**
+ * Gets the default group
+ * .
+ * @param none
+ * @return string representation of the group
+ **/
+ const char* getDefGroup()
+ {
+ return m_sGroup.c_str();
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sAttr;
+ string m_sOwner;
+ string m_sGroup;
+ vector<XMLFile> m_vFiles;
+};
+
+#endif
--- /dev/null
+// our includes
+#include "XMLMacro.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+// attribute structure for XMLMacro
+structValidAttrs g_paMacroAttrs[] =
+{
+ {0x0000, true, false, "name"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLMacro::parseCreate(XMLAttrs* pAttrs,
+ const char* szMacro,
+ XMLSpec* pSpec)
+{
+ if (!pSpec || !szMacro || !pAttrs->validate(g_paMacroAttrs, (XMLBase*)pAttrs))
+ return false;
+ XMLMacro macro(pAttrs->get("name"), szMacro);
+ pSpec->addXMacro(macro);
+ return true;
+}
+
+XMLMacro::XMLMacro(const char* szName,
+ const char* szMacro)
+ : XMLBase()
+{
+ if (szName)
+ m_sName.assign(szName);
+ if (szMacro)
+ m_sValue.assign(szMacro);
+}
+
+XMLMacro::XMLMacro(const XMLMacro& rMacro)
+ : XMLBase()
+{
+ m_sName.assign(rMacro.m_sName);
+ m_sValue.assign(rMacro.m_sValue);
+}
+
+XMLMacro::~XMLMacro()
+{
+}
+
+XMLMacro XMLMacro::operator=(XMLMacro macro)
+{
+ m_sName.assign(macro.m_sName);
+ m_sValue.assign(macro.m_sValue);
+}
+
+void XMLMacro::toSpecFile(ostream& rOut)
+{
+ rOut << "%define " << getName() << " " << getValue() << endl;
+}
+
+void XMLMacro::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t<macro name=\"" << getName() << "\">";
+ rOut << getValue() << "</macro>";
+}
--- /dev/null
+#ifndef _H_XMLMACRO_
+#define _H_XMLMACRO_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+
+// our includes
+#include "XMLAttrs.h"
+
+// forward class definitions
+class XMLSpec;
+
+using namespace std;
+
+//<macro ...>
+class XMLMacro : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Creates an XMLMacro object
+ * .
+ * @param pAttrs XML tag attributes
+ * @param szMacro The macro contents
+ * @param pSpec the spec to add the macro to
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ const char* szMacro,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName The name of the macro
+ * @param szMacro The expanded macro
+ * @return none
+ **/
+ XMLMacro(const char* szName,
+ const char* szMacro);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rMacro the macro to copy
+ * @return none
+ **/
+ XMLMacro(const XMLMacro& rMacro);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLMacro();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param macro The macro to copy
+ * @return our copied object
+ **/
+ XMLMacro operator=(XMLMacro macro);
+
+//
+// member functions
+//
+public:
+ /**
+ * Outputs the macro into an RPM spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Outputs the macro into an XML spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member get/set functions
+//
+public:
+ /**
+ * Gets the macro name
+ * .
+ * @param none
+ * @return string containing the macro name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Gets tha macro value
+ * .
+ * @param none
+ * @return string contatining the macro value
+ **/
+ const char* getValue()
+ {
+ return m_sValue.c_str();
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sName;
+ string m_sValue;
+};
+
+#endif
--- /dev/null
+// our includes
+#include "XMLMirror.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+// attribute structure for XMLMirror
+structValidAttrs g_paMirrorAttrs[] =
+{
+ {0x0000, true, false, "path"},
+ {0x0001, false, false, "description"},
+ {0x0002, false, false, "country"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLMirror::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec,
+ bool bPatch)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paMirrorAttrs, (XMLBase*)pSpec))
+ return false;
+
+ XMLMirror mirror(pAttrs->get("path"),
+ pAttrs->get("description"),
+ pAttrs->get("country"));
+ if (bPatch && pSpec->numPatches())
+ pSpec->lastPatch().addMirror(mirror);
+ else if (!bPatch && pSpec->numSources())
+ pSpec->lastSource().addMirror(mirror);
+ return true;
+}
+
+XMLMirror::XMLMirror(const char* szPath,
+ const char* szDescription,
+ const char* szCountry) : XMLBase()
+{
+ if (szPath)
+ m_sPath.assign(szPath);
+ if (szDescription)
+ m_sDescription.assign(szDescription);
+ if (szCountry)
+ m_sCountry.assign(szCountry);
+}
+
+XMLMirror::XMLMirror(const XMLMirror& rMirror)
+ : XMLBase()
+{
+ m_sPath.assign(rMirror.m_sPath);
+ m_sDescription.assign(rMirror.m_sDescription);
+ m_sCountry.assign(rMirror.m_sCountry);
+}
+
+XMLMirror::~XMLMirror()
+{
+}
+
+XMLMirror XMLMirror::operator=(XMLMirror mirror)
+{
+ m_sPath.assign(mirror.m_sPath);
+ m_sDescription.assign(mirror.m_sDescription);
+ m_sCountry.assign(mirror.m_sCountry);
+}
+
+void XMLMirror::toSpecFile(ostream& rOut)
+{
+ rOut << endl << "# mirror: " << getPath();
+}
+
+void XMLMirror::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t\t<mirror path=\"" << getPath() << "\"";
+ if (hasDescription())
+ rOut << endl << "\t\t description=\"" << getDescription() << "\"";
+ if (hasCountry())
+ rOut << endl << "\t\t country=\"" << getCountry() << "\"";
+ rOut << " />";
+}
--- /dev/null
+#ifndef _H_XMLMIRROR_
+#define _H_XMLMIRROR_
+
+// standard C++ includes
+#include <string>
+#include <vector>
+#include <iostream>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+
+// forward declaration
+class XMLSpec;
+
+using namespace std;
+
+// <mirror ...>
+class XMLMirror : public XMLBase
+{
+//
+// static object creation functions
+//
+public:
+ /**
+ * static function for creation of an XMLMirror object
+ * .
+ * @param pAttrs Pointer to our attribute structure
+ * @param pSpec Pointer to our spec that is to ultimately
+ * contain the object
+ * @param bPatch true if we are handling the mirror for a patch
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec,
+ bool bPatch = false);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor for the XMLMirror object
+ * .
+ * @param szPath Full path for the mirror
+ * @param szDescription Full mirror description
+ * @param szCoutry Country code for the mirror
+ * @return none
+ **/
+ XMLMirror(const char* szPath,
+ const char* szDescription,
+ const char* szCountry);
+
+ /**
+ * Copy contructor
+ * .
+ * @param rMirror Reference to the object to copy
+ * @return none
+ **/
+ XMLMirror(const XMLMirror& rMirror);
+
+ /**
+ * Destructor for an XMLMirror object
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLMirror();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param mirror The mirror to get the values from
+ * @return The modified object
+ **/
+ XMLMirror operator=(XMLMirror mirror);
+
+//
+// public member functions
+//
+public:
+ /**
+ * Converts an XMLMirror object to a RPM spec file
+ * .
+ * @param rOut File stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts an XMLMirror object to an XML spec file
+ * .
+ * @param rOut File stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Checks if we have a path
+ * .
+ * @param none
+ * @return true if we have a path, false otherise
+ **/
+ bool hasPath()
+ {
+ return m_sPath.length() ? true : false;
+ }
+
+ /**
+ * Returns the path
+ * .
+ * @param none
+ * @return The path strinbg
+ **/
+ const char* getPath()
+ {
+ return m_sPath.c_str();
+ }
+
+ /**
+ * Checks if we have a description set
+ * .
+ * @param none
+ * @return true is we have a description, false otherwise
+ **/
+ bool hasDescription()
+ {
+ return m_sDescription.length() ? true : false;
+ }
+
+ /**
+ * Returns the description
+ * .
+ * @param none
+ * @return the description string
+ **/
+ const char* getDescription()
+ {
+ return m_sDescription.c_str();
+ }
+
+ /**
+ * Checks if we have a country set
+ * .
+ * @param none
+ * @return true if we have a country, false otherwise
+ **/
+ bool hasCountry()
+ {
+ return m_sCountry.length() ? true : false;
+ }
+
+ /**
+ * Gets the country
+ * .
+ * @param none
+ * @return The country string
+ **/
+ const char* getCountry()
+ {
+ return m_sCountry.c_str();
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sPath;
+ string m_sDescription;
+ string m_sCountry;
+};
+
+#endif
--- /dev/null
+// standard C++ includes
+#include <string>
+
+// our includes
+#include "XMLPackage.h"
+#include "XMLSpec.h"
+
+// attribute structure for XMLPackage
+structValidAttrs g_paPackageAttrs[] =
+{
+ {0x0000, false, false, "name"},
+ {0x0001, false, false, "group"},
+ {0x0002, false, false, "sub"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLPackage::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paPackageAttrs, (XMLBase*)pSpec))
+ return false;
+
+ // setup the name attribute
+ string sName;
+ if (pAttrs->get("name"))
+ sName.assign(pAttrs->get("name"));
+
+ // is this something else but a sub-package
+ bool bSub = true;
+ if (pAttrs->get("sub"))
+ if (strcasecmp(pAttrs->get("sub"), "no") == 0)
+ bSub = false;
+
+ // if we have a name, cool, now test if the package already exists
+ if (sName.length()) {
+ XMLPackage package(sName.c_str(),
+ pAttrs->get("group"),
+ bSub);
+ pSpec->addPackage(package);
+ }
+
+ // already something existing with %{name} ?
+ else {
+ XMLPackage package(NULL,
+ pAttrs->get("group"),
+ bSub);
+ pSpec->addPackage(package);
+ }
+ return true;
+}
+
+bool XMLPackage::setDescription(const char* szDescription,
+ XMLSpec* pSpec)
+{
+ if (pSpec) {
+ pSpec->lastPackage().setDescription(szDescription);
+ return true;
+ }
+ else
+ return false;
+}
+
+bool XMLPackage::setSummary(const char* szSummary,
+ XMLSpec* pSpec)
+{
+ if (pSpec) {
+ pSpec->lastPackage().setSummary(szSummary);
+ return true;
+ }
+ else
+ return false;
+}
+
+XMLPackage::XMLPackage(const char* szName,
+ const char* szGroup,
+ bool bSub)
+ : XMLBase()
+{
+ if (szName)
+ m_sName.assign(szName);
+ if (szGroup)
+ m_sGroup.assign(szGroup);
+ m_bSub = bSub;
+}
+
+XMLPackage::XMLPackage(const XMLPackage& rPackage)
+ : XMLBase()
+{
+ m_sName.assign(rPackage.m_sName);
+ m_sGroup.assign(rPackage.m_sGroup);
+ m_sSummary.assign(rPackage.m_sSummary);
+ m_sDescription.assign(rPackage.m_sDescription);
+ m_bSub = rPackage.m_bSub;
+ m_Requires = rPackage.m_Requires;
+ m_BuildRequires = rPackage.m_BuildRequires;
+ m_Provides = rPackage.m_Provides;
+ m_Obsoletes = rPackage.m_Obsoletes;
+ m_Post = rPackage.m_Post;
+ m_PostUn = rPackage.m_PostUn;
+ m_Pre = rPackage.m_Pre;
+ m_PreUn = rPackage.m_PreUn;
+ m_Verify = rPackage.m_Verify;
+ m_Files = rPackage.m_Files;
+}
+
+XMLPackage::~XMLPackage()
+{
+}
+
+void XMLPackage::toSpecFile(ostream& rOut)
+{
+ // top package bit
+ if (hasName()) {
+ rOut << endl << "%package";
+ rOut << (!isSubPackage() ? " -n " : " ") << getName() << endl;
+ }
+ else
+ rOut << endl << endl;
+
+ // add the summary
+ if (hasSummary())
+ rOut << "summary: " << getSummary() << endl;
+
+ // do we have a group?
+ if (hasGroup())
+ rOut << "group: " << getGroup() << endl;
+
+ getProvides().toSpecFile(rOut, "provides");
+ getObsoletes().toSpecFile(rOut, "obsoletes");
+ getRequires().toSpecFile(rOut, "requires");
+ getBuildRequires().toSpecFile(rOut, "buildrequires");
+
+ // add the description
+ if (hasDescription()) {
+ rOut << "%description ";
+ if (hasName()) {
+ rOut << (!isSubPackage() ? "-n " : "");
+ rOut << getName();
+ }
+ rOut << endl << getDescription() << endl;
+ }
+}
+
+void toSectionSpecFile(ostream& rOut,
+ const char* szSection,
+ XMLPackage* pPkg)
+{
+ rOut << endl << "%" << szSection;
+ if (pPkg->hasName())
+ rOut << (!pPkg->isSubPackage() ? " -n " : " ") << pPkg->getName();
+ rOut << endl;
+}
+
+void XMLPackage::toScriptsSpecFile(ostream& rOut)
+{
+ if (getPre().numScripts()) {
+ toSectionSpecFile(rOut, "pre", this);
+ getPre().toSpecFile(rOut, "pre");
+ }
+
+ if (getPost().numScripts()) {
+ toSectionSpecFile(rOut, "post", this);
+ getPost().toSpecFile(rOut, "post");
+ }
+
+ if (getPreUn().numScripts()) {
+ toSectionSpecFile(rOut, "preun", this);
+ getPreUn().toSpecFile(rOut, "preun");
+ }
+
+ if (getPostUn().numScripts()) {
+ toSectionSpecFile(rOut, "postun", this);
+ getPostUn().toSpecFile(rOut, "postun");
+ }
+
+ if (getVerify().numScripts()) {
+ toSectionSpecFile(rOut, "verifyscript", this);
+ getVerify().toSpecFile(rOut, "verifyscript");
+ }
+}
+
+void XMLPackage::toFilesSpecFile(ostream& rOut)
+{
+ rOut << endl << "%files";
+ if (hasName())
+ rOut << (!isSubPackage() ? " -n " : " ") << getName();
+ rOut << endl;
+ getFiles().toSpecFile(rOut);
+}
+
+void XMLPackage::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t<package";
+ if (hasName()) {
+ rOut << " name=\"" << getName() << "\"";
+ if (!isSubPackage())
+ rOut << " sub=\"no\"";
+ }
+ if (hasGroup())
+ rOut << " group=\"" << getGroup() << "\"";
+ rOut << ">";
+ if (hasSummary())
+ rOut << endl << "\t\t<summary>" << getSummary() << "\t\t</summary>";
+ if (hasDescription())
+ rOut << endl << "\t\t<description>" << getDescription() << "\t\t</description>";
+
+ getProvides().toXMLFile(rOut, "provides");
+ getObsoletes().toXMLFile(rOut, "obsoletes");
+ getRequires().toXMLFile(rOut, "requires");
+ getBuildRequires().toXMLFile(rOut, "buildrequires");
+
+ getPre().toXMLFile(rOut, "pre");
+ getPost().toXMLFile(rOut, "post");
+ getPreUn().toXMLFile(rOut, "preun");
+ getPostUn().toXMLFile(rOut, "postun");
+ getVerify().toXMLFile(rOut, "verify");
+
+ getFiles().toXMLFile(rOut);
+
+ rOut << endl << "\t</package>";
+}
+
+void XMLPackage::toRPMStruct(Spec spec)
+{
+ //Package pkg = newPackage(spec);
+ //if (!hasName() && pkg == spec->packages)
+ // fillOutMainPackage(pkg->header);
+ //else if (pkg != spec->packages)
+ // headerCopyTags(spec->packages->header,
+ // pkg->header,
+ // (int_32 *)copyTagsDuringParse);
+}
--- /dev/null
+#ifndef _H_XMLPACKAGE_
+#define _H_XMLPACKAGE_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+#include "XMLFiles.h"
+#include "XMLRequires.h"
+#include "XMLScript.h"
+
+// rpm includes
+#include <rpmbuild.h>
+
+// forward class declarations
+class XMLSpec;
+
+using namespace std;
+
+class XMLPackage : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Creates an object as parsed from an XML spec
+ * .
+ * @param pAttrs XML atrtributes to use
+ * @param pSpec The spec to which we are adding this object to
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+ /**
+ * Sets the description for the last package
+ * .
+ * @param szDescription the description
+ * @param pSpec The spec containing the package
+ * @return true on success, false otherwise
+ **/
+ static bool setDescription(const char* szDescription,
+ XMLSpec* pSpec);
+
+ /**
+ * Sets the summary for the last added package
+ * .
+ * @param szSummary The summary to set
+ * @param pSpec The spec contraining the package
+ * @return trus on success, false otherwise
+ **/
+ static bool setSummary(const char* szSummary,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructors
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName The package name
+ * @param szGroup The group this package belongs to
+ * @param bSub true if this is a sub-package
+ * @return none
+ **/
+ XMLPackage(const char* szName,
+ const char* szGroup,
+ bool bSub);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rPackage The package to copy from
+ * @return none
+ **/
+ XMLPackage(const XMLPackage& rPackage);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLPackage();
+
+//
+// public member functions
+//
+public:
+ /**
+ * Converts the object to a spec file
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the scripts part of the object to a spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toScriptsSpecFile(ostream& rOut);
+
+ /**
+ * Converts the files part of the object to a spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toFilesSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object to an XML spec
+ * .
+ * @param rOut The output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the object to an RPM structure
+ * .
+ * @param Spec The main Spec object
+ * @param none
+ **/
+ void toRPMStruct(Spec spec);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Checks of we have a package name
+ * .
+ * @param none
+ * @return true if we have a name, false otherwise
+ **/
+ bool hasName()
+ {
+ return m_sName.length() ? true : false;
+ }
+
+ /**
+ * Gets the package name
+ * .
+ * @param none
+ * @return string containing the package name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Checks if we have a group
+ * .
+ * @param none
+ * @return true if we have a group, false otherwise
+ **/
+ bool hasGroup()
+ {
+ return m_sGroup.length() ? true : false;
+ }
+
+ /**
+ * Returns the group
+ * .
+ * @param none
+ * @return string containing the group
+ **/
+ const char* getGroup()
+ {
+ return m_sGroup.c_str();
+ }
+
+ /**
+ * Tests if we are a sub-package
+ * .
+ * @param none
+ * @return true if this is a sub-package
+ **/
+ bool isSubPackage()
+ {
+ return m_bSub;
+ }
+
+ /**
+ * Checks if we have a summary
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasSummary()
+ {
+ return m_sSummary.length() ? true : false;
+ }
+
+ /**
+ * Gets the summary
+ * .
+ * @param none
+ * @return the summary string
+ **/
+ const char* getSummary()
+ {
+ return m_sSummary.c_str();
+ }
+
+ /**
+ * Set the summary
+ * .
+ * @param szSummary the summary
+ * @return none
+ **/
+ void setSummary(const char* szSummary)
+ {
+ if (szSummary)
+ m_sSummary.assign(szSummary);
+ }
+
+ /**
+ * Checks if we have a description
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasDescription()
+ {
+ return m_sDescription.length() ? true : false;
+ }
+
+ /**
+ * Get the description
+ * .
+ * @param none
+ * @return string containing the description
+ **/
+ const char* getDescription()
+ {
+ return m_sDescription.c_str();
+ }
+
+ /**
+ * Sets the description
+ * .
+ * @param szDescription The description string
+ * @return nonew
+ **/
+ void setDescription(const char* szDescription)
+ {
+ if (szDescription)
+ m_sDescription.assign(szDescription);
+ }
+
+ /**
+ * Gets the provides
+ * .
+ * @param none
+ * @return reference to the provides
+ **/
+ XMLPackageContainer& getProvides()
+ {
+ return m_Provides;
+ }
+
+ /**
+ * Gets the package requires
+ * .
+ * @param none
+ * @return reference to the requires
+ **/
+ XMLPackageContainer& getRequires()
+ {
+ return m_Requires;
+ }
+
+ /**
+ * Get the buildrequires
+ * .
+ * @param none
+ * @return reference to the buildrequires
+ **/
+ XMLPackageContainer& getBuildRequires()
+ {
+ return m_BuildRequires;
+ }
+
+ /**
+ * Gets the obsoletes
+ * .
+ * @param none
+ * @return reference to the obsoletes
+ **/
+ XMLPackageContainer& getObsoletes()
+ {
+ return m_Obsoletes;
+ }
+
+ /**
+ * Gets the files
+ * .
+ * @param none
+ * @return reference to the files
+ **/
+ XMLFiles& getFiles()
+ {
+ return m_Files;
+ }
+
+ /**
+ * Gets the pre section
+ * .
+ * @param none
+ * @return reference to the pre section
+ **/
+ XMLPackageScripts& getPre()
+ {
+ return m_Pre;
+ }
+
+ /**
+ * Gets the post section
+ * .
+ * @param none
+ * @return reference to the post section
+ **/
+ XMLPackageScripts& getPost()
+ {
+ return m_Post;
+ }
+
+ /**
+ * Gets the preun section
+ * .
+ * @param none
+ * @return reference to the preun section
+ **/
+ XMLPackageScripts& getPreUn()
+ {
+ return m_PreUn;
+ }
+
+ /**
+ * Gets the postun section
+ * .
+ * @param none
+ * @return reference to the postun section
+ **/
+ XMLPackageScripts& getPostUn()
+ {
+ return m_PostUn;
+ }
+
+ /**
+ * Gets the verify section
+ * .
+ * @param none
+ * @return reference to the verify section
+ **/
+ XMLPackageScripts& getVerify()
+ {
+ return m_Verify;
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sName;
+ string m_sGroup;
+ string m_sSummary;
+ string m_sDescription;
+ bool m_bSub;
+ XMLPackageContainer m_Requires;
+ XMLPackageContainer m_BuildRequires;
+ XMLPackageContainer m_Provides;
+ XMLPackageContainer m_Obsoletes;
+ XMLPackageScripts m_Pre;
+ XMLPackageScripts m_PreUn;
+ XMLPackageScripts m_Post;
+ XMLPackageScripts m_PostUn;
+ XMLPackageScripts m_Verify;
+ XMLFiles m_Files;
+};
+
+#endif
--- /dev/null
+// standard library includes
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+// standard C++ includes
+#include <fstream>
+#include <string>
+
+// 3rd party library includes
+#include <expat.h>
+
+// our includes
+#include "XMLSpec.h"
+
+// this is the maximum tree dept we will require as
+// well as the number of scructures a specific tag can
+// occur in
+#define XML_MAX_TREE_DEPTH 5
+#define XML_MAX_PRE_TAGS 10
+
+using namespace std;
+
+// these define the error values
+enum eXMLErr
+{
+ XMLERR_WARNING = 0x0000,
+ XMLERR_ERROR,
+ XMLERR_FATAL
+};
+
+// this defines the structure that we are using in the callback
+// containing all the parse-specific data we might need.
+struct structCBData
+{
+ XML_Parser* m_pParser;
+ string m_sFilename;
+ int m_nWarnings;
+ int m_nErrors;
+ int m_nDepth;
+ unsigned int m_pnTree[XML_MAX_TREE_DEPTH];
+ string m_sData;
+ XMLSpec* m_pSpec;
+ XMLAttrs* m_pAttrs;
+};
+
+// enumeration of all XML tags that are recognised
+enum enumXMLTAGValid
+{
+ XTAG_NO = 0x0000,
+ XTAG_WRONGSTRUCT,
+ XTAG_SPEC,
+ XTAG_SOURCE,
+ XTAG_PATCH,
+ XTAG_NOSOURCE,
+ XTAG_MIRROR,
+ XTAG_PACKAGE,
+ XTAG_SUMMARY,
+ XTAG_DESC,
+ XTAG_REQS,
+ XTAG_BREQS,
+ XTAG_PROVS,
+ XTAG_OBSOLS,
+ XTAG_FILES,
+ XTAG_FILE,
+ XTAG_MACRO,
+ XTAG_PREP,
+ XTAG_SETUP,
+ XTAG_BUILD,
+ XTAG_INSTALL,
+ XTAG_CLEAN,
+ XTAG_PRE,
+ XTAG_POST,
+ XTAG_PREUN,
+ XTAG_POSTUN,
+ XTAG_VERIFY,
+ XTAG_SCRIPT,
+ XTAG_CHANGELOG,
+ XTAG_CHANGES,
+ XTAG_CHANGE,
+ XTAG_ANY = 0xFFFF // this always needs to be the last entry
+};
+
+// this is a structure to match tags to their values
+struct structXMLMatch
+{
+ unsigned int m_nVal;
+ int m_pnDepth[XML_MAX_TREE_DEPTH+1];
+ unsigned int m_pnFollows[XML_MAX_PRE_TAGS+1];
+ char* m_szName;
+};
+
+// this allows for the matching of all tags
+structXMLMatch g_pMatches[] =
+{
+ {
+ XTAG_SPEC, { 0, -1, -1}, {
+ XTAG_ANY,
+ XTAG_NO
+ },
+ "spec"
+ },
+ {
+ XTAG_PACKAGE, { 1, 3, -1}, {
+ XTAG_SPEC,
+ XTAG_REQS,
+ XTAG_BREQS,
+ XTAG_PROVS,
+ XTAG_OBSOLS,
+ XTAG_NO
+ },
+ "package"
+ },
+ {
+ XTAG_SOURCE, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "source"
+ },
+ {
+ XTAG_PATCH, { 1, 2, -1}, {
+ XTAG_SPEC,
+ XTAG_PREP,
+ XTAG_NO
+ },
+ "patch"
+ },
+ {
+ XTAG_NOSOURCE, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "nosource"
+ },
+ {
+ XTAG_MIRROR, { 2, -1, -1}, {
+ XTAG_SOURCE,
+ XTAG_NO
+ },
+ "mirror"
+ },
+ {
+ XTAG_SUMMARY, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "summary"
+ },
+ {
+ XTAG_DESC, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "description"
+ },
+ {
+ XTAG_REQS, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "requires"
+ },
+ {
+ XTAG_BREQS, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "buildrequires"
+ },
+ {
+ XTAG_PROVS, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "provides"
+ },
+ {
+ XTAG_OBSOLS, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "obsoletes"
+ },
+ {
+ XTAG_FILES, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "files"
+ },
+ {
+ XTAG_FILE, { 3, -1, -1}, {
+ XTAG_FILES,
+ XTAG_NO
+ },
+ "file"
+ },
+ {
+ XTAG_MACRO, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "macro"
+ },
+ {
+ XTAG_PREP, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "prep"
+ },
+ {
+ XTAG_SETUP, { 2, -1, -1}, {
+ XTAG_PREP,
+ XTAG_NO
+ },
+ "setup"
+ },
+ {
+ XTAG_BUILD, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "build"
+ },
+ {
+ XTAG_INSTALL, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "install"
+ },
+ {
+ XTAG_CLEAN, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "clean"
+ },
+ {
+ XTAG_PRE, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "pre"
+ },
+ {
+ XTAG_POST, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "post"
+ },
+ {
+ XTAG_PREUN, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "preun"
+ },
+ {
+ XTAG_POSTUN, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "postun"
+ },
+ {
+ XTAG_VERIFY, { 2, -1, -1}, {
+ XTAG_PACKAGE,
+ XTAG_NO
+ },
+ "verify"
+ },
+ {
+ XTAG_SCRIPT, { 2, 3, -1}, {
+ XTAG_PREP,
+ XTAG_BUILD,
+ XTAG_INSTALL,
+ XTAG_CLEAN,
+ XTAG_PRE,
+ XTAG_POST,
+ XTAG_PREUN,
+ XTAG_POSTUN,
+ XTAG_VERIFY,
+ XTAG_NO
+ },
+ "script"
+ },
+ {
+ XTAG_CHANGELOG, { 1, -1, -1}, {
+ XTAG_SPEC,
+ XTAG_NO
+ },
+ "changelog"
+ },
+ {
+ XTAG_CHANGES, { 2, -1, -1}, {
+ XTAG_CHANGELOG,
+ XTAG_NO
+ },
+ "changes"
+ },
+ {
+ XTAG_CHANGE, { 3, -1, -1}, {
+ XTAG_CHANGES,
+ XTAG_NO
+ },
+ "change"
+ },
+ // this always needs to be the last entry
+ {
+ XTAG_NO, {-1, -1, -1}, {
+ XTAG_NO
+ },
+ "none"
+ }
+};
+
+const char* treeToString(unsigned int* pnTree,
+ int nDepth)
+{
+ // internal string storage
+ string sTree;
+
+ // build the tree to the specified depth
+ for (int i = 0; i < nDepth; i++) {
+ int j = 0;
+ while (g_pMatches[j].m_nVal != pnTree[i])
+ j++;
+ sTree += string("<") + string(g_pMatches[j].m_szName) + string(">");
+ }
+
+ // return the tree string
+ return sTree.c_str();
+}
+
+unsigned int getTagValue(const char* szElement,
+ int nDepth,
+ unsigned int nPrev)
+{
+ // first convert the tag to a tag value
+ unsigned int nTagVal = XTAG_NO;
+
+ // loop through all matches to see if we have a valid
+ // tag here
+ int i = 0;
+ do {
+ // test if we have a match
+ if (strcasecmp(g_pMatches[i].m_szName, szElement) == 0) {
+ // look for a match on the tree depth
+ int j = 0;
+ nTagVal = XTAG_WRONGSTRUCT;
+ while (g_pMatches[i].m_pnDepth[j] != -1) {
+ if (g_pMatches[i].m_pnDepth[j++] == nDepth) {
+ j = 0;
+ do {
+ if (g_pMatches[i].m_pnFollows[j] == nPrev) {
+ nTagVal = g_pMatches[i].m_nVal;
+ break;
+ }
+ } while (g_pMatches[i].m_pnFollows[++j] != XTAG_NO);
+ break;
+ }
+ }
+ // break out
+ break;
+ }
+ } while (g_pMatches[++i].m_nVal != XTAG_NO);
+
+ // return
+ return nTagVal;
+}
+
+void createError(int nErrType,
+ structCBData* pData,
+ const char* szFormat, ...)
+{
+ // one more error/warning
+ nErrType == XMLERR_WARNING ? pData->m_nWarnings++ : pData->m_nErrors++;
+
+ // setup internal variables
+ FILE* fOut = stderr;
+ switch (nErrType) {
+ case XMLERR_WARNING:
+ fOut = stdout;
+ fprintf(fOut, "%s(%d): warning: ", pData->m_sFilename.c_str(),
+ XML_GetCurrentLineNumber(*(pData->m_pParser)));
+ break;
+ case XMLERR_ERROR:
+ fprintf(fOut, "%s(%d): error: ", pData->m_sFilename.c_str(),
+ XML_GetCurrentLineNumber(*(pData->m_pParser)));
+ break;
+ case XMLERR_FATAL:
+ fprintf(fOut, "%s(%d): fatal: ", pData->m_sFilename.c_str(),
+ XML_GetCurrentLineNumber(*(pData->m_pParser)));
+ break;
+ default:
+ return;
+ }
+
+ // create the argument list and print
+ va_list vaArgList;
+ va_start(vaArgList, szFormat);
+ vfprintf(fOut, szFormat, vaArgList);
+ fprintf(fOut, "\n");
+}
+
+void startDepth0(structCBData* pData)
+{
+ // this indicates a spec start
+ if (pData->m_pnTree[0] == XTAG_SPEC) {
+ // if we have a spec already, we are in trouble
+ if (pData->m_pSpec)
+ createError(XMLERR_ERROR, pData, "Extra 'spec' tag found.");
+ else if (!(pData->m_pSpec = XMLSpec::parseCreate(pData->m_pAttrs,
+ pData->m_sFilename.c_str())))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'spec' tag (%s).",
+ pData->m_pAttrs->getError());
+ else if (pData->m_pAttrs->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pAttrs->getWarning());
+ }
+}
+
+void startDepth1(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // hanlde tag
+ switch (pData->m_pnTree[1]) {
+ case XTAG_PACKAGE:
+ if (!XMLPackage::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'package' tag or package already exists (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_SOURCE:
+ if (!XMLSource::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'source' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_PATCH:
+ if (!XMLPatch::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'patch' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_NOSOURCE:
+ if (!XMLNoSource::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'nosource' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_CHANGELOG:
+ case XTAG_PREP:
+ case XTAG_BUILD:
+ case XTAG_INSTALL:
+ case XTAG_CLEAN:
+ default:
+ break;
+ }
+}
+
+void startDepth2(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // handle tag
+ switch (pData->m_pnTree[2]) {
+ case XTAG_MIRROR:
+ switch (pData->m_pnTree[1]) {
+ case XTAG_SOURCE:
+ if (!XMLMirror::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'mirror' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_PATCH:
+ if (!XMLMirror::parseCreate(pData->m_pAttrs, pData->m_pSpec, true))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'mirror' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ }
+ break;
+ case XTAG_FILES:
+ if (!XMLFiles::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'change' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_CHANGES:
+ if (!XMLChangelogDate::parseCreate(pData->m_pAttrs, pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'change' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_REQS:
+ case XTAG_BREQS:
+ case XTAG_PROVS:
+ case XTAG_OBSOLS:
+ default:
+ break;
+ }
+}
+
+void startDepth3(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // handle tag
+ switch (pData->m_pnTree[3]) {
+ case XTAG_PACKAGE:
+ switch (pData->m_pnTree[2]) {
+ case XTAG_REQS:
+ if (!XMLPackageContainer::addRequire(pData->m_pAttrs,
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'package' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_BREQS:
+ if (!XMLPackageContainer::addBuildRequire(pData->m_pAttrs,
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'package' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_PROVS:
+ if (!XMLPackageContainer::addProvide(pData->m_pAttrs,
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'package' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_OBSOLS:
+ if (!XMLPackageContainer::addObsolete(pData->m_pAttrs,
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'package' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void startElementCB(void* pCBData,
+ const char* szElement,
+ const char** szAttr)
+{
+ // get the data structure we are working with and
+ structCBData* pData = (structCBData*)pCBData;
+
+ // validate and get the tag we are working with
+ unsigned int nTag = getTagValue(szElement,
+ pData->m_nDepth,
+ pData->m_nDepth ? pData->m_pnTree[pData->m_nDepth-1] : XTAG_ANY);
+
+ if (nTag == XTAG_NO || nTag == XTAG_WRONGSTRUCT)
+ return createError(XMLERR_WARNING, pData, "Unexpected tag '%s' in structure '%s'.",
+ szElement,
+ treeToString(pData->m_pnTree, pData->m_nDepth++));
+ pData->m_pnTree[pData->m_nDepth] = nTag;
+ pData->m_sData.assign("");
+
+ if (pData->m_pAttrs)
+ delete pData->m_pAttrs;
+ pData->m_pAttrs = new XMLAttrs(szAttr);
+
+ switch (pData->m_nDepth++) {
+ case 0:
+ startDepth0(pData);
+ break;
+ case 1:
+ startDepth1(pData);
+ break;
+ case 2:
+ startDepth2(pData);
+ break;
+ case 3:
+ startDepth3(pData);
+ break;
+ default:
+ break;
+ }
+}
+
+void endDepth1(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // handle tag
+ switch (pData->m_pnTree[1]) {
+ case XTAG_MACRO:
+ if (!XMLMacro::parseCreate(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add macro entry (%s).",
+ pData->m_pAttrs->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ default:
+ break;
+ }
+}
+
+void endDepth2(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // do the tag
+ switch (pData->m_pnTree[2]) {
+ case XTAG_SUMMARY:
+ if (!XMLPackage::setSummary(pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add 'summary'.");
+ break;
+ case XTAG_DESC:
+ if (!XMLPackage::setDescription(pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add 'description'.");
+ break;
+ case XTAG_SCRIPT:
+ switch (pData->m_pnTree[1]) {
+ case XTAG_PREP:
+ if (!XMLScripts::addPrepScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add shell entry.");
+ break;
+ case XTAG_BUILD:
+ if (!XMLScripts::addBuildScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add shell entry.");
+ break;
+ case XTAG_INSTALL:
+ if (!XMLScripts::addInstallScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add shell entry.");
+ break;
+ case XTAG_CLEAN:
+ if (!XMLScripts::addCleanScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add shell entry.");
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void endDepth3(structCBData* pData)
+{
+ // make sure we have a spec
+ if (!pData->m_pSpec) {
+ createError(XMLERR_ERROR, pData, "Spec has not been defined.");
+ return;
+ }
+
+ // handle tag
+ switch (pData->m_pnTree[3]) {
+ case XTAG_CHANGE:
+ if (!XMLChangelogEntry::parseCreate(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to add changelog entry.");
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_FILE:
+ if (!XMLFile::parseCreate(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData, "Failed to parse 'file' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning());
+ break;
+ case XTAG_SCRIPT:
+ switch (pData->m_pnTree[2]) {
+ case XTAG_PRE:
+ if (!XMLPackageScripts::addPreScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'script' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_POST:
+ if (!XMLPackageScripts::addPostScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'script' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_PREUN:
+ if (!XMLPackageScripts::addPreUnScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'script' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_POSTUN:
+ if (!XMLPackageScripts::addPostUnScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'script' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ case XTAG_VERIFY:
+ if (!XMLPackageScripts::addVerifyScript(pData->m_pAttrs,
+ pData->m_sData.c_str(),
+ pData->m_pSpec))
+ createError(XMLERR_ERROR, pData,
+ "Failed to parse 'script' tag (%s).",
+ pData->m_pSpec->getError());
+ else if (pData->m_pSpec->hasWarning())
+ createError(XMLERR_WARNING, pData,
+ pData->m_pSpec->getWarning());
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void endElementCB(void* pCBData,
+ const char* szElement)
+{
+ // get the data structure we are working with
+ structCBData* pData = (structCBData*)pCBData;
+ pData->m_nDepth--;
+
+ // validate and get the tag we are working with
+ unsigned int nTag = getTagValue(szElement,
+ pData->m_nDepth,
+ pData->m_nDepth ? pData->m_pnTree[pData->m_nDepth-1] : XTAG_ANY);
+ if (nTag == XTAG_NO || nTag == XTAG_WRONGSTRUCT)
+ return;
+
+ // handle the tree depth
+ switch (pData->m_nDepth) {
+ case 0:
+ break;
+ case 1:
+ endDepth1(pData);
+ break;
+ case 2:
+ endDepth2(pData);
+ break;
+ case 3:
+ endDepth3(pData);
+ break;
+ default:
+ break;
+ }
+
+ // clean up
+ pData->m_sData.assign("");
+}
+
+void characterCB(void* pCBData,
+ const char* szStr,
+ int nLen)
+{
+ // get the data structure we are working with
+ structCBData* pData = (structCBData*)pCBData;
+
+ // append the string to our internal data
+ if (nLen) {
+ char* szTmp = new char[nLen+1];
+ strncpy(szTmp, szStr, nLen);
+ szTmp[nLen] = '\0';
+ pData->m_sData.append(szTmp);
+ delete[] szTmp;
+ }
+}
+
+int parseXMLSpec(const char* szXMLFilename,
+ XMLSpec*& pSpec)
+{
+ // create and setup our parser for use
+ printf("Creating XML parser instance ... ");
+ XML_Parser parser = XML_ParserCreate(NULL);
+ if (!parser) {
+ printf("Failed.\n\tERROR: Couldn't allocate memory for parser\n\n");
+ return -1;
+ }
+ else
+ printf("Ok.\n");
+ XML_SetElementHandler(parser, startElementCB, endElementCB);
+ XML_SetCharacterDataHandler(parser, characterCB);
+ structCBData stData;
+ stData.m_pParser = &parser;
+ stData.m_sFilename.assign(szXMLFilename);
+ stData.m_nWarnings = 0;
+ stData.m_nErrors = 0;
+ stData.m_nDepth = 0;
+ stData.m_pSpec = NULL;
+ stData.m_pAttrs = NULL;
+ XML_SetUserData(parser, (void*)&stData);
+
+ // open the input and output files here
+ printf("Opening input XML spec ... ");
+ ifstream fIn(szXMLFilename);
+ if (!fIn.is_open()) {
+ printf("Failed.\n\tERROR: Could not open %s\n\n", szXMLFilename);
+ return -2;
+ }
+ else
+ printf("Ok.\n");
+
+ // parse our configuration (loop through file,
+ // doing a break if needed (fatal error))
+ printf("Parsing %s: \n", szXMLFilename);
+ char szBuff[1024+1];
+ unsigned int nLength = 0;
+ while (!fIn.eof()) {
+ fIn.get(szBuff, 1024, '\0');
+ unsigned int nRead = strlen(szBuff);
+ nLength += nRead;
+ if (!XML_Parse(parser, szBuff, nRead, fIn.eof() ? 1 : 0)) {
+ createError(XMLERR_FATAL, &stData, "XML parsing: %s",
+ XML_ErrorString(XML_GetErrorCode(parser)));
+ break;
+ }
+ }
+
+ // print the end results
+ printf("\t%d bytes parsed, %d errors(s), %d warnings(s)\n",
+ nLength, stData.m_nErrors, stData.m_nWarnings);
+ printf("Closing input XML spec ... ");
+ fIn.close();
+ printf("Ok.\n");
+
+ // clean up
+ if (stData.m_nErrors) {
+ if (stData.m_pSpec != NULL)
+ delete stData.m_pSpec;
+ pSpec = NULL;
+ }
+ else
+ pSpec = stData.m_pSpec;
+
+ // return number of errors
+ return stData.m_nErrors;
+}
--- /dev/null
+#ifndef _H_XMLPARSER_
+#define _H_XMLPARSER_
+
+// our includes
+#include "XMLSpec.h"
+
+/**
+ * Parses an XML spec into the internal data structures as
+ * defined in the XML* classes.
+ * .
+ * @param szXMLFilename The Spec to read as parser input
+ * @param pSpec A reference to the spec data structure we
+ * are to fill.
+ * @return The number of parsing/other errors (0 == success)
+ **/
+extern int parseXMLSpec(const char* szXMLFilename,
+ XMLSpec*& pSpec);
+
+#endif
--- /dev/null
+// our includes
+#include "XMLAttrs.h"
+#include "XMLPackage.h"
+#include "XMLRequires.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+// attribute structure for XMLPackageEntry
+structValidAttrs g_paEntryAttrs[] =
+{
+ {0x0000, true, false, "name"},
+ {0x0001, false, false, "version"},
+ {0x0002, false, false, "cmp"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLPackageEntry::parseCreate(XMLAttrs* pAttrs,
+ XMLPackageContainer& rContainer)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paEntryAttrs, (XMLBase*)pAttrs))
+ return false;
+
+ // create and return
+ XMLPackageEntry entry(pAttrs->get("name"),
+ pAttrs->get("version"),
+ pAttrs->get("cmp"));
+ rContainer.addEntry(entry);
+ return true;
+}
+
+XMLPackageEntry::XMLPackageEntry(const char* szName,
+ const char* szVersion,
+ const char* szCmp)
+ : XMLBase()
+{
+ if (szName)
+ m_sName.assign(szName);
+ if (szVersion)
+ m_sVersion.assign(szVersion);
+ m_sCmp.assign("=");
+ if (szCmp) {
+ if (strcasecmp(szCmp, "lt") == 0)
+ m_sCmp.assign("<");
+ else if (strcasecmp(szCmp, "le") == 0)
+ m_sCmp.assign("<=");
+ else if (strcasecmp(szCmp, "gt") == 0)
+ m_sCmp.assign(">");
+ else if (strcasecmp(szCmp, "ge") == 0)
+ m_sCmp.assign(">=");
+ }
+}
+
+XMLPackageEntry::XMLPackageEntry(const XMLPackageEntry& rEntry)
+ : XMLBase()
+{
+ m_sName.assign(rEntry.m_sName);
+ m_sVersion.assign(rEntry.m_sVersion);
+ m_sCmp.assign(rEntry.m_sCmp);
+}
+
+XMLPackageEntry::~XMLPackageEntry()
+{
+}
+
+XMLPackageEntry XMLPackageEntry::operator=(XMLPackageEntry entry)
+{
+ m_sName.assign(entry.m_sName);
+ m_sVersion.assign(entry.m_sVersion);
+ m_sCmp.assign(entry.m_sCmp);
+ return *this;
+}
+
+void XMLPackageEntry::toSpecFile(ostream& rOut)
+{
+ rOut << getName();
+ if (hasVersion()) {
+ rOut << " " << getCompare() << " " << getVersion();
+ }
+}
+
+void XMLPackageEntry::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t\t\t<package name=\"" << getName() << "\"";
+ if (hasVersion()) {
+ if (m_sCmp.compare("=") == 0)
+ rOut << " cmp=\"eq\"";
+ else if (m_sCmp.compare("<") == 0)
+ rOut << " cmp=\"lt\"";
+ else if (m_sCmp.compare("<=") == 0)
+ rOut << " cmp=\"le\"";
+ else if (m_sCmp.compare(">") == 0)
+ rOut << " cmp=\"gt\"";
+ else if (m_sCmp.compare(">=") == 0)
+ rOut << " cmp=\"ge\"";
+ rOut << " version=\"" << getVersion() << "\"";
+ }
+ rOut << " />";
+}
+
+XMLPackageContainer::XMLPackageContainer()
+ : XMLBase()
+{
+}
+
+XMLPackageContainer::XMLPackageContainer(const XMLPackageContainer& rContainer)
+ : XMLBase()
+{
+ m_vPackages = rContainer.m_vPackages;
+}
+
+XMLPackageContainer::~XMLPackageContainer()
+{
+}
+
+XMLPackageContainer XMLPackageContainer::operator=(XMLPackageContainer container)
+{
+ m_vPackages = container.m_vPackages;
+ return *this;
+}
+
+void XMLPackageContainer::toSpecFile(ostream& rOut,
+ const char* szTag)
+{
+ if (numEntries()) {
+ rOut << szTag << ": ";
+ for (unsigned int i = 0; i < numEntries(); i++) {
+ rOut << (i ? ", " : "");
+ getEntry(i).toSpecFile(rOut);
+ }
+ rOut << endl;
+ }
+}
+
+void XMLPackageContainer::toXMLFile(ostream& rOut,
+ const char* szTag)
+{
+ if (numEntries()) {
+ rOut << endl << "\t\t<" << szTag << ">";
+ for (unsigned int i = 0; i < numEntries(); i++)
+ getEntry(i).toXMLFile(rOut);
+ rOut << endl << "\t\t</" << szTag << ">";
+ }
+}
+
+bool XMLPackageContainer::addRequire(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getRequires());
+}
+
+bool XMLPackageContainer::addBuildRequire(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getBuildRequires());
+}
+
+bool XMLPackageContainer::addProvide(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getProvides());
+}
+
+bool XMLPackageContainer::addObsolete(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getObsoletes());
+}
--- /dev/null
+#ifndef _H_XMLREQUIRES_
+#define _H_XMLREQUIRES_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// standard C includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+
+// forward definitions
+class XMLPackage;
+class XMLPackageContainer;
+class XMLSpec;
+
+using namespace std;
+
+//<package ...> (after requires, buildrequires, obsoletes, provides)
+class XMLPackageEntry : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Creates an object as parsed from an XML spec
+ * .
+ * @param pAttrs XML atrtributes to use
+ * @param rContainer The container to which to add the object
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLPackageContainer& rContainer);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName Name of the package
+ * @param szVersion version of the package
+ * @param szCmp the comparator (eq,lt,le,gt,ge)
+ * @return none
+ **/
+ XMLPackageEntry(const char* szName,
+ const char* szVersion,
+ const char* szCmp);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rEntry reference to the entrry to copy
+ * @return none
+ **/
+ XMLPackageEntry(const XMLPackageEntry& rEntry);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLPackageEntry();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param entry The entry to assigne to
+ * @return thye modified object
+ **/
+ XMLPackageEntry operator=(XMLPackageEntry entry);
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut output stream
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Gets the name
+ * .
+ * @param none
+ * @return string containing the name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Checks if we have a version
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasVersion()
+ {
+ return m_sVersion.length() ? true : false;
+ }
+
+ /**
+ * Gets the version
+ * .
+ * @param none
+ * @return string containing the version
+ **/
+ const char* getVersion()
+ {
+ return m_sVersion.c_str();
+ }
+
+ /**
+ * Gets the comparision string
+ * .
+ * @param none
+ * @return string with the comparator (=, <, <=, >, >=, <>)
+ **/
+ const char* getCompare()
+ {
+ return m_sCmp.c_str();
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sName;
+ string m_sVersion;
+ string m_sCmp;
+};
+
+//<requires,obsoletes,buildrequires,provides ...>
+class XMLPackageContainer : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Adds a require
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpecx pointer to the spec to add to
+ * @return true on success, false otherwise
+ **/
+ static bool addRequire(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a buildrequire
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpecx pointer to the spec to add to
+ * @return true on success, false otherwise
+ **/
+ static bool addBuildRequire(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a provide
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpecx pointer to the spec to add to
+ * @return true on success, false otherwise
+ **/
+ static bool addProvide(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds an obsolete
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpecx pointer to the spec to add to
+ * @return true on success, false otherwise
+ **/
+ static bool addObsolete(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param none
+ * @return none
+ **/
+ XMLPackageContainer();
+
+ /**
+ * Copy constructor
+ * .
+ * @param rContainer The container to copy
+ * @return none
+ **/
+ XMLPackageContainer(const XMLPackageContainer& rContainer);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ virtual ~XMLPackageContainer();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param container The container to copy
+ * @return a copy of the object
+ **/
+ XMLPackageContainer operator=(XMLPackageContainer container);
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec
+ * .
+ * @param rOut Output stream
+ * @param szTag the tag for this object (eg. buildrequires)
+ * @return none
+ **/
+ virtual void toSpecFile(ostream& rOut,
+ const char* szTag);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @para szTag the tag for this object (eg. buildrequires)
+ * @return none
+ **/
+ virtual void toXMLFile(ostream& rOut,
+ const char* szTag);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Gets the number of entries
+ * .
+ * @param none
+ * @return the number of entries
+ **/
+ unsigned int numEntries()
+ {
+ return m_vPackages.size();
+ }
+
+ /**
+ * Gets a specific entry
+ * .
+ * @param nNum The number of the entry
+ * @return reference to the entry
+ **/
+ XMLPackageEntry& getEntry(unsigned int nNum)
+ {
+ return m_vPackages[nNum];
+ }
+
+ /**
+ * Adds an entry
+ * .
+ * @param rPackage the entry to add
+ * @return none
+ **/
+ void addEntry(XMLPackageEntry& rPackage)
+ {
+ m_vPackages.push_back(rPackage);
+ }
+
+//
+// member variables
+//
+protected:
+ vector<XMLPackageEntry> m_vPackages;
+};
+
+#endif
--- /dev/null
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLPackage.h"
+#include "XMLScript.h"
+#include "XMLSpec.h"
+
+// attribute structure for XMLScript
+structValidAttrs g_paScriptAttrs[] =
+{
+ {0x0000, false, false, "dir"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLScript::parseCreate(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLScripts& rContainer)
+{
+ if (!pAttrs->validate(g_paScriptAttrs, (XMLBase*)pAttrs))
+ return false;
+ XMLScript script(szScript, pAttrs->get("dir"));
+ rContainer.add(script);
+ return true;
+}
+
+XMLScript::XMLScript(const char* szScript,
+ const char* szDir)
+ : XMLBase()
+{
+ if (szScript)
+ m_sValue.assign(szScript);
+ if (szDir)
+ m_sDir.assign(szDir);
+}
+
+XMLScript::XMLScript(const XMLScript& rScript)
+ : XMLBase()
+{
+ m_sValue.assign(rScript.m_sValue);
+ m_sDir.assign(rScript.m_sDir);
+}
+
+XMLScript::~XMLScript()
+{
+}
+
+XMLScript XMLScript::operator=(XMLScript script)
+{
+ m_sValue.assign(script.m_sValue);
+ m_sDir.assign(script.m_sDir);
+}
+
+void XMLScript::toSpecFile(ostream& rOut)
+{
+ if (hasDirectory())
+ rOut << "cd " << getDirectory() << endl;
+ rOut << getValue() << endl;
+}
+
+void XMLScript::toXMLFile(ostream& rOut,
+ const char* szIndent)
+{
+ rOut << endl << szIndent << "\t\t<script";
+ if (hasDirectory())
+ rOut << " dir=\"" << getDirectory() << "\"";
+ rOut << ">" << getValue() << "</script>";
+}
+
+void XMLScript::toRPMStruct(StringBuf* pSB)
+{
+ if (hasDirectory()) {
+ char szBuff[getDirectoryLen()+3+1];
+ sprintf(szBuff, "cd %s", getDirectory());
+ appendStringBuf(*pSB, szBuff);
+ }
+ appendStringBuf(*pSB, getValue());
+}
+
+bool XMLScripts::addPrepScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ // no spec or already set
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->getPrep());
+}
+
+bool XMLScripts::addBuildScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ // no spec or already set
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->getBuild());
+}
+
+bool XMLScripts::addInstallScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ // no spec or already set
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->getInstall());
+}
+
+bool XMLScripts::addCleanScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ // no spec or already set
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->getClean());
+}
+
+XMLScripts::XMLScripts()
+ : XMLBase()
+{
+}
+
+XMLScripts::XMLScripts(const XMLScripts& rContainer)
+ : XMLBase()
+{
+ m_vScripts = rContainer.m_vScripts;
+}
+
+XMLScripts::~XMLScripts()
+{
+}
+
+void XMLScripts::toSpecFile(ostream& rOut,
+ const char* szTag)
+{
+ if (numScripts()) {
+ rOut << endl << "%" << szTag << endl;
+ for (unsigned int i = 0; i < numScripts(); i++)
+ getScript(i).toSpecFile(rOut);
+ }
+}
+
+void XMLScripts::toXMLFile(ostream& rOut,
+ const char* szTag)
+{
+ if (numScripts()) {
+ rOut << endl << "\t<" << szTag << ">";
+ for (unsigned int i = 0; i < numScripts(); i++)
+ getScript(i).toXMLFile(rOut, "");
+ rOut << endl << "\t</" << szTag << ">";
+ }
+}
+
+bool XMLPackageScripts::addPreScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPre());
+}
+
+bool XMLPackageScripts::addPostScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPost());
+}
+
+bool XMLPackageScripts::addPreUnScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPreUn());
+}
+
+bool XMLPackageScripts::addPostUnScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPostUn());
+}
+
+bool XMLPackageScripts::addVerifyScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec)
+{
+ if (!pSpec)
+ return false;
+ return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getVerify());
+}
+
+XMLPackageScripts::XMLPackageScripts()
+ : XMLScripts()
+{
+}
+
+XMLPackageScripts::XMLPackageScripts(const XMLPackageScripts& rContainer)
+ : XMLScripts(rContainer)
+{
+}
+
+XMLPackageScripts::~XMLPackageScripts()
+{
+}
+
+void XMLPackageScripts::toSpecFile(ostream& rOut,
+ const char* szTag)
+{
+ // NOTE: header not done here, but by "package"
+ for (unsigned int i = 0; i < numScripts(); i++)
+ getScript(i).toSpecFile(rOut);
+}
+
+void XMLPackageScripts::toXMLFile(ostream& rOut,
+ const char* szTag)
+{
+ if (numScripts()) {
+ rOut << endl << "\t\t<" << szTag << ">";
+ for (unsigned int i = 0; i < numScripts(); i++)
+ getScript(i).toXMLFile(rOut, "\t");
+ rOut << endl << "\t\t</" << szTag << ">";
+ }
+}
--- /dev/null
+#ifndef _H_XMLSCRIPT_
+#define _H_XMLSCRIPT_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+
+// rpm includes
+#include <rpmbuild.h>
+
+// forward definitions
+class XMLPackage;
+class XMLSpec;
+class XMLScripts;
+
+using namespace std;
+
+class XMLScript : public XMLBase
+{
+//
+// factory methods
+//
+public:
+ /**
+ * Creates a script object and adds it to the container
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script value
+ * @param rContainer reference to the script container to add to
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLScripts& rContainer);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szScript The script
+ * @param szDir Directory to execute the script in
+ * @return none
+ **/
+ XMLScript(const char* szScript,
+ const char* szDir);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rScript Script to copy
+ * @return none
+ **/
+ XMLScript(const XMLScript& rScript);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ virtual ~XMLScript();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param script the script to copy
+ * @return the copied object
+ **/
+ XMLScript operator=(XMLScript script);
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec file
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @param szIndent Indent string
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut,
+ const char* szIndent = "");
+
+ /**
+ * Converts the object into an RPM structure
+ * .
+ * @param pSB Pointer to the string buffer
+ * @return none
+ **/
+ virtual void toRPMStruct(StringBuf* pSB);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Gets the script value
+ * .
+ * @param none
+ * @return string containing the script
+ **/
+ const char* getValue()
+ {
+ return m_sValue.c_str();
+ }
+
+ /**
+ * Checks if we have a direcory
+ * .
+ * @param none
+ * @return true if we have a directory, false otherwise
+ **/
+ bool hasDirectory()
+ {
+ return m_sDir.length() ? true : false;
+ }
+
+ /**
+ * Gets the directory
+ * .
+ * @param none
+ * @return string contating the directory
+ **/
+ const char* getDirectory()
+ {
+ return m_sDir.c_str();
+ }
+
+ /**
+ * Gets the length of the directory string
+ * .
+ * @param none
+ * @return length of the description string
+ **/
+ unsigned int getDirectoryLen()
+ {
+ return m_sDir.length();
+ }
+
+//
+// member variables
+//
+public:
+ string m_sValue;
+ string m_sDir;
+};
+
+//<prep,build,install,clean ...>
+class XMLScripts : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ static bool addPrepScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ static bool addBuildScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ static bool addInstallScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ static bool addCleanScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param none
+ * @return none
+ **/
+ XMLScripts();
+
+ /**
+ * Copy constructor
+ * .
+ * @param rContainer the object to copy
+ * @return none
+ **/
+ XMLScripts(const XMLScripts& rContainer);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ virtual ~XMLScripts();
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec file
+ * .
+ * @param rOut Output stream
+ * @param szTag The tag name
+ * @return none
+ **/
+ virtual void toSpecFile(ostream& rOut,
+ const char* szTag);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @param szTag The tag name
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut,
+ const char* szTag);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Gets the number of script entries
+ * .
+ * @param none
+ * @return the number of scripts
+ **/
+ unsigned int numScripts()
+ {
+ return m_vScripts.size();
+ }
+
+ /**
+ * Gets a specific script entry
+ * .
+ * @param nNum The entry number
+ * @return Reference to the script entry
+ **/
+ XMLScript& getScript(unsigned int nNum)
+ {
+ return m_vScripts[nNum];
+ }
+
+ /**
+ * Adds an script entry
+ * .
+ * @param szScript the script to add
+ * @return none
+ **/
+ void add(XMLScript& rScript)
+ {
+ m_vScripts.push_back(rScript);
+ }
+
+//
+// member variables
+//
+protected:
+ vector<XMLScript> m_vScripts;
+};
+
+//<post, postun, ...>
+class XMLPackageScripts : public XMLScripts
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Adds a pre script
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script to add
+ * @param pSpec The spec to which we are adding
+ * @return true on success, false otherwise
+ **/
+ static bool addPreScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a post script
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script to add
+ * @param pSpec The spec to which we are adding
+ * @return true on success, false otherwise
+ **/
+ static bool addPostScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a preun script
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script to add
+ * @param pSpec The spec to which we are adding
+ * @return true on success, false otherwise
+ **/
+ static bool addPreUnScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a postun script
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script to add
+ * @param pSpec The spec to which we are adding
+ * @return true on success, false otherwise
+ **/
+ static bool addPostUnScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+
+ /**
+ * Adds a verify script
+ * .
+ * @param pAttrs The XML attributes
+ * @param szScript The script to add
+ * @param pSpec The spec to which we are adding
+ * @return true on success, false otherwise
+ **/
+ static bool addVerifyScript(XMLAttrs* pAttrs,
+ const char* szScript,
+ XMLSpec* pSpec);
+//
+// constructors/destructors
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param none
+ * @return none
+ **/
+ XMLPackageScripts();
+
+ /**
+ * Copy constructor
+ * .
+ * @param rScripts Reference to the object to copy
+ * @return none
+ **/
+ XMLPackageScripts(const XMLPackageScripts& rScripts);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLPackageScripts();
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec
+ * .
+ * @param rOut Output stream
+ * @param szTag The tag name
+ * @return none
+ **/
+ virtual void toSpecFile(ostream& rOut,
+ const char* szTag);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @param szTag The tag name
+ * @return none
+ **/
+ virtual void toXMLFile(ostream& rOut,
+ const char* szTag);
+
+};
+
+#endif
--- /dev/null
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLSource.h"
+#include "XMLSpec.h"
+
+// rpm includes
+#include <rpmspec.h>
+
+using namespace std;
+
+bool XMLSource::structCreate(Source* pSource,
+ XMLSpec* pSpec)
+{
+ if (!pSpec || !pSource)
+ return false;
+
+ do {
+ // create our mirror
+ XMLMirror *pMirror = NULL;
+ if (pSource->source != pSource->fullSource) {
+ unsigned int nLen = pSource->source-pSource->fullSource;
+ char szPath[nLen+1];
+ strncpy(szPath, pSource->fullSource, nLen);
+ szPath[nLen] = '\0';
+ pMirror = new XMLMirror(szPath, NULL, NULL);
+ }
+
+ // generate the source, nosource, patch
+ XMLSource* pXSource = NULL;
+ XMLNoSource* pXNoSource = NULL;
+ XMLPatch* pXPatch = NULL;
+ switch (pSource->flags) {
+ case RPMBUILD_ISSOURCE:
+ pXSource = new XMLSource(pSource->source,
+ pSource->num,
+ NULL,
+ NULL,
+ NULL);
+ pSpec->addSource(*pXSource);
+ if (pMirror)
+ pSpec->lastSource().addMirror(*pMirror);
+ delete pXSource;
+ break;
+ case RPMBUILD_ISNO:
+ pXNoSource = new XMLNoSource(pSource->source,
+ pSource->num,
+ NULL,
+ NULL,
+ NULL);
+ pSpec->addNoSource(*pXNoSource);
+ if (pMirror)
+ pSpec->lastNoSource().addMirror(*pMirror);
+ delete pXNoSource;
+ break;
+ case RPMBUILD_ISPATCH:
+ pXPatch = new XMLPatch(pSource->source,
+ pSource->num,
+ NULL,
+ NULL);
+ pSpec->addPatch(*pXPatch);
+ if (pMirror)
+ pSpec->lastPatch().addMirror(*pMirror);
+ delete pXPatch;
+ break;
+ default:
+ break;
+ }
+ if (pMirror)
+ delete pMirror;
+ } while ((pSource = pSource->next));
+ return true;
+}
+
+// attribute structure for XMLSource
+structValidAttrs g_paSourceAttrs[] =
+{
+ {0x0000, true, false, "name"},
+ {0x0001, false, false, "num"},
+ {0x0002, false, false, "dir"},
+ {0x0003, false, false, "size"},
+ {0x0004, false, false, "md5"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLSource::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paSourceAttrs, (XMLBase*)pSpec))
+ return false;
+
+ // create and return
+ unsigned int nNum = 0;
+ if (pAttrs->get("num"))
+ nNum = atoi(pAttrs->get("num"));
+ XMLSource source(pAttrs->get("name"),
+ nNum,
+ pAttrs->get("dir"),
+ pAttrs->get("size"),
+ pAttrs->get("md5"));
+ pSpec->addSource(source);
+
+ return true;
+}
+
+XMLSource::XMLSource(const char* szName,
+ unsigned int nNum,
+ const char* szDir,
+ const char* szSize,
+ const char* szMD5)
+ : XMLBase()
+{
+ if (szName)
+ m_sName.assign(szName);
+ m_nNum = nNum;
+ if (szDir)
+ m_sDir.assign(szDir);
+ if (szSize)
+ m_sSize.assign(szSize);
+ if (szMD5)
+ m_sMD5.assign(szMD5);
+}
+
+XMLSource::XMLSource(const XMLSource& rSource)
+ : XMLBase()
+{
+ m_sName.assign(rSource.m_sName);
+ m_nNum = rSource.m_nNum;
+ m_sDir.assign(rSource.m_sDir);
+ m_sSize.assign(rSource.m_sSize);
+ m_sMD5.assign(rSource.m_sMD5);
+ m_vMirrors = rSource.m_vMirrors;
+}
+
+XMLSource::~XMLSource()
+{
+}
+
+XMLSource XMLSource::operator=(XMLSource source)
+{
+ m_sName.assign(source.m_sName);
+ m_nNum = source.m_nNum;
+ m_sDir.assign(source.m_sDir);
+ m_sSize.assign(source.m_sSize);
+ m_sMD5.assign(source.m_sMD5);
+ m_vMirrors = source.m_vMirrors;
+ return *this;
+}
+
+void XMLSource::toSpecFile(ostream& rOut)
+{
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toSpecFile(rOut);
+
+ rOut << endl << "source";
+ rOut << getNum();
+ rOut << ": ";
+ if (numMirrors())
+ rOut << getMirror(0).getPath();
+ rOut << getName();
+}
+
+void XMLSource::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t<source name=\"" << getName() << "\"";
+ rOut << endl << "\t num=\"";
+ rOut << getNum();
+ rOut << "\"";
+ if (hasSize())
+ rOut << endl << "\t size=\"" << getSize() << "\"";
+ if (hasMD5())
+ rOut << endl << "\t md5=\"" << getMD5() << "\"";
+ if (hasDir())
+ rOut << endl << "\t dir=\"" << getDir() << "\"";
+ rOut << ">";
+
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toXMLFile(rOut);
+
+ rOut << endl << "\t</source>";
+}
+
+void XMLSource::toRPMStruct(Spec pRPMSpec)
+{
+ /*Source* pCurr = new Source;
+ unsigned int nNameLen = strlen(getName());
+ unsigned int nMirrorLen = 0;
+ if (pPrev)
+ pPrev->next = pCurr;
+ pCurr->next = NULL;
+ if (numMirrors())
+ nMirrorlen = strlen(getMirror(0).getPath());
+ pCurr->fullSource = new char[nNamelen+nMirrorLen+1];
+ pCurr->fullSources[0] = '\0';
+ if (numMirrors())
+ strcpy(pCurr->fullSource, getMirror(0).getPath());
+ strcat(pCurr->fullSource, getName());
+ pCurr->source = pCurr->fullSource+nMirrorLen;
+ pCurr->num = getNum();
+ pCurr->flags = RPMBUILD_ISSOURCE;
+ return pCurr;*/
+}
+
+bool XMLNoSource::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paSourceAttrs, (XMLBase*)pSpec))
+ return false;
+
+ unsigned int nNum = 0;
+ if (pAttrs->get("num"))
+ nNum = atoi(pAttrs->get("num"));
+ XMLNoSource source(pAttrs->get("name"),
+ nNum,
+ pAttrs->get("dir"),
+ pAttrs->get("size"),
+ pAttrs->get("md5"));
+ pSpec->addNoSource(source);
+ return true;
+}
+
+XMLNoSource::XMLNoSource(const char* szName,
+ unsigned int nNum,
+ const char* szDir,
+ const char* szSize,
+ const char* szMD5)
+ : XMLSource(szName,
+ nNum,
+ szDir,
+ szSize,
+ szMD5)
+{
+}
+
+XMLNoSource::XMLNoSource(const XMLNoSource& rNoSource)
+ : XMLSource(rNoSource.m_sName.c_str(),
+ rNoSource.m_nNum,
+ rNoSource.m_sDir.c_str(),
+ rNoSource.m_sSize.c_str(),
+ rNoSource.m_sMD5.c_str())
+{
+}
+
+XMLNoSource::~XMLNoSource()
+{
+}
+
+void XMLNoSource::toSpecFile(ostream& rOut)
+{
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toSpecFile(rOut);
+
+ rOut << endl << "nosource";
+ rOut << getNum();
+ rOut << ": " << getName();
+}
+
+void XMLNoSource::toXMLFile(ostream& rOut)
+{
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toXMLFile(rOut);
+}
+
+void XMLNoSource::toRPMStruct(Spec pRPMSpec)
+{
+ //Source* pCurr = XMLSource::toRPMStruct(pPrev);
+ //pCurr->flags = RPMBUILD_ISNO;
+ //return pCurr;
+}
+
+// attribute structure for XMLPatch
+structValidAttrs g_paPatchAttrs[] =
+{
+ {0x0000, true, false, "name"},
+ {0x0001, false, false, "num"},
+ {0x0002, false, false, "size"},
+ {0x0003, false, false, "md5"},
+ {XATTR_END, false, false, "end"}
+};
+
+bool XMLPatch::parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec)
+{
+ // validate the attributes
+ if (!pAttrs->validate(g_paPatchAttrs, (XMLBase*)pSpec))
+ return false;
+
+ unsigned int nNum = 0;
+ if (pAttrs->get("num"))
+ nNum = atoi(pAttrs->get("num"));
+ XMLPatch patch(pAttrs->get("name"),
+ nNum,
+ pAttrs->get("size"),
+ pAttrs->get("md5"));
+ pSpec->addPatch(patch);
+ return true;
+}
+
+XMLPatch::XMLPatch(const char* szName,
+ unsigned int nNum,
+ const char* szSize,
+ const char* szMD5)
+ : XMLSource(szName,
+ nNum,
+ NULL,
+ szSize,
+ szMD5)
+{
+}
+
+XMLPatch::XMLPatch(const XMLPatch& rPatch)
+ : XMLSource(rPatch.m_sName.c_str(),
+ rPatch.m_nNum,
+ NULL,
+ rPatch.m_sSize.c_str(),
+ rPatch.m_sMD5.c_str())
+{
+}
+
+XMLPatch::~XMLPatch()
+{
+}
+
+void XMLPatch::toSpecFile(ostream& rOut)
+{
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toSpecFile(rOut);
+ rOut << endl << "patch";
+ rOut << getNum();
+ rOut << ": " << getName();
+}
+
+void XMLPatch::toXMLFile(ostream& rOut)
+{
+ rOut << endl << "\t<patch name=\"" << getName() << "\"";
+ rOut << endl << "\t num=\"";
+ rOut << getNum();
+ rOut << "\"";
+ if (hasSize())
+ rOut << endl << "\t size=\"" << getSize() << "\"";
+ if (hasMD5())
+ rOut << endl << "\t md5=\"" << getMD5() << "\"";
+ if (hasDir())
+ rOut << endl << "\t dir=\"" << getDir() << "\"";
+ rOut << ">";
+
+ for (unsigned int i = 0; i < numMirrors(); i++)
+ getMirror(i).toXMLFile(rOut);
+
+ rOut << endl << "\t</patch>";
+}
+
+void XMLPatch::toRPMStruct(Spec pRPMSpec)
+{
+
+ //Source* pCurr = XMLSource::toRPMStruct(pPrev);
+ //pCurr->flags = RPMBUILD_ISPATCH;
+ //return pCurr;
+}
--- /dev/null
+#ifndef _H_XMLSOURCE_
+#define _H_XMLSOURCE_
+
+// standard C++ includes
+#include <string>
+#include <vector>
+#include <iostream>
+
+// standard includes
+#include <stdio.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+#include "XMLMirror.h"
+
+// rpm includes
+#include <rpmbuild.h>
+
+// forward declaration
+class XMLSpec;
+
+using namespace std;
+
+// <source ...>
+class XMLSource : public XMLBase
+{
+//
+// factory functions
+//
+public:
+ /**
+ * Static factory function for the creation of XMLSource, XMLPatch, ...
+ * objects from RPM Source* structure.
+ * .
+ * @param pSpource Pointer to a list of sources
+ * @param pSpec pointer to our spec object
+ * @return true on success, false otherwise
+ **/
+ static bool structCreate(Source* pSource,
+ XMLSpec* pSpec);
+
+ /**
+ * Static factory function for the creation of an XMLSource
+ * object from details parsed from an XML spec.
+ * .
+ * @param pAttrs Pointer to an XML attribute object
+ * @param pspec Ponter to our spec object
+ * @param bPatch True if this source is a patch
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default contructor
+ * .
+ * @param szName The name
+ * @param szNum The source number
+ * @param szDir The unpack directory
+ * @param szSize The size of the source archive
+ * @param szMD5 The MD5 sum of the archive
+ * @return none
+ **/
+ XMLSource(const char* szName,
+ unsigned int nNum,
+ const char* szDir,
+ const char* szSize,
+ const char* szMD5);
+
+ /**
+ * Copy contructor
+ * .
+ * @param rSource The source that we are to copy
+ * @return none
+ **/
+ XMLSource(const XMLSource& rSource);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ virtual ~XMLSource();
+
+//
+// operators
+//
+public:
+ /**
+ * Assignment operator
+ * .
+ * @param source The source to copy
+ * @return copied object
+ **/
+ XMLSource operator=(XMLSource source);
+
+//
+// Member functions
+//
+public:
+ /**
+ * Convert the object into an RPM spec file
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ virtual void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ virtual void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the object into an RPM structure
+ * .
+ * @param spec the RPM structure to use
+ * @return none
+ **/
+ virtual void toRPMStruct(Spec spec);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Checks if we have a source name
+ * .
+ * @param none
+ * @return true if we have a name, false otherwise
+ **/
+ bool hasName()
+ {
+ return m_sName.length() ? true : false;
+ }
+
+ /**
+ * Get the source name
+ * .
+ * @param none
+ * @return string containing the name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Get the length of the name
+ * .
+ * @param none
+ * @return the length of the name
+ **/
+ unsigned int getNameLen()
+ {
+ return m_sName.length();
+ }
+
+ /**
+ * Get the source number
+ * .
+ * @param none
+ * @return the number
+ **/
+ unsigned int getNum()
+ {
+ return m_nNum;
+ }
+
+ /**
+ * Checks to see if we have an unpack directory
+ * .
+ * @param none
+ * @return true if we have a specified directory, false otherwise
+ **/
+ bool hasDir()
+ {
+ return m_sDir.length() ? true : false;
+ }
+
+ /**
+ * Gets the directory that we are to unpack this source to
+ * .
+ * @param none
+ * @return string contating the directory
+ **/
+ const char* getDir()
+ {
+ return m_sDir.c_str();
+ }
+
+ /**
+ * Checks to see if we have a source size
+ * .
+ * @param none
+ * @return true if we have a size, false otherwise
+ **/
+ bool hasSize()
+ {
+ return m_sSize.length() ? true : false;
+ }
+
+ /**
+ * Gets the size of the source
+ * .
+ * @param none
+ * @return string contating the size
+ **/
+ const char* getSize()
+ {
+ return m_sSize.c_str();
+ }
+
+ /**
+ * Checks to see if this source has an MD5 sum
+ * .
+ * @param none
+ * @return true if we have an MD5, false oterwise
+ **/
+ bool hasMD5()
+ {
+ return m_sMD5.length() ? true : false;
+ }
+
+ /**
+ * Gets the MD5 sum for this source
+ * .
+ * @param none
+ * @return string contating the MD5
+ **/
+ const char* getMD5()
+ {
+ return m_sMD5.c_str();
+ }
+
+ /**
+ * Add a mirror for this source
+ * .
+ * @param rMirror The mirror to add
+ * @return none
+ **/
+ void addMirror(XMLMirror& rMirror)
+ {
+ m_vMirrors.push_back(rMirror);
+ }
+
+ /**
+ * Gets the number of mirrors for this source
+ * .
+ * @param none
+ * @return the number oif mirrors
+ **/
+ unsigned int numMirrors()
+ {
+ return m_vMirrors.size();
+ }
+
+ /**
+ * Gets a specific mirror by number
+ * .
+ * @param nNum The mirror to get
+ * @param the mirror
+ **/
+ XMLMirror& getMirror(unsigned int nNum)
+ {
+ return m_vMirrors[nNum];
+ }
+
+//
+// member variables
+//
+protected:
+ string m_sName;
+ unsigned int m_nNum;
+ string m_sDir;
+ string m_sSize;
+ string m_sMD5;
+ vector<XMLMirror> m_vMirrors;
+};
+
+// <nosource ...>
+class XMLNoSource : public XMLSource
+{
+//
+// factory methods
+//
+public:
+ /**
+ * Create an XMLNoSource object
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpec The spec to add the object o
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName The name
+ * @param nNum source number
+ * @param szDir Thje director to extract to
+ * @param szSize size of the archive
+ * @param szMD5 the MD5 sum of the archive
+ * @return none
+ **/
+ XMLNoSource(const char* szName,
+ unsigned int nNum,
+ const char* szDir,
+ const char* szSize,
+ const char* szMD5);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rNoSource Reference to the object ot copy
+ * @return none
+ **/
+ XMLNoSource(const XMLNoSource& rNoSource);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ virtual ~XMLNoSource();
+
+//
+// public member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec file
+ * .
+ * @param rOut Output stream
+ * @param none
+ **/
+ virtual void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ virtual void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the object into an RPM structure
+ * .
+ * @param spec The RPM spec structure
+ * @return none
+ **/
+ virtual void toRPMStruct(Spec spec);
+};
+
+// <patch ...>
+class XMLPatch : public XMLSource
+{
+//
+// factory methods
+//
+public:
+ /**
+ * Create an XMLPatch object
+ * .
+ * @param pAttrs XML attributes
+ * @param pSpec The spec to add the object o
+ * @return true on success, false otherwise
+ **/
+ static bool parseCreate(XMLAttrs* pAttrs,
+ XMLSpec* pSpec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szName archive name
+ * @param nNum source number
+ * @param szSize size of the archive
+ * @param szMD5 MD5 sum
+ * @return none
+ **/
+ XMLPatch(const char* szName,
+ unsigned int nNum,
+ const char* szSize,
+ const char* szMD5);
+
+ /**
+ * Copy constructor
+ * .
+ * @param rPatch Reference to the object to copy
+ * @return none
+ **/
+ XMLPatch(const XMLPatch& rPatch);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return nonew
+ **/
+ virtual ~XMLPatch();
+
+//
+// member functions
+//
+public:
+ /**
+ * Converts the object into an RPM spec file
+ * .
+ * @param rOut Output stream
+ * @param none
+ **/
+ virtual void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the object into an XML spec
+ * .
+ * @param rOut Output stream
+ * @return none
+ **/
+ virtual void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the object into an RPM structure
+ * .
+ * @param spec The RPM spec structure
+ * @return none
+ **/
+ virtual void toRPMStruct(Spec spec);
+};
+
+#endif
--- /dev/null
+// 3rd party includes
+#include <expat.h>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLSpec.h"
+
+using namespace std;
+
+// attribute structure for XMLSpec
+structValidAttrs g_paSpecAttrs[] =
+{
+ {0x0000, true, false, "name"},
+ {0x0001, true, false, "version"},
+ {0x0002, true, false, "release"},
+ {0x0003, false, false, "epoch"},
+ {0x0004, false, false, "distribution"},
+ {0x0005, false, false, "vendor"},
+ {0x0006, false, false, "packager"},
+ {0x0007, false, false, "packager-email"},
+ {0x0008, false, false, "copyright"},
+ {0x0009, false, false, "url"},
+ {0x000A, false, false, "buildroot"},
+ {XATTR_END, false, false, "end"}
+};
+
+XMLSpec* XMLSpec::parseCreate(XMLAttrs* pAttrs,
+ const char* szFilename)
+{
+ // verify the attributes
+ if (!pAttrs->validate(g_paSpecAttrs, (XMLBase*)pAttrs))
+ return NULL;
+
+ // create and return
+ return new XMLSpec(szFilename,
+ pAttrs->get("name"),
+ pAttrs->get("version"),
+ pAttrs->get("release"),
+ pAttrs->get("epoch"),
+ pAttrs->get("distribution"),
+ pAttrs->get("vendor"),
+ pAttrs->get("packager"),
+ pAttrs->get("packager-email"),
+ pAttrs->get("copyright"),
+ pAttrs->get("url"),
+ pAttrs->get("buildroot"));
+}
+
+XMLSpec* XMLSpec::structCreate(Spec spec)
+{
+ if (!spec)
+ return NULL;
+
+ XMLSpec* pSpec = new XMLSpec(spec->specFile,
+ spec->specFile,
+ "1.0",
+ "1",
+ "0",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ spec->buildRootURL);
+
+ XMLSource::structCreate(spec->sources,
+ pSpec);
+ return pSpec;
+}
+
+XMLSpec::XMLSpec(const char* szFilename,
+ const char* szName,
+ const char* szVersion,
+ const char* szRelease,
+ const char* szEpoch,
+ const char* szDistribution,
+ const char* szVendor,
+ const char* szPackager,
+ const char* szPkgrEmail,
+ const char* szCopyright,
+ const char* szURL,
+ const char* szBuildRoot) : XMLBase()
+{
+ if (szFilename)
+ m_sFilename.assign(szFilename);
+ if (szName)
+ m_sName.assign(szName);
+ if (szVersion)
+ m_sVersion.assign(szVersion);
+ if (szRelease)
+ m_sRelease.assign(szRelease);
+ if (szEpoch)
+ m_sEpoch.assign(szEpoch);
+ if (szDistribution)
+ m_sDistribution.assign(szDistribution);
+ if (szVendor)
+ m_sVendor.assign(szVendor);
+ if (szPackager)
+ m_sPackager.assign(szPackager);
+ if (szPkgrEmail)
+ m_sPkgrEmail.assign(szPkgrEmail);
+ if (szCopyright)
+ m_sCopyright.assign(szCopyright);
+ if (szURL)
+ m_sURL.assign(szURL);
+ if (szBuildRoot)
+ m_sBuildRoot.assign(szBuildRoot);
+}
+
+XMLSpec::~XMLSpec()
+{
+}
+
+void XMLSpec::toSpecFile(ostream& rOut)
+{
+ for (unsigned int i = 0; i < numXMacros(); i++)
+ getXMacro(i).toSpecFile(rOut);
+
+ rOut << "name: " << getName() << endl;
+ rOut << "version: " << getVersion() << endl;
+ rOut << "release: " << getRelease() << endl;
+ if (hasEpoch())
+ rOut << "epoch: " << getEpoch() << endl;
+ if (hasCopyright())
+ rOut << "copyright: " << getCopyright() << endl;
+ if (hasURL())
+ rOut << "url: " << getURL() << endl;
+ if (hasBuildRoot())
+ rOut << "buildroot: " << getBuildRoot() << endl;
+ if (hasDistribution())
+ rOut << "distribution: " << getDistribution() << endl;
+ if (hasVendor())
+ rOut << "vendor: " << getVendor() << endl;
+ if (hasPackager()) {
+ rOut << "packager: " << getPackager();
+ if (hasPkgrEmail())
+ rOut << " <" << getPkgrEmail() << ">";
+ rOut << endl;
+ }
+
+ for (unsigned int i = 0; i < numSources(); i++)
+ getSource(i).toSpecFile(rOut);
+ for (unsigned int i = 0; i < numNoSources(); i++)
+ getNoSource(i).toSpecFile(rOut);
+ for (unsigned int i = 0; i < numPatches(); i++)
+ getPatch(i).toSpecFile(rOut);
+ for (unsigned int i = 0; i < numPackages(); i++)
+ getPackage(i).toSpecFile(rOut);
+
+ getPrep().toSpecFile(rOut, "prep");
+ getBuild().toSpecFile(rOut, "build");
+ getInstall().toSpecFile(rOut, "install");
+ getClean().toSpecFile(rOut, "clean");
+
+ for (unsigned int i = 0; i < numPackages(); i++)
+ getPackage(i).toScriptsSpecFile(rOut);
+
+ for (unsigned int i = 0; i < numPackages(); i++)
+ getPackage(i).toFilesSpecFile(rOut);
+
+ getChangelog().toSpecFile(rOut);
+}
+
+void XMLSpec::toXMLFile(ostream& rOut)
+{
+ // spec start
+ rOut << "<?xml version=\"1.0\"?>";
+ rOut << endl << "<spec name=\"" << getName() << "\"";
+ rOut << endl << " version=\"" << getVersion() << "\"";
+ rOut << endl << " release=\"" << getRelease() << "\"";
+ if (hasEpoch())
+ rOut << endl << " epoch=\"" << getEpoch() << "\"";
+ if (hasCopyright())
+ rOut << endl << " copyright=\"" << getCopyright() << "\"";
+ if (hasURL())
+ rOut << endl << " url=\"" << getURL() << "\"";
+ if (hasBuildRoot())
+ rOut << endl << " buildroot=\"" << getBuildRoot() << "\"";
+ if (hasDistribution())
+ rOut << endl << " distribution=\"" << getDistribution() << "\"";
+ if (hasVendor())
+ rOut << endl << " vendor=\"" << getVendor() << "\"";
+ if (hasPackager()) {
+ rOut << endl << " packager=\"" << getPackager() << "\"";
+ if (hasPkgrEmail())
+ rOut << endl << " packager-email=\"" << getPkgrEmail() << "\"";
+ }
+ rOut << ">";
+
+ for (unsigned int i = 0; i < numXMacros(); i++)
+ getXMacro(i).toXMLFile(rOut);
+ for (unsigned int i = 0; i < numSources(); i++)
+ getSource(i).toXMLFile(rOut);
+ for (unsigned int i = 0; i < numNoSources(); i++)
+ getNoSource(i).toXMLFile(rOut);
+ for (unsigned int i = 0; i < numPatches(); i++)
+ getPatch(i).toXMLFile(rOut);
+ for (unsigned int i = 0; i < numPackages(); i++)
+ getPackage(i).toXMLFile(rOut);
+
+ getPrep().toXMLFile(rOut, "prep");
+ getBuild().toXMLFile(rOut, "build");
+ getInstall().toXMLFile(rOut, "install");
+ getClean().toXMLFile(rOut, "clean");
+
+ getChangelog().toXMLFile(rOut);
+
+ rOut << endl << "</spec>";
+}
+
+void XMLSpec::toRPMStruct(Spec* pRPMSpec)
+{
+ Spec spec = newSpec();
+ if (hasBuildRoot()) {
+ spec->gotBuildRootURL = 1;
+ spec->buildRootURL = strdup(getBuildRoot());
+ addMacro(spec->macros, "buildroot", NULL, getBuildRoot(), RMIL_SPEC);
+ }
+ addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
+ spec->timeCheck = rpmExpandNumeric("%{_timecheck}");
+
+ //getChangelog().toRPMStruct(spec);
+ /*for (unsigned int i = 0; i < numPackages(); i++)
+ getPackage(i).toRPMStruct(pRPMSpec);
+ for (unsigned int i = 0; i < numSources(); i++)
+ getSource(i).toRPMStruct(pRPMSpec);
+ for (unsigned int i = 0; i < numNoSources(); i++)
+ getNoSource(i).toRPMStruct(pRPMSpec);
+ for (unsigned int i = 0; i < numPatches(); i++)
+ getPatch(i).toRPMStruct(pRPMSpec);*/
+
+ //getPrep().toRPMStruct(spec);
+ //getBuild().toRPMStruct(spec);
+ //getInstall().toRPMStruct(spec);
+ //getClean().toRPMStruct(spec);
+
+ *pRPMSpec = spec;
+}
--- /dev/null
+#ifndef _H_XMLSPEC_
+#define _H_XMLSPEC_
+
+// standard C++ includes
+#include <iostream>
+#include <string>
+#include <vector>
+
+// our includes
+#include "XMLAttrs.h"
+#include "XMLBase.h"
+#include "XMLChangelog.h"
+#include "XMLMacro.h"
+#include "XMLPackage.h"
+#include "XMLScript.h"
+#include "XMLSource.h"
+
+// rpm includes
+#include <rpmbuild.h>
+
+using namespace std;
+
+// <spec ...>
+class XMLSpec : public XMLBase
+{
+//
+// static object creation functions
+//
+public:
+ /**
+ * Creates an XMLSpec from values parsed
+ * .
+ * @param pAttrs The XML attributes
+ * @param szFilename The XML spec filename
+ * @return Pointer to the created spec
+ **/
+ static XMLSpec* parseCreate(XMLAttrs* pAttrs,
+ const char* szFilename);
+
+ /**
+ * Creates and XMLSpec from an RPM Spec structure
+ * .
+ * @param spec The RPM spec structure
+ * @return Pointer to the created spec
+ **/
+ static XMLSpec* structCreate(Spec spec);
+
+//
+// constructors/destructor
+//
+public:
+ /**
+ * Default constructor
+ * .
+ * @param szFilename Filename of the spec on disk
+ * @param szName spec name
+ * @param szVersion Spec version
+ * @param szRelease spec release
+ * @param szEpoch spec epoch
+ * @param szDistribution spec distribution
+ * @param szVendor spec vendor
+ * @param szPackage spec packager
+ * @param szPkgEmail email address for the packager
+ * @param szCopyright spec copyright/licence
+ * @param szURL main package url
+ * @param szBuildRoot buildroot
+ * @return none
+ **/
+ XMLSpec(const char* szFilename,
+ const char* szName,
+ const char* szVersion,
+ const char* szRelease,
+ const char* szEpoch,
+ const char* szDistribution,
+ const char* szVendor,
+ const char* szPackager,
+ const char* szPkgrEmail,
+ const char* szCopyright,
+ const char* szURL,
+ const char* szBuildRoot);
+
+ /**
+ * Destructor
+ * .
+ * @param none
+ * @return none
+ **/
+ ~XMLSpec();
+
+//
+// public member functions
+//
+public:
+ /**
+ * Converts the spec object to a normal RPM spec file
+ * .
+ * @param rOut Reference to the stream to write the information to
+ * @return none
+ **/
+ void toSpecFile(ostream& rOut);
+
+ /**
+ * Converts the spec object to an XML spec file
+ * .
+ * @param rOut Reference to the stream to write the information to
+ * @return none
+ **/
+ void toXMLFile(ostream& rOut);
+
+ /**
+ * Converts the spec object to an internal RPM structure
+ * .
+ * @param none
+ * @return the created RPM structure
+ **/
+ void toRPMStruct(Spec* pRPMSpec);
+
+//
+// member variable get/set functions
+//
+public:
+ /**
+ * Adds a package to the internal list
+ * .
+ * @param rPkg Reference to the package to add
+ * @return none
+ **/
+ void addPackage(XMLPackage& rPkg)
+ {
+ m_vPackages.push_back(rPkg);
+ }
+
+ /**
+ * Gets the number of packages
+ * .
+ * @param none
+ * @return the number of packages
+ **/
+ unsigned int numPackages()
+ {
+ return m_vPackages.size();
+ }
+
+ /**
+ * Gets a specific package
+ * .
+ * @param nNum The package number
+ * @return the required package
+ **/
+ XMLPackage& getPackage(unsigned int nNum)
+ {
+ return m_vPackages[nNum];
+ }
+
+ /**
+ * Gets the last package added
+ * .
+ * @param none
+ * @return the last package added
+ **/
+ XMLPackage& lastPackage()
+ {
+ return m_vPackages[numPackages()-1];
+ }
+
+ /**
+ * Adds a source to the internal list
+ * .
+ * @param rSource Reference to the source to add
+ * @return none
+ **/
+ void addSource(XMLSource& rSource)
+ {
+ m_vSources.push_back(rSource);
+ }
+
+ /**
+ * Gets the number of sources
+ * .
+ * @param none
+ * @return the number of sources
+ **/
+ unsigned int numSources()
+ {
+ return m_vSources.size();
+ }
+
+ /**
+ * Gets a specific source
+ * .
+ * @param nNum The source number
+ * @return the required source
+ **/
+ XMLSource& getSource(unsigned int nNum)
+ {
+ return m_vSources[nNum];
+ }
+
+ /**
+ * Gets the last source added
+ * .
+ * @param none
+ * @return the last source added
+ **/
+ XMLSource& lastSource()
+ {
+ return m_vSources[numSources()-1];
+ }
+
+ /**
+ * Adds a source to the internal list
+ * .
+ * @param rSource Reference to the source to add
+ * @return none
+ **/
+ void addNoSource(XMLNoSource& rSource)
+ {
+ m_vNoSources.push_back(rSource);
+ }
+
+ /**
+ * Gets the number of nosources
+ * .
+ * @param none
+ * @return the number of nsources
+ **/
+ unsigned int numNoSources()
+ {
+ return m_vNoSources.size();
+ }
+
+ /**
+ * Gets a specific nosource
+ * .
+ * @param nNum The nosource number
+ * @return the required nosource
+ **/
+ XMLNoSource& getNoSource(unsigned int nNum)
+ {
+ return m_vNoSources[nNum];
+ }
+
+ /**
+ * Gets the last nosource added
+ * .
+ * @param none
+ * @return the last nosource added
+ **/
+ XMLNoSource& lastNoSource()
+ {
+ return m_vNoSources[numNoSources()-1];
+ }
+
+ /**
+ * Adds a patch to the internal list
+ * .
+ * @param rSource Reference to the patch to add
+ * @return none
+ **/
+ void addPatch(XMLPatch& rSource)
+ {
+ m_vPatches.push_back(rSource);
+ }
+
+ /**
+ * Gets the number of patches
+ * .
+ * @param none
+ * @return the number of patches
+ **/
+ unsigned int numPatches()
+ {
+ return m_vPatches.size();
+ }
+
+ /**
+ * Gets a specific patch
+ * .
+ * @param nNum The patch number
+ * @return the required patch
+ **/
+ XMLPatch& getPatch(unsigned int nNum)
+ {
+ return m_vPatches[nNum];
+ }
+
+ /**
+ * Gets the last patch added
+ * .
+ * @param none
+ * @return the last patch added
+ **/
+ XMLPatch& lastPatch()
+ {
+ return m_vPatches[numPatches()-1];
+ }
+
+ /**
+ * Adds a macro to the internal list
+ * .
+ * @param rMacro Reference to the macro to add
+ * @return none
+ **/
+ void addXMacro(XMLMacro& rMacro)
+ {
+ m_vMacros.push_back(rMacro);
+ }
+
+ /**
+ * Gets the number of macros
+ * .
+ * @param none
+ * @return the number of macros
+ **/
+ unsigned int numXMacros()
+ {
+ return m_vMacros.size();
+ }
+
+ /**
+ * Gets a specific macro
+ * .
+ * @param nNum The macro number
+ * @return the required macro
+ **/
+ XMLMacro& getXMacro(unsigned int nNum)
+ {
+ return m_vMacros[nNum];
+ }
+
+ /**
+ * Checks if we have a filename
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasFilename()
+ {
+ return m_sFilename.length() ? true : false;
+ }
+
+ /**
+ * Gets the filename
+ * .
+ * @param none
+ * @return string containing the filename
+ **/
+ const char* getFilename()
+ {
+ return m_sFilename.c_str();
+ }
+
+ /**
+ * Checks if we have a name
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasName()
+ {
+ return m_sName.length() ? true : false;
+ }
+
+ /**
+ * Gets the name
+ * .
+ * @param none
+ * @return string containing the name
+ **/
+ const char* getName()
+ {
+ return m_sName.c_str();
+ }
+
+ /**
+ * Checks if we have a version
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasVersion()
+ {
+ return m_sVersion.length() ? true : false;
+ }
+
+ /**
+ * Gets the version
+ * .
+ * @param none
+ * @return string containing the version
+ **/
+ const char* getVersion()
+ {
+ return m_sVersion.c_str();
+ }
+
+ /**
+ * Checks if we have a release
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasRelease()
+ {
+ return m_sRelease.length() ? true : false;
+ }
+
+ /**
+ * Gets the release
+ * .
+ * @param none
+ * @return string containing the release
+ **/
+ const char* getRelease()
+ {
+ return m_sRelease.c_str();
+ }
+
+ /**
+ * Checks if we have a epoch
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasEpoch()
+ {
+ return m_sEpoch.length() ? true : false;
+ }
+
+ /**
+ * Gets the epoch
+ * .
+ * @param none
+ * @return string containing the epoch
+ **/
+ const char* getEpoch()
+ {
+ return m_sEpoch.c_str();
+ }
+
+ /**
+ * Checks if we have a distribution
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasDistribution()
+ {
+ return m_sDistribution.length() ? true : false;
+ }
+
+ /**
+ * Gets the distribution
+ * .
+ * @param none
+ * @return string containing the distribution
+ **/
+ const char* getDistribution()
+ {
+ return m_sDistribution.c_str();
+ }
+
+ /**
+ * Checks if we have a vendor
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasVendor()
+ {
+ return m_sVendor.length() ? true : false;
+ }
+
+ /**
+ * Gets the vendor
+ * .
+ * @param none
+ * @return string containing the vendor
+ **/
+ const char* getVendor()
+ {
+ return m_sVendor.c_str();
+ }
+
+ /**
+ * Checks if we have a packager
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasPackager()
+ {
+ return m_sPackager.length() ? true : false;
+ }
+
+ /**
+ * Gets the packager
+ * .
+ * @param none
+ * @return string containing the packager
+ **/
+ const char* getPackager()
+ {
+ return m_sPackager.c_str();
+ }
+
+ /**
+ * Checks if we have a packager email
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasPkgrEmail()
+ {
+ return m_sPkgrEmail.length() ? true : false;
+ }
+
+ /**
+ * Gets the packager's email address
+ * .
+ * @param none
+ * @return string containing the packager's email address
+ **/
+ const char* getPkgrEmail()
+ {
+ return m_sPkgrEmail.c_str();
+ }
+
+ /**
+ * Checks if we have a copyright
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasCopyright()
+ {
+ return m_sCopyright.length() ? true : false;
+ }
+
+ /**
+ * Gets the copyright
+ * .
+ * @param none
+ * @return string containing the copyright
+ **/
+ const char* getCopyright()
+ {
+ return m_sCopyright.c_str();
+ }
+
+ /**
+ * Checks if we have an URL
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasURL()
+ {
+ return m_sURL.length() ? true : false;
+ }
+
+ /**
+ * Gets the URL
+ * .
+ * @param none
+ * @return string containing the URL
+ **/
+ const char* getURL()
+ {
+ return m_sURL.c_str();
+ }
+
+ /**
+ * Checks if we have a BuildRoot
+ * .
+ * @param none
+ * @return true if available, false otherwise
+ **/
+ bool hasBuildRoot()
+ {
+ return m_sBuildRoot.length() ? true : false;
+ }
+
+ /**
+ * Gets the buildroot
+ * .
+ * @param none
+ * @return string containing the buildroor
+ **/
+ const char* getBuildRoot()
+ {
+ return m_sBuildRoot.c_str();
+ }
+
+ /**
+ * Gets the prep section
+ * .
+ * @param none
+ * @return reference to the prep section
+ **/
+ XMLScripts& getPrep()
+ {
+ return m_Prep;
+ }
+
+ /**
+ * Gets the build section
+ * .
+ * @param none
+ * @return reference to the build section
+ **/
+ XMLScripts& getBuild()
+ {
+ return m_Build;
+ }
+
+ /**
+ * Gets the install section
+ * .
+ * @param none
+ * @return reference to the install section
+ **/
+ XMLScripts& getInstall()
+ {
+ return m_Install;
+ }
+
+ /**
+ * Gets the clean section
+ * .
+ * @param none
+ * @return reference to the clean section
+ **/
+ XMLScripts& getClean()
+ {
+ return m_Clean;
+ }
+
+ /**
+ * Gets the changelog section
+ * .
+ * @param none
+ * @return reference to the changelog section
+ **/
+ XMLChangelog& getChangelog()
+ {
+ return m_Changelog;
+ }
+
+//
+// internal member variables
+//
+protected:
+ string m_sFilename;
+ string m_sName;
+ string m_sVersion;
+ string m_sRelease;
+ string m_sEpoch;
+ string m_sDistribution;
+ string m_sVendor;
+ string m_sPackager;
+ string m_sPkgrEmail;
+ string m_sCopyright;
+ string m_sURL;
+ string m_sBuildRoot;
+ vector<XMLPackage> m_vPackages;
+ vector<XMLSource> m_vSources;
+ vector<XMLNoSource> m_vNoSources;
+ vector<XMLPatch> m_vPatches;
+ vector<XMLMacro> m_vMacros;
+ XMLScripts m_Prep;
+ XMLScripts m_Build;
+ XMLScripts m_Install;
+ XMLScripts m_Clean;
+ XMLChangelog m_Changelog;
+};
+
+#endif
--- /dev/null
+<?xml version="1.0"?>
+<!--
+ This is an example XML spec file to demonstrate the xml2spec
+ conversion program. By running "xml2spec example.spec.xml" it
+ will create an output spec in "normal" RPM spec format, ready
+ for comsumption by rpmbuild.
+-->
+<spec name="example"
+ version="1.0"
+ release="03"
+ copyright="GPL"
+ url="http://www.rpm.org/"
+ distribution="Any distribution"
+ vendor="rpm.org"
+ packager="Jaco Greeff"
+ packager-email="jaco@puxedo.org"
+ buildroot="%{tmppath}/lvr-%{name}-build">
+
+ <macro name="test">value is this</macro>
+
+ <source name="rpm-4.0.4.tar.bz2"
+ num="0"
+ size="4296845"
+ md5="bb80a5d06a48623ecbe3f2d41cac15f9">
+ <mirror path="ftp://ftp.rpm.org/"
+ description="Main RPM FTP site" />
+ <mirror path="http://www.puxedo.org/downloads/source/"
+ description="puxedo.org source distribution"
+ country="za" />
+ </source>
+ <source name="expat-1.95.2.tar.bz2"
+ num="1"
+ size="156575"
+ md5="919c78ddaf7f319b7e07792309ae2f22">
+ <mirror path="http://expat.sourceforge.net/"
+ description="SourceForge Mirror"
+ country="us" />
+ </source>
+
+ <patch name="example-1.0-1.patch.bz2"
+ num="0"
+ size="3276"
+ md5="467c78cbdf75619b7e0abc2309ae2f11" />
+
+ <nosource name="nosource-sample-0.98.bz2"
+ num="33" />
+
+ <package group="System/Libraries">
+ <buildrequires>
+ <package name="automake" />
+ <package name="autoconf" />
+ <package name="bash" />
+ <package name="binutils" />
+ <package name="gcc" />
+ <package name="glibc-devel" />
+ </buildrequires>
+ <requires>
+ <package name="gcc" cmp="ge" version="2.95" />
+ <package name="glibc" cmp="ge" version="2.2" />
+ <package name="libogg" />
+ </requires>
+ <provides>
+ <package name="%{name}" />
+ </provides>
+ <obsoletes>
+ <package name="old-example" />
+ </obsoletes>
+ <summary>This spec is just an example for some funny purpose.</summary>
+ <description>%{summary}</description>
+ <post>
+ <script>/sbin/ldconfig</script>
+ </post>
+ <postun>
+ <script>/sbin/ldconfig</script>
+ </postun>
+ <files>
+ <file uid="root" gid="root">/usr/lib/*.so*</file>
+ </files>
+ </package>
+
+ <package name="devel"
+ group="Development/Libraries">
+ <requires>
+ <package name="%{name}" />
+ <package name="libtool" />
+ <package name="m4" />
+ </requires>
+ <summary>The libvorbis-devel package contains development headers.</summary>
+ <description>%{summary}</description>
+ <pre>
+ <script>some pre stuff under devel</script>
+ <script dir="/here/while/we/are/at/it">That ^^^ changed directory</script>
+ </pre>
+ <files uid="root"
+ gid="root">
+ <file>/usr/include/*.h</file>
+ <file gid="rpm">/usr/lib/*.la</file>
+ <file uid="rpm">/usr/share/aclocal/*</file>
+ <file attr="777">/usr/share/m4/*</file>
+ <file uid="uid" gid="gid" attr="444">/usr/share/man/*</file>
+ </files>
+ </package>
+
+ <package name="toys" sub="no">
+ <requires>
+ <package name="%{name}" />
+ </requires>
+ <obsoletes>
+ <package name="oldtoys" />
+ </obsoletes>
+ <summary>The toys package contains toys</summary>
+ <description>%{summary}</description>
+ <preun>
+ <script>some preun stuff under toys</script>
+ </preun>
+ <verify>
+ <script>Some verify stuff under toys</script>
+ </verify>
+ <files>
+ <file>/usr/doc/*</file>
+ </files>
+ </package>
+
+ <prep>
+ <script>rm -rf $RPM_BUILD_DIR/%{name}-%{version}rc3</script>
+ <script>rm -rf %{buildroot}</script>
+ <setup path="%{name}-%{version}rc3" />
+ </prep>
+
+ <build>
+ <script>./configure --prefix=/usr</script>
+ <script>make PROFILE='-Wall -W -pg -g -O2 -ffast-math -D_REENTRANT -fsigned-char -fno-inline -static' CFLAGS='-O2 -ffast-math -D_REENTRANT -fsigned-char -DUSE_MEMORY_H'</script>
+ </build>
+
+ <install>
+ <script>make DESTDIR=%{buildroot} install</script>
+ </install>
+
+ <clean>
+ <script>rm -rf %{buildroot}</script>
+ <script>rm -rf $RPM_BUILD_DIR/%{name}-%{version}rc3</script>
+ </clean>
+
+ <changelog>
+ <changes date="Sat May 25 2002"
+ author="Jaco Greeff"
+ author-email="jaco@puxedo.org"
+ version="1.0-03">
+ <change>Moved <files> into <package> structure</change>
+ <change>Added <nosource> tag as example</change>
+ <change>Changed <shell> to <script></change>
+ </changes>
+ <changes date="Sun May 19 2002"
+ author="Jaco Greeff"
+ author-email="jaco@puxedo.org"
+ version="1.0-02">
+ <change>Changed the formatting of the XML file to fit in with new implementation</change>
+ <change>Commented the spec to allow others to understand it as well</change>
+ </changes>
+ <changes date="Wed May 15 2002"
+ author="Jaco Greeff"
+ author-email="jaco@puxedo.org"
+ version="1.0-01">
+ <change>Converted spec file to .spec.xml file for illustrative purposes</change>
+ </changes>
+ </changelog>
+</spec>
--- /dev/null
+// TODO: Comment properly
+
+// standard C++ includes
+#include <fstream>
+
+// our includes
+#include "XMLParser.h"
+#include "XMLSpec.h"
+
+// display some usage
+int usage()
+{
+ printf("Usage: xml2spec input [output]\n");
+ printf("Converts the input pkg.spec.xml file to a pkg.spec\n");
+ printf("file for use in an rpmbuild command.\n\n");
+ return 1;
+}
+
+// program entry point
+int main(int argc,
+ char** argv)
+{
+ if (argc != 2 && argc != 3) {
+ usage();
+ return 1;
+ }
+
+ XMLSpec* pSpec = NULL;
+ if (parseXMLSpec(argv[1], pSpec) == 0 && pSpec) {
+ if (argc == 3) {
+ printf("Writing spec to %s ... ", argv[2]);
+ ofstream fOut(argv[2]);
+ if (fOut.is_open()) {
+ pSpec->toSpecFile(fOut);
+ fOut.close();
+ printf("Ok.\n");
+ }
+ else {
+ delete pSpec;
+ printf("Failed.\n");
+ return 2;
+ }
+ }
+ else if (argc == 2) {
+ pSpec->toSpecFile(cout);
+ pSpec->toXMLFile(cout);
+ }
+
+ delete pSpec;
+ return 0;
+ }
+
+ return 3;
+}