Update from "Jaco Greeff" <jaco@puxedo.org>.
authorjbj <devnull@localhost>
Tue, 4 Jun 2002 15:06:36 +0000 (15:06 +0000)
committerjbj <devnull@localhost>
Tue, 4 Jun 2002 15:06:36 +0000 (15:06 +0000)
CVS patchset: 5462
CVS date: 2002/06/04 15:06:36

21 files changed:
xmlspec/Makefile
xmlspec/XMLAttrs.cpp
xmlspec/XMLAttrs.h
xmlspec/XMLChangelog.cpp
xmlspec/XMLChangelog.h
xmlspec/XMLFiles.cpp
xmlspec/XMLFiles.h
xmlspec/XMLMacro.cpp
xmlspec/XMLMirror.cpp
xmlspec/XMLPackage.cpp
xmlspec/XMLPackage.h
xmlspec/XMLParser.cpp
xmlspec/XMLRequires.cpp
xmlspec/XMLRequires.h
xmlspec/XMLScript.cpp
xmlspec/XMLScript.h
xmlspec/XMLSource.cpp
xmlspec/XMLSource.h
xmlspec/XMLSpec.cpp
xmlspec/XMLSpec.h
xmlspec/example.spec.xml

index 6b4fb2a..a3c789d 100644 (file)
@@ -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
 
index a20b29a..7a2d9f9 100644 (file)
@@ -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();
 }
index 4ae4d28..8498050 100644 (file)
@@ -5,13 +5,27 @@
 #include <string>
 #include <vector>
 
+// standard C includes
+#include <string.h>
+
 // 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
 //
index 52aaf9a..5110789 100644 (file)
@@ -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()
 {
index 959936d..45c7b43 100644 (file)
@@ -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:
index f4da05a..bccd493 100644 (file)
@@ -7,15 +7,21 @@
 #include "XMLPackage.h"
 #include "XMLSpec.h"
 
+// rpm includes
+#include <rpmlib.h>
+#include <stringbuf.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"}
+       {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() << "</file>";
 }
@@ -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;
 }
 
index 7cf9444..681fd21 100644 (file)
@@ -13,6 +13,9 @@
 #include "XMLAttrs.h"
 #include "XMLBase.h"
 
+// rpm includes
+#include <rpmbuild.h>
+
 // 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;
 };
 
 // <files ...>
@@ -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
 //
index 31f0b21..5ff9e1b 100644 (file)
@@ -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;
 }
index a94a4cf..6f7251c 100644 (file)
@@ -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())
index 39a81c6..a6fc2c9 100644 (file)
@@ -3,15 +3,22 @@
 
 // our includes
 #include "XMLPackage.h"
+#include "XMLRPMWrap.h"
 #include "XMLSpec.h"
 
+// rpm includes
+#include <rpmlib.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"}
+       {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<summary>" << getSummary() << "\t\t</summary>";
        if (hasDescription())
index a2202a4..6e4b58e 100644 (file)
@@ -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;
index 8045a71..ac89214 100644 (file)
@@ -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:
index 3840c8c..8c6893e 100644 (file)
@@ -2,17 +2,21 @@
 #include "XMLAttrs.h"
 #include "XMLPackage.h"
 #include "XMLRequires.h"
+#include "XMLRPMWrap.h"
 #include "XMLSpec.h"
 
+// rpm includes
+#include <rpmlib.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"}
+       {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;
+}
index 4fc9fd6..8daccad 100644 (file)
@@ -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
 //
index 7b808ec..ccfb699 100644 (file)
@@ -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()
 {
index 9b6e332..fd6d8ac 100644 (file)
@@ -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<XMLScript> 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
 //
index a01e1e9..02cba34 100644 (file)
 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;
 }
index 9457bb4..1084b94 100644 (file)
@@ -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
index 0e18640..2f4e69d 100644 (file)
@@ -3,25 +3,29 @@
 
 // our includes
 #include "XMLAttrs.h"
+#include "XMLRPMWrap.h"
 #include "XMLSpec.h"
 
+// rpm includes
+#include <rpmlib.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"}
+       {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,
index 5550a5a..48f361a 100644 (file)
@@ -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
index 791c260..83abaec 100644 (file)
@@ -68,7 +68,7 @@
                <summary>This spec is just an example for some funny purpose.</summary>
                <description>%{summary}</description>
                 <post>
-                       <script>/sbin/ldconfig</script>
+                       <script interpreter="/bin/sh">/sbin/ldconfig</script>
                </post>
                <postun>
                        <script>/sbin/ldconfig</script>
        </clean>
 
        <changelog>
+               <changes date="Thu May 30 2002"
+                                author="Jaco Greeff"
+                                author-email="jaco@puxedo.org"
+                                version="1.0-04">
+                       <change>Added attribute &quot;interpreter&quot; to script</change>
+               </changes>
                <changes date="Sat May 25 2002"
                                 author="Jaco Greeff"
                                 author-email="jaco@puxedo.org"