moved YUM parser from yast2-packagemanager here, some adaptations
authorJiri Srain <jsrain@suse.cz>
Tue, 15 Nov 2005 13:11:07 +0000 (13:11 +0000)
committerJiri Srain <jsrain@suse.cz>
Tue, 15 Nov 2005 13:11:07 +0000 (13:11 +0000)
44 files changed:
configure.ac
test/devel.jsrain/Makefile.am
test/devel.jsrain/yum/Makefile.am [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.err.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.ref [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/Makefile.am [new file with mode: 0644]
test/devel.jsrain/yum/YUMParser.test/README [new file with mode: 0644]
test/devel.jsrain/yum/YUMtest.cc [new file with mode: 0644]
test/devel.jsrain/yum/testit.sh [new file with mode: 0755]
zypp/Makefile.am
zypp/parser/Makefile.am
zypp/parser/yum/Makefile.am [new file with mode: 0644]
zypp/parser/yum/YUMFileListParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMFileListParser.h [new file with mode: 0644]
zypp/parser/yum/YUMGroupParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMGroupParser.h [new file with mode: 0644]
zypp/parser/yum/YUMOtherParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMOtherParser.h [new file with mode: 0644]
zypp/parser/yum/YUMParser.h [new file with mode: 0644]
zypp/parser/yum/YUMParserData.cc [new file with mode: 0644]
zypp/parser/yum/YUMParserData.h [new file with mode: 0644]
zypp/parser/yum/YUMPatchParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMPatchParser.h [new file with mode: 0644]
zypp/parser/yum/YUMPrimaryParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMPrimaryParser.h [new file with mode: 0644]
zypp/parser/yum/YUMRepomdParser.cc [new file with mode: 0644]
zypp/parser/yum/YUMRepomdParser.h [new file with mode: 0644]
zypp/parser/yum/schemanames.h [new file with mode: 0644]

index 8a23021..6b92a14 100644 (file)
@@ -101,12 +101,14 @@ AC_OUTPUT(        \
        test/Makefile           \
        test/genclass           \
        test/devel.jsrain/Makefile      \
+       test/devel.jsrain/yum/Makefile  \
        test/devel.ma/Makefile          \
        zypp/Makefile           \
        zypp/base/Makefile      \
        zypp/detail/Makefile    \
        zypp/capability/Makefile        \
-       zypp/parser/Makefile
+       zypp/parser/Makefile            \
+       zypp/parser/yum/Makefile
 )
 dnl ==================================================
 
index e947399..45f1784 100644 (file)
@@ -1,6 +1,8 @@
 ## Process this file with automake to produce Makefile.in
 ## ##################################################
 
+SUBDIRS = yum
+
 noinst_PROGRAMS =      Main Main.debug Msg Msg.debug Patch Patch.debug Script Script.debug PatchSelect PatchSelect.debug PatchRead PatchRead.debug
 
 
diff --git a/test/devel.jsrain/yum/Makefile.am b/test/devel.jsrain/yum/Makefile.am
new file mode 100644 (file)
index 0000000..d19cce8
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Makefile.am for packagemanager/testsuite/devel.mir
+#
+
+SUBDIRS = YUMParser.test
+
+AUTOMAKE_OPTIONS = dejagnu
+
+PACKAGE = YUMParser
+
+INCLUDES = -I$(top_srcdir)/zypp/parser/yum -I$(top_srcdir)/zypp -I$(oldincludedir)/libxml2 -I$(includedir)
+
+
+check_PROGRAMS = YUMtest
+
+YUMtest_SOURCES = YUMtest.cc
+YUMtest_LDADD = $(top_builddir)/zypp/libzypp.la /usr/lib/libxml2.a /usr/lib/libz.a
+       
+YUMtest_LDFLAGS = -static
+
+EXTRA_DIST = testit.sh
diff --git a/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml
new file mode 100644 (file)
index 0000000..3f34400
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<repomd xmlns="http://linux.duke.edu/metadata/repo">
+  <data type="other">
+    <location href="repodata/other.xml.gz"/>
+    <checksum type="sha">e7ba668ab0d49486f0a3e7a0b168406a88a46ed9</checksum>
+    <timestamp>1119534896</timestamp>
+    <open-checksum type="sha">394bb178eb19423f1c9f255acfd50719809cabba</open-checksum>
+  </data>
+  <data type="filelists">
+    <location href="repodata/filelists.xml.gz"/>
+    <checksum type="sha">603594e2dd7d875a876babaf1b39f3aede460ef1</checksum>
+    <timestamp>1119534896</timestamp>
+    <open-checksum type="sha">047041a0149308416aa1b62eb5e11a191ca6c2e9</open-checksum>
+  </data>
+  <data type="primary">
+    <location href="repodata/primary.xml.gz"/>
+    <checksum type="sha">20f45621426fcd74364d6fabe6929d1164797801</checksum>
+    <timestamp>1119534896</timestamp>
+    <open-checksum type="sha">e8f9b1f8b3aa049ba3e3e813ee33e37302e9b16a</open-checksum>
+  </data>
+</repomd>
diff --git a/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/001-repomd-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..e4e1bd6
--- /dev/null
@@ -0,0 +1,25 @@
+Repomd Data: 
+  type: 'other'
+  location: 'repodata/other.xml.gz'
+  checksumType: 'sha'
+  checksum: 'e7ba668ab0d49486f0a3e7a0b168406a88a46ed9'
+  timestamp: '1119534896'
+  openChecksumType: 'sha'
+  openChecksum: '394bb178eb19423f1c9f255acfd50719809cabba'
+Repomd Data: 
+  type: 'filelists'
+  location: 'repodata/filelists.xml.gz'
+  checksumType: 'sha'
+  checksum: '603594e2dd7d875a876babaf1b39f3aede460ef1'
+  timestamp: '1119534896'
+  openChecksumType: 'sha'
+  openChecksum: '047041a0149308416aa1b62eb5e11a191ca6c2e9'
+Repomd Data: 
+  type: 'primary'
+  location: 'repodata/primary.xml.gz'
+  checksumType: 'sha'
+  checksum: '20f45621426fcd74364d6fabe6929d1164797801'
+  timestamp: '1119534896'
+  openChecksumType: 'sha'
+  openChecksum: 'e8f9b1f8b3aa049ba3e3e813ee33e37302e9b16a'
+Exit Code: 0
diff --git a/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml
new file mode 100644 (file)
index 0000000..cbd021b
--- /dev/null
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata xmlns="http://linux.duke.edu/metadata/common" 
+          xmlns:rpm="http://linux.duke.edu/metadata/rpm" 
+          xmlns:suse="http://novell.com/package/metadata/suse/common"
+          packages="8">
+<package type="rpm">
+  <name>packetfilter</name>
+  <arch>noarch</arch>
+  <version epoch="0" ver="0.9.1" rel="3"/>
+  <checksum type="sha" pkgid="YES">8121d38334a682f5bf2c8320388395ba7e4b276d</checksum>
+  <summary>A packetfilter wrapper compatible with ipfwadm, ipchains, iptables</summary>
+  <description>This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.</description>
+  <packager/>
+  <url/>
+  <time file="1011218465" build="1011218465"/>
+  <size package="7333" installed="16835" archive="17904"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="packetfilter-0.9.1-3.noarch.rpm"/>
+  <format>
+    <rpm:license>(c) 2002, Michael Radziej, under Gnu LPL</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>unsorted</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm>packetfilter-0.9.1-3.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="168" end="2268"/>
+    <rpm:provides>
+      <rpm:entry name="packetfilter" flags="EQ" epoch="0" ver="0.9.1" rel="3"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="/bin/bash"/>
+      <rpm:entry name="/bin/sh" pre="1"/>
+    </rpm:requires>
+    <file>/etc/packetfilter/def</file>
+    <file>/etc/init.d/packetfilter</file>
+    <file>/usr/sbin/rcpacketfilter</file>
+    <file>/etc/packetfilter/ppp0</file>
+    <file type="dir">/etc/packetfilter</file>
+  </format>
+</package>
+<package type="rpm">
+  <name>packetfilter</name>
+  <arch>noarch</arch>
+  <version epoch="0" ver="0.9.1" rel="4"/>
+  <checksum type="sha" pkgid="YES">5f5547fe534991d161f5cbd9b823276a86eb55ea</checksum>
+  <summary>A packetfilter wrapper compatible with ipfwadm, ipchains, iptables</summary>
+  <description>This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.</description>
+  <packager/>
+  <url/>
+  <time file="1011218885" build="1011218885"/>
+  <size package="9119" installed="23203" archive="25560"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="packetfilter-0.9.1-4.noarch.rpm"/>
+  <format>
+    <rpm:license>(c) 2002, Michael Radziej, under Gnu LPL</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>unsorted</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm>packetfilter-0.9.1-4.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="168" end="3397"/>
+    <rpm:provides>
+      <rpm:entry name="packetfilter" flags="EQ" epoch="0" ver="0.9.1" rel="4"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="/bin/bash"/>
+      <rpm:entry name="/bin/sh" pre="1"/>
+    </rpm:requires>
+    <file>/etc/packetfilter/def</file>
+    <file>/etc/init.d/packetfilter</file>
+    <file>/usr/sbin/rcpacketfilter</file>
+    <file>/etc/packetfilter/ppp0</file>
+    <file type="dir">/etc/packetfilter</file>
+  </format>
+</package>
+<package type="rpm">
+  <name>bbconf</name>
+  <arch>i386</arch>
+  <version epoch="0" ver="1.2" rel="1"/>
+  <checksum type="sha" pkgid="YES">f9d63f4369eda675a65522ab6c985a60e73a1ceb</checksum>
+  <summary>bbconf</summary>
+  <description>bbconf is a complete GUI blackbox configuration tool, using plugins to
+allow other developers to easily develop plugins to run inside bbconf to
+allow every aspect of blackbox and its companion programs to be configured
+easily in a single application.  bbconf comes with 4 plugins, allowing
+configuration of blackbox's keybindings, blackbox's menus, and blackbox's
+style files/themes.</description>
+  <packager>movingparts.net</packager>
+  <url>http://bbconf.sourceforge.net/</url>
+  <time file="1010404157" build="1010404154"/>
+  <size package="295403" installed="901567" archive="905072"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="bbconf-1.2-1.i386.rpm"/>
+  <format>
+    <rpm:license>GPL</rpm:license>
+    <rpm:vendor>movingparts.net &lt;http://movingparts.net&gt;</rpm:vendor>
+    <rpm:group>X11/Applications</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm>bbconf-1.2-1.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="168" end="5168"/>
+    <rpm:provides>
+      <rpm:entry name="libbbconf.so"/>
+      <rpm:entry name="libmenu.so"/>
+      <rpm:entry name="libkeybindings.so"/>
+      <rpm:entry name="libthemes.so"/>
+      <rpm:entry name="bbconf" flags="EQ" epoch="0" ver="1.2" rel="1"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libXrender.so.1"/>
+      <rpm:entry name="libstdc++-libc6.2-2.so.3"/>
+      <rpm:entry name="libmng.so.1"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.0)"/>
+      <rpm:entry name="libICE.so.6"/>
+      <rpm:entry name="ld-linux.so.2"/>
+      <rpm:entry name="libpng.so.2"/>
+      <rpm:entry name="/sbin/ldconfig" pre="1"/>
+      <rpm:entry name="liblcms.so.1"/>
+      <rpm:entry name="libc.so.6"/>
+      <rpm:entry name="libdl.so.2(GLIBC_2.0)"/>
+      <rpm:entry name="libz.so.1"/>
+      <rpm:entry name="libXmu.so.6"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.1.3)"/>
+      <rpm:entry name="libXi.so.6"/>
+      <rpm:entry name="libresolv.so.2"/>
+      <rpm:entry name="libGL.so.1"/>
+      <rpm:entry name="libGLU.so.1"/>
+      <rpm:entry name="libfreetype.so.6"/>
+      <rpm:entry name="libXft.so.1"/>
+      <rpm:entry name="libX11.so.6"/>
+      <rpm:entry name="libqt.so.2"/>
+      <rpm:entry name="libSM.so.6"/>
+      <rpm:entry name="libXt.so.6"/>
+      <rpm:entry name="libdl.so.2(GLIBC_2.1)"/>
+      <rpm:entry name="libjpeg.so.62"/>
+      <rpm:entry name="libXext.so.6"/>
+      <rpm:entry name="libdl.so.2"/>
+      <rpm:entry name="/bin/sh" pre="1"/>
+      <rpm:entry name="libm.so.6"/>
+    </rpm:requires>
+    <file>/usr/bin/bbconf</file>
+    <suse:authors>
+      <suse:author>First Author</suse:author>
+      <suse:author>Second Author</suse:author>
+    </suse:authors>
+    <suse:keywords>
+      <suse:keyword>One keyword</suse:keyword>
+      <suse:keyword>Another one</suse:keyword>
+    </suse:keywords>
+    <suse:media mediaid='2'/>
+    <suse:dirsizes>
+      <suse:dirsize path="/usr/bin" size-kbyte="520" filecount="2"/>
+      <suse:dirsize path="/usr/share/doc" size-kbyte="100" filecount="25"/>
+    </suse:dirsizes>
+    <suse:freshen>
+      <suse:entry name="nothing" flags="EQ" epoch="0" ver="1.1" rel="521"/>
+      <suse:entry name="anything" flags="LT" epoch="0" ver="1.2" rel="125"/>
+    </suse:freshen>
+    <suse:install_only/>
+  </format>
+</package>
+<package type="rpm">
+  <name>PlatinGUI</name>
+  <arch>noarch</arch>
+  <version epoch="0" ver="620" rel="0"/>
+  <checksum type="sha" pkgid="YES">eced88b6e724e4a45b82f2723912ef2e29ee134b</checksum>
+  <summary>SAPGUI for the JAVA Environment</summary>
+  <description>This package provides the frontend application to connect to a SAP R/3 System.
+There are two scripts for starting the application, "guilogon" and "guistart".
+For further information, direct your browser to the documentation in
+file: /usr/share/doc/packages/PlatinGUI/doc/manual.htm</description>
+  <packager/>
+  <url/>
+  <time file="1016026813" build="1016026421"/>
+  <size package="36667755" installed="95672876" archive="95690012"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="PlatinGUI-620-0.noarch.rpm"/>
+  <format>
+    <rpm:license>(c) by SAP</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>SuSE internal</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm>PlatinGUI-620-0.src.rpm</rpm:sourcerpm>
+    <rpm:header-range start="168" end="17093"/>
+    <rpm:provides>
+      <rpm:entry name="libJPlatin.so"/>
+      <rpm:entry name="PlatinGUI" flags="EQ" epoch="0" ver="620" rel="0"/>
+    </rpm:provides>
+    <rpm:requires>
+      <rpm:entry name="libm.so.6(GLIBC_2.0)"/>
+      <rpm:entry name="libstdc++-libc6.2-2.so.3"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.0)"/>
+      <rpm:entry name="libICE.so.6"/>
+      <rpm:entry name="ld-linux.so.2"/>
+      <rpm:entry name="libc.so.6"/>
+      <rpm:entry name="libdl.so.2(GLIBC_2.0)"/>
+      <rpm:entry name="libpthread.so.0(GLIBC_2.0)"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.2)"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.1.2)"/>
+      <rpm:entry name="/bin/sh"/>
+      <rpm:entry name="libdl.so.2"/>
+      <rpm:entry name="libX11.so.6"/>
+      <rpm:entry name="libSM.so.6"/>
+      <rpm:entry name="libc.so.6(GLIBC_2.1)"/>
+      <rpm:entry name="libXt.so.6"/>
+      <rpm:entry name="libdl.so.2(GLIBC_2.1)"/>
+      <rpm:entry name="libXpm.so.4"/>
+      <rpm:entry name="libpthread.so.0"/>
+      <rpm:entry name="libXext.so.6"/>
+      <rpm:entry name="libpthread.so.0(GLIBC_2.1)"/>
+      <rpm:entry name="libm.so.6"/>
+    </rpm:requires>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilnl.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/saphttp</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmuxsvr</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilsv.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilpt.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/guilogon</file>
+    <file>/usr/bin/guilogon</file>
+    <file>/opt/PlatinGUI/6.20/bin/sapftp</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmbux</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmpox</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwiles.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilx2.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilen.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwiltr.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilde.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilru.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmsux</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmhox</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmhpx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilhr.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilpl.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmmsx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmhix</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilfr.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilth.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/sapgui</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmgax</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilcs.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmbmx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilx1.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilda.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxvalogo.gmf</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilsl.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/sapgui</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmbtx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmbax</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilhu.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilit.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmscx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmupx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmbfx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmnex</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmstx</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxvasap1.gmf</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilko.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilno.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxvasap2.gmf</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilro.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/guistart</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilzh.txt</file>
+    <file>/opt/PlatinGUI/6.20/bin/gmux/gmdlx</file>
+    <file>/opt/PlatinGUI/6.20/bin/libJPlatin.so</file>
+    <file type="dir">/opt/PlatinGUI/6.20/bin/gmux</file>
+  </format>
+</package>
+<package type="rpm">
+  <name>packetfilter</name>
+  <arch>src</arch>
+  <version epoch="0" ver="0.9.1" rel="3"/>
+  <checksum type="sha" pkgid="YES">77b165fcb30789fb8c4c669e21fed3d04938f607</checksum>
+  <summary>A packetfilter wrapper compatible with ipfwadm, ipchains, iptables</summary>
+  <description>This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.</description>
+  <packager/>
+  <url/>
+  <time file="1011218465" build="1011218465"/>
+  <size package="8889" installed="7775" archive="8160"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="packetfilter-0.9.1-3.src.rpm"/>
+  <format>
+    <rpm:license>(c) 2002, Michael Radziej, under Gnu LPL</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>unsorted</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm/>
+    <rpm:header-range start="168" end="1488"/>
+  </format>
+</package>
+<package type="rpm">
+  <name>bbconf</name>
+  <arch>src</arch>
+  <version epoch="0" ver="1.2" rel="1"/>
+  <checksum type="sha" pkgid="YES">548c0cac5b1e89c0200879a9b337e7d5fc183122</checksum>
+  <summary>bbconf</summary>
+  <description>bbconf is a complete GUI blackbox configuration tool, using plugins to
+allow other developers to easily develop plugins to run inside bbconf to
+allow every aspect of blackbox and its companion programs to be configured
+easily in a single application.  bbconf comes with 4 plugins, allowing
+configuration of blackbox's keybindings, blackbox's menus, and blackbox's
+style files/themes.</description>
+  <packager>movingparts.net</packager>
+  <url>http://bbconf.sourceforge.net/</url>
+  <time file="1010402287" build="1010364098"/>
+  <size package="559740" installed="561644" archive="562024"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="bbconf-1.2-1.src.rpm"/>
+  <format>
+    <rpm:license>GPL</rpm:license>
+    <rpm:vendor>movingparts.net &lt;http://movingparts.net&gt;</rpm:vendor>
+    <rpm:group>X11/Applications</rpm:group>
+    <rpm:buildhost>macmir.spieleck.de</rpm:buildhost>
+    <rpm:sourcerpm/>
+    <rpm:header-range start="168" end="1600"/>
+  </format>
+</package>
+<package type="rpm">
+  <name>PlatinGUI</name>
+  <arch>src</arch>
+  <version epoch="0" ver="620" rel="0"/>
+  <checksum type="sha" pkgid="YES">5d34c98c42302406c5c0a31c163ee6145c014f9d</checksum>
+  <summary>SAPGUI for the JAVA Environment</summary>
+  <description>This package provides the frontend application to connect to a SAP R/3 System.
+There are two scripts for starting the application, "guilogon" and "guistart".
+For further information, direct your browser to the documentation in
+file: /usr/share/doc/packages/PlatinGUI/doc/manual.htm</description>
+  <packager/>
+  <url/>
+  <time file="1016026466" build="1016026421"/>
+  <size package="36057152" installed="36898821" archive="36899204"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="PlatinGUI-620-0.src.rpm"/>
+  <format>
+    <rpm:license>(c) by SAP</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>SuSE internal</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm/>
+    <rpm:header-range start="168" end="1412"/>
+  </format>
+</package>
+<package type="rpm">
+  <name>packetfilter</name>
+  <arch>src</arch>
+  <version epoch="0" ver="0.9.1" rel="4"/>
+  <checksum type="sha" pkgid="YES">dffba597ee9614af9ad1db6a82141d024a94ab6a</checksum>
+  <summary>A packetfilter wrapper compatible with ipfwadm, ipchains, iptables</summary>
+  <description>This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.</description>
+  <packager/>
+  <url/>
+  <time file="1011218885" build="1011218885"/>
+  <size package="8896" installed="7790" archive="8172"/>
+  <location xml:base="http://w3.suse.de/~mir/repo" href="packetfilter-0.9.1-4.src.rpm"/>
+  <format>
+    <rpm:license>(c) 2002, Michael Radziej, under Gnu LPL</rpm:license>
+    <rpm:vendor/>
+    <rpm:group>unsorted</rpm:group>
+    <rpm:buildhost>martin.suse.de</rpm:buildhost>
+    <rpm:sourcerpm/>
+    <rpm:header-range start="168" end="1488"/>
+  </format>
+</package>
+
+</metadata>
diff --git a/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/002-primary-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..a5b56a7
--- /dev/null
@@ -0,0 +1,512 @@
+-------------------------------------------------
+Primary Data: 
+name: 'packetfilter'
+type: 'rpm'
+ arch: 'noarch'
+ ver: '0.9.1'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: '8121d38334a682f5bf2c8320388395ba7e4b276d'
+summary: 'A packetfilter wrapper compatible with ipfwadm, ipchains, iptables'
+description: 'This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.'
+packager: ''
+url: ''
+timeFile: '1011218465'
+timeBuild: '1011218465'
+sizePackage: '7333'
+sizeInstalled: '16835'
+sizeArchive: '17904'
+location: 'packetfilter-0.9.1-3.noarch.rpm'
+license: '(c) 2002, Michael Radziej, under Gnu LPL'
+vendor: ''
+group: 'unsorted'
+buildhost: 'martin.suse.de'
+sourcerpm: 'packetfilter-0.9.1-3.src.rpm'
+headerStart: '168'
+headerEnd: '2268'
+provides:
+packetfilter EQ 0-0.9.1-3
+conflicts:
+
+obsoletes:
+
+requires:
+/bin/bash  -
+/bin/sh  - (pre=1)
+files:
+/etc/packetfilter/def
+/etc/init.d/packetfilter
+/usr/sbin/rcpacketfilter
+/etc/packetfilter/ppp0
+/etc/packetfilter: dir
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'packetfilter'
+type: 'rpm'
+ arch: 'noarch'
+ ver: '0.9.1'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: '5f5547fe534991d161f5cbd9b823276a86eb55ea'
+summary: 'A packetfilter wrapper compatible with ipfwadm, ipchains, iptables'
+description: 'This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.'
+packager: ''
+url: ''
+timeFile: '1011218885'
+timeBuild: '1011218885'
+sizePackage: '9119'
+sizeInstalled: '23203'
+sizeArchive: '25560'
+location: 'packetfilter-0.9.1-4.noarch.rpm'
+license: '(c) 2002, Michael Radziej, under Gnu LPL'
+vendor: ''
+group: 'unsorted'
+buildhost: 'martin.suse.de'
+sourcerpm: 'packetfilter-0.9.1-4.src.rpm'
+headerStart: '168'
+headerEnd: '3397'
+provides:
+packetfilter EQ 0-0.9.1-4
+conflicts:
+
+obsoletes:
+
+requires:
+/bin/bash  -
+/bin/sh  - (pre=1)
+files:
+/etc/packetfilter/def
+/etc/init.d/packetfilter
+/usr/sbin/rcpacketfilter
+/etc/packetfilter/ppp0
+/etc/packetfilter: dir
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'bbconf'
+type: 'rpm'
+ arch: 'i386'
+ ver: '1.2'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: 'f9d63f4369eda675a65522ab6c985a60e73a1ceb'
+summary: 'bbconf'
+description: 'bbconf is a complete GUI blackbox configuration tool, using plugins to
+allow other developers to easily develop plugins to run inside bbconf to
+allow every aspect of blackbox and its companion programs to be configured
+easily in a single application.  bbconf comes with 4 plugins, allowing
+configuration of blackbox's keybindings, blackbox's menus, and blackbox's
+style files/themes.'
+packager: 'movingparts.net'
+url: 'http://bbconf.sourceforge.net/'
+timeFile: '1010404157'
+timeBuild: '1010404154'
+sizePackage: '295403'
+sizeInstalled: '901567'
+sizeArchive: '905072'
+location: 'bbconf-1.2-1.i386.rpm'
+license: 'GPL'
+vendor: 'movingparts.net <http://movingparts.net>'
+group: 'X11/Applications'
+buildhost: 'martin.suse.de'
+sourcerpm: 'bbconf-1.2-1.src.rpm'
+headerStart: '168'
+headerEnd: '5168'
+provides:
+libbbconf.so  -
+libmenu.so  -
+libkeybindings.so  -
+libthemes.so  -
+bbconf EQ 0-1.2-1
+conflicts:
+
+obsoletes:
+
+requires:
+libXrender.so.1  -
+libstdc++-libc6.2-2.so.3  -
+libmng.so.1  -
+libc.so.6(GLIBC_2.0)  -
+libICE.so.6  -
+ld-linux.so.2  -
+libpng.so.2  -
+/sbin/ldconfig  - (pre=1)
+liblcms.so.1  -
+libc.so.6  -
+libdl.so.2(GLIBC_2.0)  -
+libz.so.1  -
+libXmu.so.6  -
+libc.so.6(GLIBC_2.1.3)  -
+libXi.so.6  -
+libresolv.so.2  -
+libGL.so.1  -
+libGLU.so.1  -
+libfreetype.so.6  -
+libXft.so.1  -
+libX11.so.6  -
+libqt.so.2  -
+libSM.so.6  -
+libXt.so.6  -
+libdl.so.2(GLIBC_2.1)  -
+libjpeg.so.62  -
+libXext.so.6  -
+libdl.so.2  -
+/bin/sh  - (pre=1)
+libm.so.6  -
+files:
+/usr/bin/bbconf
+authors: First Author, Second Author
+keywords: One keyword, Another one
+media: 2
+dirsizes: 
+/usr/bin: 520 kByte, 2 files
+/usr/share/doc: 100 kByte, 25 files
+freshen: 
+nothing EQ 0-1.1-521
+anything LT 0-1.2-125
+install-only: '1'
+-------------------------------------------------
+Primary Data: 
+name: 'PlatinGUI'
+type: 'rpm'
+ arch: 'noarch'
+ ver: '620'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: 'eced88b6e724e4a45b82f2723912ef2e29ee134b'
+summary: 'SAPGUI for the JAVA Environment'
+description: 'This package provides the frontend application to connect to a SAP R/3 System.
+There are two scripts for starting the application, "guilogon" and "guistart".
+For further information, direct your browser to the documentation in
+file: /usr/share/doc/packages/PlatinGUI/doc/manual.htm'
+packager: ''
+url: ''
+timeFile: '1016026813'
+timeBuild: '1016026421'
+sizePackage: '36667755'
+sizeInstalled: '95672876'
+sizeArchive: '95690012'
+location: 'PlatinGUI-620-0.noarch.rpm'
+license: '(c) by SAP'
+vendor: ''
+group: 'SuSE internal'
+buildhost: 'martin.suse.de'
+sourcerpm: 'PlatinGUI-620-0.src.rpm'
+headerStart: '168'
+headerEnd: '17093'
+provides:
+libJPlatin.so  -
+PlatinGUI EQ 0-620-0
+conflicts:
+
+obsoletes:
+
+requires:
+libm.so.6(GLIBC_2.0)  -
+libstdc++-libc6.2-2.so.3  -
+libc.so.6(GLIBC_2.0)  -
+libICE.so.6  -
+ld-linux.so.2  -
+libc.so.6  -
+libdl.so.2(GLIBC_2.0)  -
+libpthread.so.0(GLIBC_2.0)  -
+libc.so.6(GLIBC_2.2)  -
+libc.so.6(GLIBC_2.1.2)  -
+/bin/sh  -
+libdl.so.2  -
+libX11.so.6  -
+libSM.so.6  -
+libc.so.6(GLIBC_2.1)  -
+libXt.so.6  -
+libdl.so.2(GLIBC_2.1)  -
+libXpm.so.4  -
+libpthread.so.0  -
+libXext.so.6  -
+libpthread.so.0(GLIBC_2.1)  -
+libm.so.6  -
+files:
+/opt/PlatinGUI/6.20/bin/gmux/gxwilnl.txt
+/opt/PlatinGUI/6.20/bin/saphttp
+/opt/PlatinGUI/6.20/bin/gmux/gmuxsvr
+/opt/PlatinGUI/6.20/bin/gmux/gxwilsv.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilpt.txt
+/opt/PlatinGUI/6.20/bin/guilogon
+/usr/bin/guilogon
+/opt/PlatinGUI/6.20/bin/sapftp
+/opt/PlatinGUI/6.20/bin/gmux/gmbux
+/opt/PlatinGUI/6.20/bin/gmux/gmpox
+/opt/PlatinGUI/6.20/bin/gmux/gxwiles.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilx2.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilen.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwiltr.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilde.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilru.txt
+/opt/PlatinGUI/6.20/bin/gmux/gmsux
+/opt/PlatinGUI/6.20/bin/gmux/gmhox
+/opt/PlatinGUI/6.20/bin/gmux/gmhpx
+/opt/PlatinGUI/6.20/bin/gmux/gxwilhr.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilpl.txt
+/opt/PlatinGUI/6.20/bin/gmux/gmmsx
+/opt/PlatinGUI/6.20/bin/gmux/gmhix
+/opt/PlatinGUI/6.20/bin/gmux/gxwilfr.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilth.txt
+/opt/PlatinGUI/6.20/bin/sapgui
+/opt/PlatinGUI/6.20/bin/gmux/gmgax
+/opt/PlatinGUI/6.20/bin/gmux/gxwilcs.txt
+/opt/PlatinGUI/6.20/bin/gmux/gmbmx
+/opt/PlatinGUI/6.20/bin/gmux/gxwilx1.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilda.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxvalogo.gmf
+/opt/PlatinGUI/6.20/bin/gmux/gxwilsl.txt
+/opt/PlatinGUI/6.20/bin/gmux/sapgui
+/opt/PlatinGUI/6.20/bin/gmux/gmbtx
+/opt/PlatinGUI/6.20/bin/gmux/gmbax
+/opt/PlatinGUI/6.20/bin/gmux/gxwilhu.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilit.txt
+/opt/PlatinGUI/6.20/bin/gmux/gmscx
+/opt/PlatinGUI/6.20/bin/gmux/gmupx
+/opt/PlatinGUI/6.20/bin/gmux/gmbfx
+/opt/PlatinGUI/6.20/bin/gmux/gmnex
+/opt/PlatinGUI/6.20/bin/gmux/gmstx
+/opt/PlatinGUI/6.20/bin/gmux/gxvasap1.gmf
+/opt/PlatinGUI/6.20/bin/gmux/gxwilko.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxwilno.txt
+/opt/PlatinGUI/6.20/bin/gmux/gxvasap2.gmf
+/opt/PlatinGUI/6.20/bin/gmux/gxwilro.txt
+/opt/PlatinGUI/6.20/bin/guistart
+/opt/PlatinGUI/6.20/bin/gmux/gxwilzh.txt
+/opt/PlatinGUI/6.20/bin/gmux/gmdlx
+/opt/PlatinGUI/6.20/bin/libJPlatin.so
+/opt/PlatinGUI/6.20/bin/gmux: dir
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'packetfilter'
+type: 'rpm'
+ arch: 'src'
+ ver: '0.9.1'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: '77b165fcb30789fb8c4c669e21fed3d04938f607'
+summary: 'A packetfilter wrapper compatible with ipfwadm, ipchains, iptables'
+description: 'This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.'
+packager: ''
+url: ''
+timeFile: '1011218465'
+timeBuild: '1011218465'
+sizePackage: '8889'
+sizeInstalled: '7775'
+sizeArchive: '8160'
+location: 'packetfilter-0.9.1-3.src.rpm'
+license: '(c) 2002, Michael Radziej, under Gnu LPL'
+vendor: ''
+group: 'unsorted'
+buildhost: 'martin.suse.de'
+sourcerpm: ''
+headerStart: '168'
+headerEnd: '1488'
+provides:
+
+conflicts:
+
+obsoletes:
+
+requires:
+
+files:
+
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'bbconf'
+type: 'rpm'
+ arch: 'src'
+ ver: '1.2'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: '548c0cac5b1e89c0200879a9b337e7d5fc183122'
+summary: 'bbconf'
+description: 'bbconf is a complete GUI blackbox configuration tool, using plugins to
+allow other developers to easily develop plugins to run inside bbconf to
+allow every aspect of blackbox and its companion programs to be configured
+easily in a single application.  bbconf comes with 4 plugins, allowing
+configuration of blackbox's keybindings, blackbox's menus, and blackbox's
+style files/themes.'
+packager: 'movingparts.net'
+url: 'http://bbconf.sourceforge.net/'
+timeFile: '1010402287'
+timeBuild: '1010364098'
+sizePackage: '559740'
+sizeInstalled: '561644'
+sizeArchive: '562024'
+location: 'bbconf-1.2-1.src.rpm'
+license: 'GPL'
+vendor: 'movingparts.net <http://movingparts.net>'
+group: 'X11/Applications'
+buildhost: 'macmir.spieleck.de'
+sourcerpm: ''
+headerStart: '168'
+headerEnd: '1600'
+provides:
+
+conflicts:
+
+obsoletes:
+
+requires:
+
+files:
+
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'PlatinGUI'
+type: 'rpm'
+ arch: 'src'
+ ver: '620'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: '5d34c98c42302406c5c0a31c163ee6145c014f9d'
+summary: 'SAPGUI for the JAVA Environment'
+description: 'This package provides the frontend application to connect to a SAP R/3 System.
+There are two scripts for starting the application, "guilogon" and "guistart".
+For further information, direct your browser to the documentation in
+file: /usr/share/doc/packages/PlatinGUI/doc/manual.htm'
+packager: ''
+url: ''
+timeFile: '1016026466'
+timeBuild: '1016026421'
+sizePackage: '36057152'
+sizeInstalled: '36898821'
+sizeArchive: '36899204'
+location: 'PlatinGUI-620-0.src.rpm'
+license: '(c) by SAP'
+vendor: ''
+group: 'SuSE internal'
+buildhost: 'martin.suse.de'
+sourcerpm: ''
+headerStart: '168'
+headerEnd: '1412'
+provides:
+
+conflicts:
+
+obsoletes:
+
+requires:
+
+files:
+
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+-------------------------------------------------
+Primary Data: 
+name: 'packetfilter'
+type: 'rpm'
+ arch: 'src'
+ ver: '0.9.1'
+checksumType: 'sha'
+checksumPkgid: 'YES'
+checksum: 'dffba597ee9614af9ad1db6a82141d024a94ab6a'
+summary: 'A packetfilter wrapper compatible with ipfwadm, ipchains, iptables'
+description: 'This package consists of a simple firewall wrapper script
+providing a packet filter mini-language to state your
+filtering needs independent of the used firewall type.
+It's just like a service start/stop script and started
+during the normal System V boot sequence.
+
+See the README for details.'
+packager: ''
+url: ''
+timeFile: '1011218885'
+timeBuild: '1011218885'
+sizePackage: '8896'
+sizeInstalled: '7790'
+sizeArchive: '8172'
+location: 'packetfilter-0.9.1-4.src.rpm'
+license: '(c) 2002, Michael Radziej, under Gnu LPL'
+vendor: ''
+group: 'unsorted'
+buildhost: 'martin.suse.de'
+sourcerpm: ''
+headerStart: '168'
+headerEnd: '1488'
+provides:
+
+conflicts:
+
+obsoletes:
+
+requires:
+
+files:
+
+authors: 
+keywords: 
+media: 
+dirsizes: 
+
+freshen: 
+
+install-only: '0'
+Exit Code: 0
diff --git a/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml
new file mode 100644 (file)
index 0000000..e6fc17a
--- /dev/null
@@ -0,0 +1,226 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<filelists xmlns="http://linux.duke.edu/metadata/filelists" packages="8">
+<package pkgid="8121d38334a682f5bf2c8320388395ba7e4b276d" name="packetfilter" arch="noarch">
+  <version epoch="0" ver="0.9.1" rel="3"/>
+  <file>/etc/init.d/packetfilter</file>
+  <file>/etc/packetfilter/def</file>
+  <file>/etc/packetfilter/ppp0</file>
+  <file>/usr/sbin/rcpacketfilter</file>
+  <file>/usr/share/doc/packages/packetfilter/README</file>
+  <file type="dir">/etc/packetfilter</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter/samples</file>
+</package>
+<package pkgid="5f5547fe534991d161f5cbd9b823276a86eb55ea" name="packetfilter" arch="noarch">
+  <version epoch="0" ver="0.9.1" rel="4"/>
+  <file>/etc/init.d/packetfilter</file>
+  <file>/etc/packetfilter/def</file>
+  <file>/etc/packetfilter/ppp0</file>
+  <file>/usr/sbin/rcpacketfilter</file>
+  <file>/usr/share/doc/packages/packetfilter/README</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/isdn-router/def</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/isdn-router/eth0</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/isdn-router/ppp0</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/tdsl-ipsec/def</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/tdsl-ipsec/eth0</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/tdsl-ipsec/ipsec0</file>
+  <file>/usr/share/doc/packages/packetfilter/samples/tdsl-ipsec/ppp0</file>
+  <file type="dir">/etc/packetfilter</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter/samples</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter/samples/isdn-router</file>
+  <file type="dir">/usr/share/doc/packages/packetfilter/samples/tdsl-ipsec</file>
+</package>
+<package pkgid="f9d63f4369eda675a65522ab6c985a60e73a1ceb" name="bbconf" arch="i386">
+  <version epoch="0" ver="1.2" rel="1"/>
+  <file>/usr/bin/bbconf</file>
+  <file>/usr/doc/bbconf/AUTHORS</file>
+  <file>/usr/doc/bbconf/COPYING</file>
+  <file>/usr/doc/bbconf/ChangeLog</file>
+  <file>/usr/doc/bbconf/README</file>
+  <file>/usr/doc/bbconf/README.html</file>
+  <file>/usr/doc/bbconf/TODO</file>
+  <file>/usr/man/man1/bbconf.1.gz</file>
+  <file>/usr/share/bbconf/plugins/libbbconf.la</file>
+  <file>/usr/share/bbconf/plugins/libbbconf.so</file>
+  <file>/usr/share/bbconf/plugins/libkeybindings.la</file>
+  <file>/usr/share/bbconf/plugins/libkeybindings.so</file>
+  <file>/usr/share/bbconf/plugins/libmenu.la</file>
+  <file>/usr/share/bbconf/plugins/libmenu.so</file>
+  <file>/usr/share/bbconf/plugins/libthemes.la</file>
+  <file>/usr/share/bbconf/plugins/libthemes.so</file>
+  <file>/usr/share/doc/packages/bbconf/AUTHORS</file>
+  <file>/usr/share/doc/packages/bbconf/COPYING</file>
+  <file>/usr/share/doc/packages/bbconf/ChangeLog</file>
+  <file>/usr/share/doc/packages/bbconf/README</file>
+  <file>/usr/share/doc/packages/bbconf/README.html</file>
+  <file>/usr/share/doc/packages/bbconf/TODO</file>
+  <file type="dir">/usr/bin</file>
+  <file type="dir">/usr/doc</file>
+  <file type="dir">/usr/doc/bbconf</file>
+  <file type="dir">/usr/man</file>
+  <file type="dir">/usr/man/man1</file>
+  <file type="dir">/usr/share</file>
+  <file type="dir">/usr/share/bbconf</file>
+  <file type="dir">/usr/share/bbconf/plugins</file>
+  <file type="dir">/usr/share/doc/packages/bbconf</file>
+</package>
+<package pkgid="eced88b6e724e4a45b82f2723912ef2e29ee134b" name="PlatinGUI" arch="noarch">
+  <version epoch="0" ver="620" rel="0"/>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmbax</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmbfx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmbmx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmbtx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmbux</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmdlx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmgax</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmhix</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmhox</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmhpx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmmsx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmnex</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmpox</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmscx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmstx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmsux</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmupx</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gmuxsvr</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxvalogo.gmf</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxvasap1.gmf</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxvasap2.gmf</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilcs.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilda.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilde.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilen.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwiles.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilfr.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilhr.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilhu.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilit.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilko.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilnl.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilno.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilpl.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilpt.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilro.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilru.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilsl.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilsv.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilth.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwiltr.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilx1.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilx2.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/gxwilzh.txt</file>
+  <file>/opt/PlatinGUI/6.20/bin/gmux/sapgui</file>
+  <file>/opt/PlatinGUI/6.20/bin/guilogon</file>
+  <file>/opt/PlatinGUI/6.20/bin/guistart</file>
+  <file>/opt/PlatinGUI/6.20/bin/libJPlatin.so</file>
+  <file>/opt/PlatinGUI/6.20/bin/sapftp</file>
+  <file>/opt/PlatinGUI/6.20/bin/sapgui</file>
+  <file>/opt/PlatinGUI/6.20/bin/saphttp</file>
+  <file>/opt/PlatinGUI/6.20/install.properties</file>
+  <file>/opt/PlatinGUI/6.20/jar/AcrobatViewerS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/GuiStartS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/IceBrowserS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/Linux-gmux.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/Linux-graphics.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/Linux-lib.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/Manual.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/Unix-localstart.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/iCubeS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/platincoreS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapCalendarS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapChartS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapContextMenuS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapGridS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapHtmlViewerS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapImageS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapTextEditS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapToolBarS.jar</file>
+  <file>/opt/PlatinGUI/6.20/jar/sapTreeS.jar</file>
+  <file>/usr/bin/guilogon</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/admconf/guiconf.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/admconf/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/admconf/msgsrv.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/admconf/router.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/conndata.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/htmlref.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/install.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/intro.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/applet/jscript.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/conndata.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/connstr.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/jnlp.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/signing.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/backgrnd/trace.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/install/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/install/install.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/install/mac.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/intro/applet.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/intro/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/intro/platin.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/main.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/manual.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/relnotes/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/relnotes/issues.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/relnotes/missing.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/relnotes/new.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/relnotes/upgrade.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/start/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/start/mac.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/start/os2.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/start/unix.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/start/win32.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/aix.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/hpux.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/linux.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/mac.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/os2.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/solaris.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/tru64.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/sysreq/win32.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/userconf/index.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/userconf/settings.htm</file>
+  <file>/usr/share/doc/packages/PlatinGUI/doc/userconf/systems.htm</file>
+  <file type="dir">/opt/PlatinGUI/6.20</file>
+  <file type="dir">/opt/PlatinGUI/6.20/bin</file>
+  <file type="dir">/opt/PlatinGUI/6.20/bin/gmux</file>
+  <file type="dir">/opt/PlatinGUI/6.20/jar</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/admconf</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/applet</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/backgrnd</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/install</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/intro</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/relnotes</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/start</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/sysreq</file>
+  <file type="dir">/usr/share/doc/packages/PlatinGUI/doc/userconf</file>
+</package>
+<package pkgid="77b165fcb30789fb8c4c669e21fed3d04938f607" name="packetfilter" arch="src">
+  <version epoch="0" ver="0.9.1" rel="3"/>
+  <file>packetfilter.spec</file>
+  <file>packetfilter.tgz</file>
+</package>
+<package pkgid="548c0cac5b1e89c0200879a9b337e7d5fc183122" name="bbconf" arch="src">
+  <version epoch="0" ver="1.2" rel="1"/>
+  <file>bbconf-1.2.tar.gz</file>
+  <file>bbconf.spec</file>
+</package>
+<package pkgid="5d34c98c42302406c5c0a31c163ee6145c014f9d" name="PlatinGUI" arch="src">
+  <version epoch="0" ver="620" rel="0"/>
+  <file>PlatinGUI-620.tgz</file>
+  <file>PlatinGUI.spec</file>
+</package>
+<package pkgid="dffba597ee9614af9ad1db6a82141d024a94ab6a" name="packetfilter" arch="src">
+  <version epoch="0" ver="0.9.1" rel="4"/>
+  <file>packetfilter.spec</file>
+  <file>packetfilter.tgz</file>
+</package>
+
+</filelists>
\ No newline at end of file
diff --git a/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..b28b04f
--- /dev/null
@@ -0,0 +1,3 @@
+
+
+
diff --git a/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/003-filelists-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..6c325d3
--- /dev/null
@@ -0,0 +1 @@
+Exit Code: 2
diff --git a/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml
new file mode 100644 (file)
index 0000000..68ce88b
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<groups  xmlns="http://linux.duke.edu/metadata/groups">
+  <group>
+    <groupid>foo</groupid>
+    <name>foobar</name>
+    <name lang='en.US'>foobar</name>
+    <default>false</default>
+    <uservisible>true</uservisible>
+    <description>This is my group, it is soooooooo coool!</description>
+    <description lang='en.US'>Duh</description>
+    <grouplist>
+       <metapkg type="mandatory">othergroup</metapkg>
+       <metapkg type="optional">stillother</metapkg>
+       <metapkg type="default">stillmore</metapkg>
+       <metapkg>other</metapkg>
+    </grouplist>
+    <packagelist>
+       <packagereq type="mandatory" epoch="0" ver="1" rel="1">pkgname</packagereq>
+       <packagereq epoch="1" ver="2" rel="0">otherpkgname</packagereq>
+    </packagelist>
+  </group>
+</groups>
+
diff --git a/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/004-group-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..cfbd865
--- /dev/null
@@ -0,0 +1,20 @@
+-------------------------------------------------
+Group Data: 
+group-id: 'foo'
+name:
+foobar
+[en.US] foobar
+default: 'false'
+user-visible: 'true'
+description:
+This is my group, it is soooooooo coool!
+[en.US] Duh
+grouplist:
+type: mandatory, name: othergroup
+type: optional, name: stillother
+type: default, name: stillmore
+type: , name: other
+packageList:
+[mandatory] pkgname 0-1-1
+[] otherpkgname 1-2-0
+Exit Code: 0
diff --git a/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml
new file mode 100644 (file)
index 0000000..95aa614
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<otherdata xmlns="http://linux.duke.edu/metadata/other" packages="8">
+<package pkgid="8121d38334a682f5bf2c8320388395ba7e4b276d" name="packetfilter" arch="noarch">
+  <version epoch="0" ver="0.9.1" rel="3"/>
+</package>
+<package pkgid="5f5547fe534991d161f5cbd9b823276a86eb55ea" name="packetfilter" arch="noarch">
+  <version epoch="0" ver="0.9.1" rel="4"/>
+</package>
+<package pkgid="f9d63f4369eda675a65522ab6c985a60e73a1ceb" name="bbconf" arch="i386">
+  <version epoch="0" ver="1.2" rel="1"/>
+</package>
+<package pkgid="eced88b6e724e4a45b82f2723912ef2e29ee134b" name="PlatinGUI" arch="noarch">
+  <version epoch="0" ver="620" rel="0"/>
+</package>
+<package pkgid="77b165fcb30789fb8c4c669e21fed3d04938f607" name="packetfilter" arch="src">
+  <version epoch="0" ver="0.9.1" rel="3"/>
+</package>
+<package pkgid="548c0cac5b1e89c0200879a9b337e7d5fc183122" name="bbconf" arch="src">
+  <version epoch="0" ver="1.2" rel="1"/>
+</package>
+<package pkgid="5d34c98c42302406c5c0a31c163ee6145c014f9d" name="PlatinGUI" arch="src">
+  <version epoch="0" ver="620" rel="0"/>
+</package>
+<package pkgid="dffba597ee9614af9ad1db6a82141d024a94ab6a" name="packetfilter" arch="src">
+  <version epoch="0" ver="0.9.1" rel="4"/>
+</package>
+
+</otherdata>
diff --git a/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/005-other-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..83e6667
--- /dev/null
@@ -0,0 +1,41 @@
+-------------------------------------------------
+Other: 
+pkgid: 8121d38334a682f5bf2c8320388395ba7e4b276dpackage: packetfilter 0-0.9.1-3
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: 5f5547fe534991d161f5cbd9b823276a86eb55eapackage: packetfilter 0-0.9.1-4
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: f9d63f4369eda675a65522ab6c985a60e73a1cebpackage: bbconf 0-1.2-1
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: eced88b6e724e4a45b82f2723912ef2e29ee134bpackage: PlatinGUI 0-620-0
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: 77b165fcb30789fb8c4c669e21fed3d04938f607package: packetfilter 0-0.9.1-3
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: 548c0cac5b1e89c0200879a9b337e7d5fc183122package: bbconf 0-1.2-1
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: 5d34c98c42302406c5c0a31c163ee6145c014f9dpackage: PlatinGUI 0-620-0
+Changelog:
+
+-------------------------------------------------
+Other: 
+pkgid: dffba597ee9614af9ad1db6a82141d024a94ab6apackage: packetfilter 0-0.9.1-4
+Changelog:
+
+Exit Code: 0
diff --git a/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml b/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml
new file mode 100644 (file)
index 0000000..9285bb6
--- /dev/null
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<patch 
+    xmlns="http://novell.com/package/metadata/suse/patch"
+    xmlns:patch="http://novell.com/package/metadata/suse/patch"
+    xmlns:yum="http://linux.duke.edu/metadata/common" 
+    xmlns:rpm="http://linux.duke.edu/metadata/rpm" 
+    xmlns:suse="http://novell.com/package/metadata/suse/common"
+    patchid="foo-12321"
+    timestamp="2342342"
+    engine="1.0">
+  <yum:name>foo</yum:name>
+  <summary lang="en">install if you have lots of foo</summary>
+  <description lang="en">fixes Bug #231312</description>
+  <yum:version epoch="0" ver="1" rel="2"/>
+  <rpm:provides><rpm:entry kind="patch" name="foo-patch-fitzefatze"/></rpm:provides>
+  <rpm:conflicts><rpm:entry kind="package" name="foo-oldpatch" epoch="1" ver="1" rel="2" flags="EQ"/></rpm:conflicts>
+  <suse:freshen>
+    <suse:entry kind="package" name="foo" epoch="2" ver="3" rel="4" flags="LE"/>
+    <suse:entry kind="package" name="foo-devel" epoch="3" ver="4" rel="5" flags="LE"/>
+  </suse:freshen>
+  <rpm:requires><rpm:entry kind="patch" name="blah-234" epoch="4" ver="5" rel="6" flags="EQ"/></rpm:requires>
+  <category>security</category>
+  <reboot_needed/>
+  <package_manager/>
+  <update_script>
+<![CDATA[#!/bin/bash
+rpm -Uhv * > /dev/null
+]]>
+  </update_script>
+  <atoms>
+    <script>
+      <yum:name>foo-patch-script-1</yum:name>
+      <yum:version epoch="0" ver="1" rel="2"/>
+      <do>#!/bin/bash</do>
+      <undo>#!/bin/unbash</undo>
+      <suse:freshen>
+       <suse:entry kind="package" name="foo" epoch="2" ver="3" rel="4" flags="LE"/>
+       <suse:entry kind="package" name="foo-devel" epoch="3" ver="4" rel="5" flags="LE"/>
+      </suse:freshen>
+    </script>
+  </atoms>
+  <atoms>
+    <message type="OK">
+      <yum:name>foo-patch-message-1</yum:name>
+      <yum:version epoch="0" ver="1" rel="2"/>
+      <text>Just note that the very critical package foo will be installed just now</text>
+      <suse:freshen>
+       <suse:entry kind="package" name="foo" epoch="2" ver="3" rel="4" flags="LE"/>
+       <suse:entry kind="package" name="foo-devel" epoch="3" ver="4" rel="5" flags="LE"/>
+      </suse:freshen>
+    </message>
+  </atoms>
+  <atoms>
+    <package xmlns="http://linux.duke.edu/metadata/common"
+             type="rpm">
+      <name>foo</name>
+      <arch>noarch</arch>
+      <version epoch="2" ver="3" rel="4"/>
+      <checksum type="sha" pkgid="YES">8121d38334a682f5bf2c8320388395ba7e4b276d</checksum>
+      <patch:summary lang="en">A packetfilter wrapper compatible with ipfwadm, ipchains, iptables</patch:summary>
+      <patch:description lang="en">This package consists of a simple firewall wrapper script
+    providing a packet filter mini-language to state your
+    filtering needs independent of the used firewall type.
+    It's just like a service start/stop script and started
+    during the normal System V boot sequence.
+
+    See the README for details.</patch:description>
+      <packager/>
+      <url/>
+      <time file="1011218465" build="1011218465"/>
+      <size package="7333" installed="16835" archive="17904"/>
+      <location xml:base="http://w3.suse.de/~mir/repo" href="packetfilter-0.9.1-3.noarch.rpm"/>
+      <format>
+        <rpm:license>(c) 2002, Michael Radziej, under Gnu LPL</rpm:license>
+        <rpm:vendor/>
+        <rpm:group>unsorted</rpm:group>
+        <rpm:buildhost>martin.suse.de</rpm:buildhost>
+        <rpm:sourcerpm>packetfilter-0.9.1-3.src.rpm</rpm:sourcerpm>
+        <rpm:header-range start="168" end="2268"/>
+        <rpm:provides>
+          <rpm:entry name="packetfilter" flags="EQ" epoch="0" ver="0.9.1" rel="3"/>
+        </rpm:provides>
+        <rpm:requires>
+          <rpm:entry name="/bin/bash"/>
+          <rpm:entry name="/bin/sh" pre="1"/>
+        </rpm:requires>
+        <file>/etc/packetfilter/def</file>
+        <file>/etc/init.d/packetfilter</file>
+        <file>/usr/sbin/rcpacketfilter</file>
+        <file>/etc/packetfilter/ppp0</file>
+        <file type="dir">/etc/packetfilter</file>
+      </format>
+      <pkgfiles xmlns="http://novell.com/package/metadata/suse/patch">
+        <plainrpm arch="noarch" filename="foo.rpm" downloadsize="56678" md5sum="234233" buildtime="23443"/>
+        <patchrpm arch="noarch" filename="foo.patch.rpm" downloadsize="56278" md5sum="2344533" buildtime="23243">
+          <base_version epoch="1" ver="2" rel="3"/>
+          <base_version epoch="2" ver="3" rel="4"/>
+        </patchrpm>
+        <deltarpm arch="noarch" filename="foo-delta-bla.delta.rpm"  downloadsize="234" md5sum="1222" buildtime="2232">
+          <base_version epoch="3" ver="4" rel="5" md5sum="312321" buildtime="3232" sequence_info="irgendwas"/>
+        </deltarpm>
+      </pkgfiles>
+    </package>
+  </atoms>
+</patch>
+
diff --git a/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.err.ref b/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.err.ref
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.ref b/test/devel.jsrain/yum/YUMParser.test/006-patch-correct.test.xml.ref
new file mode 100644 (file)
index 0000000..0ed16e1
--- /dev/null
@@ -0,0 +1,164 @@
+-------------------------------------------------
+Patch Data: 
+  patch ID: foo-12321
+  timestamp: '2342342'
+  engine: '1.0'
+  name: foo
+  summary: [en] install if you have lots of foo
+  description: [en] fixes Bug #231312
+  epoch: 0
+  version: 1
+  release: 2
+  provides: foo-patch-fitzefatze  -
+  conflicts: foo-oldpatch EQ 1-1-2
+  obsoletes: 
+  freshen: 
+  requires: foo LE 2-3-4
+foo-devel LE 3-4-5
+blah-234 EQ 4-5-6
+  category: security
+  reboot needed: 1
+  affects package manager: 1
+  update script: 
+#!/bin/bash
+rpm -Uhv * > /dev/null
+
+  
+  atoms:
+Atom data
+  atom type: script
+Script Data: 
+  name: foo-patch-script-1
+  epoch: 0
+  version: 1
+  release: 2
+  provides: 
+  conflicts: 
+  obsoletes: 
+  freshen: 
+  requires: foo LE 2-3-4
+foo-devel LE 3-4-5
+  do script: #!/bin/bash
+  undo script: #!/bin/unbash
+
+Atom data
+  atom type: message
+Message Data: 
+  name: foo-patch-message-1
+  type: OK
+  epoch: 0
+  version: 1
+  release: 2
+  provides: 
+  conflicts: 
+  obsoletes: 
+  freshen: 
+  requires: foo LE 2-3-4
+foo-devel LE 3-4-5
+  text: Just note that the very critical package foo will be installed just now
+
+Atom data
+  atom type: package
+Package Data: 
+  name: 'foo'
+  type: 'rpm'
+   arch: 'noarch'
+   ver: '3'
+  checksumType: 'sha'
+  checksumPkgid: 'YES'
+  checksum: '8121d38334a682f5bf2c8320388395ba7e4b276d'
+  summary: 'A packetfilter wrapper compatible with ipfwadm, ipchains, iptables'
+  description: 'This package consists of a simple firewall wrapper script
+    providing a packet filter mini-language to state your
+    filtering needs independent of the used firewall type.
+    It's just like a service start/stop script and started
+    during the normal System V boot sequence.
+
+    See the README for details.'
+  packager: ''
+  url: ''
+  timeFile: '1011218465'
+  timeBuild: '1011218465'
+  sizePackage: '7333'
+  sizeInstalled: '16835'
+  sizeArchive: '17904'
+  location: 'packetfilter-0.9.1-3.noarch.rpm'
+  license: '(c) 2002, Michael Radziej, under Gnu LPL'
+  vendor: ''
+  group: 'unsorted'
+  buildhost: 'martin.suse.de'
+  sourcerpm: 'packetfilter-0.9.1-3.src.rpm'
+  headerStart: '168'
+  headerEnd: '2268'
+  provides:
+packetfilter EQ 0-0.9.1-3
+  conflicts:
+
+  obsoletes:
+
+  requires:
+/bin/bash  -
+/bin/sh  - (pre=1)
+  files:
+/etc/packetfilter/def
+/etc/init.d/packetfilter
+/usr/sbin/rcpacketfilter
+/etc/packetfilter/ppp0
+/etc/packetfilter: dir
+  authors: 
+  keywords: 
+  media: 
+  dirsizes: 
+
+  freshen: 
+
+  install-only: '0'
+  files:
+/etc/packetfilter/def
+/etc/init.d/packetfilter
+/usr/sbin/rcpacketfilter
+/etc/packetfilter/ppp0
+/etc/packetfilter: dir
+  Changelog:
+
+  Plain RPM:
+    arch: noarch
+    filename: foo.rpm
+    download size: 56678
+    MD5: 234233
+    build time: 23443
+  Patch RPM:
+    arch: noarch
+    filename: foo.patch.rpm
+    download size: 56278
+    MD5: 2344533
+    build time: 23243
+    Base version:
+      epoch: 1
+      version: 2
+      release: 3
+      MD5: 
+      build time: 
+      source info: 
+
+    Base version:
+      epoch: 2
+      version: 3
+      release: 4
+      MD5: 
+      build time: 
+      source info: 
+  Delta RPM:
+    arch: noarch
+    filename: foo-delta-bla.delta.rpm
+    download size: 234
+    MD5: 1222
+    build time: 2232
+    Base version:
+      epoch: 3
+      version: 4
+      release: 5
+      MD5: 312321
+      build time: 3232
+      source info: 
+Exit Code: 0
diff --git a/test/devel.jsrain/yum/YUMParser.test/Makefile.am b/test/devel.jsrain/yum/YUMParser.test/Makefile.am
new file mode 100644 (file)
index 0000000..4ea7550
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile.am for packagemanager/testsuite/devel.mir/tests-YUMParser
+#
+
+EXTRA_DIST = YUMParser.exp $(wildcard *.test.xml *.ref)
diff --git a/test/devel.jsrain/yum/YUMParser.test/README b/test/devel.jsrain/yum/YUMParser.test/README
new file mode 100644 (file)
index 0000000..8dd1d06
--- /dev/null
@@ -0,0 +1,32 @@
+contents
+--------
+
+This is a collection of testcases for the YUM Parser. 
+
+Each testcase contains:
+
+- the input file, <number>-<mode>-<description>.test.xml
+  mode is the first argument to YUMtest, describing the type 
+  of file
+
+- the output file, <number>-<mode>-<description>.test.xml.ref
+
+- the error output (with all syntax warnings),
+  <number>-<mode>-<description>.test.xml.err.ref
+  Here, the first characters have been cut away to remove time
+  and hostname
+
+testit.sh walks through all testcases ("*.test.xml"), creates
+.out and .err.out files and compares them with the reference files.
+If everything matches, it outputs "pass", else it outputs "fail".
+
+
+
+testcase descriptions
+---------------------
+
+001-005: Correct, full xml files
+006-   : full xml files with additional elements
+       : not well-formed files
+       : just a bunch of zeroes
+       : just an empty input file
diff --git a/test/devel.jsrain/yum/YUMtest.cc b/test/devel.jsrain/yum/YUMtest.cc
new file mode 100644 (file)
index 0000000..ad3b875
--- /dev/null
@@ -0,0 +1,121 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMtest.cc
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    main() to test the YUM parsers
+/-*/
+
+#include <YUMParser.h>
+#include <zypp/base/Logger.h>
+
+using namespace zypp;
+using namespace zypp::parser;
+using namespace zypp::parser::YUM;
+using namespace std;
+
+namespace {
+  void usage() {
+    cerr << "YUMtest usage: "<< endl
+    << "YUMtest TYPE" << endl
+    << "TYPE: repomd|primary|group|filelist|other|patch" << endl;
+  }
+}
+
+
+int main(int argc, char **argv)
+{
+  if (argc < 2) {
+    usage();
+    return 2;
+  }
+
+//  set_log_filename("-");
+
+  try {
+    if (!strcmp(argv[1],"repomd")) {
+      YUMRepomdParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else if (!strcmp(argv[1],"primary")) {
+      YUMPrimaryParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else if (!strcmp(argv[1],"group")) {
+      YUMGroupParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else if (!strcmp(argv[1],"filelist")) {
+      YUMFileListParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else if (!strcmp(argv[1],"other")) {
+      YUMOtherParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else if (!strcmp(argv[1],"patch")) {
+      YUMPatchParser iter(cin,"");
+      for (;
+           !iter.atEnd();
+           ++iter) {
+             cout << **iter;
+           }
+      if (iter.errorStatus())
+        throw *iter.errorStatus();
+    }
+    else {
+      usage();
+      return 2;
+    }
+  }  
+  catch (XMLParserError& err) {
+    cerr << "** ouch **" << endl
+      << "syntax error encountered in XML input:" << endl
+      << err.msg() << " " << err.position() << endl;
+    return 1;
+  }
+  
+           return 0;
+}
diff --git a/test/devel.jsrain/yum/testit.sh b/test/devel.jsrain/yum/testit.sh
new file mode 100755 (executable)
index 0000000..7486f8b
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+# goes through each testcase in this directory
+# see README
+for testcase in $1/*.test.xml
+do
+    # echo "$testcase" > testit.log
+    mode="${testcase#*-}"
+    mode="${mode%%-*}"
+    ref="$testcase.ref"
+    err_ref="$testcase.err.ref"
+
+    ./YUMtest "$mode" < "$testcase" > "$testcase.out" 2>"$testcase.err.tmp"
+    echo "Exit Code: $?" >> "$testcase.out"
+
+    # remove date and host name from logs
+    cut -d \  -f 5- < "$testcase.err.tmp" > "$testcase.err.out"
+    rm "$testcase.err.tmp"
+
+    if diff "$ref" "$testcase.out" \
+       && diff "$err_ref" "$testcase.err.out" 
+    then
+        echo "OK: $testcase"
+    else
+        echo "FAILED: $testcase"
+        exit 1
+    fi
+done
+
+
index 75589e1..f478c5c 100644 (file)
@@ -49,7 +49,8 @@ lib@PACKAGE@_la_LDFLAGS =     @LIB_VERSION_INFO@
 
 lib@PACKAGE@_la_LIBADD =        base/lib@PACKAGE@_base.la      \
                                detail/lib@PACKAGE@_detail.la   \
-                               capability/lib@PACKAGE@_capability.la
-                               parser/lib@PACKAGE@_parser.la
+                               capability/lib@PACKAGE@_capability.la   \
+                               parser/lib@PACKAGE@_parser.la   \
+                               parser/yum/lib@PACKAGE@_parser_yum.la
 
 ## ##################################################
index df1349d..cf39769 100644 (file)
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 ## ##################################################
 
-SUBDIRS =
+SUBDIRS = yum
 
 INCLUDES = -I$(oldincludedir)/libxml2
 
diff --git a/zypp/parser/yum/Makefile.am b/zypp/parser/yum/Makefile.am
new file mode 100644 (file)
index 0000000..906cafa
--- /dev/null
@@ -0,0 +1,36 @@
+## Process this file with automake to produce Makefile.in
+## ##################################################
+
+SUBDIRS =
+
+INCLUDES = -I$(oldincludedir)/libxml2 -I..
+
+## ##################################################
+
+include_HEADERS = \
+       YUMFileListParser.h     \
+       YUMOtherParser.h        \
+       YUMParser.h             \
+       YUMPrimaryParser.h      \
+       YUMGroupParser.h        \
+       YUMParserData.h         \
+       YUMPatchParser.h        \
+       YUMRepomdParser.h       \
+       schemanames.h
+
+
+noinst_LTLIBRARIES =   lib@PACKAGE@_parser_yum.la
+
+## ##################################################
+
+lib@PACKAGE@_parser_yum_la_SOURCES = \
+       YUMParserData.cc        \
+       YUMFileListParser.cc    \
+       YUMRepomdParser.cc      \
+       YUMGroupParser.cc       \
+       YUMPatchParser.cc       \
+       YUMOtherParser.cc       \
+       YUMPrimaryParser.cc
+
+
+## ##################################################
diff --git a/zypp/parser/yum/YUMFileListParser.cc b/zypp/parser/yum/YUMFileListParser.cc
new file mode 100644 (file)
index 0000000..0e815ac
--- /dev/null
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMFileListParser.cc
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    Parses file list files in a YUM repository
+
+/-*/
+
+
+#include <YUMFileListParser.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <LibXMLHelper.h>
+#include <schemanames.h>
+#include <iostream>
+#include <zypp/base/Logger.h>
+
+
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+
+YUMFileListParser::YUMFileListParser(istream &is, const string& baseUrl)
+: XMLNodeIterator<YUMFileListDataPtr>(is, baseUrl,FILELISTSCHEMA)
+{
+  fetchNext();
+}
+
+YUMFileListParser::YUMFileListParser()
+{ }
+
+YUMFileListParser::YUMFileListParser(YUMFileListDataPtr& entry)
+: XMLNodeIterator<YUMFileListDataPtr>(entry)
+{ }
+
+
+
+YUMFileListParser::~YUMFileListParser()
+{
+}
+
+
+
+
+// select for which elements process() will be called
+bool 
+YUMFileListParser::isInterested(const xmlNodePtr nodePtr)
+{
+  bool result = (_helper.isElement(nodePtr)
+                 && _helper.name(nodePtr) == "package");
+  return result;
+}
+
+
+// do the actual processing
+YUMFileListDataPtr
+YUMFileListParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMFileListDataPtr dataPtr = new YUMFileListData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+
+  dataPtr->pkgId = _helper.attribute(dataNode,"pkgid");
+  dataPtr->name = _helper.attribute(dataNode,"name");
+  dataPtr->arch = _helper.attribute(dataNode,"arch");
+
+  for (xmlNodePtr child = dataNode->children;
+       child != 0;
+       child = child->next) {
+         if (_helper.isElement(child)) {
+           string name = _helper.name(child);
+           if (name == "version") {
+             dataPtr->epoch = _helper.attribute(child,"epoch");
+             dataPtr->ver = _helper.attribute(child,"ver");
+             dataPtr->rel = _helper.attribute(child,"rel");
+           }
+           else if (name == "file") {
+             dataPtr->files.push_back
+               (FileData(_helper.content(child),
+                         _helper.attribute(child,"type")));
+           }
+           else {
+             WAR << "YUM <filelists> contains the unknown element <" << name << "> "
+               << _helper.positionInfo(child) << ", skipping" << endl;
+           }
+         }
+       }
+  return dataPtr;
+}
+
+
+}}}
diff --git a/zypp/parser/yum/YUMFileListParser.h b/zypp/parser/yum/YUMFileListParser.h
new file mode 100644 (file)
index 0000000..de4f947
--- /dev/null
@@ -0,0 +1,93 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMFileListParser.h
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose: Parses file list files in a YUM repository
+
+/-*/
+
+#ifndef YUMFileListParser_h
+#define YUMFileListParser_h
+
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+#include <list>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  * @short Parser for YUM filelists files
+  * Use this class as an iterator that produces, one after one,
+  * YUMFileListDataPtr(s) for the XML package elements.
+  * Here's an example:
+  * 
+  * for (YUMFileListParser iter(anIstream, baseUrl),
+  *      iter != YUMFileListParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  *
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMFileListParser : public XMLNodeIterator<YUMFileListDataPtr>
+  {
+  public:
+    /**
+     * Constructor.
+     * @param is the istream to read from
+     * @param baseUrl the base URL of the XML document. Can be left empty.
+     */
+    YUMFileListParser(std::istream &is, const std::string &baseUrl);
+    YUMFileListParser();
+    YUMFileListParser(YUMFileListDataPtr& entry);
+
+    
+    /**
+     * Destructor.
+     */
+    virtual ~YUMFileListParser();
+    
+  private:
+    /**
+     * decides if the parser is interested in the node (and subtree) of an element.
+     * @param nodePtr the XML node
+     * @return true if the parser is interested.
+     */
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    
+    /**
+     * creates a new object from the xml subtree
+     * @param reader 
+     * @return 
+     */
+    virtual YUMFileListDataPtr process(const xmlTextReaderPtr reader);
+
+    /**
+     * converts the xml stuff to c++ stuff and filters the right namespaces
+     */
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/YUMGroupParser.cc b/zypp/parser/yum/YUMGroupParser.cc
new file mode 100644 (file)
index 0000000..5870dce
--- /dev/null
@@ -0,0 +1,141 @@
+#include <YUMGroupParser.h>
+#include <zypp/parser/LibXMLHelper.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <zypp/base/Logger.h>
+#include <schemanames.h>
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+YUMGroupParser::YUMGroupParser()
+{ }
+
+YUMGroupParser::YUMGroupParser(YUMGroupDataPtr& entry)
+: XMLNodeIterator<YUMGroupDataPtr>(entry)
+{ }
+
+
+YUMGroupParser::~YUMGroupParser()
+{ }
+
+
+// select for which elements process() will be called
+bool 
+YUMGroupParser::isInterested(const xmlNodePtr nodePtr)
+{
+  return _helper.isElement(nodePtr) && _helper.name(nodePtr) == "group";
+}
+
+// do the actual processing
+YUMGroupDataPtr
+YUMGroupParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMGroupDataPtr dataPtr = new YUMGroupData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+  
+  for (xmlNodePtr child = dataNode->children;
+       child && child != dataNode;
+       child = child->next) {
+         if (_helper.isElement(child)) {
+           string name = _helper.name(child);
+           if (name == "groupid") {
+             dataPtr->groupId = _helper.content(child);
+           }
+           else if (name == "name") {
+             dataPtr->name.push_back
+               (MultiLang(_helper.attribute(child,"lang"),
+                          _helper.content(child)));
+           }
+           else if (name == "default") {
+             dataPtr->default_ = _helper.content(child);
+           }
+           else if (name == "uservisible") {
+             dataPtr->userVisible = _helper.content(child);
+           }
+           else if (name == "description") {
+             dataPtr->description.push_back
+               (MultiLang(_helper.attribute(child,"lang"),
+                          _helper.content(child)));
+           }
+           else if (name == "grouplist") {
+             parseGrouplist(dataPtr, child);
+           }
+           else if (name == "packagelist") {
+             parsePackageList(dataPtr, child);
+           }
+           else {
+             WAR << "YUM <group> contains the unknown element <" << name << "> "
+               << _helper.positionInfo(child) << ", skipping" << endl;
+           }
+         }
+       }
+  return dataPtr;
+} /* end process */
+
+void YUMGroupParser::parseGrouplist(YUMGroupDataPtr dataPtr,
+                                          xmlNodePtr node)
+{
+  assert(dataPtr);
+  assert(node);
+  
+  for (xmlNodePtr child = node->children;
+       child != 0;
+       child = child ->next) {
+         if (_helper.isElement(child)) {
+           string name = _helper.name(child);
+           if (name == "metapkg" || name == "groupreq") {
+             dataPtr->grouplist.push_back
+               (MetaPkg(_helper.attribute(child,"type"),
+                        _helper.content(child)));
+           }
+           else {
+             WAR << "YUM <grouplist> contains the unknown element <" << name << "> "
+               << _helper.positionInfo(child) << ", skipping" << endl;
+           }
+         }
+       }
+}
+
+
+void YUMGroupParser::parsePackageList(YUMGroupDataPtr dataPtr,
+                                            xmlNodePtr node)
+{
+  assert(dataPtr);
+  assert(node);
+  
+  for (xmlNodePtr child = node->children;
+       child != 0;
+       child = child ->next) {
+         if (_helper.isElement(child)) {
+           string name = _helper.name(child);
+           if (name == "packagereq") {
+           dataPtr->packageList.push_back
+             (PackageReq(_helper.attribute(child,"type"),
+                         _helper.attribute(child,"epoch"),
+                         _helper.attribute(child,"ver"),
+                         _helper.attribute(child,"rel"),
+                         _helper.content(child)));
+           }
+           else {
+             WAR << "YUM <packagelist> contains the unknown element <" << name << "> "
+               << _helper.positionInfo(child) << ", skipping" << endl;
+           }
+         }
+       }
+}
+
+
+
+YUMGroupParser::YUMGroupParser(istream &is, const string &baseUrl)
+: XMLNodeIterator<YUMGroupDataPtr>(is, baseUrl,GROUPSCHEMA)
+{ 
+  fetchNext();
+}
+
+}}}
diff --git a/zypp/parser/yum/YUMGroupParser.h b/zypp/parser/yum/YUMGroupParser.h
new file mode 100644 (file)
index 0000000..e5a457d
--- /dev/null
@@ -0,0 +1,55 @@
+
+
+#ifndef YUMGroupParser_h
+#define YUMGroupParser_h
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+#include <list>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  *
+  * @short Parser for YUM group files.
+  *
+  * Use this class as an iterator that produces, one after one,
+  * YUMGroupDataPtr(s) for the XML group elements.
+  * Here's an example:
+  *
+  * for (YUMGroupParser iter(anIstream, baseUrl),
+  *      iter != YUMFileListParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  *
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMGroupParser : public XMLNodeIterator<YUMGroupDataPtr>
+  {
+  public:
+    YUMGroupParser(std::istream &is, const std::string &baseUrl);
+    YUMGroupParser();
+    YUMGroupParser(YUMGroupDataPtr& entry);
+    virtual ~YUMGroupParser();
+    
+  private:
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    virtual YUMGroupDataPtr process(const xmlTextReaderPtr reader);
+    void parseGrouplist(YUMGroupDataPtr dataPtr,
+                        xmlNodePtr node);
+    void parsePackageList(YUMGroupDataPtr dataPtr,
+                          xmlNodePtr node);
+    
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/YUMOtherParser.cc b/zypp/parser/yum/YUMOtherParser.cc
new file mode 100644 (file)
index 0000000..d69e727
--- /dev/null
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMOtherParser.cc
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    Parses other.xml files in a YUM repository
+
+/-*/
+
+
+#include <YUMOtherParser.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <zypp/parser/LibXMLHelper.h>
+#include <zypp/base/Logger.h>
+#include <schemanames.h>
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+
+YUMOtherParser::YUMOtherParser(istream &is, const string& baseUrl)
+: XMLNodeIterator<YUMOtherDataPtr>(is, baseUrl,OTHERSCHEMA)
+{
+  fetchNext();
+}
+
+YUMOtherParser::YUMOtherParser()
+{ }
+
+YUMOtherParser::YUMOtherParser(YUMOtherDataPtr& entry)
+: XMLNodeIterator<YUMOtherDataPtr>(entry)
+{ }
+
+
+
+YUMOtherParser::~YUMOtherParser()
+{
+}
+
+
+
+
+// select for which elements process() will be called
+bool 
+YUMOtherParser::isInterested(const xmlNodePtr nodePtr)
+{
+  bool result = (_helper.isElement(nodePtr)
+                 && _helper.name(nodePtr) == "package");
+  return result;
+}
+
+
+// do the actual processing
+YUMOtherDataPtr
+YUMOtherParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMOtherDataPtr dataPtr = new YUMOtherData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+
+  dataPtr->pkgId = _helper.attribute(dataNode,"pkgid");
+  dataPtr->name = _helper.attribute(dataNode,"name");
+  dataPtr->arch = _helper.attribute(dataNode,"arch");
+
+  for (xmlNodePtr child = dataNode->children;
+       child != 0;
+       child = child->next) {
+         if (_helper.isElement(child)) {
+           string name = _helper.name(child);
+           if (name == "version") {
+             dataPtr->epoch = _helper.attribute(child,"epoch");
+             dataPtr->ver = _helper.attribute(child,"ver");
+             dataPtr->rel = _helper.attribute(child,"rel");
+           }
+           else if (name == "file") {
+             dataPtr->changelog.push_back
+               (ChangelogEntry(_helper.attribute(child,"author"),
+                               _helper.attribute(child,"date"),
+                               _helper.content(child)));
+           }
+           else {
+             WAR << "YUM <otherdata> contains the unknown element <" << name << "> "
+               << _helper.positionInfo(child) << ", skipping" << endl;
+           }
+         }
+       }
+  return dataPtr;
+}
+
+}}}
diff --git a/zypp/parser/yum/YUMOtherParser.h b/zypp/parser/yum/YUMOtherParser.h
new file mode 100644 (file)
index 0000000..00536b4
--- /dev/null
@@ -0,0 +1,93 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMOtherParser.h
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    Parses other.xml files in a YUM repository
+
+/-*/
+
+#ifndef YUMOtherParser_h
+#define YUMOtherParser_h
+
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+#include <list>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  * @short Parser for YUM other.xml files
+  * Use this class as an iterator that produces, one after one,
+  * YUMOtherDataPtr(s) for the XML package elements.
+  * Here's an example:
+  * 
+  * for (YUMOtherParser iter(anIstream, baseUrl),
+  *      iter != YUMOtherParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  * 
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMOtherParser : public XMLNodeIterator<YUMOtherDataPtr>
+  {
+  public:
+    /**
+     * Constructor.
+     * @param is the istream to read from
+     * @param baseUrl the base URL of the XML document. Can be left empty.
+     */
+    YUMOtherParser(std::istream &is, const std::string &baseUrl);
+
+    YUMOtherParser();
+    YUMOtherParser(YUMOtherDataPtr& entry);
+    
+    /**
+     * Destructor.
+     */
+    virtual ~YUMOtherParser();
+    
+  private:
+    /**
+     * decides if the parser is interested in the node (and subtree) of an element.
+     * @param nodePtr the XML node
+     * @return true if the parser is interested.
+     */
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    
+    /**
+     * creates a new object from the xml subtree
+     * @param reader 
+     * @return 
+     */
+    virtual YUMOtherDataPtr process(const xmlTextReaderPtr reader);
+
+    /**
+     * converts the xml stuff to c++ stuff and filters the right namespaces
+     */
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/YUMParser.h b/zypp/parser/yum/YUMParser.h
new file mode 100644 (file)
index 0000000..d24e279
--- /dev/null
@@ -0,0 +1,32 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMParser.h
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose: Declare everything you need to use YUM parsers.
+/-*/
+
+#ifndef YUMParser_h
+#define YUMParser_h
+
+#include <YUMParserData.h>
+#include <YUMRepomdParser.h>
+#include <YUMPrimaryParser.h>
+#include <YUMGroupParser.h>
+#include <YUMFileListParser.h>
+#include <YUMOtherParser.h>
+#include <YUMPatchParser.h>
+
+#endif
diff --git a/zypp/parser/yum/YUMParserData.cc b/zypp/parser/yum/YUMParserData.cc
new file mode 100644 (file)
index 0000000..194fdf9
--- /dev/null
@@ -0,0 +1,504 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMParserData.cc
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    Boring constructors of YUM repository data structures
+            and also boring output operators
+            Don't read in a tired mood.
+/-*/
+
+
+#include <YUMParserData.h>
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+YUMDependency::YUMDependency()
+{ }
+
+YUMDependency::YUMDependency(const std::string& name,
+                             const std::string& flags,
+                             const std::string& epoch,
+                             const std::string& ver,
+                             const std::string& rel,
+                             const std::string& pre)
+: name(name),
+flags(flags),
+epoch(epoch),
+ver(ver),
+rel(rel),
+pre(pre)
+{ };
+
+YUMDirSize::YUMDirSize()
+{ }
+
+YUMDirSize::YUMDirSize(const std::string& path,
+                       const std::string& sizeKByte,
+                       const std::string& fileCount)
+: path(path), sizeKByte(sizeKByte), fileCount(fileCount)
+{ }
+
+YUMRepomdData::YUMRepomdData()
+{ }
+
+YUMPrimaryData::YUMPrimaryData()
+{ }
+
+FileData::FileData()
+{ }
+
+YUMPatchData::YUMPatchData()
+{ }
+
+FileData::FileData(const std::string &name,
+                   const std::string &type)
+: name(name), type(type)
+{ }
+
+
+YUMGroupData::YUMGroupData()
+{ }
+
+MultiLang::MultiLang()
+{ }
+
+MultiLang::MultiLang(const std::string& language,
+                     const std::string& text)
+: language(language), text(text)
+{ }
+
+
+MetaPkg::MetaPkg()
+{ }
+
+MetaPkg::MetaPkg(const std::string& type,
+                 const std::string& name)
+: type(type), name(name)
+{ }
+
+PackageReq::PackageReq()
+{ }
+
+PackageReq::PackageReq(const std::string& type,
+                       const std::string& epoch,
+                       const std::string& ver,
+                       const std::string& rel,
+                       const std::string& name)
+: type(type), epoch(epoch), ver(ver), rel(rel), name(name)
+{ }
+
+ChangelogEntry::ChangelogEntry()
+{ }
+
+ChangelogEntry::ChangelogEntry(const std::string& author,
+                               const std::string& date,
+                               const std::string& entry)
+: author(author), date(date), entry(entry)
+{ }
+
+                
+YUMFileListData::YUMFileListData()
+{ }
+
+YUMOtherData::YUMOtherData()
+{ }
+
+
+/* Define pointer classes */
+
+IMPL_PTR_TYPE(YUMRepomdData);
+IMPL_PTR_TYPE(YUMPrimaryData);
+IMPL_PTR_TYPE(YUMGroupData);
+IMPL_PTR_TYPE(YUMFileListData);
+IMPL_PTR_TYPE(YUMOtherData);
+IMPL_PTR_TYPE(YUMPatchData);
+IMPL_PTR_TYPE(YUMPatchPackage);
+IMPL_PTR_TYPE(YUMPatchScript);
+IMPL_PTR_TYPE(YUMPatchMessage);
+
+/* output operators */
+
+namespace {
+  /**
+   * @short Generic stream output for lists of Ptrs
+   * @param out the ostream where the output goes to
+   * @param aList the list to output
+   * @return is out
+   */
+  template<class T>
+  ostream& operator<<(ostream &out, const list<T>& aList)
+  {
+    typedef typename list<T>::const_iterator IterType;
+    for (IterType iter = aList.begin();
+        iter != aList.end();
+        ++iter) {
+          if (iter != aList.begin())
+            out << endl;
+          ::operator<<(out,*iter);
+        }
+    return out;
+  }
+}
+
+  /**
+   * Join a list of strings into a single string
+   * @param aList the list of strings
+   * @param joiner what to put between the list elements
+   * @return the joined string
+   */
+  string join(const list<string>& aList,
+              const string& joiner)
+  {
+    string res;
+    for (list<string>::const_iterator iter = aList.begin();
+        iter != aList.end();
+        ++ iter) {
+          if (iter != aList.begin())
+            res += joiner;
+          res += *iter;
+        }
+    return res;
+  }
+
+}}} // namespaces
+
+using namespace zypp::parser::YUM;
+  
+ostream& operator<<(ostream &out, const YUMDependency& data)
+{
+  out << data.name << " " << data.flags << " ";
+  if (! data.epoch.empty())
+    out << data.epoch << "-";
+  out << data.ver << "-" << data.rel ;
+  if (! data.pre.empty() && data.pre != "0")
+    out << " (pre=" << data.pre << ")";
+  return out;
+}
+  
+ostream& operator<<(ostream &out, const YUMDirSize& data)
+{
+  out << data.path
+    << ": " << data.sizeKByte << " kByte, "
+    << data.fileCount << " files";
+  return out;
+}
+    
+ostream& operator<<(ostream &out, const FileData& data)
+{
+  out << data.name;
+  if (! data.type.empty()) {
+    out << ": " << data.type;
+  }
+  return out;
+}
+
+ostream& operator<<(ostream &out, const MultiLang& data)
+{
+  if (!data.language.empty())
+    out << "[" << data.language << "] ";
+  out << data.text;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const MetaPkg& data)
+{
+  out << "type: " << data.type
+    << ", name: " << data.name;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const PackageReq& data)
+{
+  out << "[" << data.type << "] "
+    << data.name
+    << " " << data.epoch
+    << "-" << data.ver
+    << "-" << data.rel;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const ChangelogEntry& data)
+{
+  out << data.date
+    << " - " << data.author << endl
+    << data.entry;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const YUMRepomdData& data)
+{
+  out << "Repomd Data: " << endl
+    << "  type: '" << data.type << "'" << endl
+    << "  location: '" << data.location << "'" <<endl
+    << "  checksumType: '" << data.checksumType << "'" << endl
+    << "  checksum: '" << data.checksum << "'" << endl
+    << "  timestamp: '" << data.timestamp << "'" << endl
+    << "  openChecksumType: '" << data.openChecksumType << "'" << endl
+    << "  openChecksum: '" << data.openChecksum << "'" << endl;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const YUMPrimaryData& data)
+{
+  out << "-------------------------------------------------" << endl
+    << "Primary Data: " << endl
+    << "name: '" << data.name << "'" << endl
+    << "type: '" << data.type << "'" << endl
+    << " arch: '" << data.arch << "'" << endl
+    << " ver: '" << data.ver << "'" << endl
+    << "checksumType: '" << data.checksumType << "'" << endl
+    << "checksumPkgid: '" << data.checksumPkgid << "'" << endl
+    << "checksum: '" << data.checksum << "'" << endl
+    << "summary: '" << data.summary << "'" << endl
+    << "description: '" << data.description << "'" << endl
+    << "packager: '" << data.packager << "'" << endl
+    << "url: '" << data.url << "'" << endl
+    << "timeFile: '" << data.timeFile << "'" << endl
+    << "timeBuild: '" << data.timeBuild << "'" << endl
+    << "sizePackage: '" << data.sizePackage << "'" << endl
+    << "sizeInstalled: '" << data.sizeInstalled << "'" << endl
+    << "sizeArchive: '" << data.sizeArchive << "'" << endl
+    << "location: '" << data.location << "'" << endl
+    << "license: '" << data.license << "'" << endl
+    << "vendor: '" << data.vendor << "'" << endl
+    << "group: '" << data.group << "'" << endl
+    << "buildhost: '" << data.buildhost << "'" << endl
+    << "sourcerpm: '" << data.sourcerpm << "'" << endl
+    << "headerStart: '" << data.headerStart << "'" << endl
+    << "headerEnd: '" << data.headerEnd << "'" << endl
+    << "provides:" << endl
+    << data.provides << endl
+    << "conflicts:" << endl
+    << data.conflicts << endl
+    << "obsoletes:" << endl
+    << data.obsoletes << endl
+    << "requires:" << endl
+    << data.requires << endl
+    << "files:" << endl
+    << data.files << endl
+    << "authors: " << join(data.authors,", ") << endl
+    << "keywords: " << join(data.keywords,", ") << endl
+    << "media: " << data.media << endl
+    << "dirsizes: " << endl
+    << data.dirSizes << endl
+    << "freshen: " << endl
+    << data.freshen << endl
+    << "install-only: '" << data.installOnly << "'" << endl;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const YUMGroupData& data)
+{
+  out << "-------------------------------------------------" << endl
+    << "Group Data: " << endl
+    << "group-id: '" << data.groupId << "'" << endl
+    << "name:" << endl
+    << data.name << endl
+    << "default: '" << data.default_  << "'" << endl
+    << "user-visible: '" << data.userVisible  << "'" << endl
+    << "description:" << endl
+    << data.description << endl
+    << "grouplist:" << endl
+    << data.grouplist << endl
+    << "packageList:" << endl
+    << data.packageList << endl;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const YUMFileListData& data)
+{
+  out << "-------------------------------------------------" << endl
+    << "File List: " << endl
+    << "pkgid: " << data.pkgId << endl
+    << "package: " << data.name << " "
+    << data.epoch << "-" << data.ver << "-" << data.rel << endl
+    << "files:" << endl
+    << data.files << endl;
+  return out;
+}
+
+ostream& operator<<(ostream& out, const YUMOtherData& data)
+{
+  out << "-------------------------------------------------" << endl
+    << "Other: " << endl
+    << "pkgid: " << data.pkgId
+    << "package: " << data.name << " "
+    << data.epoch << "-" << data.ver << "-" << data.rel << endl
+    << "Changelog:" << endl
+    << data.changelog << endl;
+  return out;
+}
+
+ostream& operator<<(ostream &out, const YUMPatchData& data)
+{
+  out << "-------------------------------------------------" << endl
+    << "Patch Data: " << endl
+    << "  patch ID: " << data.patchId << endl
+    << "  timestamp: '" << data.timestamp << "'" << endl
+    << "  engine: '" << data.engine << "'" << endl
+    << "  name: " << data.name << endl
+    << "  summary: " << data.summary << endl
+    << "  description: " << data.description << endl
+    << "  epoch: " << data.epoch << endl
+    << "  version: " << data.ver << endl
+    << "  release: " << data.rel << endl
+    << "  provides: " << data.provides << endl
+    << "  conflicts: " << data.conflicts << endl
+    << "  obsoletes: " << data.obsoletes << endl
+    << "  freshen: " << data.freshen << endl
+    << "  requires: " << data.requires << endl
+    << "  category: " << data.category << endl
+    << "  reboot needed: " << data.rebootNeeded << endl
+    << "  affects package manager: " << data.packageManager << endl
+    << "  update script: " << data.updateScript << endl
+    << "  atoms:" << endl
+    << data.atoms;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const YUMPatchAtom& data)
+{
+  out << "Atom data" << endl
+    << "  atom type: " << data.type << endl;
+  if (data.type == "message")
+    out << *data.message;
+  else if (data.type == "script")
+    out << *data.script;
+  else if (data.type == "package")
+    out << *data.package;
+  else
+    out << "Unknown atom type" << endl;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const YUMPatchMessage& data)
+{
+  out << "Message Data: " << endl
+    << "  name: " << data.name << endl
+    << "  type: " << data.type << endl
+    << "  epoch: " << data.epoch << endl
+    << "  version: " << data.ver << endl
+    << "  release: " << data.rel << endl
+    << "  provides: " << data.provides << endl
+    << "  conflicts: " << data.conflicts << endl
+    << "  obsoletes: " << data.obsoletes << endl
+    << "  freshen: " << data.freshen << endl
+    << "  requires: " << data.requires << endl
+    << "  text: " << data.text << endl;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const YUMPatchScript& data)
+{
+  out << "Script Data: " << endl
+    << "  name: " << data.name << endl
+    << "  epoch: " << data.epoch << endl
+    << "  version: " << data.ver << endl
+    << "  release: " << data.rel << endl
+    << "  provides: " << data.provides << endl
+    << "  conflicts: " << data.conflicts << endl
+    << "  obsoletes: " << data.obsoletes << endl
+    << "  freshen: " << data.freshen << endl
+    << "  requires: " << data.requires << endl
+    << "  do script: " << data.do_script << endl
+    << "  undo script: " << data.undo_script << endl;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const YUMPatchPackage& data)
+{
+  out << "Package Data: " << endl
+    << "  name: '" << data.name << "'" << endl
+    << "  type: '" << data.type << "'" << endl
+    << "   arch: '" << data.arch << "'" << endl
+    << "   ver: '" << data.ver << "'" << endl
+    << "  checksumType: '" << data.checksumType << "'" << endl
+    << "  checksumPkgid: '" << data.checksumPkgid << "'" << endl
+    << "  checksum: '" << data.checksum << "'" << endl
+    << "  summary: '" << data.summary << "'" << endl
+    << "  description: '" << data.description << "'" << endl
+    << "  packager: '" << data.packager << "'" << endl
+    << "  url: '" << data.url << "'" << endl
+    << "  timeFile: '" << data.timeFile << "'" << endl
+    << "  timeBuild: '" << data.timeBuild << "'" << endl
+    << "  sizePackage: '" << data.sizePackage << "'" << endl
+    << "  sizeInstalled: '" << data.sizeInstalled << "'" << endl
+    << "  sizeArchive: '" << data.sizeArchive << "'" << endl
+    << "  location: '" << data.location << "'" << endl
+    << "  license: '" << data.license << "'" << endl
+    << "  vendor: '" << data.vendor << "'" << endl
+    << "  group: '" << data.group << "'" << endl
+    << "  buildhost: '" << data.buildhost << "'" << endl
+    << "  sourcerpm: '" << data.sourcerpm << "'" << endl
+    << "  headerStart: '" << data.headerStart << "'" << endl
+    << "  headerEnd: '" << data.headerEnd << "'" << endl
+    << "  provides:" << endl
+    << data.provides << endl
+    << "  conflicts:" << endl
+    << data.conflicts << endl
+    << "  obsoletes:" << endl
+    << data.obsoletes << endl
+    << "  requires:" << endl
+    << data.requires << endl
+    << "  files:" << endl
+    << data.files << endl
+    << "  authors: " << join(data.authors,", ") << endl
+    << "  keywords: " << join(data.keywords,", ") << endl
+    << "  media: " << data.media << endl
+    << "  dirsizes: " << endl
+    << data.dirSizes << endl
+    << "  freshen: " << endl
+    << data.freshen << endl
+    << "  install-only: '" << data.installOnly << "'" << endl
+    << "  files:" << endl
+    << data.files << endl
+    << "  Changelog:" << endl
+    << data.changelog << endl
+    << "  Plain RPM:" << endl
+    << "    arch: " << data.plainRpm.arch << endl
+    << "    filename: " << data.plainRpm.filename << endl
+    << "    download size: " << data.plainRpm.downloadsize << endl
+    << "    MD5: " << data.plainRpm.md5sum << endl
+    << "    build time: " << data.plainRpm.buildtime << endl
+    << "  Patch RPM:" << endl
+    << "    arch: " << data.patchRpm.arch << endl
+    << "    filename: " << data.patchRpm.filename << endl
+    << "    download size: " << data.patchRpm.downloadsize << endl
+    << "    MD5: " << data.patchRpm.md5sum << endl
+    << "    build time: " << data.patchRpm.buildtime << endl
+    << data.patchRpm.baseVersions
+    << "  Delta RPM:" << endl
+    << "    arch: " << data.deltaRpm.arch << endl
+    << "    filename: " << data.deltaRpm.filename << endl
+    << "    download size: " << data.deltaRpm.downloadsize << endl
+    << "    MD5: " << data.deltaRpm.md5sum << endl
+    << "    build time: " << data.deltaRpm.buildtime << endl
+    << data.deltaRpm.baseVersion;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const YUMBaseVersion& data)
+{
+  out << "    Base version:" << endl
+    << "      epoch: " << data.epoch << endl
+    << "      version: " << data.ver << endl
+    << "      release: " << data.rel << endl
+    << "      MD5: " << data.md5sum << endl
+    << "      build time: " << data.buildtime << endl
+    << "      source info: " << data.source_info << endl;
+  return out;
+}
diff --git a/zypp/parser/yum/YUMParserData.h b/zypp/parser/yum/YUMParserData.h
new file mode 100644 (file)
index 0000000..07e225b
--- /dev/null
@@ -0,0 +1,446 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       YUMParserData.h
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose: Declares the various YUMData classes, which are rather dumb
+         structure-like classes that hold the data of specific YUM
+         repository files. The parsers (YUM...Parser) create these objects,
+         and the YUM installation source use them to build more sophisticated
+         objects.
+/-*/
+
+#ifndef YUMParserData_h
+#define YUMParserData_h
+
+#include "zypp/base/ReferenceCounted.h"
+#include "zypp/base/NonCopyable.h"
+#include <string>
+#include <list>
+#include <iostream>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  DEFINE_PTR_TYPE( YUMRepomdData );
+  DEFINE_PTR_TYPE( YUMPrimaryData );
+  DEFINE_PTR_TYPE( YUMGroupData );
+  DEFINE_PTR_TYPE( YUMFileListData );
+  DEFINE_PTR_TYPE( YUMOtherData );
+  DEFINE_PTR_TYPE( YUMPatchData );
+  DEFINE_PTR_TYPE( YUMPatchPackage );
+  DEFINE_PTR_TYPE( YUMPatchScript );
+  DEFINE_PTR_TYPE( YUMPatchMessage );
+
+  /**
+  * @short Holds dependency data
+  */
+  class YUMDependency {
+  public:
+    YUMDependency();
+    YUMDependency(const std::string& name,
+                  const std::string& flags,
+                  const std::string& epoch,
+                  const std::string& ver,
+                  const std::string& rel,
+                  const std::string& pre);
+    std::string name;
+    std::string flags;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string pre;
+  };
+
+
+  /**
+  * @short Holds data about how much space will be needed per directory
+  **/
+  class YUMDirSize {
+  public:
+    YUMDirSize();
+    YUMDirSize(const std::string& path,
+              const std::string& size,
+              const std::string& fileCount);
+    const std::string path;
+    const std::string sizeKByte;
+    const std::string fileCount;
+  };
+
+  /**
+   * @short Holds Data about file and file type
+   *  (directory, plain) within other YUM data
+   **/
+  class FileData {
+  public:
+    std::string name;
+    std::string type;
+    FileData();
+    FileData(const std::string &name,
+             const std::string &type);
+  };
+
+  /**
+   * @short A Multi-language text
+   * (usually you have a list<MultiLang>)
+   **/
+  class MultiLang {
+  public:
+    MultiLang();
+    MultiLang(const std::string& langugage,
+              const std::string& text);
+    std::string language;
+    std::string text;
+  };
+
+  /**
+   * @short Defines "meta packages" that are in YUMGroupData
+   * FIXME: I'm not certain what this is ;-)
+   **/
+  class MetaPkg {
+  public:
+    MetaPkg();
+    MetaPkg(const std::string& type,
+            const std::string& name);
+    std::string type;
+    std::string name;
+  };
+
+  /**
+   * @short A Package reference, e.g. within YUMGroupData
+   * this is without architecture.
+   **/
+  class PackageReq {
+  public:
+    PackageReq();
+    PackageReq(const std::string& type,
+              const std::string& epoch,
+              const std::string& ver,
+              const std::string& rel,
+              const std::string& name);
+    std::string type;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string name;
+  };
+
+  /**
+  * @short A single changelog entry
+  **/
+  class ChangelogEntry {
+  public:
+    ChangelogEntry();
+    ChangelogEntry(const std::string& author,
+                  const std::string& date,
+                  const std::string& entry);
+    std::string author;
+    std::string date;
+    std::string entry;
+  };
+
+  class YUMBaseVersion {
+  public:
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string md5sum;
+    std::string buildtime;
+    std::string source_info;
+  };
+
+  class YUMPatchPackage : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMPatchPackage() {};
+    // data for primary
+    std::string type;
+    std::string name;
+    std::string arch;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string checksumType;
+    std::string checksumPkgid;
+    std::string checksum;
+    std::string summary;
+    std::string description;
+    std::string packager;
+    std::string url;
+    std::string timeFile;
+    std::string timeBuild;
+    std::string sizePackage;
+    std::string sizeInstalled;
+    std::string sizeArchive;
+    std::string location;
+    std::string license;
+    std::string vendor;
+    std::string group;
+    std::string buildhost;
+    std::string sourcerpm;
+    std::string headerStart;
+    std::string headerEnd;
+    std::list<YUMDependency> provides;
+    std::list<YUMDependency> conflicts;
+    std::list<YUMDependency> obsoletes;
+    std::list<YUMDependency> requires;
+    std::list<FileData> files;
+    // SuSE specific data
+    std::list<std::string> authors;
+    std::list<std::string> keywords;
+    std::string  media;
+    std::list<YUMDirSize> dirSizes;
+    std::list<YUMDependency> freshen;
+    bool installOnly;
+    // Change Log
+    std::list<ChangelogEntry> changelog;
+    // Package Files
+    struct {
+      std::string arch;
+      std::string filename;
+      std::string downloadsize;
+      std::string md5sum;
+      std::string buildtime;
+    } plainRpm;
+    struct {
+      std::string arch;
+      std::string filename;
+      std::string downloadsize;
+      std::string md5sum;
+      std::string buildtime;
+      std::list<YUMBaseVersion> baseVersions;
+    } patchRpm;
+    struct {
+      std::string arch;
+      std::string filename;
+      std::string downloadsize;
+      std::string md5sum;
+      std::string buildtime;
+      YUMBaseVersion baseVersion;
+    } deltaRpm;
+  };
+
+  class YUMPatchScript : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMPatchScript() {};
+    std::string name;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string do_script;
+    std::string undo_script;
+    std::list<YUMDependency> provides;
+    std::list<YUMDependency> conflicts;
+    std::list<YUMDependency> obsoletes;
+    std::list<YUMDependency> freshen;
+    std::list<YUMDependency> requires;
+  };
+
+  class YUMPatchMessage : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMPatchMessage() {};
+    std::string name;
+    std::string type;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::list<YUMDependency> provides;
+    std::list<YUMDependency> conflicts;
+    std::list<YUMDependency> obsoletes;
+    std::list<YUMDependency> freshen;
+    std::list<YUMDependency> requires;
+    std::string text;
+  };
+
+  class YUMPatchAtom {
+  public:
+    std::string type;
+    // union not possibel due to constructors
+    // there is no common parent
+    YUMPatchPackagePtr package;
+    YUMPatchScriptPtr script;
+    YUMPatchMessagePtr message;
+  };
+
+  /**
+   * @short Holds the metadata about a YUM repository
+   **/
+  class YUMRepomdData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMRepomdData();
+    std::string type;
+    std::string location;
+    std::string checksumType;
+    std::string checksum;
+    std::string timestamp;
+    std::string openChecksumType;
+    std::string openChecksum;
+  };
+
+  /**
+   * @short Describes a package in a YUM repository
+   **/
+  class YUMPrimaryData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMPrimaryData();
+    std::string type;
+    std::string name;
+    std::string arch;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::string checksumType;
+    std::string checksumPkgid;
+    std::string checksum;
+    std::string summary;
+    std::string description;
+    std::string packager;
+    std::string url;
+    std::string timeFile;
+    std::string timeBuild;
+    std::string sizePackage;
+    std::string sizeInstalled;
+    std::string sizeArchive;
+    std::string location;
+    std::string license;
+    std::string vendor;
+    std::string group;
+    std::string buildhost;
+    std::string sourcerpm;
+    std::string headerStart;
+    std::string headerEnd;
+    std::list<YUMDependency> provides;
+    std::list<YUMDependency> conflicts;
+    std::list<YUMDependency> obsoletes;
+    std::list<YUMDependency> requires;
+    std::list<FileData> files;
+
+    // SuSE specific data
+    std::list<std::string> authors;
+    std::list<std::string> keywords;
+    std::string  media;
+    std::list<YUMDirSize> dirSizes;
+    std::list<YUMDependency> freshen;
+    bool installOnly;
+  };
+
+  /**
+  * @short Describes the groups in a YUM repository
+  **/
+
+  class YUMGroupData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+
+    YUMGroupData();
+    std::string groupId;
+    std::list<MultiLang> name;
+    std::string default_;
+    std::string userVisible;
+    std::list<MultiLang> description;
+    std::list<MetaPkg> grouplist;
+    std::list<PackageReq> packageList;
+  };
+
+  /**
+   * @short Contains the file list for a YUM package.
+   **/
+  class YUMFileListData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+
+    YUMFileListData();
+
+    std::string pkgId;
+    std::string name;
+    std::string arch;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::list<FileData> files;
+  };
+
+  /**
+  * @short Data from other.mxl, i.e., changelogs
+  **/
+  class YUMOtherData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMOtherData();
+    std::string pkgId;
+    std::string name;
+    std::string arch;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::list<ChangelogEntry> changelog;
+  };
+
+/* ** YUMPatchData not yet finalized **/
+
+  class YUMPatchData : public base::ReferenceCounted, private base::NonCopyable {
+  public:
+    YUMPatchData();
+    ~YUMPatchData() {
+
+    }
+
+    std::string patchId;
+    std::string timestamp;
+    std::string engine;
+    std::string name;
+    MultiLang summary;
+    MultiLang description;
+    std::string epoch;
+    std::string ver;
+    std::string rel;
+    std::list<YUMDependency> provides;
+    std::list<YUMDependency> conflicts;
+    std::list<YUMDependency> obsoletes;
+    std::list<YUMDependency> freshen;
+    std::list<YUMDependency> requires;
+    std::string category;
+    bool rebootNeeded;
+    bool packageManager;
+    std::string updateScript;
+    // FIXME this copying of structures is inefective
+    std::list<YUMPatchAtom> atoms;
+  };
+
+
+}}} /* end of namespace YUM */
+
+
+  /* Easy output */
+
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMDependency& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMDirSize& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMRepomdData& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::FileData& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::MultiLang& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::MetaPkg& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::PackageReq& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::ChangelogEntry& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMRepomdData& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMPrimaryData& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMGroupData& data);
+std::ostream& operator<<(std::ostream &out, const zypp::parser::YUM::YUMFileListData& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMOtherData& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMPatchData& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMPatchAtom& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMPatchMessage& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMPatchScript& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMPatchPackage& data);
+std::ostream& operator<<(std::ostream& out, const zypp::parser::YUM::YUMBaseVersion& data);
+
+
+
+
+#endif
diff --git a/zypp/parser/yum/YUMPatchParser.cc b/zypp/parser/yum/YUMPatchParser.cc
new file mode 100644 (file)
index 0000000..3c9b6d0
--- /dev/null
@@ -0,0 +1,533 @@
+#include <YUMPatchParser.h>
+#include <YUMPrimaryParser.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <zypp/parser/LibXMLHelper.h>
+#include <zypp/base/Logger.h>
+#include <schemanames.h>
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+YUMPatchParser::~YUMPatchParser()
+{ }
+
+YUMPatchParser::YUMPatchParser(istream &is, const string& baseUrl)
+: XMLNodeIterator<YUMPatchDataPtr>(is, baseUrl,PATCHSCHEMA)
+{
+  fetchNext();
+}
+
+YUMPatchParser::YUMPatchParser()
+{ }
+
+YUMPatchParser::YUMPatchParser(YUMPatchDataPtr& entry)
+: XMLNodeIterator<YUMPatchDataPtr>(entry)
+{ }
+
+
+// select for which elements process() will be called
+bool 
+YUMPatchParser::isInterested(const xmlNodePtr nodePtr)
+{
+  return _helper.isElement(nodePtr) && _helper.name(nodePtr) == "patch";
+}
+
+// do the actual processing
+YUMPatchDataPtr
+YUMPatchParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMPatchDataPtr patchPtr = new YUMPatchData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+  patchPtr->timestamp = _helper.attribute(dataNode,"timestamp");
+  patchPtr->patchId = _helper.attribute(dataNode,"patchid");
+  patchPtr->engine = _helper.attribute(dataNode,"engine");
+
+  // default values for optional entries
+  patchPtr->rebootNeeded = false;
+  patchPtr->packageManager = false;
+
+  // FIXME move the respective method to a common class, inherit it  
+  YUMPrimaryParser prim;
+
+  for (xmlNodePtr child = dataNode->children; 
+       child && child != dataNode;
+       child = child->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "name") {
+       patchPtr->name = _helper.content(child);
+      }
+      else if (name == "summary") {
+        patchPtr->summary = MultiLang(
+         _helper.attribute(child,"lang"),
+         _helper.content(child));
+      }
+      else if (name == "description") {
+        patchPtr->description = MultiLang(
+         _helper.attribute(child,"lang"),
+         _helper.content(child));
+      }
+      else if (name == "version") {
+        patchPtr->epoch = _helper.attribute(child,"epoch");
+        patchPtr->ver = _helper.attribute(child,"ver");
+        patchPtr->rel = _helper.attribute(child,"rel");
+      }
+      else if (name == "provides") {
+        prim.parseDependencyEntries(& patchPtr->provides, child);
+      }
+      else if (name == "conflicts") {
+        prim.parseDependencyEntries(& patchPtr->conflicts, child);
+      }
+      else if (name == "obsoletes") {
+        prim.parseDependencyEntries(& patchPtr->obsoletes, child);
+      }
+      else if (name == "requires") {
+        prim.parseDependencyEntries(& patchPtr->requires, child);
+      }
+      else if (name == "freshen") {
+        prim.parseDependencyEntries(& patchPtr->requires, child);
+      }
+      else if (name == "category") {
+       patchPtr->category = _helper.content(child);
+      }
+      else if (name == "reboot_needed") {
+       patchPtr->rebootNeeded = true;
+      }
+      else if (name == "package_manager") {
+       patchPtr->packageManager = true;
+      }
+      else if (name == "update_script") {
+       patchPtr->updateScript = _helper.content(child);
+      }
+      else if (name == "atoms") {
+        parseAtomsNode(patchPtr, child);
+      }
+      else {
+        WAR << "YUM <data> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  return patchPtr;
+} /* end process */
+
+
+void 
+YUMPatchParser::parseAtomsNode(YUMPatchDataPtr dataPtr,
+                               xmlNodePtr formatNode)
+{
+  assert(formatNode);
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "package")
+      {
+       parsePackageNode (dataPtr, child);
+      }
+      else if (name == "script")
+      {
+       parseScriptNode (dataPtr, child);
+      }
+      else if (name == "message")
+      {
+       parseMessageNode (dataPtr, child);
+      }
+      else {
+        WAR << "YUM <atoms> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void 
+YUMPatchParser::parseFormatNode(YUMPatchPackage *dataPtr,
+                                        xmlNodePtr formatNode)
+{
+  assert(formatNode);
+  dataPtr->installOnly = false;
+
+  // FIXME move the respective method to a common class, inherit it  
+  YUMPrimaryParser prim;
+
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "license") {
+        dataPtr->license = _helper.content(child);
+      }
+      else if (name == "vendor") {
+        dataPtr->vendor = _helper.content(child);
+      }
+      else if (name == "group") {
+        dataPtr->group = _helper.content(child);
+      }
+      else if (name == "buildhost") {
+        dataPtr->buildhost = _helper.content(child);
+      }
+      else if (name == "sourcerpm") {
+        dataPtr->sourcerpm = _helper.content(child);
+      }
+      else if (name == "header-range") {
+        dataPtr->headerStart = _helper.attribute(child,"start");
+        dataPtr->headerEnd = _helper.attribute(child,"end");
+      }
+      else if (name == "provides") {
+        prim.parseDependencyEntries(& dataPtr->provides, child);
+      }
+      else if (name == "conflicts") {
+        prim.parseDependencyEntries(& dataPtr->conflicts, child);
+      }
+      else if (name == "obsoletes") {
+        prim.parseDependencyEntries(& dataPtr->obsoletes, child);
+      }
+      else if (name == "requires") {
+        prim.parseDependencyEntries(& dataPtr->requires, child);
+      }
+      else if (name == "file") {
+        dataPtr->files.push_back
+          (FileData(_helper.content(child),
+                    _helper.attribute(child,"type")));
+      }
+      /* SUSE specific elements */
+      else if (name == "authors") {
+        prim.parseAuthorEntries(& dataPtr->authors, child);
+      }
+      else if (name == "keywords") {
+        prim.parseKeywordEntries(& dataPtr->keywords, child);
+      }
+      else if (name == "media") {
+        dataPtr->media = _helper.attribute(child,"mediaid");
+      }
+      else if (name == "dirsizes") {
+        prim.parseDirsizeEntries(& dataPtr->dirSizes, child);
+      }
+      else if (name == "freshen") {
+        prim.parseDependencyEntries(& dataPtr->freshen, child);
+      }
+      else if (name == "install_only") {
+        dataPtr->installOnly = true;
+      }
+      else {
+        WAR << "YUM <atom/package/format> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void
+YUMPatchParser::parsePkgPlainRpmNode(YUMPatchPackage *dataPtr,
+                               xmlNodePtr formatNode)
+{
+  dataPtr->plainRpm.arch = _helper.attribute( formatNode, "arch" );
+  dataPtr->plainRpm.filename = _helper.attribute( formatNode, "filename" );
+  dataPtr->plainRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
+  dataPtr->plainRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
+  dataPtr->plainRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      WAR << "YUM <atom/package/pkgfiles/plain> contains the unknown element <"
+       << name << "> "
+        << _helper.positionInfo(child) << ", skipping" << endl;
+    }
+  }
+}
+
+void
+YUMPatchParser::parsePkgPatchRpmNode(YUMPatchPackage *dataPtr,
+                               xmlNodePtr formatNode)
+{
+  dataPtr->patchRpm.arch = _helper.attribute( formatNode, "arch" );
+  dataPtr->patchRpm.filename = _helper.attribute( formatNode, "filename" );
+  dataPtr->patchRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
+  dataPtr->patchRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
+  dataPtr->patchRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "base_version") {
+       YUMBaseVersion base_version;
+       parsePkgBaseVersionNode( &base_version, child);
+        dataPtr->patchRpm.baseVersions.push_back( base_version );
+      }
+      else {
+        WAR << "YUM <atom/package/pkgfiles/patch> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void
+YUMPatchParser::parsePkgDeltaRpmNode(YUMPatchPackage *dataPtr,
+                               xmlNodePtr formatNode)
+{
+  dataPtr->deltaRpm.arch = _helper.attribute( formatNode, "arch" );
+  dataPtr->deltaRpm.filename = _helper.attribute( formatNode, "filename" );
+  dataPtr->deltaRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
+  dataPtr->deltaRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
+  dataPtr->deltaRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "base_version") {
+       parsePkgBaseVersionNode( &(dataPtr->deltaRpm.baseVersion), child);
+      }
+      else {
+        WAR << "YUM <atom/package/pkgfiles/delta> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+
+void
+YUMPatchParser::parsePkgBaseVersionNode(YUMBaseVersion *dataPtr,
+                                       xmlNodePtr formatNode)
+{
+  dataPtr->epoch = _helper.attribute( formatNode, "epoch" );
+  dataPtr->ver = _helper.attribute( formatNode, "ver" );
+  dataPtr->rel = _helper.attribute( formatNode, "rel" );
+  dataPtr->md5sum = _helper.attribute( formatNode, "md5sum" );
+  dataPtr->buildtime = _helper.attribute( formatNode, "buildtime" );
+  dataPtr->source_info = _helper.attribute( formatNode, "source_info" );
+}
+
+void
+YUMPatchParser::parsePkgFilesNode(YUMPatchPackage *dataPtr,
+                                xmlNodePtr formatNode)
+{
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "plainrpm") {
+       parsePkgPlainRpmNode( dataPtr, child );
+      }
+      else if (name == "patchrpm") {
+       parsePkgPatchRpmNode( dataPtr, child );
+      }
+      else if (name == "deltarpm") {
+       parsePkgDeltaRpmNode( dataPtr, child );
+      }
+      else {
+        WAR << "YUM <atom/package/pkgfiles> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+
+
+
+
+
+void
+YUMPatchParser::parsePackageNode(YUMPatchDataPtr dataPtr,
+                               xmlNodePtr formatNode)
+{
+  YUMPatchAtom at;
+  at.type = "package";
+  at.package = new YUMPatchPackage;
+  at.package->type = _helper.attribute(formatNode,"type");
+  at.package->installOnly = false;
+
+  // FIXME move the respective method to a common class, inherit it  
+  YUMPrimaryParser prim;
+
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "name") {
+       at.package->name = _helper.content(child);
+      }
+      else if (name == "arch") {
+        at.package->arch = _helper.content(child);
+      }
+      else if (name == "version") {
+        at.package->epoch = _helper.attribute(child,"epoch");
+        at.package->ver = _helper.attribute(child,"ver");
+        at.package->rel = _helper.attribute(child,"rel");
+      }
+      else if (name == "checksum") {
+        at.package->checksumType = _helper.attribute(child,"type");
+        at.package->checksumPkgid = _helper.attribute(child,"pkgid");
+        at.package->checksum = _helper.content(child);
+      }
+      else if (name == "summary") {
+        at.package->summary = _helper.content(child);
+      }
+      else if (name == "description") {
+        at.package->description = _helper.content(child);
+      }
+      else if (name == "packager") {
+        at.package->packager = _helper.content(child);
+      }
+      else if (name == "url") {
+        at.package->url = _helper.content(child);
+      }
+      else if (name == "time") {
+        at.package->timeFile = _helper.attribute(child,"file");
+        at.package->timeBuild = _helper.attribute(child,"build");
+      }
+      else if (name == "size") {
+        at.package->sizePackage = _helper.attribute(child,"package");
+        at.package->sizeInstalled = _helper.attribute(child,"installed");
+        at.package->sizeArchive = _helper.attribute(child,"archive");
+      }
+      else if (name == "location") {
+        at.package->location = _helper.attribute(child,"href");
+      }
+      else if (name == "format") {
+       parseFormatNode (&*at.package, child);
+      }
+      else if (name == "pkgfiles")
+      {
+       parsePkgFilesNode (&*at.package, child);
+      }
+      else {
+        WAR << "YUM <atoms/package> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  dataPtr->atoms.push_back(at);
+}
+
+void
+YUMPatchParser::parseScriptNode(YUMPatchDataPtr dataPtr,
+                               xmlNodePtr formatNode)
+{
+  YUMPatchAtom at;
+  at.type = "script";
+  at.script = new YUMPatchScript;
+
+  // FIXME move the respective method to a common class, inherit it  
+  YUMPrimaryParser prim;
+
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "name") {
+       at.script->name = _helper.content(child);
+      }
+      else if (name == "version") {
+        at.script->epoch = _helper.attribute(child,"epoch");
+        at.script->ver = _helper.attribute(child,"ver");
+        at.script->rel = _helper.attribute(child,"rel");
+      }
+      else if (name == "do") {
+       at.script->do_script = _helper.content(child);
+      }
+      else if (name == "undo") {
+       at.script->undo_script = _helper.content(child);
+      }
+      else if (name == "provides") {
+        prim.parseDependencyEntries(& at.script->provides, child);
+      }
+      else if (name == "conflicts") {
+        prim.parseDependencyEntries(& at.script->conflicts, child);
+      }
+      else if (name == "obsoletes") {
+        prim.parseDependencyEntries(& at.script->obsoletes, child);
+      }
+      else if (name == "requires") {
+        prim.parseDependencyEntries(& at.script->requires, child);
+      }
+      else if (name == "freshen") {
+        prim.parseDependencyEntries(& at.script->requires, child);
+      }
+      else {
+        WAR << "YUM <atoms/script> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  dataPtr->atoms.push_back(at);
+}
+
+void
+YUMPatchParser::parseMessageNode(YUMPatchDataPtr dataPtr,
+                               xmlNodePtr formatNode)
+{
+  YUMPatchAtom at;
+  at.type = "message";
+  at.message = new YUMPatchMessage;
+  at.message->type = _helper.attribute(formatNode,"type");
+
+  // FIXME move the respective method to a common class, inherit it  
+  YUMPrimaryParser prim;
+
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "name") {
+       at.message->name = _helper.content(child);
+      }
+      else if (name == "version") {
+        at.message->epoch = _helper.attribute(child,"epoch");
+        at.message->ver = _helper.attribute(child,"ver");
+        at.message->rel = _helper.attribute(child,"rel");
+      }
+      else if (name == "text") {
+       at.message->text = _helper.content(child);
+      }
+      else if (name == "provides") {
+        prim.parseDependencyEntries(& at.message->provides, child);
+      }
+      else if (name == "conflicts") {
+        prim.parseDependencyEntries(& at.message->conflicts, child);
+      }
+      else if (name == "obsoletes") {
+        prim.parseDependencyEntries(& at.message->obsoletes, child);
+      }
+      else if (name == "requires") {
+        prim.parseDependencyEntries(& at.message->requires, child);
+      }
+      else if (name == "freshen") {
+        prim.parseDependencyEntries(& at.message->requires, child);
+      }
+      else {
+        WAR << "YUM <atoms/message> contains the unknown element <"
+         << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  dataPtr->atoms.push_back(at);
+}
+
+}}}
diff --git a/zypp/parser/yum/YUMPatchParser.h b/zypp/parser/yum/YUMPatchParser.h
new file mode 100644 (file)
index 0000000..8c48bcb
--- /dev/null
@@ -0,0 +1,58 @@
+
+
+#ifndef YUMPatchParser_h
+#define YUMPatchParser_h
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+#include <list>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  * @short Parser for YUM primary.xml files (containing package metadata)
+  * Use this class as an iterator that produces, one after one,
+  * YUMPatchDataPtr(s) for the XML package elements in the input.
+  * Here's an example:
+  *
+  * for (YUMPatchParser iter(anIstream, baseUrl),
+  *      iter != YUMOtherParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  *
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMPatchParser : public XMLNodeIterator<YUMPatchDataPtr>
+  {
+  public:
+    YUMPatchParser(std::istream &is, const std::string &baseUrl);
+    YUMPatchParser();
+    YUMPatchParser(YUMPatchDataPtr& entry);
+    virtual ~YUMPatchParser();
+
+  private:
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    virtual YUMPatchDataPtr process(const xmlTextReaderPtr reader);
+    void parseAtomsNode(YUMPatchDataPtr dataPtr, xmlNodePtr formatNode);
+    void parsePackageNode(YUMPatchDataPtr dataPtr, xmlNodePtr formatNode);
+    void parseMessageNode(YUMPatchDataPtr dataPtr, xmlNodePtr formatNode);
+    void parseScriptNode(YUMPatchDataPtr dataPtr, xmlNodePtr formatNode);
+    void parseFormatNode(YUMPatchPackage *dataPtr, xmlNodePtr formatNode);
+    void parsePkgFilesNode(YUMPatchPackage *dataPtr, xmlNodePtr formatNode);
+    void parsePkgPlainRpmNode(YUMPatchPackage *dataPtr, xmlNodePtr formatNode);
+    void parsePkgPatchRpmNode(YUMPatchPackage *dataPtr, xmlNodePtr formatNode);
+    void parsePkgDeltaRpmNode(YUMPatchPackage *dataPtr, xmlNodePtr formatNode);
+    void parsePkgBaseVersionNode(YUMBaseVersion *dataPtr, xmlNodePtr formatNode);
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/YUMPrimaryParser.cc b/zypp/parser/yum/YUMPrimaryParser.cc
new file mode 100644 (file)
index 0000000..bead36e
--- /dev/null
@@ -0,0 +1,292 @@
+#include <YUMPrimaryParser.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlstring.h>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <zypp/parser/LibXMLHelper.h>
+#include <zypp/base/Logger.h>
+#include <schemanames.h>
+
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+
+YUMPrimaryParser::YUMPrimaryParser(istream &is, const string& baseUrl)
+  : XMLNodeIterator<YUMPrimaryDataPtr>(is, baseUrl,PRIMARYSCHEMA)
+{
+  fetchNext();
+}
+
+YUMPrimaryParser::YUMPrimaryParser()
+{ }
+
+YUMPrimaryParser::YUMPrimaryParser(YUMPrimaryDataPtr& entry)
+: XMLNodeIterator<YUMPrimaryDataPtr>(entry)
+{ }
+
+
+YUMPrimaryParser::~YUMPrimaryParser()
+{
+}
+  
+
+
+
+// select for which elements process() will be called
+bool 
+YUMPrimaryParser::isInterested(const xmlNodePtr nodePtr)
+{
+  bool result = (_helper.isElement(nodePtr)
+                 && _helper.name(nodePtr) == "package");
+  return result;
+}
+
+
+// do the actual processing
+YUMPrimaryDataPtr
+YUMPrimaryParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMPrimaryDataPtr dataPtr = new YUMPrimaryData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+
+  dataPtr->type = _helper.attribute(dataNode,"type");
+  dataPtr->installOnly = false;
+  
+  for (xmlNodePtr child = dataNode->children; 
+       child != 0;
+       child = child->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "name") {
+        dataPtr->name = _helper.content(child);
+      }
+      else if (name == "arch") {
+        dataPtr->arch = _helper.content(child);
+      }
+      else if (name == "version") {
+        dataPtr->epoch = _helper.attribute(child,"epoch");
+        dataPtr->ver = _helper.attribute(child,"ver");
+        dataPtr->rel = _helper.attribute(child,"rel");
+      }
+      else if (name == "checksum") {
+        dataPtr->checksumType = _helper.attribute(child,"type");
+        dataPtr->checksumPkgid = _helper.attribute(child,"pkgid");
+        dataPtr->checksum = _helper.content(child);
+      }
+      else if (name == "summary") {
+        dataPtr->summary = _helper.content(child);
+      }
+      else if (name == "description") {
+        dataPtr->description = _helper.content(child);
+      }
+      else if (name == "packager") {
+        dataPtr->packager = _helper.content(child);
+      }
+      else if (name == "url") {
+        dataPtr->url = _helper.content(child);
+      }
+      else if (name == "time") {
+        dataPtr->timeFile = _helper.attribute(child,"file");
+        dataPtr->timeBuild = _helper.attribute(child,"build");
+      }
+      else if (name == "size") {
+        dataPtr->sizePackage = _helper.attribute(child,"package");
+        dataPtr->sizeInstalled = _helper.attribute(child,"installed");
+        dataPtr->sizeArchive = _helper.attribute(child,"archive");
+      }
+      else if (name == "location") {
+        dataPtr->location = _helper.attribute(child,"href");
+      }
+      else if (name == "format") {
+        parseFormatNode(dataPtr, child);
+      }
+      else {
+        WAR << "YUM <metadata> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  return dataPtr;
+} /* end process */
+
+
+
+void 
+YUMPrimaryParser::parseFormatNode(YUMPrimaryDataPtr dataPtr,
+                                        xmlNodePtr formatNode)
+{
+  assert(formatNode);
+  dataPtr->installOnly = false;
+  for (xmlNodePtr child = formatNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "license") {
+        dataPtr->license = _helper.content(child);
+      }
+      else if (name == "vendor") {
+        dataPtr->vendor = _helper.content(child);
+      }
+      else if (name == "group") {
+        dataPtr->group = _helper.content(child);
+      }
+      else if (name == "buildhost") {
+        dataPtr->buildhost = _helper.content(child);
+      }
+      else if (name == "sourcerpm") {
+        dataPtr->sourcerpm = _helper.content(child);
+      }
+      else if (name == "header-range") {
+        dataPtr->headerStart = _helper.attribute(child,"start");
+        dataPtr->headerEnd = _helper.attribute(child,"end");
+      }
+      else if (name == "provides") {
+        parseDependencyEntries(& dataPtr->provides, child);
+      }
+      else if (name == "conflicts") {
+        parseDependencyEntries(& dataPtr->conflicts, child);
+      }
+      else if (name == "obsoletes") {
+        parseDependencyEntries(& dataPtr->obsoletes, child);
+      }
+      else if (name == "requires") {
+        parseDependencyEntries(& dataPtr->requires, child);
+      }
+      else if (name == "file") {
+        dataPtr->files.push_back
+          (FileData(_helper.content(child),
+                    _helper.attribute(child,"type")));
+      }
+      /* SUSE specific elements */
+      else if (name == "authors") {
+        parseAuthorEntries(& dataPtr->authors, child);
+      }
+      else if (name == "keywords") {
+        parseKeywordEntries(& dataPtr->keywords, child);
+      }
+      else if (name == "media") {
+        dataPtr->media = _helper.attribute(child,"mediaid");
+      }
+      else if (name == "dirsizes") {
+        parseDirsizeEntries(& dataPtr->dirSizes, child);
+      }
+      else if (name == "freshen") {
+        parseDependencyEntries(& dataPtr->freshen, child);
+      }
+      else if (name == "install_only") {
+        dataPtr->installOnly = true;
+      }
+      else {
+        WAR << "YUM <format> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+
+void
+YUMPrimaryParser::parseDependencyEntries(list<YUMDependency> *depList,
+                                               xmlNodePtr depNode)
+{
+  assert(depList);
+  assert(depNode);
+
+  for (xmlNodePtr child = depNode->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "entry") { 
+        depList->push_back
+          (YUMDependency(_helper.attribute(child,"name"),
+                         _helper.attribute(child,"flags"),
+                         _helper.attribute(child,"epoch"),
+                         _helper.attribute(child,"ver"),
+                         _helper.attribute(child,"rel"),
+                         _helper.attribute(child,"pre")));
+      }
+      else {
+        WAR << "YUM dependency within <format> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void
+YUMPrimaryParser::parseAuthorEntries(list<string> *authors,
+                                           xmlNodePtr node)
+{
+  assert(authors);
+  assert(node);
+
+  for (xmlNodePtr child = node->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "author") { 
+        authors->push_back(_helper.content(child));
+      }
+      else {
+        WAR << "YUM <authors> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void YUMPrimaryParser::parseKeywordEntries(list<string> *keywords,
+                                                 xmlNodePtr node)
+{
+  assert(keywords);
+  assert(node);
+
+  for (xmlNodePtr child = node->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "keyword") { 
+        keywords->push_back(_helper.content(child));
+      }
+      else {
+        WAR << "YUM <keywords> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+void YUMPrimaryParser::parseDirsizeEntries(list<YUMDirSize> *sizes,
+                                                 xmlNodePtr node)
+{
+  assert(sizes);
+  assert(node);
+
+  for (xmlNodePtr child = node->children; 
+       child != 0;
+       child = child ->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "dirsize") { 
+        sizes->push_back(YUMDirSize(_helper.attribute(child,"path"),
+                                    _helper.attribute(child,"size-kbyte"),
+                                    _helper.attribute(child,"filecount")));
+      }
+      else {
+        WAR << "YUM <dirsizes> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+}
+
+}}}
diff --git a/zypp/parser/yum/YUMPrimaryParser.h b/zypp/parser/yum/YUMPrimaryParser.h
new file mode 100644 (file)
index 0000000..5a811ee
--- /dev/null
@@ -0,0 +1,61 @@
+
+
+#ifndef YUMPrimaryParser_h
+#define YUMPrimaryParser_h
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+#include <list>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  * @short Parser for YUM primary.xml files (containing package metadata)
+  * Use this class as an iterator that produces, one after one,
+  * YUMPrimaryDataPtr(s) for the XML package elements in the input.
+  * Here's an example:
+  *
+  * for (YUMPrimaryParser iter(anIstream, baseUrl),
+  *      iter != YUMOtherParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  *
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMPrimaryParser : public XMLNodeIterator<YUMPrimaryDataPtr>
+  {
+  public:
+    YUMPrimaryParser(std::istream &is, const std::string &baseUrl);
+    YUMPrimaryParser();
+    YUMPrimaryParser(YUMPrimaryDataPtr& entry);
+    virtual ~YUMPrimaryParser();
+
+  private:
+    // FIXME move needed method to a common class, inherit it
+    friend class YUMPatchParser;
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    virtual YUMPrimaryDataPtr process(const xmlTextReaderPtr reader);
+    void parseFormatNode(YUMPrimaryDataPtr dataPtr,
+                         xmlNodePtr formatNode);
+    void parseDependencyEntries(std::list<YUMDependency> *depList, 
+                                xmlNodePtr depNode);
+    void parseAuthorEntries(std::list<std::string> *authors,
+                            xmlNodePtr node);
+    void parseKeywordEntries(std::list<std::string> *keywords,
+                             xmlNodePtr node);
+    void parseDirsizeEntries(std::list<YUMDirSize> *sizes,
+                             xmlNodePtr node);
+
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/YUMRepomdParser.cc b/zypp/parser/yum/YUMRepomdParser.cc
new file mode 100644 (file)
index 0000000..9df7779
--- /dev/null
@@ -0,0 +1,77 @@
+#include <YUMRepomdParser.h>
+#include <zypp/parser/LibXMLHelper.h>
+#include <istream>
+#include <string>
+#include <cassert>
+#include <libxml/xmlreader.h>
+#include <libxml/tree.h>
+#include <zypp/base/Logger.h>
+#include <schemanames.h>
+
+using namespace std;
+namespace zypp { namespace parser { namespace YUM {
+
+YUMRepomdParser::~YUMRepomdParser()
+{ }
+
+YUMRepomdParser::YUMRepomdParser()
+{ }
+
+YUMRepomdParser::YUMRepomdParser(YUMRepomdDataPtr& entry)
+: XMLNodeIterator<YUMRepomdDataPtr>(entry)
+{ }
+
+
+// select for which elements process() will be called
+bool 
+YUMRepomdParser::isInterested(const xmlNodePtr nodePtr)
+{
+  return _helper.isElement(nodePtr) && _helper.name(nodePtr) == "data";
+}
+
+// do the actual processing
+YUMRepomdDataPtr
+YUMRepomdParser::process(const xmlTextReaderPtr reader)
+{
+  assert(reader);
+  YUMRepomdDataPtr repoPtr = new YUMRepomdData;
+  xmlNodePtr dataNode = xmlTextReaderExpand(reader);
+  assert(dataNode);
+  repoPtr->type = _helper.attribute(dataNode,"type");
+  
+  for (xmlNodePtr child = dataNode->children; 
+       child && child != dataNode;
+       child = child->next) {
+    if (_helper.isElement(child)) {
+      string name = _helper.name(child);
+      if (name == "location") {
+        repoPtr->location = _helper.attribute(child,"href");
+      }
+      else if (name == "checksum") {
+        repoPtr->checksumType = _helper.attribute(child,"type");
+        repoPtr->checksum = _helper.content(child);
+      }
+      else if (name == "timestamp") {
+        repoPtr->timestamp = _helper.content(child);
+      }
+      else if (name == "open-checksum") {
+        repoPtr->openChecksumType = _helper.attribute(child, "type");
+        repoPtr->openChecksum = _helper.content(child);
+      }
+      else {
+        WAR << "YUM <data> contains the unknown element <" << name << "> "
+          << _helper.positionInfo(child) << ", skipping" << endl;
+      }
+    }
+  }
+  return repoPtr;
+} /* end process */
+
+  
+YUMRepomdParser::YUMRepomdParser(istream &is, const string &baseUrl)
+: XMLNodeIterator<YUMRepomdDataPtr>(is, baseUrl,REPOMDSCHEMA)
+{
+  fetchNext();
+}
+
+}}}
diff --git a/zypp/parser/yum/YUMRepomdParser.h b/zypp/parser/yum/YUMRepomdParser.h
new file mode 100644 (file)
index 0000000..14b81b9
--- /dev/null
@@ -0,0 +1,48 @@
+
+
+#ifndef YUMRepomdParser_h
+#define YUMRepomdParser_h
+
+#include <YUMParserData.h>
+#include <XMLNodeIterator.h>
+#include <LibXMLHelper.h>
+
+namespace zypp { namespace parser { namespace YUM {
+
+  /**
+  * @short Parser for YUM repomd.xml files (describing the repository)
+  * Use this class as an iterator that produces, one after one,
+  * YUMRepomdDataPtr(s) for the XML package elements.
+  * Here's an example:
+  *
+  * for (YUMRepomdParser iter(anIstream, baseUrl),
+  *      iter != YUMOtherParser.end(),     // or: iter() != 0, or ! iter.atEnd()
+  *      ++iter) {
+  *    doSomething(*iter)
+  * }
+  *
+  * The iterator owns the pointer (i.e., caller must not delete it)
+  * until the next ++ operator is called. At this time, it will be
+  * destroyed (and a new ENTRYTYPE is created.)
+  *
+  * If the input is fundamentally flawed so that it makes no sense to
+  * continue parsing, XMLNodeIterator will log it and consider the input as finished.
+  * You can query the exit status with errorStatus().
+  */
+  class YUMRepomdParser : public XMLNodeIterator<YUMRepomdDataPtr>
+  {
+  public:
+    YUMRepomdParser(std::istream &is, const std::string &baseUrl);
+    YUMRepomdParser();
+    YUMRepomdParser(YUMRepomdDataPtr& entry);
+    virtual ~YUMRepomdParser();
+
+  private:
+    virtual bool isInterested(const xmlNodePtr nodePtr);
+    virtual YUMRepomdDataPtr process(const xmlTextReaderPtr reader);
+
+    LibXMLHelper _helper;
+  };
+}}}
+
+#endif
diff --git a/zypp/parser/yum/schemanames.h b/zypp/parser/yum/schemanames.h
new file mode 100644 (file)
index 0000000..b98eb8f
--- /dev/null
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------\
+|                                                                      |
+|                      __   __    ____ _____ ____                      |
+|                      \ \ / /_ _/ ___|_   _|___ \                     |
+|                       \ V / _` \___ \ | |   __) |                    |
+|                        | | (_| |___) || |  / __/                     |
+|                        |_|\__,_|____/ |_| |_____|                    |
+|                                                                      |
+|                               core system                            |
+|                                                        (C) SuSE GmbH |
+\----------------------------------------------------------------------/
+
+File:       schemanames.h
+
+Author:     Michael Radziej <mir@suse.de>
+Maintainer: Michael Radziej <mir@suse.de>
+
+Purpose:    Pathnames of schemas for validation
+
+/-*/
+
+#ifndef schemanames_h
+#define schemanames_h
+
+namespace zypp { namespace parser { namespace YUM {
+/* FIXME: How do I do this properly? */
+#define SCHEMABASE "/usr/share/YaST2/schema/packagemanager/"
+#define REPOMDSCHEMA (SCHEMABASE "repomd.rng")
+#define PRIMARYSCHEMA (SCHEMABASE "suse-primary.rng")
+#define GROUPSCHEMA (SCHEMABASE "groups.rng")
+#define FILELISTSCHEMA (SCHEMABASE "filelists.rng")
+#define OTHERSCHEMA (SCHEMABASE "other.rng")
+#define PATCHSCHEMA (SCHEMABASE "patch.rng")
+}}}
+
+
+#endif