From 9d880e91429b66f64f4d162a7b50ef5c4c5ac7f3 Mon Sep 17 00:00:00 2001 From: jbj Date: Tue, 4 Jun 2002 15:06:36 +0000 Subject: [PATCH] Update from "Jaco Greeff" . CVS patchset: 5462 CVS date: 2002/06/04 15:06:36 --- xmlspec/Makefile | 5 +- xmlspec/XMLAttrs.cpp | 164 +++++++++++++++++++++++++++++++++++++++++++---- xmlspec/XMLAttrs.h | 85 ++++++++++++++++++++---- xmlspec/XMLChangelog.cpp | 27 +++++--- xmlspec/XMLChangelog.h | 14 ++++ xmlspec/XMLFiles.cpp | 54 +++++++++++----- xmlspec/XMLFiles.h | 48 ++++++++++++-- xmlspec/XMLMacro.cpp | 6 +- xmlspec/XMLMirror.cpp | 14 ++-- xmlspec/XMLPackage.cpp | 98 ++++++++++++++++++++++------ xmlspec/XMLPackage.h | 40 ++++++++++++ xmlspec/XMLParser.cpp | 44 +++++++++++++ xmlspec/XMLRequires.cpp | 26 ++++++-- xmlspec/XMLRequires.h | 12 ++++ xmlspec/XMLScript.cpp | 61 ++++++++++++++++-- xmlspec/XMLScript.h | 111 ++++++++++++++++++++++++++++++++ xmlspec/XMLSource.cpp | 159 ++++++++++++++++++++------------------------- xmlspec/XMLSource.h | 6 +- xmlspec/XMLSpec.cpp | 95 +++++++++++++++------------ xmlspec/XMLSpec.h | 4 +- xmlspec/example.spec.xml | 8 ++- 21 files changed, 849 insertions(+), 232 deletions(-) diff --git a/xmlspec/Makefile b/xmlspec/Makefile index 6b4fb2a..a3c789d 100644 --- a/xmlspec/Makefile +++ b/xmlspec/Makefile @@ -6,9 +6,10 @@ 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 + XMLRPMWrap.cpp XMLScript.cpp XMLSource.cpp XMLSpec.cpp \ + xml2spec.cpp CPPOBJS = $(CPPSRCS:.cpp=.o) -INCS = -I. -I.. -I../build -I../lib -I../rpmdb -I../rpmio -I../popt +INCS = -I. -I.. -I../build -I../lib -I../popt -I../rpmio LIBDIR = #-L../build/.libs LIBS = -lexpat -lrpm -lrpmbuild -lrpmdb -lrpmio -lpopt diff --git a/xmlspec/XMLAttrs.cpp b/xmlspec/XMLAttrs.cpp index a20b29a..7a2d9f9 100644 --- a/xmlspec/XMLAttrs.cpp +++ b/xmlspec/XMLAttrs.cpp @@ -41,8 +41,7 @@ XMLAttrs::XMLAttrs(const char** szAttrs) : XMLBase() { for (int i = 0; szAttrs && szAttrs[i]; i += 2) { - XMLAttr attr(szAttrs[i], - szAttrs[i+1]); + XMLAttr attr(szAttrs[i], szAttrs[i+1]); m_vAttrs.push_back(attr); } } @@ -57,6 +56,123 @@ XMLAttrs::~XMLAttrs() { } +static char* szaDays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; +static char* szaMonths[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; +static int naLengths[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +static char* szaBools[] = { "no", "yes", "false", "true", "0", "1", NULL }; + +char* splitStr(const char* szInput, + char cTerm, + int& nLen) +{ + nLen = 0; + while (szInput[nLen] != cTerm && szInput[nLen] != '\0') { + nLen++; + } + char* szTemp = ((char*)szInput)+nLen; + while (*szTemp == ' ' && *szTemp != '\0') + szTemp++; + return szTemp; +} + +int findStr(char* szaMatches[], + const char* szValue, + int nLen = -1) +{ + for (unsigned int i = 0; szaMatches[i] != NULL; i++) { + if (strcmp(szaMatches[i], "*") == 0) + return i; + else if (nLen == -1) { + if (strcasecmp(szaMatches[i], szValue) == 0) + return i; + } + else if (strncasecmp(szaMatches[i], szValue, nLen) == 0) + return i; + } + return -1; +} + +bool isInteger(const char* szValue, + int nLen = -1) +{ + if (nLen == -1) + nLen = strlen(szValue); + for (unsigned int i = 0; i < strlen(szValue); i++) { + if (szValue[i] < '0' || szValue[i] > '9') + return false; + } + return true; +} + +bool isDate(const char* szValue) +{ + int nLen, nPos; + char* szTemp = splitStr(szValue, ' ', nLen); + if ((nPos = findStr(szaDays, szValue, nLen)) != -1) { + if ((nPos = findStr(szaMonths, szTemp, nLen)) != -1) { + szTemp = splitStr(szTemp, ' ', nLen); + char* szBuffer = new char[nLen+1]; + sprintf(szBuffer, "%s", szTemp); + szBuffer[nLen] = '\0'; + if (atoi(szBuffer) <= naLengths[nPos]) { + delete[] szBuffer; + szTemp = splitStr(szTemp, ' ', nLen); + return isInteger(szTemp, nLen); + } + delete[] szBuffer; + } + } + return false; +} + +bool isEmail(const char* szValue) +{ + bool bFound = false; + for (unsigned int j = 0; j < strlen(szValue); j++) { + if (szValue[j] == '@') { + if (bFound) + return false; + else + bFound = true; + } + } + return bFound; +} + +bool validateAttr(structValidAttrs& rAttr, + const char* szValue) +{ + switch (rAttr.m_nType) { + case XATTRTYPE_STRING: + return findStr(rAttr.m_szaMatches, szValue) != -1 ? true : false; + break; + case XATTRTYPE_INTEGER: + return isInteger(szValue); + break; + case XATTRTYPE_BOOL: + return findStr(szaBools, szValue) != -1 ? true : false; + break; + case XATTRTYPE_DATE: + return isDate(szValue); + break; + case XATTRTYPE_MAIL: + return isEmail(szValue); + break; + case XATTRTYPE_NONE: + default: + return true; + break; + } + return false; +} + +static char* szaTypeDesc[] = { "string", + "integer", + "bool [Values: true|false]", + "date [Format: DDD MMM DD YYYY]", + "e-mail" }; + bool XMLAttrs::validate(structValidAttrs* paValids, XMLBase* pError) { @@ -69,8 +185,16 @@ bool XMLAttrs::validate(structValidAttrs* paValids, 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; + paValids[j].m_bFound = true; + if (!validateAttr(paValids[j], get(i).asString())) { + char szTmp[1024]; + sprintf(szTmp, "Attribute value '%s' is not a valid %s.", + get(i).asString(), szaTypeDesc[paValids[j].m_nType]); + pError->setError(szTmp); + return false; + } + else + bInvalid = false; break; } } @@ -96,14 +220,32 @@ bool XMLAttrs::validate(structValidAttrs* paValids, return true; } -const char* XMLAttrs::get(const char* szName) +unsigned int getPos(const char* szName, + XMLAttrs* pAttrs) { - if (szName) - { - for (unsigned int i = 0; i < num(); i++) { - if (strcasecmp(szName, get(i).getName()) == 0) - return get(i).getValue(); + if (szName) { + for (unsigned int i = 0; i < pAttrs->num(); i++) { + if (strcasecmp(szName, pAttrs->get(i).getName()) == 0) + return i; } } - return NULL; + return XATTR_END; +} + +const char* XMLAttrs::asString(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? NULL : get(nPos).asString(); +} + +unsigned int XMLAttrs::asInteger(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? 0 : get(nPos).asInteger(); +} + +bool XMLAttrs::asBool(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? true : get(nPos).asBool(); } diff --git a/xmlspec/XMLAttrs.h b/xmlspec/XMLAttrs.h index 4ae4d28..8498050 100644 --- a/xmlspec/XMLAttrs.h +++ b/xmlspec/XMLAttrs.h @@ -5,13 +5,27 @@ #include #include +// standard C includes +#include + // our includes #include "XMLBase.h" using namespace std; // definition for the end of the attributes -#define XATTR_END 0xFFFF +#define XATTR_END 0xFFFF +#define XATTR_NUM_VALSTR 5 + +enum eAttrType +{ + XATTRTYPE_STRING = 0, + XATTRTYPE_INTEGER, + XATTRTYPE_BOOL, + XATTRTYPE_DATE, + XATTRTYPE_MAIL, + XATTRTYPE_NONE = XATTR_END +}; struct structValidAttrs { @@ -19,6 +33,8 @@ struct structValidAttrs bool m_bMandatory; bool m_bFound; char* m_szName; + unsigned int m_nType; + char* m_szaMatches[XATTR_NUM_VALSTR+1]; }; // forward class definitions @@ -84,16 +100,43 @@ public: } /** - * Returns the attribute value + * Returns the attribute value (as string) * . * @param none * @return string containing the attribute value **/ - const char* getValue() + const char* asString() { return m_sValue.c_str(); } + /** + * Returns the attribute value (as integer) + * . + * @param none + * @return the attribute as an integer + **/ + unsigned int asInteger() + { + return atoi(m_sValue.c_str()); + } + + /** + * Returns the attribute value as a boolean + * . + * @param none + * @return true if set, false otherwise + **/ + bool asBool() + { + bool isSet = true; + if (strcasecmp(m_sValue.c_str(), "no") == 0 || + strcasecmp(m_sValue.c_str(), "0") == 0 || + strcasecmp(m_sValue.c_str(), "false") == 0) + isSet = false; + return isSet; + } + // // member variables // @@ -149,15 +192,6 @@ public: 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 // @@ -184,6 +218,33 @@ public: return m_vAttrs[nNum]; } + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as a string + **/ + const char* asString(const char* szName); + + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as an integer + **/ + unsigned int asInteger(const char* szName); + + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as a bool + **/ + bool asBool(const char* szName); + // // protected data members // diff --git a/xmlspec/XMLChangelog.cpp b/xmlspec/XMLChangelog.cpp index 52aaf9a..5110789 100644 --- a/xmlspec/XMLChangelog.cpp +++ b/xmlspec/XMLChangelog.cpp @@ -3,6 +3,7 @@ // our includes #include "XMLChangelog.h" +#include "XMLRPMWrap.h" #include "XMLSpec.h" using namespace std; @@ -48,11 +49,11 @@ void XMLChangelogEntry::toXMLFile(ostream& rOut) // 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"} + {0x0000, true, false, "date", XATTRTYPE_DATE, {NULL}}, + {0x0001, true, false, "author", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "author-email", XATTRTYPE_MAIL, {NULL}}, + {0x0003, false, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLChangelogDate::parseCreate(XMLAttrs* pAttrs, @@ -62,10 +63,10 @@ bool XMLChangelogDate::parseCreate(XMLAttrs* pAttrs, if (!pAttrs->validate(g_paChangelogDateAttrs, (XMLBase*)pSpec)) return false; - XMLChangelogDate date(pAttrs->get("date"), - pAttrs->get("author"), - pAttrs->get("author-email"), - pAttrs->get("version")); + XMLChangelogDate date(pAttrs->asString("date"), + pAttrs->asString("author"), + pAttrs->asString("author-email"), + pAttrs->asString("version")); pSpec->getChangelog().addDate(date); return true; } @@ -130,6 +131,14 @@ void XMLChangelogDate::toXMLFile(ostream& rOut) } } +bool XMLChangelog::structCreate(Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec) + return false; + return true; +} + XMLChangelog::XMLChangelog() : XMLBase() { diff --git a/xmlspec/XMLChangelog.h b/xmlspec/XMLChangelog.h index 959936d..45c7b43 100644 --- a/xmlspec/XMLChangelog.h +++ b/xmlspec/XMLChangelog.h @@ -308,6 +308,20 @@ protected: class XMLChangelog : public XMLBase { // +// static factory functions +// +public: + /** + * Creates changelog objects from an RPM Spec structure + * . + * @param pSpec Pointer to the RPM spec + * @param pXSpec pointer to the XMLSpec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(Spec pSpec, + XMLSpec* pXSpec); + +// // constructors/destructor // public: diff --git a/xmlspec/XMLFiles.cpp b/xmlspec/XMLFiles.cpp index f4da05a..bccd493 100644 --- a/xmlspec/XMLFiles.cpp +++ b/xmlspec/XMLFiles.cpp @@ -7,15 +7,21 @@ #include "XMLPackage.h" #include "XMLSpec.h" +// rpm includes +#include +#include + 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"} + {0x0000, false, false, "attr", XATTRTYPE_INTEGER, {NULL}}, + {0x0001, false, false, "gid", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "uid", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "config", XATTRTYPE_STRING, {"noreplace", + "*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLFile::parseCreate(XMLAttrs* pAttrs, @@ -27,10 +33,8 @@ bool XMLFile::parseCreate(XMLAttrs* pAttrs, return false; // create and return - XMLFile file(pAttrs->get("attr"), - pAttrs->get("uid"), - pAttrs->get("gid"), - szPath); + XMLFile file(pAttrs->asString("attr"), pAttrs->asString("uid"), + pAttrs->asString("gid"), pAttrs->asString("config"), szPath); pSpec->lastPackage().getFiles().addFile(file); return true; } @@ -38,6 +42,7 @@ bool XMLFile::parseCreate(XMLAttrs* pAttrs, XMLFile::XMLFile(const char* szAttr, const char* szOwner, const char* szGroup, + const char* szConfig, const char* szPath) : XMLBase() { @@ -47,6 +52,8 @@ XMLFile::XMLFile(const char* szAttr, m_sOwner.assign(szOwner); if (szGroup) m_sGroup.assign(szGroup); + if (szConfig) + m_sConfig.assign(szConfig); if (szPath) m_sPath.assign(szPath); } @@ -57,6 +64,7 @@ XMLFile::XMLFile(const XMLFile& rFile) m_sAttr.assign(rFile.m_sAttr); m_sOwner.assign(rFile.m_sOwner); m_sGroup.assign(rFile.m_sGroup); + m_sConfig.assign(rFile.m_sConfig); m_sPath.assign(rFile.m_sPath); } @@ -69,6 +77,7 @@ XMLFile XMLFile::operator=(XMLFile file) m_sAttr.assign(file.m_sAttr); m_sOwner.assign(file.m_sOwner); m_sGroup.assign(file.m_sGroup); + m_sConfig.assign(file.m_sConfig); m_sPath.assign(file.m_sPath); } @@ -81,6 +90,9 @@ void XMLFile::toSpecFile(ostream& rOut) rOut << "," << (hasGroup() ? getGroup() : "-"); rOut << ") "; } + if (hasConfig()) { + rOut << "%config(" << getConfig() << ") "; + } rOut << getPath() << endl; } @@ -93,6 +105,8 @@ void XMLFile::toXMLFile(ostream& rOut) rOut << " uid=\"" << getOwner() << "\""; if (hasGroup()) rOut << " gid=\"" << getAttr() << "\""; + if (hasConfig()) + rOut << " config=\"" << getConfig() << "\""; rOut << ">"; rOut << getPath() << ""; } @@ -100,10 +114,10 @@ void XMLFile::toXMLFile(ostream& rOut) // attribute structure for XMLFiles structValidAttrs g_paFilesAttrs[] = { - {0x0000, false, false, "attr"}, - {0x0001, false, false, "gid"}, - {0x0002, false, false, "uid"}, - {XATTR_END, false, false, "end"} + {0x0000, false, false, "attr", XATTRTYPE_INTEGER, {NULL}}, + {0x0001, false, false, "gid", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "uid", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLFiles::parseCreate(XMLAttrs* pAttrs, @@ -113,9 +127,19 @@ bool XMLFiles::parseCreate(XMLAttrs* pAttrs, 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")); + pSpec->lastPackage().getFiles().setDefAttr(pAttrs->asString("attr")); + pSpec->lastPackage().getFiles().setDefOwner(pAttrs->asString("uid")); + pSpec->lastPackage().getFiles().setDefGroup(pAttrs->asString("gid")); + return true; +} + +bool XMLFiles::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pPackage || !pPackage->fileList) + return false; + return true; } diff --git a/xmlspec/XMLFiles.h b/xmlspec/XMLFiles.h index 7cf9444..681fd21 100644 --- a/xmlspec/XMLFiles.h +++ b/xmlspec/XMLFiles.h @@ -13,6 +13,9 @@ #include "XMLAttrs.h" #include "XMLBase.h" +// rpm includes +#include + // forward class definitions class XMLPackage; class XMLFiles; @@ -50,12 +53,14 @@ public: * @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 szConfig The configuration parameter * @param szPath The file path * @return none **/ XMLFile(const char* szAttr, const char* szOwner, const char* szGroup, + const char* szConfig, const char* szPath); /** @@ -187,14 +192,37 @@ public: return m_sGroup.c_str(); } + /** + * Checks for config directives + * . + * @param none + * @return true if we have one, false otherwise + **/ + bool hasConfig() + { + return m_sConfig.length() ? true : false; + } + + /** + * Returns the config attribute + * . + * @param none + * @return the sttribute string + **/ + const char* getConfig() + { + return m_sConfig.c_str(); + } + // // member variables // protected: - string m_sPath; - string m_sAttr; - string m_sOwner; - string m_sGroup; + string m_sPath; + string m_sAttr; + string m_sOwner; + string m_sGroup; + string m_sConfig; }; // @@ -214,6 +242,18 @@ public: static bool parseCreate(XMLAttrs* pAttrs, XMLSpec* pSpec); + /** + * Creates file objects from an RPM Spec structure + * . + * @param pPackage Pointer to the package + * @param pSpec Pointer to the RPM spec + * @param pXSpec pointer to the XMLSpec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + // // constructors/destructor // diff --git a/xmlspec/XMLMacro.cpp b/xmlspec/XMLMacro.cpp index 31f0b21..5ff9e1b 100644 --- a/xmlspec/XMLMacro.cpp +++ b/xmlspec/XMLMacro.cpp @@ -7,8 +7,8 @@ using namespace std; // attribute structure for XMLMacro structValidAttrs g_paMacroAttrs[] = { - {0x0000, true, false, "name"}, - {XATTR_END, false, false, "end"} + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLMacro::parseCreate(XMLAttrs* pAttrs, @@ -17,7 +17,7 @@ bool XMLMacro::parseCreate(XMLAttrs* pAttrs, { if (!pSpec || !szMacro || !pAttrs->validate(g_paMacroAttrs, (XMLBase*)pAttrs)) return false; - XMLMacro macro(pAttrs->get("name"), szMacro); + XMLMacro macro(pAttrs->asString("name"), szMacro); pSpec->addXMacro(macro); return true; } diff --git a/xmlspec/XMLMirror.cpp b/xmlspec/XMLMirror.cpp index a94a4cf..6f7251c 100644 --- a/xmlspec/XMLMirror.cpp +++ b/xmlspec/XMLMirror.cpp @@ -7,10 +7,10 @@ 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"} + {0x0000, true, false, "path", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "description", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "country", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLMirror::parseCreate(XMLAttrs* pAttrs, @@ -21,9 +21,9 @@ bool XMLMirror::parseCreate(XMLAttrs* pAttrs, if (!pAttrs->validate(g_paMirrorAttrs, (XMLBase*)pSpec)) return false; - XMLMirror mirror(pAttrs->get("path"), - pAttrs->get("description"), - pAttrs->get("country")); + XMLMirror mirror(pAttrs->asString("path"), + pAttrs->asString("description"), + pAttrs->asString("country")); if (bPatch && pSpec->numPatches()) pSpec->lastPatch().addMirror(mirror); else if (!bPatch && pSpec->numSources()) diff --git a/xmlspec/XMLPackage.cpp b/xmlspec/XMLPackage.cpp index 39a81c6..a6fc2c9 100644 --- a/xmlspec/XMLPackage.cpp +++ b/xmlspec/XMLPackage.cpp @@ -3,15 +3,22 @@ // our includes #include "XMLPackage.h" +#include "XMLRPMWrap.h" #include "XMLSpec.h" +// rpm includes +#include + // attribute structure for XMLPackage structValidAttrs g_paPackageAttrs[] = { - {0x0000, false, false, "name"}, - {0x0001, false, false, "group"}, - {0x0002, false, false, "sub"}, - {XATTR_END, false, false, "end"} + {0x0000, false, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "group", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "autoreq", XATTRTYPE_BOOL, {NULL}}, + {0x0003, false, false, "autoprov", XATTRTYPE_BOOL, {NULL}}, + {0x0004, false, false, "autoreqprov", XATTRTYPE_BOOL, {NULL}}, + {0x0005, false, false, "sub", XATTRTYPE_BOOL, {NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLPackage::parseCreate(XMLAttrs* pAttrs, @@ -23,33 +30,61 @@ bool XMLPackage::parseCreate(XMLAttrs* pAttrs, // 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 (pAttrs->asString("name")) + sName.assign(pAttrs->asString("name")); // 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); + XMLPackage package(sName.c_str(), pAttrs->asString("group"), + pAttrs->asBool("autoreq") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("autoprov") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("sub")); pSpec->addPackage(package); } // already something existing with %{name} ? else { - XMLPackage package(NULL, - pAttrs->get("group"), - bSub); + XMLPackage package(NULL, pAttrs->asString("group"), + pAttrs->asBool("autoreq") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("autoprov") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("sub")); pSpec->addPackage(package); } return true; } +bool XMLPackage::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pPackage || !pPackage->header) + return false; + + string sSummary, sGroup, sName; + if (!getRPMHeader(pPackage->header, RPMTAG_GROUP, sGroup) || + !getRPMHeader(pPackage->header, RPMTAG_GROUP, sSummary)) + return false; + getRPMHeader(pPackage->header, RPMTAG_NAME, sName); + bool bSub = false; + if (sName.compare(pXSpec->getName()) == 0) { + bSub = true; + } + // TODO: Description to be added.... + + XMLPackage package(bSub ? NULL : sName.c_str(), sGroup.c_str(), + pPackage->autoReq ? true : false, + pPackage->autoProv ? true : false, + bSub); + package.setSummary(sSummary.c_str()); + pXSpec->addPackage(package); + XMLPackageContainer::structCreate(pPackage, pSpec, pXSpec); + XMLFiles::structCreate(pPackage, pSpec, pXSpec); + + // do the next package and return + XMLPackage::structCreate(pPackage->next, pSpec, pXSpec); + return true; +} + bool XMLPackage::setDescription(const char* szDescription, XMLSpec* pSpec) { @@ -74,6 +109,8 @@ bool XMLPackage::setSummary(const char* szSummary, XMLPackage::XMLPackage(const char* szName, const char* szGroup, + bool bAutoReq, + bool bAutoProv, bool bSub) : XMLBase() { @@ -82,6 +119,8 @@ XMLPackage::XMLPackage(const char* szName, if (szGroup) m_sGroup.assign(szGroup); m_bSub = bSub; + m_bAutoReq = bAutoReq; + m_bAutoProv = bAutoProv; } XMLPackage::XMLPackage(const XMLPackage& rPackage) @@ -92,6 +131,8 @@ XMLPackage::XMLPackage(const XMLPackage& rPackage) m_sSummary.assign(rPackage.m_sSummary); m_sDescription.assign(rPackage.m_sDescription); m_bSub = rPackage.m_bSub; + m_bAutoReq = rPackage.m_bAutoReq; + m_bAutoProv = rPackage.m_bAutoProv; m_Requires = rPackage.m_Requires; m_BuildRequires = rPackage.m_BuildRequires; m_Provides = rPackage.m_Provides; @@ -118,13 +159,19 @@ void XMLPackage::toSpecFile(ostream& rOut) else rOut << endl << endl; - // add the summary + // add the "optional' stuff if (hasSummary()) rOut << "summary: " << getSummary() << endl; - - // do we have a group? if (hasGroup()) rOut << "group: " << getGroup() << endl; + if (!hasAutoRequires() && !hasAutoProvides()) + rOut << "autoreqprov: no" << endl; + else { + if (!hasAutoRequires()) + rOut << "autoreq: no" << endl; + if (!hasAutoProvides()) + rOut << "autoprov: no" << endl; + } getProvides().toSpecFile(rOut, "provides"); getObsoletes().toSpecFile(rOut, "obsoletes"); @@ -199,7 +246,16 @@ void XMLPackage::toXMLFile(ostream& rOut) } if (hasGroup()) rOut << " group=\"" << getGroup() << "\""; + if (!hasAutoRequires() && !hasAutoProvides()) + rOut << " autoreqprov=\"no\""; + else { + if (!hasAutoRequires()) + rOut << " autoreq=\"no\""; + if (!hasAutoProvides()) + rOut << " autoprov=\"no\""; + } rOut << ">"; + if (hasSummary()) rOut << endl << "\t\t" << getSummary() << "\t\t"; if (hasDescription()) diff --git a/xmlspec/XMLPackage.h b/xmlspec/XMLPackage.h index a2202a4..6e4b58e 100644 --- a/xmlspec/XMLPackage.h +++ b/xmlspec/XMLPackage.h @@ -41,6 +41,18 @@ public: XMLSpec* pSpec); /** + * Creates package objects from an RPM Spec structure + * . + * @param pPackage Pointer to the start package + * @param pSpec pointer to the RPM spec + * @param pXSpec Pointer to the spec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + + /** * Sets the description for the last package * . * @param szDescription the description @@ -69,11 +81,15 @@ public: * . * @param szName The package name * @param szGroup The group this package belongs to + * @param bAutoReq Auto Requires + * @param bAutoProv Auto Provides * @param bSub true if this is a sub-package * @return none **/ XMLPackage(const char* szName, const char* szGroup, + bool bAutoReq, + bool bAutoProv, bool bSub); /** @@ -196,6 +212,28 @@ public: } /** + * Tests for auto requires + * . + * @param none + * @return true if we have auto requires, false otherwise + **/ + bool hasAutoRequires() + { + return m_bAutoReq; + } + + /** + * Tests for auto requires + * . + * @param none + * @return true if we have auto requires, false otherwise + **/ + bool hasAutoProvides() + { + return m_bAutoProv; + } + + /** * Checks if we have a summary * . * @param none @@ -382,6 +420,8 @@ protected: string m_sSummary; string m_sDescription; bool m_bSub; + bool m_bAutoReq; + bool m_bAutoProv; XMLPackageContainer m_Requires; XMLPackageContainer m_BuildRequires; XMLPackageContainer m_Provides; diff --git a/xmlspec/XMLParser.cpp b/xmlspec/XMLParser.cpp index 8045a71..ac89214 100644 --- a/xmlspec/XMLParser.cpp +++ b/xmlspec/XMLParser.cpp @@ -50,6 +50,10 @@ enum enumXMLTAGValid XTAG_NO = 0x0000, XTAG_WRONGSTRUCT, XTAG_SPEC, + XTAG_EXCLUDEARCH, + XTAG_EXCLUDEOS, + XTAG_EXCLUSIVEARCH, + XTAG_EXCLUSIVEOS, XTAG_SOURCE, XTAG_PATCH, XTAG_NOSOURCE, @@ -524,6 +528,46 @@ void startDepth2(structCBData* pData) else if (pData->m_pSpec->hasWarning()) createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); break; + case XTAG_PRE: + if (!XMLPackageScripts::createPreScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' 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::createPostScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' 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::createPreUnScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' 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::createPostUnScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' 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::createVerifyScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' 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: diff --git a/xmlspec/XMLRequires.cpp b/xmlspec/XMLRequires.cpp index 3840c8c..8c6893e 100644 --- a/xmlspec/XMLRequires.cpp +++ b/xmlspec/XMLRequires.cpp @@ -2,17 +2,21 @@ #include "XMLAttrs.h" #include "XMLPackage.h" #include "XMLRequires.h" +#include "XMLRPMWrap.h" #include "XMLSpec.h" +// rpm includes +#include + 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"} + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "cmp", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLPackageEntry::parseCreate(XMLAttrs* pAttrs, @@ -23,9 +27,8 @@ bool XMLPackageEntry::parseCreate(XMLAttrs* pAttrs, return false; // create and return - XMLPackageEntry entry(pAttrs->get("name"), - pAttrs->get("version"), - pAttrs->get("cmp")); + XMLPackageEntry entry(pAttrs->asString("name"), pAttrs->asString("version"), + pAttrs->asString("cmp")); rContainer.addEntry(entry); return true; } @@ -175,3 +178,12 @@ bool XMLPackageContainer::addObsolete(XMLAttrs* pAttrs, return false; return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getObsoletes()); } + +bool XMLPackageContainer::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pPackage || !pPackage->header) + return false; + return true; +} diff --git a/xmlspec/XMLRequires.h b/xmlspec/XMLRequires.h index 4fc9fd6..8daccad 100644 --- a/xmlspec/XMLRequires.h +++ b/xmlspec/XMLRequires.h @@ -204,6 +204,18 @@ public: static bool addObsolete(XMLAttrs* pAttrs, XMLSpec* pSpec); + /** + * Adds requires/provides/obsoletes from RPM structures + * . + * @param pPackage pointer to the RPM package + * @param pSpec pointer to the RPM spec + * @param pXSpec pointer to the XML spec to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + // // constructors/destructor // diff --git a/xmlspec/XMLScript.cpp b/xmlspec/XMLScript.cpp index 7b808ec..ccfb699 100644 --- a/xmlspec/XMLScript.cpp +++ b/xmlspec/XMLScript.cpp @@ -9,8 +9,9 @@ // attribute structure for XMLScript structValidAttrs g_paScriptAttrs[] = { - {0x0000, false, false, "dir"}, - {XATTR_END, false, false, "end"} + {0x0000, false, false, "dir", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "interpreter", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLScript::parseCreate(XMLAttrs* pAttrs, @@ -19,17 +20,22 @@ bool XMLScript::parseCreate(XMLAttrs* pAttrs, { if (!pAttrs->validate(g_paScriptAttrs, (XMLBase*)pAttrs)) return false; - XMLScript script(szScript, pAttrs->get("dir")); + XMLScript script(szScript, + pAttrs->asString("interpreter"), + pAttrs->asString("dir")); rContainer.add(script); return true; } XMLScript::XMLScript(const char* szScript, + const char* szInterpreter, const char* szDir) : XMLBase() { if (szScript) m_sValue.assign(szScript); + if (szInterpreter) + m_sInterpreter.assign(szInterpreter); if (szDir) m_sDir.assign(szDir); } @@ -38,6 +44,7 @@ XMLScript::XMLScript(const XMLScript& rScript) : XMLBase() { m_sValue.assign(rScript.m_sValue); + m_sInterpreter.assign(rScript.m_sInterpreter); m_sDir.assign(rScript.m_sDir); } @@ -48,6 +55,7 @@ XMLScript::~XMLScript() XMLScript XMLScript::operator=(XMLScript script) { m_sValue.assign(script.m_sValue); + m_sInterpreter.assign(script.m_sInterpreter); m_sDir.assign(script.m_sDir); } @@ -70,7 +78,7 @@ void XMLScript::toXMLFile(ostream& rOut, void XMLScript::toRPMStruct(StringBuf* pSB) { if (hasDirectory()) { - char szBuff[getDirectoryLen()+3+1]; + char szBuff[getDirectoryLen()+3+1]; // 3 == strlen("cd ") sprintf(szBuff, "cd %s", getDirectory()); appendStringBuf(*pSB, szBuff); } @@ -198,6 +206,51 @@ bool XMLPackageScripts::addVerifyScript(XMLAttrs* pAttrs, return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getVerify()); } +bool XMLPackageScripts::createPreScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPre().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPostScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPost().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPreUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPreUn().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPostUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPostUn().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createVerifyScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getVerify().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + XMLPackageScripts::XMLPackageScripts() : XMLScripts() { diff --git a/xmlspec/XMLScript.h b/xmlspec/XMLScript.h index 9b6e332..fd6d8ac 100644 --- a/xmlspec/XMLScript.h +++ b/xmlspec/XMLScript.h @@ -46,10 +46,12 @@ public: * Default constructor * . * @param szScript The script + * @param szInterpreter The interpreter to use for script execution * @param szDir Directory to execute the script in * @return none **/ XMLScript(const char* szScript, + const char* szInterpreter, const char* szDir); /** @@ -126,6 +128,28 @@ public: } /** + * Checks if we have an interpreter + * . + * @param none + * @return true if we have an interpreter, false otherwise + **/ + bool hasInterpreter() + { + return m_sInterpreter.length() ? true : false; + } + + /** + * Gets the interpreter + * . + * @param none + * @return string contating the interpreter + **/ + const char* getInterpreter() + { + return m_sInterpreter.c_str(); + } + + /** * Checks if we have a direcory * . * @param none @@ -163,6 +187,7 @@ public: // public: string m_sValue; + string m_sInterpreter; string m_sDir; }; @@ -246,6 +271,40 @@ public: // public: /** + * Checks if we have an interpreter + * . + * @param none + * @return true if we have an interpreter, false otherwise + **/ + bool hasInterpreter() + { + return m_sInterpreter.length() ? true : false; + } + + /** + * Gets the interpreter + * . + * @param none + * @return string contatining the interpreter + **/ + const char* getInterpreter() + { + return m_sInterpreter.c_str(); + } + + /** + * Sets the script interpreter + * . + * @param szInterpreter The interpreter + * @return none + **/ + void setInterpreter(const char* szInterpreter) + { + if (szInterpreter) + m_sInterpreter.assign(szInterpreter); + } + + /** * Gets the number of script entries * . * @param none @@ -282,6 +341,7 @@ public: // member variables // protected: + string m_sInterpreter; vector m_vScripts; }; @@ -351,6 +411,57 @@ public: static bool addVerifyScript(XMLAttrs* pAttrs, const char* szScript, XMLSpec* pSpec); + + /** + * Initialises a pre script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPreScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a post script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPostScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a preun script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPreUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a postun script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPostUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a verify script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createVerifyScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + // // constructors/destructors // diff --git a/xmlspec/XMLSource.cpp b/xmlspec/XMLSource.cpp index a01e1e9..02cba34 100644 --- a/xmlspec/XMLSource.cpp +++ b/xmlspec/XMLSource.cpp @@ -11,77 +11,70 @@ using namespace std; bool XMLSource::structCreate(Source* pSource, - XMLSpec* pSpec) + Spec pSpec, + XMLSpec* pXSpec) { - if (!pSpec || !pSource) + if (!pXSpec || !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)); + // 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); + pXSpec->addSource(*pXSource); + if (pMirror) + pXSpec->lastSource().addMirror(*pMirror); + delete pXSource; + break; + case RPMBUILD_ISNO: + pXNoSource = new XMLNoSource(pSource->source, pSource->num, + NULL, NULL, NULL); + pXSpec->addNoSource(*pXNoSource); + if (pMirror) + pXSpec->lastNoSource().addMirror(*pMirror); + delete pXNoSource; + break; + case RPMBUILD_ISPATCH: + pXPatch = new XMLPatch(pSource->source, pSource->num, NULL, NULL); + pXSpec->addPatch(*pXPatch); + if (pMirror) + pXSpec->lastPatch().addMirror(*pMirror); + delete pXPatch; + break; + default: + break; + } + if (pMirror) + delete pMirror; + + // do the next source and return + XMLSource::structCreate(pSource->next, pSpec, pXSpec); 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"} + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "num", XATTRTYPE_INTEGER, {NULL}}, + {0x0002, false, false, "dir", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "size", XATTRTYPE_INTEGER, {NULL}}, + {0x0004, false, false, "md5", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLSource::parseCreate(XMLAttrs* pAttrs, @@ -91,15 +84,9 @@ bool XMLSource::parseCreate(XMLAttrs* pAttrs, 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")); + XMLSource source(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("dir"), pAttrs->asString("size"), + pAttrs->asString("md5")); pSpec->addSource(source); return true; @@ -210,14 +197,9 @@ bool XMLNoSource::parseCreate(XMLAttrs* pAttrs, 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")); + XMLNoSource source(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("dir"), pAttrs->asString("size"), + pAttrs->asString("md5")); pSpec->addNoSource(source); return true; } @@ -274,11 +256,11 @@ void XMLNoSource::toRPMStruct(Spec pRPMSpec) // 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"} + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "num", XATTRTYPE_INTEGER, {NULL}}, + {0x0002, false, false, "size", XATTRTYPE_INTEGER, {NULL}}, + {0x0003, false, false, "md5", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; bool XMLPatch::parseCreate(XMLAttrs* pAttrs, @@ -288,13 +270,8 @@ bool XMLPatch::parseCreate(XMLAttrs* pAttrs, 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")); + XMLPatch patch(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("size"), pAttrs->asString("md5")); pSpec->addPatch(patch); return true; } diff --git a/xmlspec/XMLSource.h b/xmlspec/XMLSource.h index 9457bb4..1084b94 100644 --- a/xmlspec/XMLSource.h +++ b/xmlspec/XMLSource.h @@ -33,12 +33,14 @@ public: * Static factory function for the creation of XMLSource, XMLPatch, ... * objects from RPM Source* structure. * . - * @param pSpource Pointer to a list of sources + * @param pSource Pointer to a list of sources + * @param pSpec pointer to the RPM spec * @param pSpec pointer to our spec object * @return true on success, false otherwise **/ static bool structCreate(Source* pSource, - XMLSpec* pSpec); + Spec pSpec, + XMLSpec* pXSpec); /** * Static factory function for the creation of an XMLSource diff --git a/xmlspec/XMLSpec.cpp b/xmlspec/XMLSpec.cpp index 0e18640..2f4e69d 100644 --- a/xmlspec/XMLSpec.cpp +++ b/xmlspec/XMLSpec.cpp @@ -3,25 +3,29 @@ // our includes #include "XMLAttrs.h" +#include "XMLRPMWrap.h" #include "XMLSpec.h" +// rpm includes +#include + 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"} + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, true, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, true, false, "release", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "epoch", XATTRTYPE_INTEGER, {NULL}}, + {0x0004, false, false, "distribution", XATTRTYPE_STRING, {"*", NULL}}, + {0x0005, false, false, "vendor", XATTRTYPE_STRING, {"*", NULL}}, + {0x0006, false, false, "packager", XATTRTYPE_STRING, {"*", NULL}}, + {0x0007, false, false, "packager-email", XATTRTYPE_MAIL, {"*", NULL}}, + {0x0008, false, false, "copyright", XATTRTYPE_STRING, {"*", NULL}}, + {0x0009, false, false, "url", XATTRTYPE_STRING, {"*", NULL}}, + {0x000A, false, false, "buildroot", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} }; XMLSpec* XMLSpec::parseCreate(XMLAttrs* pAttrs, @@ -33,40 +37,49 @@ XMLSpec* XMLSpec::parseCreate(XMLAttrs* pAttrs, // 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")); + pAttrs->asString("name"), + pAttrs->asString("version"), + pAttrs->asString("release"), + pAttrs->asString("epoch"), + pAttrs->asString("distribution"), + pAttrs->asString("vendor"), + pAttrs->asString("packager"), + pAttrs->asString("packager-email"), + pAttrs->asString("copyright"), + pAttrs->asString("url"), + pAttrs->asString("buildroot")); } -XMLSpec* XMLSpec::structCreate(Spec spec) +XMLSpec* XMLSpec::structCreate(Spec pSpec) { - if (!spec) + if (!pSpec || !pSpec->packages || !pSpec->packages->header) 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; + // create the spec with values from the RPM stuff + string sName, sVersion, sRelease, sEpoch, sDistro; + string sVendor, sPackager, sMail, sLicense, sURL; + if (!getRPMHeader(pSpec->packages->header, RPMTAG_NAME, sName) || + !getRPMMacro("PACKAGE_VERSION", sVersion) || + !getRPMMacro("PACKAGE_RELEASE", sRelease)) + return NULL; + getRPMHeader(pSpec->packages->header, RPMTAG_EPOCH, sEpoch); + getRPMHeader(pSpec->packages->header, RPMTAG_DISTRIBUTION, sDistro); + getRPMHeader(pSpec->packages->header, RPMTAG_VENDOR, sVendor); + getRPMHeader(pSpec->packages->header, RPMTAG_PACKAGER, sPackager); + getRPMHeader(pSpec->packages->header, RPMTAG_LICENSE, sLicense); + getRPMHeader(pSpec->packages->header, RPMTAG_URL, sURL); + XMLSpec* pXSpec = new XMLSpec(pSpec->specFile, sName.c_str(), sVersion.c_str(), + sRelease.c_str(), sEpoch.c_str(), sDistro.c_str(), + sVendor.c_str(), sPackager.c_str(), sMail.c_str(), + sLicense.c_str(), sURL.c_str(), pSpec->buildRootURL); + + // add sources, packages all kinds of funny stuff + XMLChangelog::structCreate(pSpec, pXSpec); + XMLSource::structCreate(pSpec->sources, pSpec, pXSpec); + XMLPackage::structCreate(pSpec->packages, pSpec, pXSpec); + + // return the created spec + return pXSpec; } XMLSpec::XMLSpec(const char* szFilename, diff --git a/xmlspec/XMLSpec.h b/xmlspec/XMLSpec.h index 5550a5a..48f361a 100644 --- a/xmlspec/XMLSpec.h +++ b/xmlspec/XMLSpec.h @@ -40,10 +40,10 @@ public: /** * Creates and XMLSpec from an RPM Spec structure * . - * @param spec The RPM spec structure + * @param pSpec The RPM spec structure * @return Pointer to the created spec **/ - static XMLSpec* structCreate(Spec spec); + static XMLSpec* structCreate(Spec pSpec); // // constructors/destructor diff --git a/xmlspec/example.spec.xml b/xmlspec/example.spec.xml index 791c260..83abaec 100644 --- a/xmlspec/example.spec.xml +++ b/xmlspec/example.spec.xml @@ -68,7 +68,7 @@ This spec is just an example for some funny purpose. %{summary} - + @@ -142,6 +142,12 @@ + + Added attribute "interpreter" to script +