Index: CHANGES =================================================================== RCS file: rpm/CHANGES,v retrieving revision 1.1130.2.23 retrieving revision 1.1130.2.27 diff -u -u -r1.1130.2.23 -r1.1130.2.27 --- rpm/CHANGES 17 Sep 2002 15:18:23 -0000 1.1130.2.23 +++ rpm/CHANGES 6 Nov 2002 17:28:19 -0000 1.1130.2.27 @@ -286,6 +286,13 @@ - fix: register SIGCHLD handler before forking (#73134). - better diagnostics on failed header parsing. - lclint clean. + - rpm-4.1 release. + - fix: make sure that psm->child pid is set before SIGCHLD is handled. + - fix: use size_t consistently, avoid segfault on ia64. + - use %%{_lib} for libraries. + - fix: permit build with --disable-nls (#76258). + - backport db-4.1.17 changes. + - add _noDirTokens macro for 6x builds. 4.0.3 -> 4.0.4: - solaris: translate i86pc to i386 (#57182). Index: autogen.sh =================================================================== RCS file: rpm/autogen.sh,v retrieving revision 2.39 retrieving revision 2.39.2.1 diff -u -u -r2.39 -r2.39.2.1 --- rpm/autogen.sh 8 Aug 2002 22:20:26 -0000 2.39 +++ rpm/autogen.sh 25 Oct 2002 17:31:37 -0000 2.39.2.1 @@ -4,13 +4,13 @@ export LDFLAGS LTV="libtoolize (GNU libtool) 1.4.2" -ACV="autoconf (GNU Autoconf) 2.53" +ACV="autoconf (GNU Autoconf) 2.54" AMV="automake (GNU automake) 1.6.3" USAGE=" This script documents the versions of the tools I'm using to build rpm: libtool-1.4.2 - autoconf-2.53 - automake-1.6.2 + autoconf-2.54 + automake-1.6.3 Simply edit this script to change the libtool/autoconf/automake versions checked if you need to, as rpm should build (and has built) with all recent versions of libtool/autoconf/automake. Index: configure.ac =================================================================== RCS file: rpm/configure.ac,v retrieving revision 2.6.2.2 retrieving revision 2.6.2.3 diff -u -u -r2.6.2.2 -r2.6.2.3 --- rpm/configure.ac 22 Aug 2002 19:18:56 -0000 2.6.2.2 +++ rpm/configure.ac 9 Oct 2002 19:05:38 -0000 2.6.2.3 @@ -437,10 +437,12 @@ if test $withval = no ; then dnl ------------------ without internal db -AC_CHECK_HEADERS(db3/db.h) +AC_CHECK_HEADERS(db.h) dnl Check for Berkeley db3 API. AC_CHECK_FUNC(db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"], + AC_CHECK_LIB(db-4.1, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-4.1"], + AC_CHECK_LIB(db-4.0, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-4.0"], AC_CHECK_LIB(db-3.2, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-3.2"], AC_CHECK_LIB(db-3.1, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-3.1"], AC_CHECK_LIB(db-3.0, db_create, [DBLIBSRCS="$DBLIBSRCS db3.c"; libdb3="-ldb-3.0"], @@ -449,6 +451,8 @@ ) ) ) + ) + ) ) if test X"$DBLIBSRCS" = X; then @@ -1094,6 +1094,7 @@ dnl Determine the canonical arch-vendor-os for the build machine case "${build_cpu}" in *86) RPMCANONARCH=i386 ;; +x86_64*) RPMCANONARCH=x86_64 ;; alpha*) RPMCANONARCH=alpha ;; sparc*) RPMCANONARCH=sparc ;; ia64*) RPMCANONARCH=ia64 ;; Index: installplatform =================================================================== RCS file: rpm/installplatform,v retrieving revision 2.34 retrieving revision 2.34.2.2 diff -u -u -r2.34 -r2.34.2.2 --- rpm/installplatform 30 Jul 2002 17:07:39 -0000 2.34 +++ rpm/installplatform 11 Oct 2002 17:23:27 -0000 2.34.2.2 @@ -34,6 +34,7 @@ alpha*) SUBSTS='s_alpha_alpha_ s_alpha_alphaev5_ s_alpha_alphaev56_ s_alpha_alphapca56_ s_alpha_alphaev6_ s_alpha_alphaev67_' ;; sparc*) SUBSTS='s_sparc\(64\|v9\)_sparc_ s_sparc64_sparcv9_;s_sparc\([^v]\|$\)_sparcv9\1_ s_sparcv9_sparc64_;s_sparc\([^6]\|$\)_sparc64\1_' ;; powerpc*|ppc*) SUBSTS='s_ppc64_ppc_ s_ppc\([^6]\|$\)_ppc64\1_' ;; + s390*) SUBSTS='s_s390x_s390_ s_s390\([^x]\|$\)_s390x\1_' ;; *) SUBSTS=y___ ;; esac @@ -60,6 +61,12 @@ sparc-linux) MULTILIBNO=1 ;; sparcv9-linux) MULTILIBNO=1 ;; sparc64-linux) ARCH_INSTALL_POST=${pkglibdir}/brp-sparc64-linux; LIB=lib64; MULTILIBNO=2 ;; + s390-linux) MULTILIBNO=1 ;; + s390x-linux) LIB=lib64; MULTILIBNO=2 ;; + ppc-linux) MULTILIBNO=1 ;; + ppc64-linux) LIB=lib64; MULTILIBNO=2 ;; + i?86-linux|athlon-linux) MULTILIBNO=1 ;; + x86_64-linux) LIB=lib64; MULTILIBNO=2 ;; esac if [ -n "$MULTILIBNO" ]; then Index: rpmqv.c =================================================================== RCS file: rpm/rpmqv.c,v retrieving revision 1.98 retrieving revision 1.98.2.2 diff -u -u -r1.98 -r1.98.2.2 --- rpm/rpmqv.c 6 Aug 2002 01:41:46 -0000 1.98 +++ rpm/rpmqv.c 6 Nov 2002 17:28:19 -0000 1.98.2.2 @@ -271,6 +271,7 @@ freeSpecVec = freeSpec; /*@=type@*/ +#if defined(ENABLE_NLS) /* set up the correct locale */ (void) setlocale(LC_ALL, "" ); @@ -279,6 +280,7 @@ #endif bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); +#endif rpmSetVerbosity(RPMMESS_NORMAL); /* XXX silly use by showrc */ @@ -614,6 +616,8 @@ (void) close(p[1]); } + _noDirTokens = rpmExpandNumeric("%{?_noDirTokens}"); + ts = rpmtsCreate(); (void) rpmtsSetRootDir(ts, rpmcliRootDir); switch (bigMode) { Index: beecrypt/base64.c =================================================================== RCS file: rpm/beecrypt/base64.c,v retrieving revision 1.20 retrieving revision 1.20.2.1 diff -u -u -r1.20 -r1.20.2.1 --- rpm/beecrypt/base64.c 2 Jul 2002 23:54:35 -0000 1.20 +++ rpm/beecrypt/base64.c 9 Oct 2002 19:05:39 -0000 1.20.2.1 @@ -246,7 +246,7 @@ /*@-boundswrite@*/ /*@-internalglobs -modfilesys @*/ -char * b64encode (const void * data, int ns) +char * b64encode (const void * data, size_t ns) { static char b64enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -275,7 +275,7 @@ lc = 0; if (te) - while (ns) { + while (ns > 0) { if (_debug) fprintf(stderr, "%7u %02x %02x %02x -> %02x %02x %02x %02x\n", @@ -335,7 +335,7 @@ #define CRC24_POLY 0x1864cfbL /*@-boundsread@*/ -char * b64crc (const unsigned char * data, int ns) +char * b64crc (const unsigned char * data, size_t ns) { const unsigned char *s = data; uint32 crc = CRC24_INIT; @@ -367,7 +367,7 @@ /*@-internalglobs -modfilesys @*/ /*@-boundswrite@*/ -int b64decode (const char * s, void ** datap, int *lenp) +int b64decode (const char * s, void ** datap, size_t *lenp) { unsigned char b64dec[256]; const unsigned char *t; Index: beecrypt/base64.h =================================================================== RCS file: rpm/beecrypt/base64.h,v retrieving revision 1.14 retrieving revision 1.14.2.2 diff -u -u -r1.14 -r1.14.2.2 --- rpm/beecrypt/base64.h 13 May 2002 22:45:31 -0000 1.14 +++ rpm/beecrypt/base64.h 6 Nov 2002 17:28:19 -0000 1.14.2.2 @@ -68,17 +68,17 @@ * @return (malloc'd) base64 string */ BEECRYPTAPI /*@only@*/ /*@null@*/ /*@unused@*/ -char * b64encode (const void * data, int ns) +char * b64encode (const void * data, size_t ns) /*@*/; /** * Encode crc of binary input data into 5 bytes of base64 output. * @param data binary data - * @param ns crc of data + * @param ns no. bytes of binary data * @return (malloc'd) base64 string */ BEECRYPTAPI /*@only@*/ /*@null@*/ /*@unused@*/ -char * b64crc (const unsigned char * data, int ns) +char * b64crc (const unsigned char * data, size_t ns) /*@*/; /** @@ -89,7 +89,7 @@ * @return 0 on success, 1: s == NULL, 2: bad length, 3: bad char */ BEECRYPTAPI /*@unused@*/ -int b64decode (const char * s, /*@out@*/ void ** datap, /*@out@*/ int *lenp) +int b64decode (const char * s, /*@out@*/ void ** datap, /*@out@*/ size_t *lenp) /*@modifies *datap, *lenp @*/; /** Index: db3/configure =================================================================== RCS file: rpm/db3/configure,v retrieving revision 1.20 retrieving revision 1.20.2.1 diff -u -u -r1.20 -r1.20.2.1 --- rpm/db3/configure 30 Jul 2002 16:39:09 -0000 1.20 +++ rpm/db3/configure 6 Nov 2002 17:28:20 -0000 1.20.2.1 @@ -4,10 +4,6 @@ rm -f config.cache -# XXX hacks to get db-3.3.4 to configure properly -#ln -sf ../dist $db_dist/../db/dist -#ln -sf ../dist $db_dist - # XXX edit CFLAGS= ... out of invocation args ??? ARGS="`echo $* | sed -e 's% [^ ]*CFLAGS=[^ ]*%%' -e 's% -[^-][^ ]*%%g' -e 's%--cache-file=.*$%%'`" @@ -15,18 +11,15 @@ --enable-shared --enable-static --enable-rpc \ --with-uniquename=_rpmdb --srcdir=$db_dist -# XXX hack to get db-3.3.4 to configure properly -#rm -f $db_dist/../db/dist $db_dist/dist - mv Makefile Makefile.orig -cat Makefile.orig | sed -e 's/ -g$/ -g -O2/' -e '/^install:/c\ +cat Makefile.orig | sed -e '/^install[:-]/c\ .PHONY: listobjs\ listobjs:\ @echo $(OBJS) $(C_OBJS) \ \ distdir install check:\ \ -db3_install: all install_setip' > Makefile +db4_install: all install_setip' > Makefile mv db.h db.h.orig cat db.h.orig | sed \ @@ -36,7 +29,7 @@ /*@=incondefs@*/' \ -e '/^#define db_create/i\ /*@-declundef -noparams -fcnuse@*/' \ - -e '/^#define db_xa_switch/a\ + -e '/^int txn_commit __P((/a\ /*@=declundef =noparams =fcnuse =fielduse =enummemuse =typeuse @*/' > db.h # Generate manifest for rpmdb. Index: lib/formats.c =================================================================== RCS file: rpm/lib/formats.c,v retrieving revision 2.71.2.1 retrieving revision 2.71.2.2 diff -u -u -r2.71.2.1 -r2.71.2.2 --- rpm/lib/formats.c 19 Aug 2002 22:21:20 -0000 2.71.2.1 +++ rpm/lib/formats.c 9 Oct 2002 19:05:39 -0000 2.71.2.2 @@ -145,7 +145,8 @@ char * t; char * val; int atype; - int lc, ns, nt; + size_t ns, nt; + int lc; switch (type) { case RPM_BIN_TYPE: @@ -238,7 +239,7 @@ const char * enc; char * t; int lc; - int nt = ((element + 2) / 3) * 4; + size_t nt = ((element + 2) / 3) * 4; /*@-boundswrite@*/ /*@-globs@*/ Index: lib/package.c =================================================================== RCS file: rpm/lib/package.c,v retrieving revision 2.112.2.10 retrieving revision 2.112.2.11 diff -u -u -r2.112.2.10 -r2.112.2.11 --- rpm/lib/package.c 17 Sep 2002 15:18:23 -0000 2.112.2.10 +++ rpm/lib/package.c 9 Oct 2002 19:05:39 -0000 2.112.2.11 @@ -360,7 +360,7 @@ if (uc > 0 && pvlen != uc) { (void) snprintf(buf, sizeof(buf), _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"), - uc, il, dl); + (int)uc, (int)il, (int)dl); goto exit; } @@ -652,7 +652,7 @@ memset(block, 0, sizeof(block)); if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) { (void) snprintf(buf, sizeof(buf), - _("hdr size(%d): BAD, read returned %d\n"), sizeof(block), xx); + _("hdr size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx); goto exit; } if (memcmp(block, header_magic, sizeof(header_magic))) { Index: lib/poptALL.c =================================================================== RCS file: rpm/lib/poptALL.c,v retrieving revision 2.10.2.2 retrieving revision 2.10.2.3 diff -u -u -r2.10.2.2 -r2.10.2.3 --- rpm/lib/poptALL.c 27 Aug 2002 20:42:17 -0000 2.10.2.2 +++ rpm/lib/poptALL.c 25 Oct 2002 17:31:37 -0000 2.10.2.3 @@ -332,9 +332,12 @@ } /*@=globs =mods@*/ -#if !defined(__LCLINT__) +#if defined(ENABLE_NLS) (void) setlocale(LC_ALL, "" ); +#ifdef __LCLINT__ +#define LOCALEDIR "/usr/share/locale" +#endif (void) bindtextdomain(PACKAGE, LOCALEDIR); (void) textdomain(PACKAGE); #endif Index: lib/psm.c =================================================================== RCS file: rpm/lib/psm.c,v retrieving revision 2.126.2.7 retrieving revision 2.126.2.9 diff -u -u -r2.126.2.7 -r2.126.2.9 --- rpm/lib/psm.c 17 Sep 2002 15:18:23 -0000 2.126.2.7 +++ rpm/lib/psm.c 9 Oct 2002 19:05:39 -0000 2.126.2.9 @@ -695,15 +695,19 @@ (void) sigaddset(&caught, signum); switch (signum) { case SIGCHLD: - { int status = 0; - pid_t reaped = waitpid(0, &status, WNOHANG); - int i; - - if (psmtbl.psms) - for (i = 0; i < psmtbl.npsms; i++) { - rpmpsm psm = psmtbl.psms[i]; - if (psm->child != reaped) - /*@innercontinue@*/ continue; + while (1) { + int status = 0; + pid_t reaped = waitpid(0, &status, WNOHANG); + int i; + + if (reaped <= 0) + /*@innerbreak@*/ break; + + if (psmtbl.psms) + for (i = 0; i < psmtbl.npsms; i++) { + rpmpsm psm = psmtbl.psms[i]; + if (psm->child != reaped) + /*@innercontinue@*/ continue; #if _PSM_DEBUG /*@-modfilesys@*/ @@ -712,11 +716,12 @@ /*@=modfilesys@*/ #endif - psm->reaped = reaped; - psm->status = status; - /*@innerbreak@*/ break; + psm->reaped = reaped; + psm->status = status; + /*@innerbreak@*/ break; + } } - } /*@switchbreak@*/ break; + /*@switchbreak@*/ break; default: /*@switchbreak@*/ break; } @@ -782,26 +787,6 @@ } /** - * Fork a new process. - * @param psm package state machine data - * @return fork(2) pid - */ -static pid_t psmFork(rpmpsm psm) - /*@globals fileSystem, internalState @*/ - /*@modifies fileSystem, internalState @*/ -{ - pid_t pid; - - if ((pid = fork()) != 0) { -/*@-modfilesys@*/ -if (_psm_debug) -fprintf(stderr, " Fork: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, pid); -/*@=modfilesys@*/ - } - return pid; -} - -/** * Register a child reaper, then fork a child. * @param psm package state machine data * @return fork(2) pid @@ -835,7 +820,6 @@ } empty = psmtbl.npsms++; } - psm->reaped = 0; if (psmtbl.psms) /* XXX can't happen */ psmtbl.psms[empty] = rpmpsmLink(psm, "psmRegister"); /*@-modfilesys@*/ @@ -844,15 +828,24 @@ /*@=modfilesys@*/ (void) enableSignal(SIGCHLD); + + psm->reaped = 0; + if ((psm->child = fork()) != 0) { +/*@-modfilesys@*/ +if (_psm_debug) +fprintf(stderr, " Fork: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child); +/*@=modfilesys@*/ + } + (void) sigprocmask(SIG_SETMASK, &oldMask, NULL); - return psmFork(psm); + return psm->child; } /** * Unregister a child reaper. */ -static int psmUnregister(rpmpsm psm, pid_t child) +static int psmWaitUnregister(rpmpsm psm, pid_t child) /*@globals psmtbl, fileSystem, internalState @*/ /*@modifies psmtbl, fileSystem, internalState @*/ { @@ -862,6 +855,19 @@ (void) sigfillset(&newMask); /* block all signals */ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); + /*@-infloops@*/ + while (psm->reaped != psm->child) { + (void) sigprocmask(SIG_SETMASK, &oldMask, NULL); + sleep(1); /* XXX sleep guarantees loop traversal. */ + (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); + } + /*@=infloops@*/ + +/*@-modfilesys@*/ +if (_psm_debug) +fprintf(stderr, " Wait: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child); +/*@=modfilesys@*/ + if (psmtbl.psms) for (i = 0; i < psmtbl.npsms; i++) { if (psmtbl.psms[i] == NULL) @@ -893,25 +899,6 @@ } /** - * Return reaped pid safely (i.e. with signals blocked). - * @param psm package state machine data - * @return - */ -static inline pid_t psmGetReaped(rpmpsm psm) - /*@globals fileSystem @*/ - /*@modifies fileSystem @*/ -{ - sigset_t newMask, oldMask; - pid_t reaped; - - (void) sigfillset(&newMask); /* block all signals */ - (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); - reaped = psm->reaped; - (void) sigprocmask(SIG_SETMASK, &oldMask, NULL); - return reaped; -} - -/** * Wait for child process to be reaped. * @param psm package state machine data * @return @@ -921,15 +908,7 @@ /*@modifies psm, fileSystem, internalState @*/ { if (psm->reaper) { - /*@-infloops@*/ - while (psmGetReaped(psm) == 0) - (void) pause(); - /*@=infloops@*/ -/*@-modfilesys@*/ -if (_psm_debug) -fprintf(stderr, " Wait: %p[%d:%d:%d] = %p child %d\n", psmtbl.psms, 0, psmtbl.npsms, psmtbl.nalloced, psm, psm->child); -/*@=modfilesys@*/ - (void) psmUnregister(psm, psm->child); + (void) psmWaitUnregister(psm, psm->child); } else { do { psm->reaped = waitpid(psm->child, &psm->status, 0); @@ -997,7 +976,6 @@ FD_t out; rpmRC rc = RPMRC_OK; const char *n, *v, *r; - pid_t pid; if (progArgv == NULL && script == NULL) return rc; @@ -1119,8 +1097,7 @@ if (out == NULL) return RPMRC_FAIL; /* XXX can't happen */ /*@-branchstate@*/ - pid = psmRegisterFork(psm); - psm->child = pid; + (void) psmRegisterFork(psm); if (psm->child == 0) { const char * rootDir; int pipes[2]; Index: lib/query.c =================================================================== RCS file: rpm/lib/query.c,v retrieving revision 2.138.2.8 retrieving revision 2.138.2.9 diff -u -u -r2.138.2.8 -r2.138.2.9 --- rpm/lib/query.c 17 Sep 2002 15:18:23 -0000 2.138.2.8 +++ rpm/lib/query.c 9 Oct 2002 19:05:39 -0000 2.138.2.9 @@ -266,7 +266,7 @@ /*@=boundswrite@*/ if (qva->qva_flags & QUERY_FOR_DUMPFILES) { - sprintf(te, "%s %d %d %s 0%o ", fn, fsize, fmtime, fmd5, fmode); + sprintf(te, "%s %d %d %s 0%o ", fn, (int)fsize, fmtime, fmd5, fmode); te += strlen(te); if (fuser && fgroup) { Index: lib/rpmcli.h =================================================================== RCS file: rpm/lib/rpmcli.h,v retrieving revision 2.47.2.2 retrieving revision 2.47.2.3 diff -u -u -r2.47.2.2 -r2.47.2.3 --- rpm/lib/rpmcli.h 17 Sep 2002 15:18:24 -0000 2.47.2.2 +++ rpm/lib/rpmcli.h 9 Oct 2002 19:05:39 -0000 2.47.2.3 @@ -557,7 +557,7 @@ * @param argv array of package file names (NULL terminated) * @return 0 on success */ -int rpmErase(rpmts ts, const struct rpmInstallArguments_s * ia, +int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, /*@null@*/ const char ** argv) /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/ /*@modifies ts, ia, rpmGlobalMacroContext, Index: lib/rpmds.h =================================================================== RCS file: rpm/lib/rpmds.h,v retrieving revision 2.36 retrieving revision 2.36.2.1 diff -u -u -r2.36 -r2.36.2.1 --- rpm/lib/rpmds.h 3 Aug 2002 22:31:39 -0000 2.36 +++ rpm/lib/rpmds.h 6 Nov 2002 17:28:20 -0000 2.36.2.1 @@ -232,6 +232,7 @@ /** * Set "Don't promote Epoch:" flag. * @param ds dependency set + * @param nopromote Should an unspecified Epoch: be treated as Epoch: 0? * @return previous "Don't promote Epoch:" flag */ int rpmdsSetNoPromote(/*@null@*/ rpmds ds, int nopromote) Index: lib/rpminstall.c =================================================================== RCS file: rpm/lib/rpminstall.c,v retrieving revision 1.118.2.5 retrieving revision 1.118.2.6 diff -u -u -r1.118.2.5 -r1.118.2.6 --- rpm/lib/rpminstall.c 31 Aug 2002 22:30:22 -0000 1.118.2.5 +++ rpm/lib/rpminstall.c 9 Oct 2002 19:05:39 -0000 1.118.2.6 @@ -723,8 +723,7 @@ } /*@=bounds@*/ -int rpmErase(rpmts ts, - const struct rpmInstallArguments_s * ia, +int rpmErase(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) { int count; Index: lib/signature.c =================================================================== RCS file: rpm/lib/signature.c,v retrieving revision 2.139.2.7 retrieving revision 2.139.2.8 diff -u -u -r2.139.2.7 -r2.139.2.8 --- rpm/lib/signature.c 17 Sep 2002 15:18:24 -0000 2.139.2.7 +++ rpm/lib/signature.c 9 Oct 2002 19:05:39 -0000 2.139.2.8 @@ -178,7 +178,7 @@ memset(block, 0, sizeof(block)); if ((xx = timedRead(fd, (char *)block, sizeof(block))) != sizeof(block)) { (void) snprintf(buf, sizeof(buf), - _("sigh size(%d): BAD, read returned %d\n"), sizeof(block), xx); + _("sigh size(%d): BAD, read returned %d\n"), (int)sizeof(block), xx); goto exit; } if (memcmp(block, header_magic, sizeof(header_magic))) { @@ -215,7 +215,7 @@ dataStart = (unsigned char *) (pe + il); if ((xx = timedRead(fd, (char *)pe, nb)) != nb) { (void) snprintf(buf, sizeof(buf), - _("sigh blob(%d): BAD, read returned %d\n"), nb, xx); + _("sigh blob(%d): BAD, read returned %d\n"), (int)nb, xx); goto exit; } @@ -985,11 +985,11 @@ if (size != dig->nbytes) { res = RPMRC_FAIL; t = stpcpy(t, rpmSigString(res)); - sprintf(t, " Expected(%d) != (%d)\n", size, dig->nbytes); + sprintf(t, " Expected(%d) != (%d)\n", (int)size, (int)dig->nbytes); } else { res = RPMRC_OK; t = stpcpy(t, rpmSigString(res)); - sprintf(t, " (%d)", dig->nbytes); + sprintf(t, " (%d)", (int)dig->nbytes); } exit: Index: lib/transaction.c =================================================================== RCS file: rpm/lib/transaction.c,v retrieving revision 1.274.2.6 retrieving revision 1.274.2.7 diff -u -u -r1.274.2.6 -r1.274.2.7 --- rpm/lib/transaction.c 31 Aug 2002 22:30:22 -0000 1.274.2.6 +++ rpm/lib/transaction.c 25 Oct 2002 17:31:38 -0000 1.274.2.7 @@ -1018,7 +1018,7 @@ * - count files. */ -rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elments\n"), rpmtsNElements(ts)); +rpmMessage(RPMMESS_DEBUG, _("sanity checking %d elements\n"), rpmtsNElements(ts)); ps = rpmtsProblems(ts); /* The ordering doesn't matter here */ pi = rpmtsiInit(ts); Index: python/_rpmdb.c =================================================================== RCS file: rpm/python/_rpmdb.c,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -u -u -r1.4 -r1.4.2.1 --- rpm/python/_rpmdb.c 7 Jun 2002 13:12:34 -0000 1.4 +++ rpm/python/_rpmdb.c 6 Nov 2002 16:47:02 -0000 1.4.2.1 @@ -90,9 +90,9 @@ /* 40 = 4.0, 33 = 3.3; this will break if the second number is > 9 */ #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) -#define PY_BSDDB_VERSION "3.3.1" +#define PY_BSDDB_VERSION "3.4.2" -static char *rcs_id = "$Id$"; +static char *rcs_id = "$Id$"; #ifdef WITH_THREAD @@ -410,6 +410,7 @@ switch (err) { case 0: /* successful, no error */ break; +#if (DBVER < 41) case DB_INCOMPLETE: #if INCOMPLETE_IS_WARNING strcpy(errTxt, db_strerror(err)); @@ -429,6 +430,7 @@ errObj = DBIncompleteError; #endif break; +#endif case DB_KEYEMPTY: errObj = DBKeyEmptyError; break; case DB_KEYEXIST: errObj = DBKeyExistError; break; @@ -1023,12 +1025,29 @@ secondaryDB->associateCallback = callback; secondaryDB->primaryDBType = _DB_get_type(self); - + /* PyEval_InitThreads is called here due to a quirk in python 1.5 + * - 2.2.1 (at least) according to Russell Williamson : + * The global interepreter lock is not initialized until the first + * thread is created using thread.start_new_thread() or fork() is + * called. that would cause the ALLOW_THREADS here to segfault due + * to a null pointer reference if no threads or child processes + * have been created. This works around that and is a no-op if + * threads have already been initialized. + * (see pybsddb-users mailing list post on 2002-08-07) + */ + PyEval_InitThreads(); MYDB_BEGIN_ALLOW_THREADS; +#if (DBVER >= 41) + err = self->db->associate(self->db, NULL, + secondaryDB->db, + _db_associateCallback, + flags); +#else err = self->db->associate(self->db, secondaryDB->db, _db_associateCallback, flags); +#endif MYDB_END_ALLOW_THREADS; if (err) { @@ -1498,7 +1517,11 @@ } MYDB_BEGIN_ALLOW_THREADS; +#if (DBVER >= 41) + err = self->db->open(self->db, NULL, filename, dbname, type, flags, mode); +#else err = self->db->open(self->db, filename, dbname, type, flags, mode); +#endif MYDB_END_ALLOW_THREADS; if (makeDBError(err)) { self->db = NULL; @@ -1851,7 +1874,9 @@ MAKE_HASH_ENTRY(nkeys); MAKE_HASH_ENTRY(ndata); MAKE_HASH_ENTRY(pagesize); +#if (DBVER < 41) MAKE_HASH_ENTRY(nelem); +#endif MAKE_HASH_ENTRY(ffactor); MAKE_HASH_ENTRY(buckets); MAKE_HASH_ENTRY(free); @@ -1896,7 +1921,7 @@ MAKE_QUEUE_ENTRY(re_len); MAKE_QUEUE_ENTRY(re_pad); MAKE_QUEUE_ENTRY(pgfree); -#if (DBVER >= 31) && (DBVER < 40) +#if (DBVER == 31) MAKE_QUEUE_ENTRY(start); #endif MAKE_QUEUE_ENTRY(first_recno); @@ -2334,8 +2359,6 @@ if (!PyArg_ParseTuple(args, ":close")) return NULL; - CHECK_CURSOR_NOT_CLOSED(self); - if (self->dbc != NULL) { MYDB_BEGIN_ALLOW_THREADS; err = self->dbc->c_close(self->dbc); @@ -2424,7 +2447,7 @@ static PyObject* DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs) { - int err, flags; + int err, flags=0; PyObject* keyobj = NULL; PyObject* dataobj = NULL; PyObject* retval = NULL; @@ -3309,7 +3332,7 @@ int err; DB_LOCK_STAT* sp; PyObject* d = NULL; - u_int32_t flags; + u_int32_t flags = 0; if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags)) return NULL; @@ -3337,7 +3360,9 @@ #define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name) +#if (DBVER < 41) MAKE_ENTRY(lastid); +#endif MAKE_ENTRY(nmodes); #if (DBVER >= 32) MAKE_ENTRY(maxlocks); @@ -3421,7 +3446,7 @@ int err; DB_TXN_STAT* sp; PyObject* d = NULL; - u_int32_t flags; + u_int32_t flags=0; if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags)) return NULL; @@ -4116,7 +4141,9 @@ ADD_INT(d, DB_APPEND); ADD_INT(d, DB_BEFORE); ADD_INT(d, DB_CACHED_COUNTS); +#if (DBVER < 41) ADD_INT(d, DB_CHECKPOINT); +#endif #if (DBVER >= 33) ADD_INT(d, DB_COMMIT); #endif @@ -4124,7 +4151,9 @@ #if (DBVER >= 32) ADD_INT(d, DB_CONSUME_WAIT); #endif +#if (DBVER < 41) ADD_INT(d, DB_CURLSN); +#endif ADD_INT(d, DB_CURRENT); #if (DBVER >= 33) ADD_INT(d, DB_FAST_STAT); @@ -4164,7 +4193,9 @@ ADD_INT(d, DB_DONOTINDEX); #endif +#if (DBVER < 41) ADD_INT(d, DB_INCOMPLETE); +#endif ADD_INT(d, DB_KEYEMPTY); ADD_INT(d, DB_KEYEXIST); ADD_INT(d, DB_LOCK_DEADLOCK); Index: python/header-py.c =================================================================== RCS file: rpm/python/header-py.c,v retrieving revision 1.20 retrieving revision 1.20.2.1 diff -u -u -r1.20 -r1.20.2.1 --- rpm/python/header-py.c 7 Aug 2002 23:19:10 -0000 1.20 +++ rpm/python/header-py.c 15 Oct 2002 19:03:22 -0000 1.20.2.1 @@ -336,6 +336,11 @@ return rpmVersionCompare(a->h, b->h); } +static long hdr_hash(hdrObject *h) +{ + return h; +} + /** \ingroup python */ /*@unchecked@*/ /*@observer@*/ @@ -594,7 +599,7 @@ 0, /* tp_as_number */ 0, /* tp_as_sequence */ &hdr_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ + hdr_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ Index: python/rpmdb/__init__.py =================================================================== RCS file: rpm/python/rpmdb/__init__.py,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -u -r1.2 -r1.2.2.1 --- rpm/python/rpmdb/__init__.py 3 Jun 2002 20:44:08 -0000 1.2 +++ rpm/python/rpmdb/__init__.py 6 Nov 2002 16:47:02 -0000 1.2.2.1 @@ -152,7 +152,7 @@ flags = _checkflag(flag) d = _db.DB() d.set_flags(hflags) - if cachesize is not None: d.set_cachesize(cachesize) + if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) if ffactor is not None: d.set_h_ffactor(ffactor) @@ -168,7 +168,7 @@ flags = _checkflag(flag) d = _db.DB() - if cachesize is not None: d.set_cachesize(cachesize) + if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) d.set_flags(btflags) @@ -186,7 +186,7 @@ flags = _checkflag(flag) d = _db.DB() - if cachesize is not None: d.set_cachesize(cachesize) + if cachesize is not None: d.set_cachesize(0, cachesize) if pgsize is not None: d.set_pagesize(pgsize) if lorder is not None: d.set_lorder(lorder) d.set_flags(rnflags) Index: python/rpmdb/dbshelve.py =================================================================== RCS file: rpm/python/rpmdb/dbshelve.py,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -u -r1.2 -r1.2.2.1 --- rpm/python/rpmdb/dbshelve.py 5 Jun 2002 20:28:03 -0000 1.2 +++ rpm/python/rpmdb/dbshelve.py 6 Nov 2002 16:47:02 -0000 1.2.2.1 @@ -53,7 +53,7 @@ if type(flags) == type(''): sflag = flags if sflag == 'r': - flags = db.DB_READONLY + flags = db.DB_RDONLY elif sflag == 'rw': flags = 0 elif sflag == 'w': Index: python/rpmdb/dbtables.py =================================================================== RCS file: rpm/python/rpmdb/dbtables.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -u -r1.1 -r1.1.2.1 --- rpm/python/rpmdb/dbtables.py 3 Jun 2002 20:44:08 -0000 1.1 +++ rpm/python/rpmdb/dbtables.py 6 Nov 2002 16:47:02 -0000 1.1.2.1 @@ -1,6 +1,7 @@ #----------------------------------------------------------------------- # # Copyright (C) 2000, 2001 by Autonomous Zone Industries +# Copyright (C) 2002 Gregory P. Smith # # License: This is free software. You may use this software for any # purpose including modification/redistribution, so long as @@ -54,6 +55,13 @@ def __call__(self, s): return s[:len(self.prefix)] == self.prefix +class PostfixCond(Cond): + """Acts as a condition function for matching a string postfix""" + def __init__(self, postfix): + self.postfix = postfix + def __call__(self, s): + return s[-len(self.postfix):] == self.postfix + class LikeCond(Cond): """ Acts as a function that will match using an SQL 'LIKE' style @@ -523,17 +531,10 @@ # if no condition was specified or the condition # succeeds, add row to our match list. if not condition or condition(data) : - # only create new entries in matcing_rowids on - # the first pass, otherwise reject the - # rowid as it must not have matched - # the previous passes - if column_num == 0 : - if not matching_rowids.has_key(rowid) : - matching_rowids[rowid] = {} - if savethiscolumndata : - matching_rowids[rowid][column] = data - else : - rejected_rowids[rowid] = rowid + if not matching_rowids.has_key(rowid) : + matching_rowids[rowid] = {} + if savethiscolumndata : + matching_rowids[rowid][column] = data else : if matching_rowids.has_key(rowid) : del matching_rowids[rowid] Index: python/rpmdb/dbutils.py =================================================================== RCS file: rpm/python/rpmdb/dbutils.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -u -r1.1 -r1.1.2.1 --- rpm/python/rpmdb/dbutils.py 3 Jun 2002 20:44:08 -0000 1.1 +++ rpm/python/rpmdb/dbutils.py 6 Nov 2002 16:47:02 -0000 1.1.2.1 @@ -1,11 +1,5 @@ #------------------------------------------------------------------------ # -# In my performance tests, using this (as in dbtest.py test4) is -# slightly slower than simply compiling _db.c with MYDB_THREAD -# undefined to prevent multithreading support in the C module. -# Using NoDeadlockDb also prevent deadlocks from mutliple processes -# accessing the same database. -# # Copyright (C) 2000 Autonomous Zone Industries # # License: This is free software. You may use this software for any @@ -18,7 +12,7 @@ # Author: Gregory P. Smith # # Note: I don't know how useful this is in reality since when a -# DBDeadlockError happens the current transaction is supposed to be +# DBLockDeadlockError happens the current transaction is supposed to be # aborted. If it doesn't then when the operation is attempted again # the deadlock is still happening... # --Robin @@ -36,33 +30,45 @@ import _rpmdb as _db -_deadlock_MinSleepTime = 1.0/64 # always sleep at least N seconds between retrys -_deadlock_MaxSleepTime = 1.0 # never sleep more than N seconds between retrys +_deadlock_MinSleepTime = 1.0/64 # always sleep at least N seconds between retrys +_deadlock_MaxSleepTime = 3.14159 # never sleep more than N seconds between retrys +_deadlock_VerboseFile = None # Assign a file object to this for a "sleeping" + # message to be written to it each retry def DeadlockWrap(function, *_args, **_kwargs): """DeadlockWrap(function, *_args, **_kwargs) - automatically retries function in case of a database deadlock. - This is a DeadlockWrapper method which DB calls can be made using to - preform infinite retrys with sleeps in between when a DBLockDeadlockError - exception is raised in a database call: + This is a function intended to be used to wrap database calls such + that they perform retrys with exponentially backing off sleeps in + between when a DBLockDeadlockError exception is raised. + + A 'max_retries' parameter may optionally be passed to prevent it + from retrying forever (in which case the exception will be reraised). d = DB(...) d.open(...) DeadlockWrap(d.put, "foo", data="bar") # set key "foo" to "bar" """ sleeptime = _deadlock_MinSleepTime - while (1) : + max_retries = _kwargs.get('max_retries', -1) + if _kwargs.has_key('max_retries'): + del _kwargs['max_retries'] + while 1: try: return apply(function, _args, _kwargs) except _db.DBLockDeadlockError: - print 'DeadlockWrap sleeping ', sleeptime + if _deadlock_VerboseFile: + _deadlock_VerboseFile.write('dbutils.DeadlockWrap: sleeping %1.3f\n' % sleeptime) _sleep(sleeptime) # exponential backoff in the sleep time sleeptime = sleeptime * 2 if sleeptime > _deadlock_MaxSleepTime : sleeptime = _deadlock_MaxSleepTime + max_retries = max_retries - 1 + if max_retries == -1: + raise #------------------------------------------------------------------------ Index: python/test/test_dbshelve.py =================================================================== RCS file: rpm/python/test/test_dbshelve.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -u -r1.1 -r1.1.2.1 --- rpm/python/test/test_dbshelve.py 3 Jun 2002 20:44:08 -0000 1.1 +++ rpm/python/test/test_dbshelve.py 6 Nov 2002 16:47:02 -0000 1.1.2.1 @@ -210,7 +210,7 @@ class HashShelveTestCase(BasicShelveTestCase): - dbtype = db.DB_BTREE + dbtype = db.DB_HASH dbflags = db.DB_CREATE @@ -220,7 +220,7 @@ class ThreadHashShelveTestCase(BasicShelveTestCase): - dbtype = db.DB_BTREE + dbtype = db.DB_HASH dbflags = db.DB_CREATE | db.DB_THREAD @@ -261,7 +261,7 @@ class EnvHashShelveTestCase(BasicEnvShelveTestCase): envflags = 0 - dbtype = db.DB_BTREE + dbtype = db.DB_HASH dbflags = db.DB_CREATE @@ -273,7 +273,7 @@ class EnvThreadHashShelveTestCase(BasicEnvShelveTestCase): envflags = db.DB_THREAD - dbtype = db.DB_BTREE + dbtype = db.DB_HASH dbflags = db.DB_CREATE | db.DB_THREAD Index: python/test/test_dbtables.py =================================================================== RCS file: rpm/python/test/test_dbtables.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -u -r1.1 -r1.1.2.1 --- rpm/python/test/test_dbtables.py 3 Jun 2002 20:44:08 -0000 1.1 +++ rpm/python/test/test_dbtables.py 6 Nov 2002 16:47:02 -0000 1.1.2.1 @@ -5,6 +5,7 @@ #----------------------------------------------------------------------- # # Copyright (C) 2000, 2001 by Autonomous Zone Industries +# Copyright (C) 2002 Gregory P. Smith # # March 20, 2000 # @@ -157,6 +158,40 @@ conditions={'c': lambda c: c == 'meep'}) assert len(values) == 1 assert values[0]['b'] == "bad" + + + def test04_MultiCondSelect(self): + tabname = "test04_MultiCondSelect" + try: + self.tdb.Drop(tabname) + except dbtables.TableDBError: + pass + self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e']) + + try: + self.tdb.Insert(tabname, {'a': "", 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 'f': "Zero"}) + assert 0 + except dbtables.TableDBError: + pass + + self.tdb.Insert(tabname, {'a': "A", 'b': "B", 'c': "C", 'd': "D", 'e': "E"}) + self.tdb.Insert(tabname, {'a': "-A", 'b': "-B", 'c': "-C", 'd': "-D", 'e': "-E"}) + self.tdb.Insert(tabname, {'a': "A-", 'b': "B-", 'c': "C-", 'd': "D-", 'e': "E-"}) + + if verbose: + self.tdb._db_print() + + # This select should return 0 rows. it is designed to test + # the bug identified and fixed in sourceforge bug # 590449 + # (Big Thanks to "Rob Tillotson (n9mtb)" for tracking this down + # and supplying a fix!! This one caused many headaches to say + # the least...) + values = self.tdb.Select(tabname, ['b', 'a', 'd'], + conditions={'e': dbtables.ExactCond('E'), + 'a': dbtables.ExactCond('A'), + 'd': dbtables.PrefixCond('-') + } ) + assert len(values) == 0, values def test_CreateOrExtend(self): Index: python/test/test_thread.py =================================================================== RCS file: rpm/python/test/test_thread.py,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -u -r1.1 -r1.1.2.1 --- rpm/python/test/test_thread.py 3 Jun 2002 20:44:08 -0000 1.1 +++ rpm/python/test/test_thread.py 6 Nov 2002 16:47:02 -0000 1.1.2.1 @@ -18,7 +18,7 @@ import unittest from test_all import verbose -from rpmdb import db +from rpmdb import db, dbutils #---------------------------------------------------------------------- @@ -31,6 +31,9 @@ def setUp(self): + if verbose: + dbutils._deadlock_VerboseFile = sys.stdout + homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home') self.homeDir = homeDir try: os.mkdir(homeDir) @@ -109,7 +112,7 @@ for x in range(start, stop): key = '%04d' % x - d.put(key, self.makeData(key)) + dbutils.DeadlockWrap(d.put, key, self.makeData(key), max_retries=12) if verbose and x % 100 == 0: print "%s: records %d - %d finished" % (name, start, x) @@ -212,7 +215,7 @@ # create a bunch of records for x in xrange(start, stop): key = '%04d' % x - d.put(key, self.makeData(key)) + dbutils.DeadlockWrap(d.put, key, self.makeData(key), max_retries=12) if verbose and x % 100 == 0: print "%s: records %d - %d finished" % (name, start, x) @@ -221,12 +224,12 @@ if random() <= 0.05: for y in xrange(start, x): key = '%04d' % x - data = d.get(key) + data = dbutils.DeadlockWrap(d.get, key, max_retries=12) assert data == self.makeData(key) # flush them try: - d.sync() + dbutils.DeadlockWrap(d.sync, max_retries=12) except db.DBIncompleteError, val: if verbose: print "could not complete sync()..." @@ -234,12 +237,12 @@ # read them back, deleting a few for x in xrange(start, stop): key = '%04d' % x - data = d.get(key) + data = dbutils.DeadlockWrap(d.get, key, max_retries=12) if verbose and x % 100 == 0: print "%s: fetched record (%s, %s)" % (name, key, data) - assert data == self.makeData(key) + assert data == self.makeData(key), (key, data, self.makeData(key)) if random() <= 0.10: - d.delete(key) + dbutils.DeadlockWrap(d.delete, key, max_retries=12) if verbose: print "%s: deleted record %s" % (name, key) @@ -273,7 +276,7 @@ class HashSimpleThreaded(SimpleThreadedBase): - dbtype = db.DB_BTREE + dbtype = db.DB_HASH #---------------------------------------------------------------------- Index: rpmdb/db3.c =================================================================== RCS file: rpm/rpmdb/db3.c,v retrieving revision 1.45 retrieving revision 1.45.2.1 diff -u -u -r1.45 -r1.45.2.1 --- rpm/rpmdb/db3.c 13 Aug 2002 20:42:39 -0000 1.45 +++ rpm/rpmdb/db3.c 6 Nov 2002 17:29:34 -0000 1.45.2.1 @@ -266,11 +266,22 @@ { int xx; /*@-noeffectuncon@*/ /* FIX: annotate db3 methods */ + + /* 4.1: dbenv->set_app_dispatch(???) */ + /* 4.1: dbenv->set_alloc(???) */ + /* 4.1: dbenv->set_data_dir(???) */ + /* 4.1: dbenv->set_encrypt(???) */ + dbenv->set_errcall(dbenv, rpmdb->db_errcall); dbenv->set_errfile(dbenv, rpmdb->db_errfile); dbenv->set_errpfx(dbenv, rpmdb->db_errpfx); /*@=noeffectuncon@*/ + + /* 4.1: dbenv->set_feedback(???) */ + /* 4.1: dbenv->set_flags(???) */ + /* dbenv->set_paniccall(???) */ + xx = dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT, (dbi->dbi_verbose & DB_VERB_CHKPOINT)); xx = dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, @@ -279,16 +290,35 @@ (dbi->dbi_verbose & DB_VERB_RECOVERY)); xx = dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR, (dbi->dbi_verbose & DB_VERB_WAITSFOR)); - /* dbenv->set_lg_max(???) */ + /* dbenv->set_lk_conflicts(???) */ /* dbenv->set_lk_detect(???) */ - /* dbenv->set_lk_max(???) */ - xx = dbenv->set_mp_mmapsize(dbenv, dbi->dbi_mp_mmapsize); - xx = cvtdberr(dbi, "dbenv->set_mp_mmapsize", xx, _debug); - xx = dbenv->set_cachesize(dbenv, 0, dbi->dbi_mp_size, 0); - xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug); + /* 4.1: dbenv->set_lk_max_lockers(???) */ + /* 4.1: dbenv->set_lk_max_locks(???) */ + /* 4.1: dbenv->set_lk_max_objects(???) */ + + /* 4.1: dbenv->set_lg_bsize(???) */ + /* 4.1: dbenv->set_lg_dir(???) */ + /* 4.1: dbenv->set_lg_max(???) */ + /* 4.1: dbenv->set_lg_regionmax(???) */ + + if (dbi->dbi_mmapsize) { + xx = dbenv->set_mp_mmapsize(dbenv, dbi->dbi_mmapsize); + xx = cvtdberr(dbi, "dbenv->set_mp_mmapsize", xx, _debug); + } + if (dbi->dbi_cachesize) { + xx = dbenv->set_cachesize(dbenv, 0, dbi->dbi_cachesize, 0); + xx = cvtdberr(dbi, "dbenv->set_cachesize", xx, _debug); + } + + /* 4.1 dbenv->set_timeout(???) */ /* dbenv->set_tx_max(???) */ + /* 4.1: dbenv->set_tx_timestamp(???) */ /* dbenv->set_tx_recover(???) */ + + /* dbenv->set_rep_transport(???) */ + /* dbenv->set_rep_limit(???) */ + if (dbi->dbi_no_fsync) { #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR != 0) || (DB_VERSION_MAJOR == 4) xx = db_env_set_func_fsync(db3_fsync_disable); @@ -366,7 +396,11 @@ if (db != NULL) rc = db->sync(db, flags); /* XXX DB_INCOMPLETE is returned occaisionally with multiple access. */ +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1) + _printit = _debug; +#else _printit = (rc == DB_INCOMPLETE ? 0 : _debug); +#endif rc = cvtdberr(dbi, "db->sync", rc, _printit); return rc; } @@ -599,10 +633,17 @@ { DB * db = dbi->dbi_db; DB * secondary = dbisecondary->dbi_db; +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1) + DB_TXN * txnid = NULL; +#endif int rc; /*@-moduncon@*/ /* FIX: annotate db3 methods */ +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1) + rc = db->associate(db, txnid, secondary, callback, flags); +#else rc = db->associate(db, secondary, callback, flags); +#endif /*@=moduncon@*/ rc = cvtdberr(dbi, "db->associate", rc, _debug); return rc; @@ -789,6 +830,9 @@ DB * db = NULL; DB_ENV * dbenv = NULL; +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1) + DB_TXN * txnid = NULL; +#endif u_int32_t oflags; int _printit; @@ -981,18 +1025,7 @@ /*@=moduncon@*/ rc = cvtdberr(dbi, "db_create", rc, _debug); if (rc == 0 && db != NULL) { - if (rc == 0 && dbi->dbi_lorder) { - rc = db->set_lorder(db, dbi->dbi_lorder); - rc = cvtdberr(dbi, "db->set_lorder", rc, _debug); - } - if (rc == 0 && dbi->dbi_cachesize) { - rc = db->set_cachesize(db, 0, dbi->dbi_cachesize, 0); - rc = cvtdberr(dbi, "db->set_cachesize", rc, _debug); - } - if (rc == 0 && dbi->dbi_pagesize) { - rc = db->set_pagesize(db, dbi->dbi_pagesize); - rc = cvtdberr(dbi, "db->set_pagesize", rc, _debug); - } + /* XXX 3.3.4 change. */ #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3) || (DB_VERSION_MAJOR == 4) if (rc == 0 && @@ -1008,6 +1041,27 @@ rc = cvtdberr(dbi, "db->set_malloc", rc, _debug); } #endif + +/* 4.1: db->set_cache_priority(???) */ + if (rc == 0 && !dbi->dbi_use_dbenv && dbi->dbi_cachesize) { + rc = db->set_cachesize(db, 0, dbi->dbi_cachesize, 0); + rc = cvtdberr(dbi, "db->set_cachesize", rc, _debug); + } +/* 4.1: db->set_encrypt(???) */ +/* 4.1: db->set_errcall(dbenv, rpmdb->db_errcall); */ +/* 4.1: db->set_errfile(dbenv, rpmdb->db_errfile); */ +/* 4.1: db->set_errpfx(dbenv, rpmdb->db_errpfx); */ + /* 4.1: db->set_feedback(???) */ + + if (rc == 0 && dbi->dbi_lorder) { + rc = db->set_lorder(db, dbi->dbi_lorder); + rc = cvtdberr(dbi, "db->set_lorder", rc, _debug); + } + if (rc == 0 && dbi->dbi_pagesize) { + rc = db->set_pagesize(db, dbi->dbi_pagesize); + rc = cvtdberr(dbi, "db->set_pagesize", rc, _debug); + } + /* 4.1: db->set_paniccall(???) */ if (rc == 0 && oflags & DB_CREATE) { switch(dbi->dbi_type) { default: @@ -1042,6 +1096,7 @@ #endif break; case DB_BTREE: +/* 4.1: db->set_append_recno(???) */ if (dbi->dbi_bt_flags) { rc = db->set_flags(db, dbi->dbi_bt_flags); rc = cvtdberr(dbi, "db->set_bt_flags", rc, _debug); @@ -1073,6 +1128,7 @@ break; case DB_RECNO: if (dbi->dbi_re_delim) { +/* 4.1: db->set_append_recno(???) */ rc = db->set_re_delim(db, dbi->dbi_re_delim); rc = cvtdberr(dbi, "db->set_re_selim", rc, _debug); if (rc) break; @@ -1124,8 +1180,13 @@ ? dbfullpath : dbfile; #endif +#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR == 1) + rc = db->open(db, txnid, dbpath, dbsubfile, + dbi->dbi_type, oflags, dbi->dbi_perms); +#else rc = db->open(db, dbpath, dbsubfile, dbi->dbi_type, oflags, dbi->dbi_perms); +#endif if (rc == 0 && dbi->dbi_type == DB_UNKNOWN) { #if (DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 3 && DB_VERSION_PATCH == 11) \ Index: rpmdb/dbconfig.c =================================================================== RCS file: rpm/rpmdb/dbconfig.c,v retrieving revision 1.33 retrieving revision 1.33.2.1 diff -u -u -r1.33 -r1.33.2.1 --- rpm/rpmdb/dbconfig.c 3 Aug 2002 22:31:39 -0000 1.33 +++ rpm/rpmdb/dbconfig.c 6 Nov 2002 17:29:34 -0000 1.33.2.1 @@ -190,9 +190,11 @@ { "lorder", 0,POPT_ARG_INT, &db3dbi.dbi_lorder, 0, NULL, NULL }, - { "mp_mmapsize", 0,POPT_ARG_INT, &db3dbi.dbi_mp_mmapsize, 0, + { "mmapsize", 0,POPT_ARG_INT, &db3dbi.dbi_mmapsize, 0, NULL, NULL }, - { "mp_size", 0,POPT_ARG_INT, &db3dbi.dbi_mp_size, 0, + { "mp_mmapsize", 0,POPT_ARG_INT, &db3dbi.dbi_mmapsize, 0, + NULL, NULL }, + { "mp_size", 0,POPT_ARG_INT, &db3dbi.dbi_cachesize, 0, NULL, NULL }, { "pagesize", 0,POPT_ARG_INT, &db3dbi.dbi_pagesize, 0, NULL, NULL }, @@ -259,7 +261,7 @@ /** @todo Set a reasonable "last gasp" default db config. */ /*@observer@*/ /*@unchecked@*/ static const char *db3_config_default = - "db3:hash:mpool:cdb:usecursors:verbose:mp_mmapsize=8Mb:mp_size=512Kb:pagesize=512:perms=0644"; + "db3:hash:mpool:cdb:usecursors:verbose:mp_mmapsize=8Mb:cachesize=512Kb:pagesize=512:perms=0644"; /*@-bounds@*/ dbiIndex db3New(rpmdb rpmdb, rpmTag rpmtag) @@ -432,8 +434,8 @@ if (!dbi->dbi_use_dbenv) { /* db3 dbenv is always used now. */ dbi->dbi_use_dbenv = 1; dbi->dbi_eflags |= (DB_INIT_MPOOL|DB_JOINENV); - dbi->dbi_mp_mmapsize = 16 * 1024 * 1024; - dbi->dbi_mp_size = 1 * 1024 * 1024; + dbi->dbi_mmapsize = 16 * 1024 * 1024; + dbi->dbi_cachesize = 1 * 1024 * 1024; } if ((dbi->dbi_bt_flags | dbi->dbi_h_flags) & DB_DUP) Index: rpmdb/header.c =================================================================== RCS file: rpm/rpmdb/header.c,v retrieving revision 1.17.2.11 retrieving revision 1.17.2.12 diff -u -u -r1.17.2.11 -r1.17.2.12 --- rpm/rpmdb/header.c 17 Sep 2002 15:19:45 -0000 1.17.2.11 +++ rpm/rpmdb/header.c 6 Nov 2002 17:29:34 -0000 1.17.2.12 @@ -2825,6 +2825,7 @@ } /*@-branchstate@*/ + if (data) switch (type) { case RPM_STRING_ARRAY_TYPE: strarray = (const char **)data; Index: rpmdb/header.h =================================================================== RCS file: rpm/rpmdb/header.h,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -u -u -r1.6 -r1.6.2.1 --- rpm/rpmdb/header.h 13 Jul 2002 19:10:02 -0000 1.6 +++ rpm/rpmdb/header.h 6 Nov 2002 17:29:34 -0000 1.6.2.1 @@ -78,7 +78,7 @@ /* RPM - Copyright (C) 1995-2001 Red Hat Software */ #include -#include +#include "rpmio.h" #ifdef __cplusplus extern "C" { @@ -717,7 +717,7 @@ } #if !defined(__HEADER_PROTOTYPES__) -#include +#include "hdrinline.h" #endif #ifdef __cplusplus Index: rpmdb/rpmdb.h =================================================================== RCS file: rpm/rpmdb/rpmdb.h,v retrieving revision 1.46.2.2 retrieving revision 1.46.2.3 diff -u -u -r1.46.2.2 -r1.46.2.3 --- rpm/rpmdb/rpmdb.h 17 Sep 2002 15:19:46 -0000 1.46.2.2 +++ rpm/rpmdb/rpmdb.h 6 Nov 2002 17:29:34 -0000 1.46.2.3 @@ -8,8 +8,8 @@ */ #include -#include -#include +#include "rpmlib.h" +#include "db.h" /*@-exportlocal@*/ /*@unchecked@*/ @@ -321,8 +321,8 @@ int dbi_region_init; int dbi_tas_spins; /* mpool sub-system parameters */ - int dbi_mp_mmapsize; /*!< (10Mb) */ - int dbi_mp_size; /*!< (128Kb) */ + int dbi_mmapsize; /*!< (10Mb) */ + int dbi_cachesize; /*!< (128Kb) */ /* lock sub-system parameters */ unsigned int dbi_lk_max; unsigned int dbi_lk_detect; @@ -340,7 +340,6 @@ /*@modifies fileSystem @*/; #endif /* dbinfo parameters */ - int dbi_cachesize; /*!< */ int dbi_pagesize; /*!< (fs blksize) */ /*@unused@*/ /*@null@*/ void * (*dbi_malloc) (size_t nbytes) Index: rpmio/rpmlog.c =================================================================== RCS file: rpm/rpmio/rpmlog.c,v retrieving revision 2.27 retrieving revision 2.27.2.1 diff -u -u -r2.27 -r2.27.2.1 --- rpm/rpmio/rpmlog.c 2 Jul 2002 23:54:38 -0000 2.27 +++ rpm/rpmio/rpmlog.c 20 Sep 2002 16:33:49 -0000 2.27.2.1 @@ -179,6 +179,7 @@ else /* glibc 2.0 */ msgnb *= 2; msgbuf = xrealloc(msgbuf, msgnb); + va_end(apc); } msgbuf[msgnb - 1] = '\0'; msg = msgbuf; Index: rpmio/rpmrpc.c =================================================================== RCS file: rpm/rpmio/rpmrpc.c,v retrieving revision 2.27.2.2 retrieving revision 2.27.2.3 diff -u -u -r2.27.2.2 -r2.27.2.3 --- rpm/rpmio/rpmrpc.c 17 Sep 2002 15:19:46 -0000 2.27.2.2 +++ rpm/rpmio/rpmrpc.c 9 Oct 2002 19:06:24 -0000 2.27.2.3 @@ -1023,7 +1023,7 @@ (unsigned)st->st_dev, (unsigned)st->st_ino, st->st_mode, - st->st_nlink, + (unsigned)st->st_nlink, st->st_uid, st->st_gid, (unsigned)st->st_rdev, Index: tools/sections.c =================================================================== RCS file: rpm/tools/sections.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.4 diff -u -u -r1.1.2.2 -r1.1.2.4 --- rpm/tools/sections.c 22 Aug 2002 19:19:47 -0000 1.1.2.2 +++ rpm/tools/sections.c 9 Oct 2002 19:06:24 -0000 1.1.2.4 @@ -24,38 +24,168 @@ } UnstripInfo32; typedef struct { - Elf32_Off orig_e_shoff; - Elf32_Off n_sections; + Elf64_Off orig_e_shoff; + Elf64_Off n_sections; UnstripInfoSection64 sections[1]; } UnstripInfo64; +static uint32_t +elf_32_to_file (uint32_t x, int file_is_little_endian) +{ + volatile uint32_t out; + unsigned char *outbytes; + + outbytes = (unsigned char *)&out; + if (file_is_little_endian) + { + outbytes[0] = (x >> 0) & 0xff; + outbytes[1] = (x >> 8) & 0xff; + outbytes[2] = (x >> 16) & 0xff; + outbytes[3] = (x >> 24) & 0xff; + } + else /* big endian */ + { + outbytes[0] = (x >> 24) & 0xff; + outbytes[1] = (x >> 16) & 0xff; + outbytes[2] = (x >> 8) & 0xff; + outbytes[3] = (x >> 0) & 0xff; + } + + return out; +} + +static uint64_t +elf_64_to_file (uint64_t x, int file_is_little_endian) +{ + volatile uint64_t out; + unsigned char *outbytes; + int i; + + outbytes = (unsigned char *)&out; + if (file_is_little_endian) + { + for (i = 0; i < 8; i++) + outbytes[i] = (x >> (8*i)) & 0xff; + } + else /* big endian */ + { + for (i = 0; i < 8; i++) + outbytes[7-i] = (x >> (8*i)) & 0xff; + } + + return out; +} static Elf32_Word word32_to_file (Elf32_Word x, Elf *elf) { - /* FIXME: implement */ - return x; + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); } static Elf32_Off off32_to_file (Elf32_Off x, Elf *elf) { - /* FIXME: implement */ - return x; + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); +} + +static Elf64_Word +word64_to_file (Elf64_Word x, Elf *elf) +{ + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + return elf_32_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); +} + +static Elf64_Off +off64_to_file (Elf64_Off x, Elf *elf) +{ + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + return elf_64_to_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); +} + +static uint32_t +elf_32_from_file (uint32_t x, int file_is_little_endian) +{ + unsigned char *inbytes; + + inbytes = (unsigned char *)&x; + if (file_is_little_endian) + { + return + (inbytes[0] << 0) | + (inbytes[1] << 8) | + (inbytes[2] << 16) | + (inbytes[3] << 24); + } + else /* big endian */ + { + return + (inbytes[0] << 24) | + (inbytes[1] << 16) | + (inbytes[2] << 8) | + (inbytes[3] << 0); + } +} + +static uint64_t +elf_64_from_file (uint64_t x, int file_is_little_endian) +{ + unsigned char *inbytes; + + inbytes = (unsigned char *)&x; + if (file_is_little_endian) + { + return + ((uint64_t)inbytes[0] << 0) | + ((uint64_t)inbytes[1] << 8) | + ((uint64_t)inbytes[2] << 16) | + ((uint64_t)inbytes[3] << 24) | + ((uint64_t)inbytes[4] << 32) | + ((uint64_t)inbytes[5] << 40) | + ((uint64_t)inbytes[6] << 48) | + ((uint64_t)inbytes[7] << 56); + } + else /* big endian */ + { + return + ((uint64_t)inbytes[0] << 56) | + ((uint64_t)inbytes[1] << 48) | + ((uint64_t)inbytes[2] << 40) | + ((uint64_t)inbytes[3] << 32) | + ((uint64_t)inbytes[4] << 24) | + ((uint64_t)inbytes[5] << 16) | + ((uint64_t)inbytes[6] << 8) | + ((uint64_t)inbytes[7] << 0); + } } static Elf32_Word word32_from_file (Elf32_Word x, Elf *elf) { - /* FIXME: implement */ - return x; + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); } static Elf32_Off off32_from_file (Elf32_Off x, Elf *elf) { - /* FIXME: implement */ - return x; + Elf32_Ehdr *ehdr = elf32_getehdr (elf); + return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); +} + +static Elf64_Word +word64_from_file (Elf64_Word x, Elf *elf) +{ + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + return elf_32_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); +} + +static Elf64_Off +off64_from_file (Elf64_Off x, Elf *elf) +{ + Elf64_Ehdr *ehdr = elf64_getehdr (elf); + return elf_64_from_file (x, ehdr->e_ident[EI_DATA] & ELFDATA2LSB); } static void @@ -93,7 +223,29 @@ Elf *elf, Elf_Data *data) { + UnstripInfo64 *info64; + int i; + data->d_align = 8; + + data->d_size = + /* orig_e_shoff */ sizeof (Elf64_Off) + + /* n_sections */ sizeof (Elf64_Off) + + /* sections */ info->n_sections * sizeof (UnstripInfoSection64); + + data->d_buf = calloc (1, data->d_size); + + info64 = (UnstripInfo64 *) data->d_buf; + + info64->orig_e_shoff = off64_to_file (info->orig_e_shoff, elf); + info64->n_sections = off64_to_file (info->n_sections, elf); + + for (i = 0; i < info->n_sections; i++) + { + info64->sections[i].debug_section = word64_to_file (info->sections[i].debug_section, elf); + info64->sections[i].name = word64_to_file (info->sections[i].name, elf); + info64->sections[i].orig_offset = off64_to_file (info->sections[i].orig_offset, elf); + } } void @@ -101,14 +253,21 @@ Elf *elf, Elf_Data *data) { + GElf_Ehdr ehdr; + data->d_type = ELF_T_BYTE; data->d_off = 0; - /* FIXME: use right version */ - unstrip_info_to_data32 (info, elf, data); + gelf_getehdr (elf, &ehdr); + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + unstrip_info_to_data32 (info, elf, data); + else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) + unstrip_info_to_data64 (info, elf, data); + else + fprintf (stderr, "Warning. unsupported elf class\n"); } -void +static void unstrip_info_from_data32 (UnstripInfo *info, Elf *elf, Elf_Data *data) @@ -130,23 +289,49 @@ } } +static void +unstrip_info_from_data64 (UnstripInfo *info, + Elf *elf, + Elf_Data *data) +{ + UnstripInfo64 *info64; + int i; + + info64 = (UnstripInfo64 *) data->d_buf; + + info->orig_e_shoff = off64_from_file (info64->orig_e_shoff, elf); + info->n_sections = off64_from_file (info64->n_sections, elf); + + info->sections = calloc (info->n_sections, sizeof (UnstripInfoSection)); + for (i = 0; i < info->n_sections; i++) + { + info->sections[i].debug_section = word64_from_file (info64->sections[i].debug_section, elf); + info->sections[i].name = word64_from_file (info64->sections[i].name, elf); + info->sections[i].orig_offset = off64_from_file (info64->sections[i].orig_offset, elf); + } +} + UnstripInfo * unstrip_info_from_data (Elf *elf, Elf_Data *data) { + GElf_Ehdr ehdr; + UnstripInfo *info; info = malloc (sizeof (UnstripInfo)); - /* FIXME: use right version */ - unstrip_info_from_data32 (info, - elf, - data); + gelf_getehdr (elf, &ehdr); + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + unstrip_info_from_data32 (info, elf, data); + else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) + unstrip_info_from_data64 (info, elf, data); + else + fprintf (stderr, "Warning. unsupported elf class\n"); return info; } - static void debug_link_to_data32 (DebugLink *debuglink, Elf *elf, @@ -166,23 +351,53 @@ data->d_buf = calloc (1, data->d_size); strcpy (data->d_buf, debuglink->filename); - p = data->d_buf + namelen_aligned; + p = ((char *)data->d_buf) + namelen_aligned; *(Elf32_Word *)p = word32_to_file (debuglink->checksum, elf); - p += sizeof (Elf32_Word); +} + +static void +debug_link_to_data64 (DebugLink *debuglink, + Elf *elf, + Elf_Data *data) +{ + size_t namelen_aligned; + char *p; + + data->d_align = 4; + + namelen_aligned = align_up (strlen(debuglink->filename) + 1, 4); + + data->d_size = + /* name */ namelen_aligned + + /* checksum */ sizeof (Elf64_Word); + + data->d_buf = calloc (1, data->d_size); + + strcpy (data->d_buf, debuglink->filename); + p = ((char *)data->d_buf) + namelen_aligned; + + *(Elf64_Word *)p = word64_to_file (debuglink->checksum, elf); } void debug_link_to_data (DebugLink *debuglink, Elf *elf, Elf_Data *data) { + GElf_Ehdr ehdr; + data->d_type = ELF_T_BYTE; data->d_off = 0; - /* FIXME: use right version */ - debug_link_to_data32 (debuglink, elf, data); + gelf_getehdr (elf, &ehdr); + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + debug_link_to_data32 (debuglink, elf, data); + else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) + debug_link_to_data64 (debuglink, elf, data); + else + fprintf (stderr, "Warning. unsupported elf class\n"); } -void +static void debug_link_from_data32 (DebugLink *debuglink, Elf *elf, Elf_Data *data) @@ -194,24 +409,44 @@ namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4); - p = data->d_buf + namelen_aligned; + p = ((char *)data->d_buf) + namelen_aligned; debuglink->checksum = word32_from_file (*(Elf32_Word *)p, elf); - p += sizeof (Elf32_Word); +} + +static void +debug_link_from_data64 (DebugLink *debuglink, + Elf *elf, + Elf_Data *data) +{ + size_t namelen_aligned; + char *p; + + debuglink->filename = strdup (data->d_buf); + + namelen_aligned = align_up (strlen (debuglink->filename) + 1, 4); + + p = ((char *)data->d_buf) + namelen_aligned; + + debuglink->checksum = word64_from_file (*(Elf64_Word *)p, elf); } DebugLink * debug_link_from_data (Elf *elf, Elf_Data *data) { + GElf_Ehdr ehdr; DebugLink *debuglink; debuglink = malloc (sizeof (DebugLink)); - /* FIXME: use right version */ - debug_link_from_data32 (debuglink, - elf, - data); + gelf_getehdr (elf, &ehdr); + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) + debug_link_from_data32 (debuglink, elf, data); + else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) + debug_link_from_data64 (debuglink, elf, data); + else + fprintf (stderr, "Warning. unsupported elf class\n"); return debuglink; } Index: tools/striptofile.c =================================================================== RCS file: rpm/tools/striptofile.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.4 diff -u -u -r1.1.2.2 -r1.1.2.4 --- rpm/tools/striptofile.c 22 Aug 2002 19:19:47 -0000 1.1.2.2 +++ rpm/tools/striptofile.c 9 Oct 2002 19:06:24 -0000 1.1.2.4 @@ -15,7 +15,8 @@ int keep_all_section_headers = 1; int add_unstrip_info = 0; -void +#if defined(NhUNUSED) +static void copy_to_file(Elf *elf, Elf *out_elf) { GElf_Ehdr ehdr; @@ -67,8 +68,9 @@ } } } +#endif -void +static void strip_to_file(Elf *elf, Elf *out_elf, DebugLink *debuglink) { GElf_Ehdr ehdr; @@ -82,7 +84,8 @@ int keep_section; int changed_offsets; GElf_Off last_offset; - int i, debuglink_name; + int i; + int debuglink_name = 0; elf_flagelf (out_elf, ELF_C_SET, ELF_F_LAYOUT); @@ -201,7 +204,7 @@ /* Update section header stringtab ref */ gelf_getehdr (out_elf, &out_ehdr); out_ehdr.e_shstrndx = section_map[out_ehdr.e_shstrndx]; - out_ehdr.e_shoff = align_up (last_offset, 4); + out_ehdr.e_shoff = align_up (last_offset, 8); gelf_update_ehdr(out_elf, &out_ehdr); /* Update section header links */ @@ -220,7 +223,7 @@ } } -void +static void copy_debuginfo_to_file(Elf *elf, Elf *out_elf) { GElf_Ehdr ehdr; @@ -231,7 +234,7 @@ unsigned char *section_strtab; int keep_section; UnstripInfo *info; - int unstripinfo_name; + int unstripinfo_name = 0; info = malloc (sizeof (UnstripInfo)); @@ -402,6 +405,7 @@ Elf *elf, *out_elf; int fd, out; const char *origname; + char *origname_base; char *debugname, *strippedname; DebugLink *debuglink; poptContext optCon; /* context for parsing command-line options */ @@ -433,14 +437,13 @@ origname = args[0]; - if (output_dir) { - const char * bn = strrchr(origname, '/'); - if ((bn = strrchr(origname, '/')) != NULL) - bn++; - else - bn = origname; - debugname = strconcat (output_dir, "/", bn, ".debug", NULL); - } else + if (output_dir) + { + origname_base = path_basename (origname); + debugname = strconcat (output_dir, "/", origname_base, ".debug", NULL); + free (origname_base); + } + else debugname = strconcat (origname, ".debug", NULL); strippedname = strconcat (origname, ".XXXXXX", NULL); Index: tools/unstripfile.c =================================================================== RCS file: rpm/tools/unstripfile.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -u -r1.1.2.2 -r1.1.2.3 --- rpm/tools/unstripfile.c 22 Aug 2002 19:19:47 -0000 1.1.2.2 +++ rpm/tools/unstripfile.c 9 Oct 2002 19:06:24 -0000 1.1.2.3 @@ -9,7 +9,7 @@ #include "debug.h" -DebugLink * +static DebugLink * read_debuglink (Elf *elf) { GElf_Ehdr ehdr; @@ -47,7 +47,7 @@ return NULL; } -Elf_Scn * +static Elf_Scn * find_section (Elf *elf, const unsigned char *name, const unsigned char *strtab) { Elf_Scn *section; @@ -69,7 +69,7 @@ return section; } -size_t +static size_t find_in_strtab (char *name, char *strtab, size_t strtab_len) { int name_len, i; @@ -82,7 +82,7 @@ return 0; } -void +static void unstrip_file (Elf *elf, Elf *debug_elf, Elf *out_elf) { UnstripInfo *info; Index: tools/utils.c =================================================================== RCS file: rpm/tools/utils.c,v retrieving revision 1.1.2.3 retrieving revision 1.1.2.4 diff -u -u -r1.1.2.3 -r1.1.2.4 --- rpm/tools/utils.c 4 Sep 2002 18:13:35 -0000 1.1.2.3 +++ rpm/tools/utils.c 9 Oct 2002 19:06:24 -0000 1.1.2.4 @@ -6,7 +6,7 @@ #include "debug.h" -char * +static char * my_stpcpy (char *dest, const char *src) { @@ -146,7 +146,7 @@ 0x2d02ef8d }; -unsigned int crc32 (unsigned int crc, unsigned char *buf, size_t len) +static unsigned int crc32 (unsigned int crc, unsigned char *buf, size_t len) { unsigned char *end; Index: xmlspec/Makefile =================================================================== RCS file: rpm/xmlspec/Makefile,v retrieving revision 1.5.2.2 retrieving revision 1.5.2.3 diff -u -u -r1.5.2.2 -r1.5.2.3 --- rpm/xmlspec/Makefile 28 Aug 2002 10:53:03 -0000 1.5.2.2 +++ rpm/xmlspec/Makefile 10 Oct 2002 22:47:59 -0000 1.5.2.3 @@ -7,7 +7,9 @@ CFLAGS = -O2 -Wall -Wpointer-arith -Wno-char-subscripts INCDIR = -I. -I.. -I../build -I../lib -I../misc -I../popt -I../rpmdb -I../rpmio RPMDIR = .. -DESTDIR = /usr/local + +prefix = /usr +DESTDIR = XMLBUILD = rpmxmlbuild XMLBUILD_SRC = rpmxmlbuild.c @@ -21,6 +23,7 @@ LIBS = $(XMLLIB) $(RPMDIR)/build/.libs/librpmbuild.a \ $(RPMDIR)/lib/.libs/librpm.a $(RPMDIR)/rpmdb/.libs/librpmdb.a \ $(RPMDIR)/rpmio/.libs/librpmio.a $(RPMDIR)/popt/.libs/libpopt.a \ + $(RPMDIR)/libelf/lib/.libs/libelf.a \ -lz -lexpat -lbz2 LIBDIR = -L. -L$(RPMDIR)/.libs -L/usr/lib @@ -33,9 +36,9 @@ $(STRIP) $(XMLBUILD) install: - @(cp $(XMLBUILD) $(DESTDIR)/bin) - @(cp $(XMLLIB) $(DESTDIR)/lib) - @(cp $(XMLLIB_H) $(DESTDIR)/include) + @(install -m 755 $(XMLBUILD) $(DESTDIR)$(prefix)/bin) + @(install -m 644 $(XMLLIB) $(DESTDIR)$(prefix)/lib) + @(install -m 644 $(XMLLIB_H) $(DESTDIR)$(prefix)/include/rpm) $(XMLLIB): $(XMLLIB_OBJ) $(AR) $(ARFLAGS) $(XMLLIB) $(XMLLIB_OBJ) Index: xmlspec/XMLAttrs.cpp =================================================================== RCS file: xmlspec/XMLAttrs.cpp diff -N xmlspec/XMLAttrs.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLAttrs.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,168 @@ +// standard C++ includes +#include + +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLMisc.h" +#include "XMLSpec.h" + +using namespace std; + +XMLAttr::XMLAttr(const char* szName, + const char* szValue) + : XMLBase() +{ + if (szName) + m_sName.assign(szName); + if (szValue) + m_sValue.assign(szValue); +} + +XMLAttr::XMLAttr(const XMLAttr& rAttr) + : XMLBase() +{ + m_sName.assign(rAttr.m_sName); + m_sValue.assign(rAttr.m_sValue); +} + +XMLAttr::~XMLAttr() +{ +} + +XMLAttr XMLAttr::operator=(XMLAttr attr) +{ + m_sName.assign(attr.m_sName); + m_sValue.assign(attr.m_sValue); +} + +XMLAttrs::XMLAttrs(const char** szAttrs) + : XMLBase() +{ + for (int i = 0; szAttrs && szAttrs[i]; i += 2) { + XMLAttr attr(szAttrs[i], szAttrs[i+1]); + m_vAttrs.push_back(attr); + } +} + +XMLAttrs::XMLAttrs(const XMLAttrs& rAttrs) + : XMLBase() +{ + m_vAttrs = rAttrs.m_vAttrs; +} + +XMLAttrs::~XMLAttrs() +{ +} + +bool validateAttr(structValidAttrs& rAttr, + const char* szValue) +{ + switch (rAttr.m_nType) { + case XATTRTYPE_STRING: + return findStr(rAttr.m_szaMatches, szValue) != -1 ? true : false; + break; + case XATTRTYPE_INTEGER: + return isInteger(szValue); + break; + case XATTRTYPE_BOOL: + return isBool(szValue); + break; + case XATTRTYPE_DATE: + return isDate(szValue); + break; + case XATTRTYPE_MAIL: + return isEmail(szValue); + break; + case XATTRTYPE_NONE: + default: + return true; + break; + } + return false; +} + +static char* szaTypeDesc[] = { "string", + "integer", + "bool [Values: true|false]", + "date [Format: DDD MMM DD YYYY]", + "e-mail" }; + +bool XMLAttrs::validate(structValidAttrs* paValids, + XMLBase* pError) +{ + // nothing found at present + for (unsigned int i = 0; paValids[i].m_nValue != XATTR_END; i++) + paValids[i].m_bFound = false; + + // test everything we have + for (unsigned int i = 0; i < num(); i++) { + bool bInvalid = true; + for (unsigned int j = 0; paValids[j].m_nValue != XATTR_END; j++) { + if (strcasecmp(paValids[j].m_szName, get(i).getName()) == 0) { + paValids[j].m_bFound = true; + if (!validateAttr(paValids[j], get(i).asString())) { + char szTmp[1024]; + sprintf(szTmp, "Attribute value '%s' is not a valid %s.", + get(i).asString(), szaTypeDesc[paValids[j].m_nType]); + pError->setError(szTmp); + return false; + } + else + bInvalid = false; + break; + } + } + if (bInvalid) { + char szTmp[1024]; + sprintf(szTmp, "Unknown attribute '%s'", get(i).getName()); + pError->setWarning(szTmp); + } + } + + // see if we have mandator tags that are not there + for (unsigned int i = 0; paValids[i].m_nValue != XATTR_END; i++) { + if (paValids[i].m_bMandatory && !paValids[i].m_bFound) { + char szTmp[1024]; + sprintf(szTmp, "Mandatory attribute '%s' not found", + paValids[i].m_szName); + pError->setError(szTmp); + return false; + } + } + + // if we got this far, everything is ok + return true; +} + +unsigned int getPos(const char* szName, + XMLAttrs* pAttrs) +{ + if (szName) { + for (unsigned int i = 0; i < pAttrs->num(); i++) { + if (strcasecmp(szName, pAttrs->get(i).getName()) == 0) + return i; + } + } + return XATTR_END; +} + +const char* XMLAttrs::asString(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? NULL : get(nPos).asString(); +} + +unsigned int XMLAttrs::asInteger(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? 0 : get(nPos).asInteger(); +} + +bool XMLAttrs::asBool(const char* szName) +{ + unsigned int nPos = getPos(szName, this); + return (nPos == XATTR_END) ? true : get(nPos).asBool(); +} Index: xmlspec/XMLAttrs.h =================================================================== RCS file: xmlspec/XMLAttrs.h diff -N xmlspec/XMLAttrs.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLAttrs.h 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,255 @@ +#ifndef _H_XMLATTRS_ +#define _H_XMLATTRS_ + +// standard C++ includes +#include +#include + +// standard C includes +#include + +// our includes +#include "XMLBase.h" + +using namespace std; + +// definition for the end of the attributes +#define XATTR_END 0xFFFF +#define XATTR_NUM_VALSTR 5 + +enum eAttrType +{ + XATTRTYPE_STRING = 0, + XATTRTYPE_INTEGER, + XATTRTYPE_BOOL, + XATTRTYPE_DATE, + XATTRTYPE_MAIL, + XATTRTYPE_NONE = XATTR_END +}; + +struct structValidAttrs +{ + unsigned int m_nValue; + bool m_bMandatory; + bool m_bFound; + char* m_szName; + unsigned int m_nType; + char* m_szaMatches[XATTR_NUM_VALSTR+1]; +}; + +// forward class definitions +class XMLSpec; + +class XMLAttr : public XMLBase +{ +// +// contructors/destructor +// +public: + /** + * Default constructor + * . + * @param szName The name of the attribute + * @param szValue The attribute value + * @return none + **/ + XMLAttr(const char* szName, + const char* szValue); + + /** + * Copy constructor + * . + * @param rAttr Reference to the attribute to copy + * @return none + **/ + XMLAttr(const XMLAttr& rAttr); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLAttr(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param attr The attribute to copy + * @return the assigned obkect + **/ + XMLAttr operator=(XMLAttr attr); + +// +// get/set functions +// +public: + /** + * Returns the attribute name + * . + * @param none + * @return string containing the attribute name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Returns the attribute value (as string) + * . + * @param none + * @return string containing the attribute value + **/ + const char* asString() + { + return m_sValue.c_str(); + } + + /** + * Returns the attribute value (as integer) + * . + * @param none + * @return the attribute as an integer + **/ + unsigned int asInteger() + { + return atoi(m_sValue.c_str()); + } + + /** + * Returns the attribute value as a boolean + * . + * @param none + * @return true if set, false otherwise + **/ + bool asBool() + { + bool isSet = true; + if (strcasecmp(m_sValue.c_str(), "no") == 0 || + strcasecmp(m_sValue.c_str(), "0") == 0 || + strcasecmp(m_sValue.c_str(), "false") == 0) + isSet = false; + return isSet; + } + +// +// member variables +// +public: + string m_sName; + string m_sValue; +}; + +class XMLAttrs : public XMLBase +{ +// +// constructors/destructor +// +public: + /** + * The default attribute constructor + * . + * @param szAttrs Pointer to an array of attributes, terminated by NULL + * @return none + **/ + XMLAttrs(const char** szAttrs); + + /** + * Copy constructor + * . + * @param rAttrs The attribute object to copy + * @return none + **/ + XMLAttrs(const XMLAttrs& rAttrs); + + /** + * The default destructor + * . + * @param none + * @return none + **/ + ~XMLAttrs(); + +// +// member functions +// +public: + /** + * Validates an attribute object against the valid attributes. This + * checks for mandatory attributes (error) as well as unexpected + * attributes. (warnings) + * . + * @param paValids Pointer to the array of valid attributes + * @param pError The class in which we will set the errors + * and/or warnings. + * @return true on valid attributes, false otherwise + **/ + bool validate(structValidAttrs* paValids, + XMLBase* pError); + +// +// member variables get/set functions +// +public: + /** + * Gets the number of attributes contained in this object + * . + * @param none + * @returns The number of attributes + **/ + unsigned int num() + { + return m_vAttrs.size(); + } + + /** + * Returns a specific attribute by number + * . + * @param nNum The number of the attribute to return + * @return The attribute or NULL if it doesn't exist + **/ + XMLAttr& get(unsigned int nNum) + { + return m_vAttrs[nNum]; + } + + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as a string + **/ + const char* asString(const char* szName); + + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as an integer + **/ + unsigned int asInteger(const char* szName); + + /** + * Returns the attribute as specified by the name + * . + * @param szName The name of the attribute whose value we are + * to return + * @return The attribute as a bool + **/ + bool asBool(const char* szName); + +// +// protected data members +// +protected: + vector m_vAttrs; +}; + +#endif Index: xmlspec/XMLBase.h =================================================================== RCS file: xmlspec/XMLBase.h diff -N xmlspec/XMLBase.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLBase.h 28 Aug 2002 10:52:43 -0000 1.1.1.1.2.1 @@ -0,0 +1,134 @@ +#ifndef _H_XMLBASE_ +#define _H_XMLBASE_ + +// standard C++ includes +#include + +// standard include +#include + +using namespace std; + +class XMLBase +{ +// +// constructors/destructor methods +// +public: + /** + * Default class constructor + * . + * param none + * @return none + **/ + XMLBase() + { + m_bHasError = false; + m_bHasWarning = false; + } + + /** + * Default class destructor + * . + * param none + * @return none + **/ + ~XMLBase() + { + } + +// +// member variable get and set functions +// +public: + /** + * Tests if the object has an error set. + * . + * @param none + * @return true if we have an error, false otherwise + **/ + bool hasError() + { + return m_bHasError; + } + + /** + * Sets the error message that can be retrieved from this + * object instance + * . + * @param szError The error string + * @return none + **/ + void setError(const char* szError = NULL) + { + if (szError) { + m_bHasError = true; + m_sError.assign(szError); + } + else + m_bHasError = false; + } + + /** + * Returns the currently set error value + * . + * @param none + * @return pointer to the error string + **/ + const char* getError() + { + m_bHasError = false; + return m_sError.c_str(); + } + + /** + * Tests if the object has a warning set. + * . + * @param none + * @return true if we have a warning, false otherwise + **/ + bool hasWarning() + { + return m_bHasWarning; + } + + /** + * Sets the warning message that can be retrieved from this + * object instance + * . + * @param szWarning The warning string + * @return none + **/ + void setWarning(const char* szWarning = NULL) + { + if (szWarning) { + m_bHasWarning = true; + m_sWarning.assign(szWarning); + } + else + m_bHasWarning = false; + } + + /** + * Returns the currently set warning value + * . + * @param none + * @return pointer to the warning string + **/ + const char* getWarning() + { + m_bHasWarning = false; + return m_sWarning.c_str(); + } + +// +// protected internal variables +// +protected: + bool m_bHasError; + string m_sError; + bool m_bHasWarning; + string m_sWarning; +}; + +#endif Index: xmlspec/XMLChangelog.cpp =================================================================== RCS file: xmlspec/XMLChangelog.cpp diff -N xmlspec/XMLChangelog.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLChangelog.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,237 @@ +// standard C++ includes +#include + +// our includes +#include "XMLChangelog.h" +#include "XMLMisc.h" +#include "XMLRPMWrap.h" +#include "XMLSpec.h" + +using namespace std; + +bool XMLChangelogEntry::parseCreate(XMLAttrs* pAttrs, + const char* szChange, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + XMLChangelogEntry change(szChange); + pSpec->getChangelog().lastDate().addEntry(change); + return true; +} + +bool XMLChangelogEntry::structCreate(const char* szEntries, + XMLSpec* pXSpec) +{ + if (!pXSpec || !szEntries) + return false; + char* szIn = (char*)szEntries; + char* szOut = NULL; + int nLen = -1; + string sChange; + while (nLen != 0) { + szOut = splitStr(szIn, '\n', nLen); + if (strncmp(szIn, "- ", 2) == 0) { + szIn += 2; + nLen -= 2; + if (sChange.length()) { + XMLChangelogEntry change(sChange.c_str()); + pXSpec->getChangelog().lastDate().addEntry(change); + } + sChange.assign(""); + } + sChange.append(szIn, nLen); + szIn = szOut; + } + if (sChange.length()) { + XMLChangelogEntry change(sChange.c_str()); + pXSpec->getChangelog().lastDate().addEntry(change); + } + return true; +} + +XMLChangelogEntry::XMLChangelogEntry(const char* szChange) + : XMLBase() +{ + m_sChange.assign(szChange); +} + +XMLChangelogEntry::XMLChangelogEntry(const XMLChangelogEntry& rEntry) + : XMLBase() +{ + m_sChange.assign(rEntry.m_sChange); +} + +XMLChangelogEntry::~XMLChangelogEntry() +{ +} + +void XMLChangelogEntry::toSpecFile(ostream& rOut) +{ + rOut << endl << "- " << getChange(); +} + +void XMLChangelogEntry::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t\t\t" << getChange() << ""; +} + +// attribute structure for XMLChangelogDate +structValidAttrs g_paChangelogDateAttrs[] = +{ + {0x0000, true, false, "date", XATTRTYPE_DATE, {NULL}}, + {0x0001, true, false, "author", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "author-email", XATTRTYPE_MAIL, {NULL}}, + {0x0003, false, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLChangelogDate::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + // validate our attributes + if (!pAttrs->validate(g_paChangelogDateAttrs, (XMLBase*)pSpec)) + return false; + + XMLChangelogDate date(pAttrs->asString("date"), + pAttrs->asString("author"), + pAttrs->asString("author-email"), + pAttrs->asString("version")); + pSpec->getChangelog().addDate(date); + return true; +} + +bool XMLChangelogDate::structCreate(const char* szDate, + const char* szName, + const char* szEntries, + XMLSpec* pXSpec) +{ + if (!szDate || !szName || !szEntries || ! pXSpec) + return false; + time_t tTime = (time_t)(atol(szDate)) - timezone; + struct tm *sTime = gmtime(&tTime); + sTime->tm_year += 1900; + char szTmp[32]; + sprintf(szTmp,"%s %s %d %d", g_szaDays[sTime->tm_wday], + g_szaMonths[sTime->tm_mon], + sTime->tm_mday, sTime->tm_year); + XMLChangelogDate date(szTmp, szName, NULL, NULL); + pXSpec->getChangelog().addDate(date); + XMLChangelogEntry::structCreate(szEntries, pXSpec); + return true; +} + +XMLChangelogDate::XMLChangelogDate(const char* szDate, + const char* szAuthor, + const char* szEmail, + const char* szVersion) + : XMLBase() +{ + if (szDate) + m_sDate.assign(szDate); + if (szAuthor) + m_sAuthor.assign(szAuthor); + if (szEmail) + m_sEmail.assign(szEmail); + if (szVersion) + m_sVersion.assign(szVersion); +} + +XMLChangelogDate::XMLChangelogDate(const XMLChangelogDate& rDate) + : XMLBase() +{ + m_sDate.assign(rDate.m_sDate); + m_sAuthor.assign(rDate.m_sAuthor); + m_sEmail.assign(rDate.m_sEmail); + m_sVersion.assign(rDate.m_sVersion); + m_vEntries = rDate.m_vEntries; +} + +XMLChangelogDate::~XMLChangelogDate() +{ +} + +void XMLChangelogDate::toSpecFile(ostream& rOut) +{ + rOut << endl << "* " << getDate() << " " << getAuthor(); + if (hasEmail()) + rOut << " <" << getEmail() << ">"; + if (hasVersion()) + rOut << " " << getVersion(); + for (unsigned int i = 0; i < numEntries(); i++) + getEntry(i).toSpecFile(rOut); + rOut << endl; +} + +void XMLChangelogDate::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t\t"; + for (unsigned int i = 0; i < numEntries(); i++) + getEntry(i).toXMLFile(rOut); + rOut << endl << "\t\t"; +} + +bool XMLChangelog::structCreate(Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pSpec->packages || !pSpec->packages->header) + return false; + // FIXME: it looks like RPM only stores the tomost date in the + // spec file so we are only allowed to get that one instead of an + // array of time_t's + string sDates; + t_StrVector svChanges; + t_StrVector svNames; + getRPMHeader(pSpec->packages->header, RPMTAG_CHANGELOGTIME, sDates); + getRPMHeaderArray(pSpec->packages->header, RPMTAG_CHANGELOGNAME, svNames); + getRPMHeaderArray(pSpec->packages->header, RPMTAG_CHANGELOGTEXT, svChanges); + for (unsigned int i = 0; i < svNames.size(); i++) + XMLChangelogDate::structCreate(sDates.c_str(), svNames[i].c_str(), + svChanges[i].c_str(), pXSpec); + return true; +} + +XMLChangelog::XMLChangelog() + : XMLBase() +{ +} + +XMLChangelog::XMLChangelog(const XMLChangelog& rChangelog) + : XMLBase() +{ + m_vDates = rChangelog.m_vDates; +} + +XMLChangelog::~XMLChangelog() +{ +} + +void XMLChangelog::toSpecFile(ostream& rOut) +{ + if (numDates()) { + rOut << endl << "%changelog"; + for (unsigned int i = 0; i < numDates(); i++) + getDate(i).toSpecFile(rOut); + rOut << endl; + } +} + +void XMLChangelog::toXMLFile(ostream& rOut) +{ + if (numDates()) { + rOut << endl << "\t"; + for (unsigned int i = 0; i < numDates(); i++) + getDate(i).toXMLFile(rOut); + rOut << endl << "\t"; + } +} + +void XMLChangelog::toRPMStruct(Spec spec) +{ +} Index: xmlspec/XMLChangelog.h =================================================================== RCS file: xmlspec/XMLChangelog.h diff -N xmlspec/XMLChangelog.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLChangelog.h 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,458 @@ +#ifndef _H_XMLCHANGELOG_ +#define _H_XMLCHANGELOG_ + +// standard C++ includes +#include +#include +#include + +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" + +// rpm includes +#include + +// forward class definitions +class XMLSpec; +class XMLChangelog; + +using namespace std; + +class XMLChangelogEntry : public XMLBase +{ +// +// factory functions +// +public: + /** + * Adds a changelog entry + * . + * @param pAttrs The XML attributes + * @param szEntry The entry to create + * @param pSpec Pointer to our spec + * @return true on success, false othersise + */ + static bool parseCreate(XMLAttrs* pAttrs, + const char* szEntry, + XMLSpec* pSpec); + + + /** + * Creates changelog entries from the data provided to us by RPM + * @param szEntries The netries we are to evaluate + * @param pXSpec pointer to the XML spec we are working with + * @return true on success,. false otherwise + **/ + static bool structCreate(const char* szEntries, + XMLSpec* pXSpec); + +// +// constructors/destructor +// +public: + /** + * Default contructor + * . + * @param szChange The change entry + * @return none + **/ + XMLChangelogEntry(const char* szChange); + + /** + * Copy constructor + * . + * @param rEntry Reference to the entry to copy + * @return none + **/ + XMLChangelogEntry(const XMLChangelogEntry& rEntry); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLChangelogEntry(); + +// +// member functions +// +public: + /** + * Outputs the object into a spec file + * . + * @param rOut Reference to our output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Outputs the object into an XML spec file + * . + * @param rOut Reference to our output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member variable get/set functions +// +public: + /** + * Returns the enrty + * . + * @param none + * @return string containing the entry + **/ + const char* getChange() + { + return m_sChange.c_str(); + } + +// +// member variables +// +public: + string m_sChange; +}; + +class XMLChangelogDate : public XMLBase +{ +// +// factory functions +// +public: + /** + * Creates a XMLChangelogDate object + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to add this object to + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Creates an XMLChangelogDate object from the information provided to + * us by RPM + * . + * @param szDate The date to generate this for + * @param szEntries The entries to add to this date + * @param pXSpec The XML spec we are working with + * @return true on success, false otherwise + **/ + static bool structCreate(const char* szDate, + const char* szName, + const char* szEntries, + XMLSpec* pXSpec); + +// +// constructors/destructor +// +public: + /** + * Default contructor + * . + * @param szDate The date + * @param szAuthor The author + * @param szEmail The author's email + * @param szVersion The version in which this change was made + * @return none + **/ + XMLChangelogDate(const char* szDate, + const char* szAuthor, + const char* szEmail, + const char* szVersion); + + /** + * Copy contructor + * . + * @param rDate Reference to the date object to copy + * @return none + **/ + XMLChangelogDate(const XMLChangelogDate& rDate); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLChangelogDate(); + +// +// public member functions +// +public: + /** + * Outputs the object into a spec file + * . + * @param rOut Reference to our output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Outputs the object into an XML spec file + * . + * @param rOut Reference to our output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member variables get/set functions +// +public: + /** + * Returns the date for the group of entries + * . + * @param none + * @return string representation of the date + **/ + const char* getDate() + { + return m_sDate.c_str(); + } + + /** + * Checks for an author + * . + * @param none + * @return true if we have an author, false otherwise + **/ + bool hasAuthor() + { + return m_sAuthor.length() ? true : false; + } + + /** + * Returns the author's name + * . + * @param none + * @return string containing the author's name + **/ + const char* getAuthor() + { + return m_sAuthor.c_str(); + } + + /** + * Checks if we have an email address for the author + * . + * @param none + * @return true if we hava an email, false otherwise + **/ + bool hasEmail() + { + return m_sEmail.length() ? true : false; + } + + /** + * Returns the author's email addresse + * . + * @param none + * @return a string containing the author's email address + **/ + const char* getEmail() + { + return m_sEmail.c_str(); + } + + /** + * Checks if we have a change version + * . + * @param none + * @return true if we have a version, false otherwise + **/ + bool hasVersion() + { + return m_sVersion.length() ? true : false; + } + + /** + * Gets the change version + * . + * @param none + * @return string containing the version + **/ + const char* getVersion() + { + return m_sVersion.c_str(); + } + + /** + * Returns the number of entries for this date + * . + * @param none + * @return the number of entries + **/ + unsigned int numEntries() + { + return m_vEntries.size(); + } + + /** + * Returns a specific entry + * . + * @param nNum The number of the entry to return + * @return the enrty + **/ + XMLChangelogEntry& getEntry(unsigned int nNum) + { + return m_vEntries[nNum]; + } + + /** + * Adds an entry for this date + * . + * @param szEntry The entry to add + * @return none + **/ + void addEntry(XMLChangelogEntry& rEntry) + { + m_vEntries.push_back(rEntry); + } + +// +// member variables +// +protected: + string m_sDate; + string m_sAuthor; + string m_sEmail; + string m_sVersion; + vector m_vEntries; +}; + +class XMLChangelog : public XMLBase +{ +// +// static factory functions +// +public: + /** + * Creates changelog objects from an RPM Spec structure + * . + * @param pSpec Pointer to the RPM spec + * @param pXSpec pointer to the XMLSpec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(Spec pSpec, + XMLSpec* pXSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param none + * @return none + **/ + XMLChangelog(); + + /** + * Copy constructor + * . + * @param rChangelog The object to copy + * @return none + **/ + XMLChangelog(const XMLChangelog& rChangelog); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLChangelog(); + +// +// public member functions +// +public: + /** + * Converts the object into a spec file + * . + * @param rOut Reference to the output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the object into an xML spec + * . + * @param rOut Reference to the output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + + /** + * Converts the object into an RPM structure + * . + * @param spec RPM structure + * @return none + **/ + void toRPMStruct(Spec spec); +// +// variable get/set functions +// +public: + /** + * Adds a date to the changelog + * . + * @param rDate The date to add + * @return none + **/ + void addDate(XMLChangelogDate& rDate) + { + m_vDates.push_back(rDate); + } + + /** + * Returns the number of dates in the changelog + * . + * @param none + * @return the number of dates + **/ + unsigned int numDates() + { + return m_vDates.size(); + } + + /** + * Gets a specific date + * . + * @param nNum The entry number + * @return The requated date + **/ + XMLChangelogDate& getDate(unsigned int nNum) + { + return m_vDates[nNum]; + } + + /** + * Gets the last date we have added + * . + * @param none + * @return the last date + **/ + XMLChangelogDate& lastDate() + { + return m_vDates[numDates()-1]; + } + +// +// member variables +// +protected: + vector m_vDates; +}; + +#endif Index: xmlspec/XMLFiles.cpp =================================================================== RCS file: xmlspec/XMLFiles.cpp diff -N xmlspec/XMLFiles.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLFiles.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,200 @@ +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLFiles.h" +#include "XMLPackage.h" +#include "XMLSpec.h" + +// rpm includes +#include +#include + +using namespace std; + +// attribute structure for XMLFile +structValidAttrs g_paFileAttrs[] = +{ + {0x0000, false, false, "mode", XATTRTYPE_INTEGER, {NULL}}, + {0x0001, false, false, "group", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "user", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "config", XATTRTYPE_STRING, {"noreplace", + "*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLFile::parseCreate(XMLAttrs* pAttrs, + const char* szPath, + XMLSpec* pSpec) +{ + // validate the attributes + if (!pSpec || !pAttrs->validate(g_paFileAttrs, (XMLBase*)pSpec)) + return false; + + // create and return + XMLFile file(pAttrs->asString("mode"), pAttrs->asString("user"), + pAttrs->asString("group"), pAttrs->asString("config"), szPath); + pSpec->lastPackage().getFiles().addFile(file); + return true; +} + +XMLFile::XMLFile(const char* szMode, + const char* szOwner, + const char* szGroup, + const char* szConfig, + const char* szPath) + : XMLBase() +{ + if (szMode) + m_sMode.assign(szMode); + if (szOwner) + m_sOwner.assign(szOwner); + if (szGroup) + m_sGroup.assign(szGroup); + if (szConfig) + m_sConfig.assign(szConfig); + if (szPath) + m_sPath.assign(szPath); +} + +XMLFile::XMLFile(const XMLFile& rFile) + : XMLBase() +{ + setMode(rFile.m_sMode.c_str()); + setOwner(rFile.m_sOwner.c_str()); + setGroup(rFile.m_sGroup.c_str()); + setConfig(rFile.m_sConfig.c_str()); + setPath(rFile.m_sPath.c_str()); +} + +XMLFile::~XMLFile() +{ +} + +XMLFile XMLFile::operator=(XMLFile file) +{ + setMode(file.m_sMode.c_str()); + setOwner(file.m_sOwner.c_str()); + setGroup(file.m_sGroup.c_str()); + setConfig(file.m_sConfig.c_str()); + setPath(file.m_sPath.c_str()); +} + +void XMLFile::toSpecFile(ostream& rOut) +{ + if (hasMode() || hasOwner() || hasGroup()) { + rOut << "%attr("; + rOut << (hasMode() ? getMode() : "-"); + rOut << "," << (hasOwner() ? getOwner() : "-"); + rOut << "," << (hasGroup() ? getGroup() : "-"); + rOut << ") "; + } + if (hasConfig()) { + rOut << "%config(" << getConfig() << ") "; + } + rOut << getPath() << endl; +} + +void XMLFile::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t\t\t"; + rOut << getPath() << ""; +} + +// attribute structure for XMLFiles +structValidAttrs g_paFilesAttrs[] = +{ + {0x0000, false, false, "mode", XATTRTYPE_INTEGER, {NULL}}, + {0x0001, false, false, "group", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "user", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLFiles::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec || !pAttrs->validate(g_paFilesAttrs, (XMLBase*)pSpec)) + return false; + pSpec->lastPackage().getFiles().setDefMode(pAttrs->asString("mode")); + pSpec->lastPackage().getFiles().setDefOwner(pAttrs->asString("user")); + pSpec->lastPackage().getFiles().setDefGroup(pAttrs->asString("group")); + return true; +} + +bool XMLFiles::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pPackage || !pPackage->fileList) + return false; + return true; +} + +XMLFiles::XMLFiles() + : XMLBase() +{ +} + +XMLFiles::XMLFiles(const XMLFiles& rFiles) + : XMLBase() +{ + setDefMode(rFiles.m_sMode.c_str()); + setDefOwner(rFiles.m_sOwner.c_str()); + setDefGroup(rFiles.m_sGroup.c_str()); + m_vFiles = rFiles.m_vFiles; +} + +XMLFiles::~XMLFiles() +{ +} + +XMLFiles XMLFiles::operator=(XMLFiles files) +{ + setDefMode(files.m_sMode.c_str()); + setDefOwner(files.m_sOwner.c_str()); + setDefGroup(files.m_sGroup.c_str()); + m_vFiles = files.m_vFiles; + return *this; +} + +void XMLFiles::toSpecFile(ostream& rOut) +{ + if (numFiles()) { + if (hasDefMode() || hasDefOwner() || hasDefGroup()) { + rOut << "%defattr("; + rOut << (hasDefMode() ? getDefMode() : "-"); + rOut << "," << (hasDefOwner() ? getDefOwner() : "-"); + rOut << "," << (hasDefGroup() ? getDefGroup() : "-"); + rOut << ")" << endl; + } + for (unsigned int i = 0; i < numFiles(); i++) + getFile(i).toSpecFile(rOut); + } +} + +void XMLFiles::toXMLFile(ostream& rOut) +{ + if (numFiles()) { + rOut << endl << "\t\t"; + for (unsigned int i = 0; i < numFiles(); i++) + getFile(i).toXMLFile(rOut); + rOut << endl << "\t\t"; + } +} Index: xmlspec/XMLFiles.h =================================================================== RCS file: xmlspec/XMLFiles.h diff -N xmlspec/XMLFiles.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLFiles.h 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,526 @@ +#ifndef _H_XMLFILES_ +#define _H_XMLFILES_ + +// standard C++ includes +#include +#include +#include + +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" + +// rpm includes +#include + +// forward class definitions +class XMLPackage; +class XMLFiles; +class XMLSpec; + +using namespace std; + +// +class XMLFile : public XMLBase +{ +// +// object creation static functions +// +public: + /** + * Creates a file object and add it to the correct XMLFiles + * container. + * . + * @param pAttrs The attributes in the XML tag + * @param szPath The file path + * @param pSpec The spec to which these files belong + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + const char* szPath, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default contructor + * . + * @param szMode The file's mode (NULL if default) + * @param szOwner The file's owner (NULL if default) + * @param szGroup The file's group (NULL if default) + * @param szConfig The configuration parameter + * @param szPath The file path + * @return none + **/ + XMLFile(const char* szMode, + const char* szUser, + const char* szGroup, + const char* szConfig, + const char* szPath); + + /** + * Copy constructire + * . + * @param rFile Reference to the object to copy + * @return none + **/ + XMLFile(const XMLFile& rFile); + + /** + * Default destructor + * . + * @param none + * @return none + **/ + ~XMLFile(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param file The file that we wish to copy + * @return a copy of the original + **/ + XMLFile operator=(XMLFile file); + +// +// member functions +// +public: + /** + * Outputs the obkect to an RPM spec file + * . + * @param rOut Reference to the output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Outputs the object to an XML spec file + * . + * @param rOut Reference to the output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member variable get/set functions +// +public: + /** + * Returns the file path + * . + * @param none + * @return string containing the path + **/ + const char* getPath() + { + return m_sPath.c_str(); + } + + /** + * Sets the file path + * . + * @param szPath The path to set + * @return none + **/ + void setPath(const char* szPath) + { + if (szPath) + m_sPath.assign(szPath); + } + + /** + * Checks for a file mode + * . + * @param none + * @return true if we have one, false otherwise + **/ + bool hasMode() + { + return m_sMode.length() ? true : false; + } + + /** + * Returns the file mode + * . + * @param none + * @return the mode string + **/ + const char* getMode() + { + return m_sMode.c_str(); + } + + /** + * Sets the file mode + * . + * @param szMode The mode to set + * @return none + **/ + void setMode(const char* szMode) + { + if (szMode) + m_sMode.assign(szMode); + } + + /** + * Checks if we have a file owner + * . + * @param none + * @return true if we have an owner, false otherwise + **/ + bool hasOwner() + { + return m_sOwner.length() ? true : false; + } + + /** + * Returns the file owner + * . + * @param none + * @return the owner as a string + **/ + const char* getOwner() + { + return m_sOwner.c_str(); + } + + /** + * Sets the file owner + * . + * @param szOwner The file owner + * @return none + **/ + void setOwner(const char* szOwner) + { + if (szOwner) + m_sOwner.assign(szOwner); + } + + /** + * Checks for a file group + * . + * @param none + * @return true if we have a group, false otherwise + **/ + bool hasGroup() + { + return m_sGroup.length() ? true : false; + } + + /** + * Returns the file group + * . + * @param none + * @return string containing the group + **/ + const char* getGroup() + { + return m_sGroup.c_str(); + } + + /** + * Sets the file group + * . + * @param szGroup The group to set + * @return none + **/ + void setGroup(const char* szGroup) + { + if (szGroup) + m_sGroup.assign(szGroup); + } + + /** + * Checks for config directives + * . + * @param none + * @return true if we have one, false otherwise + **/ + bool hasConfig() + { + return m_sConfig.length() ? true : false; + } + + /** + * Returns the config attribute + * . + * @param none + * @return the sttribute string + **/ + const char* getConfig() + { + return m_sConfig.c_str(); + } + + /** + * Sets the config attribute + * . + * @param szConfig The configuration + * @return none + **/ + void setConfig(const char* szConfig) + { + if (szConfig) + m_sConfig.assign(szConfig); + } + +// +// member variables +// +protected: + string m_sPath; + string m_sMode; + string m_sOwner; + string m_sGroup; + string m_sConfig; +}; + +// +class XMLFiles : public XMLBase +{ +// +// object creation static functions +// +public: + /** + * Creates an object as parsed from an XML spec + * . + * @param pAttrs XML atrtributes to use + * @param pSpec The spec to which we are adding this object to + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Creates file objects from an RPM Spec structure + * . + * @param pPackage Pointer to the package + * @param pSpec Pointer to the RPM spec + * @param pXSpec pointer to the XMLSpec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param none + * @return none + **/ + XMLFiles(); + + /** + * Copy constructor + * . + * @param rFiles Reference to the object to copy + * @return none + **/ + XMLFiles(const XMLFiles& rFiles); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLFiles(); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec + * . + * @param rOut Output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param files XMLFiles object to copy + * @return copied object + **/ + XMLFiles operator=(XMLFiles files); + +// +// member variable get/set functions +// +public: + /** + * Adds a file to our file list + * . + * @param rFile File to add + * @return none + **/ + void addFile(XMLFile& rFile) + { + m_vFiles.push_back(rFile); + } + + /** + * Returns the number of files in our list + * . + * @param none + * @return none + **/ + unsigned int numFiles() + { + return m_vFiles.size(); + } + + /** + * Returns a specific file + * . + * @param nNum Number of the file to return + * @return the file object + **/ + XMLFile& getFile(unsigned int nNum) + { + return m_vFiles[nNum]; + } + + /** + * Checks for a default mode + * . + * @param none + * @return true if we have a default mode, false otherwise + **/ + bool hasDefMode() + { + return m_sMode.length() ? true : false; + } + + /** + * Sets the default mode + * . + * @param szMode The mode value + * @return none + **/ + void setDefMode(const char* szMode) + { + if (szMode) + m_sMode.assign(szMode); + } + + /** + * Returns the default mode + * . + * @param none + * @return string containing the mode + **/ + const char* getDefMode() + { + return m_sMode.c_str(); + } + + /** + * Check if we have a default owner + * . + * @param none + * @return true if we have an owner, false otherwise + **/ + bool hasDefOwner() + { + return m_sOwner.length() ? true : false; + } + + /** + * Sets the default owner + * . + * @param szOwner The owner + * @return none + **/ + void setDefOwner(const char* szOwner) + { + if (szOwner) + m_sOwner.assign(szOwner); + } + + /** + * Returns the default owner + * . + * @param none + * @return the owner string + **/ + const char* getDefOwner() + { + return m_sOwner.c_str(); + } + + /** + * Checks if we have a default group + * . + * @param none + * @return true if we have an owner, false otherwise + **/ + bool hasDefGroup() + { + return m_sGroup.length() ? true : false; + } + + /** + * Sets the default group + * . + * @param szGroup The group to set + * @return none + **/ + void setDefGroup(const char* szGroup) + { + if (szGroup) + m_sGroup.assign(szGroup); + } + + /** + * Gets the default group + * . + * @param none + * @return string representation of the group + **/ + const char* getDefGroup() + { + return m_sGroup.c_str(); + } + +// +// member variables +// +protected: + string m_sMode; + string m_sOwner; + string m_sGroup; + vector m_vFiles; +}; + +#endif Index: xmlspec/XMLMacro.cpp =================================================================== RCS file: xmlspec/XMLMacro.cpp diff -N xmlspec/XMLMacro.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMacro.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,61 @@ +// our includes +#include "XMLMacro.h" +#include "XMLSpec.h" + +using namespace std; + +// attribute structure for XMLMacro +structValidAttrs g_paMacroAttrs[] = +{ + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLMacro::parseCreate(XMLAttrs* pAttrs, + const char* szMacro, + XMLSpec* pSpec) +{ + if (!pSpec || !szMacro || !pAttrs->validate(g_paMacroAttrs, (XMLBase*)pAttrs)) + return false; + XMLMacro macro(pAttrs->asString("name"), szMacro); + pSpec->addXMacro(macro); + return true; +} + +XMLMacro::XMLMacro(const char* szName, + const char* szMacro) + : XMLBase() +{ + if (szName) + m_sName.assign(szName); + if (szMacro) + m_sValue.assign(szMacro); +} + +XMLMacro::XMLMacro(const XMLMacro& rMacro) + : XMLBase() +{ + m_sName.assign(rMacro.m_sName); + m_sValue.assign(rMacro.m_sValue); +} + +XMLMacro::~XMLMacro() +{ +} + +XMLMacro XMLMacro::operator=(XMLMacro macro) +{ + m_sName.assign(macro.m_sName); + m_sValue.assign(macro.m_sValue); +} + +void XMLMacro::toSpecFile(ostream& rOut) +{ + rOut << "%define " << getName() << " " << getValue() << endl; +} + +void XMLMacro::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t"; + rOut << getValue() << ""; +} Index: xmlspec/XMLMacro.h =================================================================== RCS file: xmlspec/XMLMacro.h diff -N xmlspec/XMLMacro.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMacro.h 28 Aug 2002 10:52:43 -0000 1.1.1.1.2.1 @@ -0,0 +1,131 @@ +#ifndef _H_XMLMACRO_ +#define _H_XMLMACRO_ + +// standard C++ includes +#include +#include + +// our includes +#include "XMLAttrs.h" + +// forward class definitions +class XMLSpec; + +using namespace std; + +// +class XMLMacro : public XMLBase +{ +// +// factory functions +// +public: + /** + * Creates an XMLMacro object + * . + * @param pAttrs XML tag attributes + * @param szMacro The macro contents + * @param pSpec the spec to add the macro to + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + const char* szMacro, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szName The name of the macro + * @param szMacro The expanded macro + * @return none + **/ + XMLMacro(const char* szName, + const char* szMacro); + + /** + * Copy constructor + * . + * @param rMacro the macro to copy + * @return none + **/ + XMLMacro(const XMLMacro& rMacro); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLMacro(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param macro The macro to copy + * @return our copied object + **/ + XMLMacro operator=(XMLMacro macro); + +// +// member functions +// +public: + /** + * Outputs the macro into an RPM spec + * . + * @param rOut Output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Outputs the macro into an XML spec + * . + * @param rOut Output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member get/set functions +// +public: + /** + * Gets the macro name + * . + * @param none + * @return string containing the macro name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Gets tha macro value + * . + * @param none + * @return string contatining the macro value + **/ + const char* getValue() + { + return m_sValue.c_str(); + } + +// +// member variables +// +protected: + string m_sName; + string m_sValue; +}; + +#endif Index: xmlspec/XMLMirror.cpp =================================================================== RCS file: xmlspec/XMLMirror.cpp diff -N xmlspec/XMLMirror.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMirror.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,78 @@ +// our includes +#include "XMLMirror.h" +#include "XMLSpec.h" + +using namespace std; + +// attribute structure for XMLMirror +structValidAttrs g_paMirrorAttrs[] = +{ + {0x0000, true, false, "path", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "description", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "country", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLMirror::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec, + bool bPatch) +{ + // validate the attributes + if (!pAttrs->validate(g_paMirrorAttrs, (XMLBase*)pSpec)) + return false; + + XMLMirror mirror(pAttrs->asString("path"), + pAttrs->asString("description"), + pAttrs->asString("country")); + if (bPatch && pSpec->numPatches()) + pSpec->lastPatch().addMirror(mirror); + else if (!bPatch && pSpec->numSources()) + pSpec->lastSource().addMirror(mirror); + return true; +} + +XMLMirror::XMLMirror(const char* szPath, + const char* szDescription, + const char* szCountry) : XMLBase() +{ + if (szPath) + m_sPath.assign(szPath); + if (szDescription) + m_sDescription.assign(szDescription); + if (szCountry) + m_sCountry.assign(szCountry); +} + +XMLMirror::XMLMirror(const XMLMirror& rMirror) + : XMLBase() +{ + m_sPath.assign(rMirror.m_sPath); + m_sDescription.assign(rMirror.m_sDescription); + m_sCountry.assign(rMirror.m_sCountry); +} + +XMLMirror::~XMLMirror() +{ +} + +XMLMirror XMLMirror::operator=(XMLMirror mirror) +{ + m_sPath.assign(mirror.m_sPath); + m_sDescription.assign(mirror.m_sDescription); + m_sCountry.assign(mirror.m_sCountry); +} + +void XMLMirror::toSpecFile(ostream& rOut) +{ + rOut << endl << "# mirror: " << getPath(); +} + +void XMLMirror::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t\t"; +} Index: xmlspec/XMLMirror.h =================================================================== RCS file: xmlspec/XMLMirror.h diff -N xmlspec/XMLMirror.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMirror.h 28 Aug 2002 10:52:43 -0000 1.1.1.1.2.1 @@ -0,0 +1,181 @@ +#ifndef _H_XMLMIRROR_ +#define _H_XMLMIRROR_ + +// standard C++ includes +#include +#include +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" + +// forward declaration +class XMLSpec; + +using namespace std; + +// +class XMLMirror : public XMLBase +{ +// +// static object creation functions +// +public: + /** + * static function for creation of an XMLMirror object + * . + * @param pAttrs Pointer to our attribute structure + * @param pSpec Pointer to our spec that is to ultimately + * contain the object + * @param bPatch true if we are handling the mirror for a patch + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec, + bool bPatch = false); + +// +// constructors/destructor +// +public: + /** + * Default constructor for the XMLMirror object + * . + * @param szPath Full path for the mirror + * @param szDescription Full mirror description + * @param szCoutry Country code for the mirror + * @return none + **/ + XMLMirror(const char* szPath, + const char* szDescription, + const char* szCountry); + + /** + * Copy contructor + * . + * @param rMirror Reference to the object to copy + * @return none + **/ + XMLMirror(const XMLMirror& rMirror); + + /** + * Destructor for an XMLMirror object + * . + * @param none + * @return none + **/ + ~XMLMirror(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param mirror The mirror to get the values from + * @return The modified object + **/ + XMLMirror operator=(XMLMirror mirror); + +// +// public member functions +// +public: + /** + * Converts an XMLMirror object to a RPM spec file + * . + * @param rOut File stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts an XMLMirror object to an XML spec file + * . + * @param rOut File stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member variable get/set functions +// +public: + /** + * Checks if we have a path + * . + * @param none + * @return true if we have a path, false otherise + **/ + bool hasPath() + { + return m_sPath.length() ? true : false; + } + + /** + * Returns the path + * . + * @param none + * @return The path strinbg + **/ + const char* getPath() + { + return m_sPath.c_str(); + } + + /** + * Checks if we have a description set + * . + * @param none + * @return true is we have a description, false otherwise + **/ + bool hasDescription() + { + return m_sDescription.length() ? true : false; + } + + /** + * Returns the description + * . + * @param none + * @return the description string + **/ + const char* getDescription() + { + return m_sDescription.c_str(); + } + + /** + * Checks if we have a country set + * . + * @param none + * @return true if we have a country, false otherwise + **/ + bool hasCountry() + { + return m_sCountry.length() ? true : false; + } + + /** + * Gets the country + * . + * @param none + * @return The country string + **/ + const char* getCountry() + { + return m_sCountry.c_str(); + } + +// +// member variables +// +protected: + string m_sPath; + string m_sDescription; + string m_sCountry; +}; + +#endif Index: xmlspec/XMLMisc.cpp =================================================================== RCS file: xmlspec/XMLMisc.cpp diff -N xmlspec/XMLMisc.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMisc.cpp 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,96 @@ +// standard c includes +#include +#include +#include + +using namespace std; + +char* g_szaDays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; +char* g_szaMonths[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; +int g_naLengths[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +char* g_szaBools[] = { "no", "yes", "false", "true", "0", "1", NULL }; + +char* splitStr(const char* szInput, + char cTerm, + int& nLen) +{ + nLen = 0; + while (szInput[nLen] != cTerm && szInput[nLen] != '\0') { + nLen++; + } + char* szTemp = ((char*)szInput)+nLen; + while (*szTemp == cTerm && *szTemp != '\0') + szTemp++; + return szTemp; +} + +int findStr(char* szaMatches[], + const char* szValue, + int nLen = -1) +{ + for (unsigned int i = 0; szaMatches[i] != NULL; i++) { + if (strcmp(szaMatches[i], "*") == 0) + return i; + else if (nLen == -1) { + if (strcasecmp(szaMatches[i], szValue) == 0) + return i; + } + else if (strncasecmp(szaMatches[i], szValue, nLen) == 0) + return i; + } + return -1; +} + +bool isInteger(const char* szValue, + int nLen = -1) +{ + if (nLen == -1) + nLen = strlen(szValue); + for (unsigned int i = 0; i < strlen(szValue); i++) { + if (szValue[i] < '0' || szValue[i] > '9') + return false; + } + return true; +} + +bool isBool(const char* szValue, + int nLen = -1) +{ + return findStr(g_szaBools, szValue, nLen) != -1 ? true : false; +} + +bool isDate(const char* szValue) +{ + int nLen, nPos; + char* szTemp = splitStr(szValue, ' ', nLen); + if ((nPos = findStr(g_szaDays, szValue, nLen)) != -1) { + if ((nPos = findStr(g_szaMonths, szTemp, nLen)) != -1) { + szTemp = splitStr(szTemp, ' ', nLen); + char* szBuffer = new char[nLen+1]; + sprintf(szBuffer, "%s", szTemp); + szBuffer[nLen] = '\0'; + if (atoi(szBuffer) <= g_naLengths[nPos]) { + delete[] szBuffer; + szTemp = splitStr(szTemp, ' ', nLen); + return isInteger(szTemp, nLen); + } + delete[] szBuffer; + } + } + return false; +} + +bool isEmail(const char* szValue) +{ + bool bFound = false; + for (unsigned int j = 0; j < strlen(szValue); j++) { + if (szValue[j] == '@') { + if (bFound) + return false; + else + bFound = true; + } + } + return bFound; +} Index: xmlspec/XMLMisc.h =================================================================== RCS file: xmlspec/XMLMisc.h diff -N xmlspec/XMLMisc.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLMisc.h 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,66 @@ +#ifndef _H_XMLMISC_ +#define _H_XMLMISC_ + +extern char* g_szaDays[]; +extern char* g_szaMonths[]; + +/** + * Splits the input string according to the terminator, returning + * the length and the new search position + * . + * @param szInput The input string + * @param cTerm The terminating character + * @param nLen the length buffer + * @return The next string position + **/ +extern char* splitStr(const char* szInput, + char cTerm, + int& nLen); + +/** + * Finds a string in an array of potential matches + * . + * @param szaMatches The potential matches + * @param szValue The value to search for + * @return The position on success, -1 if not found + **/ +extern int findStr(char* szaMatches[], + const char* szValue, + int nLen = -1); + +/** + * Checks if a string contains an integer + * . + * @param szValue The string to check + * @param nLen The length to check, -1 to end of string + * @return true if the string is an integer, false otherwise + **/ +extern bool isInteger(const char* szValue, + int nLen = -1); + +/** + * Checks if a string contains a boolean value + * . + * @param szValue The value to check + * @return true if we have a boolean, false otherwise + **/ +extern bool isBool(const char* szValue, + int nLen = -1); + +/** + * Checks if a string is in a valid date format + * . + * @param szValue The string to check + * @return true is this is a date, false otherwise + **/ +extern bool isDate(const char* szValue); + +/** + * Checks if a string contains a valid e-mail address + * . + * @param szValue the string to check + * @return true if this is an email address, false otherwise + **/ +extern bool isEmail(const char* szValue); + +#endif Index: xmlspec/XMLPackage.cpp =================================================================== RCS file: xmlspec/XMLPackage.cpp diff -N xmlspec/XMLPackage.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLPackage.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,327 @@ +// standard C++ includes +#include + +// our includes +#include "XMLPackage.h" +#include "XMLRPMWrap.h" +#include "XMLSpec.h" + +// rpm includes +#include + +// attribute structure for XMLPackage +structValidAttrs g_paPackageAttrs[] = +{ + {0x0000, false, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, true, false, "group", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "autoreq", XATTRTYPE_BOOL, {NULL}}, + {0x0003, false, false, "autoprov", XATTRTYPE_BOOL, {NULL}}, + {0x0004, false, false, "autoreqprov", XATTRTYPE_BOOL, {NULL}}, + {0x0005, false, false, "sub", XATTRTYPE_BOOL, {NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLPackage::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + // validate the attributes + if (!pAttrs->validate(g_paPackageAttrs, (XMLBase*)pSpec)) + return false; + + // setup the name attribute + string sName; + if (pAttrs->asString("name")) + sName.assign(pAttrs->asString("name")); + + // if we have a name, cool, now test if the package already exists + if (sName.length()) { + XMLPackage package(sName.c_str(), pAttrs->asString("group"), + pAttrs->asBool("autoreq") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("autoprov") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("sub")); + pSpec->addPackage(package); + } + + // already something existing with %{name} ? + else { + XMLPackage package(NULL, pAttrs->asString("group"), + pAttrs->asBool("autoreq") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("autoprov") || pAttrs->asBool("autoreqprov"), + pAttrs->asBool("sub")); + pSpec->addPackage(package); + } + return true; +} + +bool XMLPackage::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pPackage || !pPackage->header) + return false; + + string sGroup, sName; + if (!getRPMHeader(pPackage->header, RPMTAG_GROUP, sGroup)) + return false; + getRPMHeader(pPackage->header, RPMTAG_NAME, sName); + bool bSub = false; + if (sName.compare(pXSpec->getName()) == 0) { + bSub = true; + } + + XMLPackage package(bSub ? NULL : sName.c_str(), sGroup.c_str(), + pPackage->autoReq ? true : false, + pPackage->autoProv ? true : false, + bSub); + t_StrVector svText; + t_StrVector svLang; + getRPMHeaderArray(pPackage->header, RPMTAG_HEADERI18NTABLE, svLang); + if (getRPMHeaderArray(pPackage->header, RPMTAG_SUMMARY, svText)) { + for (unsigned int i = 0; i < svText.size(); i++) + package.addSummary(svText[i].c_str(), svLang[i].c_str()); + } + if (getRPMHeaderArray(pPackage->header, RPMTAG_DESCRIPTION, svText)) { + for (unsigned int i = 0; i < svText.size(); i++) + package.addDescription(svText[i].c_str(), svLang[i].c_str()); + } + pXSpec->addPackage(package); + + XMLPackageContainer::structCreate(pPackage, pSpec, pXSpec); + XMLFiles::structCreate(pPackage, pSpec, pXSpec); + + // do the next package and return + XMLPackage::structCreate(pPackage->next, pSpec, pXSpec); + return true; +} + +// attribute structure for summaries +structValidAttrs g_paDescriptionAttrs[] = +{ + {0x0000, false, false, "lang", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLPackage::addDescription(XMLAttrs* pAttrs, + const char* szDescription, + XMLSpec* pSpec) +{ + if (pSpec && pAttrs->validate(g_paDescriptionAttrs, (XMLBase*)pSpec)) { + pSpec->lastPackage().addDescription(szDescription, pAttrs->asString("lang")); + return true; + } + else + return false; +} + +// attribute structure for summaries +structValidAttrs g_paSummaryAttrs[] = +{ + {0x0000, false, false, "lang", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLPackage::addSummary(XMLAttrs* pAttrs, + const char* szSummary, + XMLSpec* pSpec) +{ + if (pSpec && pAttrs->validate(g_paSummaryAttrs, (XMLBase*)pSpec)) { + pSpec->lastPackage().addSummary(szSummary, pAttrs->asString("lang")); + return true; + } + else + return false; +} + +XMLPackage::XMLPackage(const char* szName, + const char* szGroup, + bool bAutoReq, + bool bAutoProv, + bool bSub) + : XMLBase() +{ + setName(szName); + setGroup(szGroup); + setSubPackage(bSub); + setAutoRequires(bAutoReq); + setAutoProvides(bAutoProv); +} + +XMLPackage::XMLPackage(const XMLPackage& rPackage) + : XMLBase() +{ + setName(rPackage.m_sName.c_str()); + setGroup(rPackage.m_sGroup.c_str()); + setSubPackage(rPackage.m_bSub); + setAutoRequires(rPackage.m_bAutoReq); + setAutoProvides(rPackage.m_bAutoProv); + m_vSummaries = rPackage.m_vSummaries; + m_vDescriptions = rPackage.m_vDescriptions; + m_Requires = rPackage.m_Requires; + m_BuildRequires = rPackage.m_BuildRequires; + m_Provides = rPackage.m_Provides; + m_Obsoletes = rPackage.m_Obsoletes; + m_Post = rPackage.m_Post; + m_PostUn = rPackage.m_PostUn; + m_Pre = rPackage.m_Pre; + m_PreUn = rPackage.m_PreUn; + m_Verify = rPackage.m_Verify; + m_Files = rPackage.m_Files; +} + +XMLPackage::~XMLPackage() +{ +} + +void XMLPackage::toSpecFile(ostream& rOut) +{ + // top package bit + if (hasName()) { + rOut << endl << "%package"; + rOut << (!isSubPackage() ? " -n " : " ") << getName() << endl; + } + else + rOut << endl << endl; + + for (unsigned int i = 0; i < numSummaries(); i++) { + rOut << "summary"; + if (getSummary(i).hasLang()) + rOut << "(" << getSummary(i).getLang() << "):"; + else + rOut << ": "; + rOut << " " << getSummary(i).getText() << endl; + } + if (hasGroup()) + rOut << "group: " << getGroup() << endl; + if (!hasAutoRequires() && !hasAutoProvides()) + rOut << "autoreqprov: no" << endl; + else { + if (!hasAutoRequires()) + rOut << "autoreq: no" << endl; + if (!hasAutoProvides()) + rOut << "autoprov: no" << endl; + } + + getProvides().toSpecFile(rOut, "provides"); + getObsoletes().toSpecFile(rOut, "obsoletes"); + getRequires().toSpecFile(rOut, "requires"); + getBuildRequires().toSpecFile(rOut, "buildrequires"); + + // add the description + for (unsigned int i = 0; i < numDescriptions(); i++) { + rOut << "%description "; + if (getDescription(i).hasLang()) + rOut << "-l " << getDescription(i).getLang() << " "; + if (hasName()) { + rOut << (!isSubPackage() ? "-n " : ""); + rOut << getName(); + } + rOut << endl << getDescription(i).getText() << endl; + } +} + +void toSectionSpecFile(ostream& rOut, + const char* szSection, + XMLPackage* pPkg) +{ + rOut << endl << "%" << szSection; + if (pPkg->hasName()) + rOut << (!pPkg->isSubPackage() ? " -n " : " ") << pPkg->getName(); + rOut << endl; +} + +void XMLPackage::toScriptsSpecFile(ostream& rOut) +{ + if (getPre().numScripts()) { + toSectionSpecFile(rOut, "pre", this); + getPre().toSpecFile(rOut, "pre"); + } + + if (getPost().numScripts()) { + toSectionSpecFile(rOut, "post", this); + getPost().toSpecFile(rOut, "post"); + } + + if (getPreUn().numScripts()) { + toSectionSpecFile(rOut, "preun", this); + getPreUn().toSpecFile(rOut, "preun"); + } + + if (getPostUn().numScripts()) { + toSectionSpecFile(rOut, "postun", this); + getPostUn().toSpecFile(rOut, "postun"); + } + + if (getVerify().numScripts()) { + toSectionSpecFile(rOut, "verifyscript", this); + getVerify().toSpecFile(rOut, "verifyscript"); + } +} + +void XMLPackage::toFilesSpecFile(ostream& rOut) +{ + rOut << endl << "%files"; + if (hasName()) + rOut << (!isSubPackage() ? " -n " : " ") << getName(); + rOut << endl; + getFiles().toSpecFile(rOut); +} + +void XMLPackage::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t"; + + for (unsigned int i = 0; i < numSummaries(); i++) { + rOut << endl << "\t\t" << getSummary(i).getText() << ""; + } + for (unsigned int i = 0; i < numDescriptions(); i++) { + rOut << endl << "\t\t" << getDescription(i).getText() << ""; + } + + getProvides().toXMLFile(rOut, "provides"); + getObsoletes().toXMLFile(rOut, "obsoletes"); + getRequires().toXMLFile(rOut, "requires"); + getBuildRequires().toXMLFile(rOut, "buildrequires"); + + getPre().toXMLFile(rOut, "pre"); + getPost().toXMLFile(rOut, "post"); + getPreUn().toXMLFile(rOut, "preun"); + getPostUn().toXMLFile(rOut, "postun"); + getVerify().toXMLFile(rOut, "verify"); + + getFiles().toXMLFile(rOut); + + rOut << endl << "\t"; +} + +void XMLPackage::toRPMStruct(Spec spec) +{ + //Package pkg = newPackage(spec); + //if (!hasName() && pkg == spec->packages) + // fillOutMainPackage(pkg->header); + //else if (pkg != spec->packages) + // headerCopyTags(spec->packages->header, + // pkg->header, + // (int_32 *)copyTagsDuringParse); +} Index: xmlspec/XMLPackage.h =================================================================== RCS file: xmlspec/XMLPackage.h diff -N xmlspec/XMLPackage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLPackage.h 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,507 @@ +#ifndef _H_XMLPACKAGE_ +#define _H_XMLPACKAGE_ + +// standard C++ includes +#include +#include +#include + +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" +#include "XMLFiles.h" +#include "XMLRequires.h" +#include "XMLScript.h" +#include "XMLText.h" + +// rpm includes +#include + +// forward class declarations +class XMLSpec; + +using namespace std; + +class XMLPackage : public XMLBase +{ +// +// factory functions +// +public: + /** + * Creates an object as parsed from an XML spec + * . + * @param pAttrs XML atrtributes to use + * @param pSpec The spec to which we are adding this object to + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Creates package objects from an RPM Spec structure + * . + * @param pPackage Pointer to the start package + * @param pSpec pointer to the RPM spec + * @param pXSpec Pointer to the spec object to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + + /** + * Adds a description for the last package + * . + * @param pAttrs The attributes + * @param szDescription the description + * @param pSpec The spec containing the package + * @return true on success, false otherwise + **/ + static bool addDescription(XMLAttrs* pAttrs, + const char* szDescription, + XMLSpec* pSpec); + + /** + * Adds the summary for the last added package + * . + * @param pAttrs The attributes + * @param szSummary The summary to set + * @param pSpec The spec contraining the package + * @return trus on success, false otherwise + **/ + static bool addSummary(XMLAttrs* pAttrs, + const char* szSummary, + XMLSpec* pSpec); + +// +// constructors/destructors +// +public: + /** + * Default constructor + * . + * @param szName The package name + * @param szGroup The group this package belongs to + * @param bAutoReq Auto Requires + * @param bAutoProv Auto Provides + * @param bSub true if this is a sub-package + * @return none + **/ + XMLPackage(const char* szName, + const char* szGroup, + bool bAutoReq, + bool bAutoProv, + bool bSub); + + /** + * Copy constructor + * . + * @param rPackage The package to copy from + * @return none + **/ + XMLPackage(const XMLPackage& rPackage); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLPackage(); + +// +// public member functions +// +public: + /** + * Converts the object to a spec file + * . + * @param rOut Output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the scripts part of the object to a spec + * . + * @param rOut Output stream + * @return none + **/ + void toScriptsSpecFile(ostream& rOut); + + /** + * Converts the files part of the object to a spec + * . + * @param rOut Output stream + * @return none + **/ + void toFilesSpecFile(ostream& rOut); + + /** + * Converts the object to an XML spec + * . + * @param rOut The output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + + /** + * Converts the object to an RPM structure + * . + * @param Spec The main Spec object + * @param none + **/ + void toRPMStruct(Spec spec); + +// +// member variable get/set functions +// +public: + /** + * Checks of we have a package name + * . + * @param none + * @return true if we have a name, false otherwise + **/ + bool hasName() + { + return m_sName.length() ? true : false; + } + + /** + * Gets the package name + * . + * @param none + * @return string containing the package name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Sets the package name + * . + * @param szName The name to set + * @return none + **/ + void setName(const char* szName) + { + if (szName) + m_sName.assign(szName); + } + + /** + * Checks if we have a group + * . + * @param none + * @return true if we have a group, false otherwise + **/ + bool hasGroup() + { + return m_sGroup.length() ? true : false; + } + + /** + * Returns the group + * . + * @param none + * @return string containing the group + **/ + const char* getGroup() + { + return m_sGroup.c_str(); + } + + /** + * Sets the group + * . + * @param szGroup The group to set + * @return none + **/ + void setGroup(const char* szGroup) + { + if (szGroup) + m_sGroup.assign(szGroup); + } + + /** + * Tests if we are a sub-package + * . + * @param none + * @return true if this is a sub-package + **/ + bool isSubPackage() + { + return m_bSub; + } + + /** + * Sets the sub-package status + * . + * @param bSub The sub-package status + * @return none + **/ + void setSubPackage(bool bSub) + { + m_bSub = bSub; + } + + /** + * Tests for auto requires + * . + * @param none + * @return true if we have auto requires, false otherwise + **/ + bool hasAutoRequires() + { + return m_bAutoReq; + } + + /** + * Sets the auto requires state + * . + * @param bAutoReq The auto requires state + * @return none + **/ + void setAutoRequires(bool bAutoReq) + { + m_bAutoReq = bAutoReq; + } + + /** + * Tests for auto requires + * . + * @param none + * @return true if we have auto requires, false otherwise + **/ + bool hasAutoProvides() + { + return m_bAutoProv; + } + + /** + * Sets the auto provides status + * . + * @param bAutoProv The auto provides status + * @return none + **/ + void setAutoProvides(bool bAutoProv) + { + m_bAutoProv = bAutoProv; + } + + /** + * Gets the number of summaries + * . + * @param none + * @return the number of summaries + **/ + unsigned int numSummaries() + { + return m_vSummaries.size(); + } + + /** + * Gets a summary + * . + * @param nNum The number to get + * @return the summary + **/ + XMLText& getSummary(unsigned int nNum) + { + return m_vSummaries[nNum]; + } + + /** + * Adds a summary + * . + * @param szSummary the summary + * @param szLang the language + * @return none + **/ + void addSummary(const char* szSummary, + const char* szLang = NULL) + { + if (szSummary && strlen(szSummary)) { + XMLText summary(szSummary, szLang); + m_vSummaries.push_back(summary); + } + } + + /** + * Gets the number of descriptions + * . + * @param none + * @return the number in our list + **/ + unsigned int numDescriptions() + { + return m_vDescriptions.size(); + } + + /** + * Get a description + * . + * @param nNum The description to get + * @return Reference to XMLText object + **/ + XMLText& getDescription(unsigned int nNum) + { + return m_vDescriptions[nNum]; + } + + /** + * Adds a description + * . + * @param szDescription The description string + * @param szLang The language + * @return nonew + **/ + void addDescription(const char* szDescription, + const char* szLang = NULL) + { + if (szDescription && strlen(szDescription)) { + XMLText description(szDescription, szLang); + m_vDescriptions.push_back(description); + } + } + + /** + * Gets the provides + * . + * @param none + * @return reference to the provides + **/ + XMLPackageContainer& getProvides() + { + return m_Provides; + } + + /** + * Gets the package requires + * . + * @param none + * @return reference to the requires + **/ + XMLPackageContainer& getRequires() + { + return m_Requires; + } + + /** + * Get the buildrequires + * . + * @param none + * @return reference to the buildrequires + **/ + XMLPackageContainer& getBuildRequires() + { + return m_BuildRequires; + } + + /** + * Gets the obsoletes + * . + * @param none + * @return reference to the obsoletes + **/ + XMLPackageContainer& getObsoletes() + { + return m_Obsoletes; + } + + /** + * Gets the files + * . + * @param none + * @return reference to the files + **/ + XMLFiles& getFiles() + { + return m_Files; + } + + /** + * Gets the pre section + * . + * @param none + * @return reference to the pre section + **/ + XMLPackageScripts& getPre() + { + return m_Pre; + } + + /** + * Gets the post section + * . + * @param none + * @return reference to the post section + **/ + XMLPackageScripts& getPost() + { + return m_Post; + } + + /** + * Gets the preun section + * . + * @param none + * @return reference to the preun section + **/ + XMLPackageScripts& getPreUn() + { + return m_PreUn; + } + + /** + * Gets the postun section + * . + * @param none + * @return reference to the postun section + **/ + XMLPackageScripts& getPostUn() + { + return m_PostUn; + } + + /** + * Gets the verify section + * . + * @param none + * @return reference to the verify section + **/ + XMLPackageScripts& getVerify() + { + return m_Verify; + } + +// +// member variables +// +protected: + string m_sName; + string m_sGroup; + bool m_bSub; + bool m_bAutoReq; + bool m_bAutoProv; + vector m_vSummaries; + vector m_vDescriptions; + XMLPackageContainer m_Requires; + XMLPackageContainer m_BuildRequires; + XMLPackageContainer m_Provides; + XMLPackageContainer m_Obsoletes; + XMLPackageScripts m_Pre; + XMLPackageScripts m_PreUn; + XMLPackageScripts m_Post; + XMLPackageScripts m_PostUn; + XMLPackageScripts m_Verify; + XMLFiles m_Files; +}; + +#endif Index: xmlspec/XMLParser.cpp =================================================================== RCS file: xmlspec/XMLParser.cpp diff -N xmlspec/XMLParser.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLParser.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,982 @@ +// standard library includes +#include +#include +#include + +// standard C++ includes +#include +#include + +// 3rd party library includes +#include + +// our includes +#include "XMLSpec.h" + +// this is the maximum tree dept we will require as +// well as the number of scructures a specific tag can +// occur in +#define XML_MAX_TREE_DEPTH 5 +#define XML_MAX_PRE_TAGS 10 + +using namespace std; + +// these define the error values +enum eXMLErr +{ + XMLERR_WARNING = 0x0000, + XMLERR_ERROR, + XMLERR_FATAL +}; + +// this defines the structure that we are using in the callback +// containing all the parse-specific data we might need. +struct structCBData +{ + XML_Parser* m_pParser; + string m_sFilename; + int m_nWarnings; + int m_nErrors; + int m_nDepth; + unsigned int m_pnTree[XML_MAX_TREE_DEPTH]; + string m_sData; + XMLSpec* m_pSpec; + XMLAttrs* m_pAttrs; +}; + +// enumeration of all XML tags that are recognised +enum enumXMLTAGValid +{ + XTAG_NO = 0x0000, + XTAG_WRONGSTRUCT, + XTAG_SPEC, + XTAG_EXCLUDEARCH, + XTAG_EXCLUDEOS, + XTAG_EXCLUSIVEARCH, + XTAG_EXCLUSIVEOS, + XTAG_SOURCE, + XTAG_PATCH, + XTAG_NOSOURCE, + XTAG_MIRROR, + XTAG_PACKAGE, + XTAG_SUMMARY, + XTAG_DESC, + XTAG_REQS, + XTAG_BREQS, + XTAG_PROVS, + XTAG_OBSOLS, + XTAG_FILES, + XTAG_FILE, + XTAG_MACRO, + XTAG_PREP, + XTAG_SETUP, + XTAG_BUILD, + XTAG_INSTALL, + XTAG_CLEAN, + XTAG_PRE, + XTAG_POST, + XTAG_PREUN, + XTAG_POSTUN, + XTAG_VERIFY, + XTAG_SCRIPT, + XTAG_CHANGELOG, + XTAG_CHANGES, + XTAG_CHANGE, + XTAG_ANY = 0xFFFF // this always needs to be the last entry +}; + +// this is a structure to match tags to their values +struct structXMLMatch +{ + unsigned int m_nVal; + int m_pnDepth[XML_MAX_TREE_DEPTH+1]; + unsigned int m_pnFollows[XML_MAX_PRE_TAGS+1]; + char* m_szName; +}; + +// this allows for the matching of all tags +structXMLMatch g_pMatches[] = +{ + { + XTAG_SPEC, { 0, -1, -1}, { + XTAG_ANY, + XTAG_NO + }, + "spec" + }, + { + XTAG_PACKAGE, { 1, 3, -1}, { + XTAG_SPEC, + XTAG_REQS, + XTAG_BREQS, + XTAG_PROVS, + XTAG_OBSOLS, + XTAG_NO + }, + "package" + }, + { + XTAG_SOURCE, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "source" + }, + { + XTAG_PATCH, { 1, 2, -1}, { + XTAG_SPEC, + XTAG_PREP, + XTAG_NO + }, + "patch" + }, + { + XTAG_NOSOURCE, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "nosource" + }, + { + XTAG_MIRROR, { 2, -1, -1}, { + XTAG_SOURCE, + XTAG_NO + }, + "mirror" + }, + { + XTAG_SUMMARY, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "summary" + }, + { + XTAG_DESC, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "description" + }, + { + XTAG_REQS, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "requires" + }, + { + XTAG_BREQS, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "buildrequires" + }, + { + XTAG_PROVS, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "provides" + }, + { + XTAG_OBSOLS, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "obsoletes" + }, + { + XTAG_FILES, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "files" + }, + { + XTAG_FILE, { 3, -1, -1}, { + XTAG_FILES, + XTAG_NO + }, + "file" + }, + { + XTAG_MACRO, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "macro" + }, + { + XTAG_PREP, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "prep" + }, + { + XTAG_SETUP, { 2, -1, -1}, { + XTAG_PREP, + XTAG_NO + }, + "setup" + }, + { + XTAG_BUILD, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "build" + }, + { + XTAG_INSTALL, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "install" + }, + { + XTAG_CLEAN, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "clean" + }, + { + XTAG_PRE, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "pre" + }, + { + XTAG_POST, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "post" + }, + { + XTAG_PREUN, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "preun" + }, + { + XTAG_POSTUN, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "postun" + }, + { + XTAG_VERIFY, { 2, -1, -1}, { + XTAG_PACKAGE, + XTAG_NO + }, + "verify" + }, + { + XTAG_SCRIPT, { 2, 3, -1}, { + XTAG_PREP, + XTAG_BUILD, + XTAG_INSTALL, + XTAG_CLEAN, + XTAG_PRE, + XTAG_POST, + XTAG_PREUN, + XTAG_POSTUN, + XTAG_VERIFY, + XTAG_NO + }, + "script" + }, + { + XTAG_CHANGELOG, { 1, -1, -1}, { + XTAG_SPEC, + XTAG_NO + }, + "changelog" + }, + { + XTAG_CHANGES, { 2, -1, -1}, { + XTAG_CHANGELOG, + XTAG_NO + }, + "changes" + }, + { + XTAG_CHANGE, { 3, -1, -1}, { + XTAG_CHANGES, + XTAG_NO + }, + "change" + }, + // this always needs to be the last entry + { + XTAG_NO, {-1, -1, -1}, { + XTAG_NO + }, + "none" + } +}; + +const char* treeToString(unsigned int* pnTree, + int nDepth) +{ + // internal string storage + string sTree; + + // build the tree to the specified depth + for (int i = 0; i < nDepth; i++) { + int j = 0; + while (g_pMatches[j].m_nVal != pnTree[i]) + j++; + sTree += string("<") + string(g_pMatches[j].m_szName) + string(">"); + } + + // return the tree string + return sTree.c_str(); +} + +unsigned int getTagValue(const char* szElement, + int nDepth, + unsigned int nPrev) +{ + // first convert the tag to a tag value + unsigned int nTagVal = XTAG_NO; + + // loop through all matches to see if we have a valid + // tag here + int i = 0; + do { + // test if we have a match + if (strcasecmp(g_pMatches[i].m_szName, szElement) == 0) { + // look for a match on the tree depth + int j = 0; + nTagVal = XTAG_WRONGSTRUCT; + while (g_pMatches[i].m_pnDepth[j] != -1) { + if (g_pMatches[i].m_pnDepth[j++] == nDepth) { + j = 0; + do { + if (g_pMatches[i].m_pnFollows[j] == nPrev) { + nTagVal = g_pMatches[i].m_nVal; + break; + } + } while (g_pMatches[i].m_pnFollows[++j] != XTAG_NO); + break; + } + } + // break out + break; + } + } while (g_pMatches[++i].m_nVal != XTAG_NO); + + // return + return nTagVal; +} + +void createError(int nErrType, + structCBData* pData, + const char* szFormat, ...) +{ + // one more error/warning + nErrType == XMLERR_WARNING ? pData->m_nWarnings++ : pData->m_nErrors++; + + // setup internal variables + FILE* fOut = stderr; + switch (nErrType) { + case XMLERR_WARNING: + fOut = stdout; + fprintf(fOut, "%s(%d): warning: ", pData->m_sFilename.c_str(), + XML_GetCurrentLineNumber(*(pData->m_pParser))); + break; + case XMLERR_ERROR: + fprintf(fOut, "%s(%d): error: ", pData->m_sFilename.c_str(), + XML_GetCurrentLineNumber(*(pData->m_pParser))); + break; + case XMLERR_FATAL: + fprintf(fOut, "%s(%d): fatal: ", pData->m_sFilename.c_str(), + XML_GetCurrentLineNumber(*(pData->m_pParser))); + break; + default: + return; + } + + // create the argument list and print + va_list vaArgList; + va_start(vaArgList, szFormat); + vfprintf(fOut, szFormat, vaArgList); + fprintf(fOut, "\n"); +} + +void startDepth0(structCBData* pData) +{ + // this indicates a spec start + if (pData->m_pnTree[0] == XTAG_SPEC) { + // if we have a spec already, we are in trouble + if (pData->m_pSpec) + createError(XMLERR_ERROR, pData, "Extra 'spec' tag found."); + else if (!(pData->m_pSpec = XMLSpec::parseCreate(pData->m_pAttrs, + pData->m_sFilename.c_str()))) + createError(XMLERR_ERROR, pData, + "Failed to parse 'spec' tag (%s).", + pData->m_pAttrs->getError()); + else if (pData->m_pAttrs->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pAttrs->getWarning()); + } +} + +void startDepth1(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // hanlde tag + switch (pData->m_pnTree[1]) { + case XTAG_PACKAGE: + if (!XMLPackage::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'package' tag or package already exists (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_SOURCE: + if (!XMLSource::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'source' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_PATCH: + if (!XMLPatch::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'patch' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_NOSOURCE: + if (!XMLNoSource::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'nosource' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_CHANGELOG: + case XTAG_PREP: + case XTAG_BUILD: + case XTAG_INSTALL: + case XTAG_CLEAN: + default: + break; + } +} + +void startDepth2(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // handle tag + switch (pData->m_pnTree[2]) { + case XTAG_MIRROR: + switch (pData->m_pnTree[1]) { + case XTAG_SOURCE: + if (!XMLMirror::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'mirror' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_PATCH: + if (!XMLMirror::parseCreate(pData->m_pAttrs, pData->m_pSpec, true)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'mirror' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + } + break; + case XTAG_FILES: + if (!XMLFiles::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'change' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_CHANGES: + if (!XMLChangelogDate::parseCreate(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'change' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_PRE: + if (!XMLPackageScripts::createPreScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_POST: + if (!XMLPackageScripts::createPostScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_PREUN: + if (!XMLPackageScripts::createPreUnScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_POSTUN: + if (!XMLPackageScripts::createPostUnScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_VERIFY: + if (!XMLPackageScripts::createVerifyScripts(pData->m_pAttrs, pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'pre' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_REQS: + case XTAG_BREQS: + case XTAG_PROVS: + case XTAG_OBSOLS: + default: + break; + } +} + +void startDepth3(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // handle tag + switch (pData->m_pnTree[3]) { + case XTAG_PACKAGE: + switch (pData->m_pnTree[2]) { + case XTAG_REQS: + if (!XMLPackageContainer::addRequire(pData->m_pAttrs, + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'package' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_BREQS: + if (!XMLPackageContainer::addBuildRequire(pData->m_pAttrs, + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'package' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_PROVS: + if (!XMLPackageContainer::addProvide(pData->m_pAttrs, + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'package' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_OBSOLS: + if (!XMLPackageContainer::addObsolete(pData->m_pAttrs, + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'package' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + default: + break; + } + break; + default: + break; + } +} + +void startElementCB(void* pCBData, + const char* szElement, + const char** szAttr) +{ + // get the data structure we are working with and + structCBData* pData = (structCBData*)pCBData; + + // validate and get the tag we are working with + unsigned int nTag = getTagValue(szElement, + pData->m_nDepth, + pData->m_nDepth ? pData->m_pnTree[pData->m_nDepth-1] : XTAG_ANY); + + if (nTag == XTAG_NO || nTag == XTAG_WRONGSTRUCT) + return createError(XMLERR_WARNING, pData, "Unexpected tag '%s' in structure '%s'.", + szElement, + treeToString(pData->m_pnTree, pData->m_nDepth++)); + pData->m_pnTree[pData->m_nDepth] = nTag; + pData->m_sData.assign(""); + + if (pData->m_pAttrs) + delete pData->m_pAttrs; + pData->m_pAttrs = new XMLAttrs(szAttr); + + switch (pData->m_nDepth++) { + case 0: + startDepth0(pData); + break; + case 1: + startDepth1(pData); + break; + case 2: + startDepth2(pData); + break; + case 3: + startDepth3(pData); + break; + default: + break; + } +} + +void endDepth1(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // handle tag + switch (pData->m_pnTree[1]) { + case XTAG_MACRO: + if (!XMLMacro::parseCreate(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add macro entry (%s).", + pData->m_pAttrs->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + default: + break; + } +} + +void endDepth2(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // do the tag + switch (pData->m_pnTree[2]) { + case XTAG_SUMMARY: + if (!XMLPackage::addSummary(pData->m_pAttrs, pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add 'summary'."); + break; + case XTAG_DESC: + if (!XMLPackage::addDescription(pData->m_pAttrs, pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add 'description'."); + break; + case XTAG_SCRIPT: + switch (pData->m_pnTree[1]) { + case XTAG_PREP: + if (!XMLScripts::addPrepScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add shell entry."); + break; + case XTAG_BUILD: + if (!XMLScripts::addBuildScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add shell entry."); + break; + case XTAG_INSTALL: + if (!XMLScripts::addInstallScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add shell entry."); + break; + case XTAG_CLEAN: + if (!XMLScripts::addCleanScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add shell entry."); + break; + default: + break; + } + break; + default: + break; + } +} + +void endDepth3(structCBData* pData) +{ + // make sure we have a spec + if (!pData->m_pSpec) { + createError(XMLERR_ERROR, pData, "Spec has not been defined."); + return; + } + + // handle tag + switch (pData->m_pnTree[3]) { + case XTAG_CHANGE: + if (!XMLChangelogEntry::parseCreate(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to add changelog entry."); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_FILE: + if (!XMLFile::parseCreate(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, "Failed to parse 'file' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, pData->m_pSpec->getWarning()); + break; + case XTAG_SCRIPT: + switch (pData->m_pnTree[2]) { + case XTAG_PRE: + if (!XMLPackageScripts::addPreScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'script' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_POST: + if (!XMLPackageScripts::addPostScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'script' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_PREUN: + if (!XMLPackageScripts::addPreUnScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'script' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_POSTUN: + if (!XMLPackageScripts::addPostUnScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'script' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + case XTAG_VERIFY: + if (!XMLPackageScripts::addVerifyScript(pData->m_pAttrs, + pData->m_sData.c_str(), + pData->m_pSpec)) + createError(XMLERR_ERROR, pData, + "Failed to parse 'script' tag (%s).", + pData->m_pSpec->getError()); + else if (pData->m_pSpec->hasWarning()) + createError(XMLERR_WARNING, pData, + pData->m_pSpec->getWarning()); + break; + default: + break; + } + break; + default: + break; + } +} + +void endElementCB(void* pCBData, + const char* szElement) +{ + // get the data structure we are working with + structCBData* pData = (structCBData*)pCBData; + pData->m_nDepth--; + + // validate and get the tag we are working with + unsigned int nTag = getTagValue(szElement, + pData->m_nDepth, + pData->m_nDepth ? pData->m_pnTree[pData->m_nDepth-1] : XTAG_ANY); + if (nTag == XTAG_NO || nTag == XTAG_WRONGSTRUCT) + return; + + // handle the tree depth + switch (pData->m_nDepth) { + case 0: + break; + case 1: + endDepth1(pData); + break; + case 2: + endDepth2(pData); + break; + case 3: + endDepth3(pData); + break; + default: + break; + } + + // clean up + pData->m_sData.assign(""); +} + +void characterCB(void* pCBData, + const char* szStr, + int nLen) +{ + // get the data structure we are working with + structCBData* pData = (structCBData*)pCBData; + + // append the string to our internal data + if (nLen) { + char* szTmp = new char[nLen+1]; + strncpy(szTmp, szStr, nLen); + szTmp[nLen] = '\0'; + pData->m_sData.append(szTmp); + delete[] szTmp; + } +} + +int parseXMLSpec(const char* szXMLFilename, + XMLSpec*& pSpec) +{ + // create and setup our parser for use + printf("Creating XML parser instance ... "); + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + printf("Failed.\n\tERROR: Couldn't allocate memory for parser\n\n"); + return -1; + } + else + printf("Ok.\n"); + XML_SetElementHandler(parser, startElementCB, endElementCB); + XML_SetCharacterDataHandler(parser, characterCB); + structCBData stData; + stData.m_pParser = &parser; + stData.m_sFilename.assign(szXMLFilename); + stData.m_nWarnings = 0; + stData.m_nErrors = 0; + stData.m_nDepth = 0; + stData.m_pSpec = NULL; + stData.m_pAttrs = NULL; + XML_SetUserData(parser, (void*)&stData); + + // open the input and output files here + printf("Opening input XML spec ... "); + ifstream fIn(szXMLFilename); + if (!fIn.is_open()) { + printf("Failed.\n\tERROR: Could not open %s\n\n", szXMLFilename); + return -2; + } + else + printf("Ok.\n"); + + // parse our configuration (loop through file, + // doing a break if needed (fatal error)) + printf("Parsing %s: \n", szXMLFilename); + char szBuff[1024+1]; + unsigned int nLength = 0; + while (!fIn.eof()) { + fIn.get(szBuff, 1024, '\0'); + unsigned int nRead = strlen(szBuff); + nLength += nRead; + if (!XML_Parse(parser, szBuff, nRead, fIn.eof() ? 1 : 0)) { + createError(XMLERR_FATAL, &stData, "XML parsing: %s", + XML_ErrorString(XML_GetErrorCode(parser))); + break; + } + } + + // print the end results + printf("\t%d bytes parsed, %d errors(s), %d warnings(s)\n", + nLength, stData.m_nErrors, stData.m_nWarnings); + printf("Closing input XML spec ... "); + fIn.close(); + printf("Ok.\n"); + + // clean up + if (stData.m_nErrors) { + if (stData.m_pSpec != NULL) + delete stData.m_pSpec; + pSpec = NULL; + } + else + pSpec = stData.m_pSpec; + + // return number of errors + return stData.m_nErrors; +} Index: xmlspec/XMLParser.h =================================================================== RCS file: xmlspec/XMLParser.h diff -N xmlspec/XMLParser.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLParser.h 28 Aug 2002 10:52:43 -0000 1.1.1.1.2.1 @@ -0,0 +1,19 @@ +#ifndef _H_XMLPARSER_ +#define _H_XMLPARSER_ + +// our includes +#include "XMLSpec.h" + +/** + * Parses an XML spec into the internal data structures as + * defined in the XML* classes. + * . + * @param szXMLFilename The Spec to read as parser input + * @param pSpec A reference to the spec data structure we + * are to fill. + * @return The number of parsing/other errors (0 == success) + **/ +extern int parseXMLSpec(const char* szXMLFilename, + XMLSpec*& pSpec); + +#endif Index: xmlspec/XMLRPMWrap.cpp =================================================================== RCS file: xmlspec/XMLRPMWrap.cpp diff -N xmlspec/XMLRPMWrap.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLRPMWrap.cpp 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,72 @@ +// standard c++ includes +#include +#include + +// rpm includes +#include +#include + +// type definitions +typedef vector t_StrVector; + +using namespace std; + +bool getRPMHeader(Header header, + int_32 nTag, + string& rResult) +{ + if (headerIsEntry(header, nTag)) { + int_32 nCount, nTagType; + void* pBuffer; + if (!headerGetEntry(header, nTag, &nTagType, &pBuffer, &nCount)) + return false; + char szTemp[32]; + switch (nTagType) { + case RPM_INT32_TYPE: + sprintf(szTemp, "%d", *((int_32*)pBuffer)); + rResult.assign(szTemp); + default: + rResult.assign((char*)pBuffer); + break; + } + headerFreeData(pBuffer, (rpmTagType_e)nTagType); + return true; + } + else + return false; +} + +bool getRPMHeaderArray(Header header, + int_32 nTag, + t_StrVector& rvResult) +{ + rvResult.clear(); + if (headerIsEntry(header, nTag)) { + int_32 nCount, nTagType; + void* pBuffer; + if (!headerGetEntry(header, nTag, &nTagType, &pBuffer, &nCount)) + return false; + if (nTagType == RPM_STRING_ARRAY_TYPE || nTagType == RPM_I18NSTRING_TYPE) { + for (int_32 i = 0; i < nCount; i++) + rvResult.push_back(((char**)pBuffer)[i]); + } + else + rvResult.push_back((char*)pBuffer); + headerFreeData(pBuffer, (rpmTagType_e)nTagType); + return true; + } + else + return false; +} + +bool getRPMMacro(const char* szMacro, + string& rResult) +{ + char* szValue = rpmExpand(szMacro, NULL); + if (szValue) { + rResult.assign(szValue); + return true; + } + else + return false; +} Index: xmlspec/XMLRPMWrap.h =================================================================== RCS file: xmlspec/XMLRPMWrap.h diff -N xmlspec/XMLRPMWrap.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLRPMWrap.h 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,49 @@ +#ifndef _H_XMLRPMWRAP_ +#define _H_XMLRPMWRAP_ + +// standard C++ includes +#include +#include + +// rpm includes +#include + +// type definitions +typedef vector t_StrVector; + +/** + * Gets an RPM header after checking that is does exist. + * . + * @param header The RPM header to interrogate + * @param nTag The header tag to extract + * @param rResult The string to populate with the result + * @return true on success, false otherwise + **/ +extern bool getRPMHeader(Header header, + int_32 nTag, + std::string& rResult); + +/** + * Gets an RPM header array into a vector after checking that it + * does indeed exist + * . + * @param header The RPM header to interrogate + * @param nTag The header tag to extract + * @param rvResult The vector to populate with the result + * @return true on success, false otherwise + **/ +extern bool getRPMHeaderArray(Header header, + int_32 nTag, + t_StrVector& rvResult); + +/** + * Gets a specific RPM macro + * . + * @param szMacro The macro to get the value of + * @param rResult The string to populate with the result + * @return true on success, false otherwise + **/ +extern bool getRPMMacro(const char* szMacro, + std::string& rResult); + +#endif Index: xmlspec/XMLRequires.cpp =================================================================== RCS file: xmlspec/XMLRequires.cpp diff -N xmlspec/XMLRequires.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLRequires.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,189 @@ +// our includes +#include "XMLAttrs.h" +#include "XMLPackage.h" +#include "XMLRequires.h" +#include "XMLRPMWrap.h" +#include "XMLSpec.h" + +// rpm includes +#include + +using namespace std; + +// attribute structure for XMLPackageEntry +structValidAttrs g_paEntryAttrs[] = +{ + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, false, false, "cmp", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLPackageEntry::parseCreate(XMLAttrs* pAttrs, + XMLPackageContainer& rContainer) +{ + // validate the attributes + if (!pAttrs->validate(g_paEntryAttrs, (XMLBase*)pAttrs)) + return false; + + // create and return + XMLPackageEntry entry(pAttrs->asString("name"), pAttrs->asString("version"), + pAttrs->asString("cmp")); + rContainer.addEntry(entry); + return true; +} + +XMLPackageEntry::XMLPackageEntry(const char* szName, + const char* szVersion, + const char* szCmp) + : XMLBase() +{ + if (szName) + m_sName.assign(szName); + if (szVersion) + m_sVersion.assign(szVersion); + m_sCmp.assign("="); + if (szCmp) { + if (strcasecmp(szCmp, "lt") == 0) + m_sCmp.assign("<"); + else if (strcasecmp(szCmp, "le") == 0) + m_sCmp.assign("<="); + else if (strcasecmp(szCmp, "gt") == 0) + m_sCmp.assign(">"); + else if (strcasecmp(szCmp, "ge") == 0) + m_sCmp.assign(">="); + } +} + +XMLPackageEntry::XMLPackageEntry(const XMLPackageEntry& rEntry) + : XMLBase() +{ + m_sName.assign(rEntry.m_sName); + m_sVersion.assign(rEntry.m_sVersion); + m_sCmp.assign(rEntry.m_sCmp); +} + +XMLPackageEntry::~XMLPackageEntry() +{ +} + +XMLPackageEntry XMLPackageEntry::operator=(XMLPackageEntry entry) +{ + m_sName.assign(entry.m_sName); + m_sVersion.assign(entry.m_sVersion); + m_sCmp.assign(entry.m_sCmp); + return *this; +} + +void XMLPackageEntry::toSpecFile(ostream& rOut) +{ + rOut << getName(); + if (hasVersion()) { + rOut << " " << getCompare() << " " << getVersion(); + } +} + +void XMLPackageEntry::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t\t\t") == 0) + rOut << " cmp=\"gt\""; + else if (m_sCmp.compare(">=") == 0) + rOut << " cmp=\"ge\""; + rOut << " version=\"" << getVersion() << "\""; + } + rOut << " />"; +} + +XMLPackageContainer::XMLPackageContainer() + : XMLBase() +{ +} + +XMLPackageContainer::XMLPackageContainer(const XMLPackageContainer& rContainer) + : XMLBase() +{ + m_vPackages = rContainer.m_vPackages; +} + +XMLPackageContainer::~XMLPackageContainer() +{ +} + +XMLPackageContainer XMLPackageContainer::operator=(XMLPackageContainer container) +{ + m_vPackages = container.m_vPackages; + return *this; +} + +void XMLPackageContainer::toSpecFile(ostream& rOut, + const char* szTag) +{ + if (numEntries()) { + rOut << szTag << ": "; + for (unsigned int i = 0; i < numEntries(); i++) { + rOut << (i ? ", " : ""); + getEntry(i).toSpecFile(rOut); + } + rOut << endl; + } +} + +void XMLPackageContainer::toXMLFile(ostream& rOut, + const char* szTag) +{ + if (numEntries()) { + rOut << endl << "\t\t<" << szTag << ">"; + for (unsigned int i = 0; i < numEntries(); i++) + getEntry(i).toXMLFile(rOut); + rOut << endl << "\t\t"; + } +} + +bool XMLPackageContainer::addRequire(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getRequires()); +} + +bool XMLPackageContainer::addBuildRequire(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getBuildRequires()); +} + +bool XMLPackageContainer::addProvide(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getProvides()); +} + +bool XMLPackageContainer::addObsolete(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLPackageEntry::parseCreate(pAttrs, pSpec->lastPackage().getObsoletes()); +} + +bool XMLPackageContainer::structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pPackage || !pPackage->header) + return false; + return true; +} Index: xmlspec/XMLRequires.h =================================================================== RCS file: xmlspec/XMLRequires.h diff -N xmlspec/XMLRequires.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLRequires.h 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,327 @@ +#ifndef _H_XMLREQUIRES_ +#define _H_XMLREQUIRES_ + +// standard C++ includes +#include +#include +#include + +// standard C includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" + +// forward definitions +class XMLPackage; +class XMLPackageContainer; +class XMLSpec; + +using namespace std; + +// (after requires, buildrequires, obsoletes, provides) +class XMLPackageEntry : public XMLBase +{ +// +// factory functions +// +public: + /** + * Creates an object as parsed from an XML spec + * . + * @param pAttrs XML atrtributes to use + * @param rContainer The container to which to add the object + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLPackageContainer& rContainer); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szName Name of the package + * @param szVersion version of the package + * @param szCmp the comparator (eq,lt,le,gt,ge) + * @return none + **/ + XMLPackageEntry(const char* szName, + const char* szVersion, + const char* szCmp); + + /** + * Copy constructor + * . + * @param rEntry reference to the entrry to copy + * @return none + **/ + XMLPackageEntry(const XMLPackageEntry& rEntry); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLPackageEntry(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param entry The entry to assigne to + * @return thye modified object + **/ + XMLPackageEntry operator=(XMLPackageEntry entry); +// +// member functions +// +public: + /** + * Converts the object into an RPM spec + * . + * @param rOut Output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut output stream + * @return none + **/ + void toXMLFile(ostream& rOut); + +// +// member variable get/set functions +// +public: + /** + * Gets the name + * . + * @param none + * @return string containing the name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Checks if we have a version + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasVersion() + { + return m_sVersion.length() ? true : false; + } + + /** + * Gets the version + * . + * @param none + * @return string containing the version + **/ + const char* getVersion() + { + return m_sVersion.c_str(); + } + + /** + * Gets the comparision string + * . + * @param none + * @return string with the comparator (=, <, <=, >, >=, <>) + **/ + const char* getCompare() + { + return m_sCmp.c_str(); + } + +// +// member variables +// +protected: + string m_sName; + string m_sVersion; + string m_sCmp; +}; + +// +class XMLPackageContainer : public XMLBase +{ +// +// factory functions +// +public: + /** + * Adds a require + * . + * @param pAttrs XML attributes + * @param pSpecx pointer to the spec to add to + * @return true on success, false otherwise + **/ + static bool addRequire(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Adds a buildrequire + * . + * @param pAttrs XML attributes + * @param pSpecx pointer to the spec to add to + * @return true on success, false otherwise + **/ + static bool addBuildRequire(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Adds a provide + * . + * @param pAttrs XML attributes + * @param pSpecx pointer to the spec to add to + * @return true on success, false otherwise + **/ + static bool addProvide(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Adds an obsolete + * . + * @param pAttrs XML attributes + * @param pSpecx pointer to the spec to add to + * @return true on success, false otherwise + **/ + static bool addObsolete(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Adds requires/provides/obsoletes from RPM structures + * . + * @param pPackage pointer to the RPM package + * @param pSpec pointer to the RPM spec + * @param pXSpec pointer to the XML spec to populate + * @return true on success, false otherwise + **/ + static bool structCreate(PackageStruct* pPackage, + Spec pSpec, + XMLSpec* pXSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param none + * @return none + **/ + XMLPackageContainer(); + + /** + * Copy constructor + * . + * @param rContainer The container to copy + * @return none + **/ + XMLPackageContainer(const XMLPackageContainer& rContainer); + + /** + * Destructor + * . + * @param none + * @return none + **/ + virtual ~XMLPackageContainer(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param container The container to copy + * @return a copy of the object + **/ + XMLPackageContainer operator=(XMLPackageContainer container); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec + * . + * @param rOut Output stream + * @param szTag the tag for this object (eg. buildrequires) + * @return none + **/ + virtual void toSpecFile(ostream& rOut, + const char* szTag); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @para szTag the tag for this object (eg. buildrequires) + * @return none + **/ + virtual void toXMLFile(ostream& rOut, + const char* szTag); + +// +// member variable get/set functions +// +public: + /** + * Gets the number of entries + * . + * @param none + * @return the number of entries + **/ + unsigned int numEntries() + { + return m_vPackages.size(); + } + + /** + * Gets a specific entry + * . + * @param nNum The number of the entry + * @return reference to the entry + **/ + XMLPackageEntry& getEntry(unsigned int nNum) + { + return m_vPackages[nNum]; + } + + /** + * Adds an entry + * . + * @param rPackage the entry to add + * @return none + **/ + void addEntry(XMLPackageEntry& rPackage) + { + m_vPackages.push_back(rPackage); + } + +// +// member variables +// +protected: + vector m_vPackages; +}; + +#endif Index: xmlspec/XMLScript.cpp =================================================================== RCS file: xmlspec/XMLScript.cpp diff -N xmlspec/XMLScript.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLScript.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,285 @@ +// standard includes +#include + +// our includes +#include "XMLPackage.h" +#include "XMLScript.h" +#include "XMLSpec.h" + +// attribute structure for XMLScript +structValidAttrs g_paScriptAttrs[] = +{ + {0x0000, false, false, "dir", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "interpreter", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLScript::parseCreate(XMLAttrs* pAttrs, + const char* szScript, + XMLScripts& rContainer) +{ + if (!pAttrs->validate(g_paScriptAttrs, (XMLBase*)pAttrs)) + return false; + XMLScript script(szScript, + pAttrs->asString("interpreter"), + pAttrs->asString("dir")); + rContainer.add(script); + return true; +} + +XMLScript::XMLScript(const char* szScript, + const char* szInterpreter, + const char* szDir) + : XMLBase() +{ + if (szScript) + m_sValue.assign(szScript); + if (szInterpreter) + m_sInterpreter.assign(szInterpreter); + if (szDir) + m_sDir.assign(szDir); +} + +XMLScript::XMLScript(const XMLScript& rScript) + : XMLBase() +{ + m_sValue.assign(rScript.m_sValue); + m_sInterpreter.assign(rScript.m_sInterpreter); + m_sDir.assign(rScript.m_sDir); +} + +XMLScript::~XMLScript() +{ +} + +XMLScript XMLScript::operator=(XMLScript script) +{ + m_sValue.assign(script.m_sValue); + m_sInterpreter.assign(script.m_sInterpreter); + m_sDir.assign(script.m_sDir); +} + +void XMLScript::toSpecFile(ostream& rOut) +{ + if (hasDirectory()) + rOut << "cd " << getDirectory() << endl; + rOut << getValue() << endl; +} + +void XMLScript::toXMLFile(ostream& rOut, + const char* szIndent) +{ + rOut << endl << szIndent << "\t\t" << getValue() << ""; +} + +void XMLScript::toRPMStruct(StringBuf* pSB) +{ + if (hasDirectory()) { + char szBuff[getDirectoryLen()+3+1]; // 3 == strlen("cd ") + sprintf(szBuff, "cd %s", getDirectory()); + appendStringBuf(*pSB, szBuff); + } + appendStringBuf(*pSB, getValue()); +} + +bool XMLScripts::addPrepScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + // no spec or already set + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->getPrep()); +} + +bool XMLScripts::addBuildScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + // no spec or already set + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->getBuild()); +} + +bool XMLScripts::addInstallScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + // no spec or already set + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->getInstall()); +} + +bool XMLScripts::addCleanScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + // no spec or already set + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->getClean()); +} + +XMLScripts::XMLScripts() + : XMLBase() +{ +} + +XMLScripts::XMLScripts(const XMLScripts& rContainer) + : XMLBase() +{ + m_vScripts = rContainer.m_vScripts; +} + +XMLScripts::~XMLScripts() +{ +} + +void XMLScripts::toSpecFile(ostream& rOut, + const char* szTag) +{ + if (numScripts()) { + rOut << endl << "%" << szTag << endl; + for (unsigned int i = 0; i < numScripts(); i++) + getScript(i).toSpecFile(rOut); + } +} + +void XMLScripts::toXMLFile(ostream& rOut, + const char* szTag) +{ + if (numScripts()) { + rOut << endl << "\t<" << szTag << ">"; + for (unsigned int i = 0; i < numScripts(); i++) + getScript(i).toXMLFile(rOut, ""); + rOut << endl << "\t"; + } +} + +bool XMLPackageScripts::addPreScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPre()); +} + +bool XMLPackageScripts::addPostScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPost()); +} + +bool XMLPackageScripts::addPreUnScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPreUn()); +} + +bool XMLPackageScripts::addPostUnScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getPostUn()); +} + +bool XMLPackageScripts::addVerifyScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + return XMLScript::parseCreate(pAttrs, szScript, pSpec->lastPackage().getVerify()); +} + +bool XMLPackageScripts::createPreScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPre().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPostScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPost().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPreUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPreUn().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createPostUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getPostUn().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +bool XMLPackageScripts::createVerifyScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + if (!pSpec) + return false; + pSpec->lastPackage().getVerify().setInterpreter(pAttrs->asString("interpreter")); + return true; +} + +XMLPackageScripts::XMLPackageScripts() + : XMLScripts() +{ +} + +XMLPackageScripts::XMLPackageScripts(const XMLPackageScripts& rContainer) + : XMLScripts(rContainer) +{ +} + +XMLPackageScripts::~XMLPackageScripts() +{ +} + +void XMLPackageScripts::toSpecFile(ostream& rOut, + const char* szTag) +{ + // NOTE: header not done here, but by "package" + for (unsigned int i = 0; i < numScripts(); i++) + getScript(i).toSpecFile(rOut); +} + +void XMLPackageScripts::toXMLFile(ostream& rOut, + const char* szTag) +{ + if (numScripts()) { + rOut << endl << "\t\t<" << szTag << ">"; + for (unsigned int i = 0; i < numScripts(); i++) + getScript(i).toXMLFile(rOut, "\t"); + rOut << endl << "\t\t"; + } +} Index: xmlspec/XMLScript.h =================================================================== RCS file: xmlspec/XMLScript.h diff -N xmlspec/XMLScript.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLScript.h 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,519 @@ +#ifndef _H_XMLSCRIPT_ +#define _H_XMLSCRIPT_ + +// standard C++ includes +#include +#include +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" + +// rpm includes +#include + +// forward definitions +class XMLPackage; +class XMLSpec; +class XMLScripts; + +using namespace std; + +class XMLScript : public XMLBase +{ +// +// factory methods +// +public: + /** + * Creates a script object and adds it to the container + * . + * @param pAttrs The XML attributes + * @param szScript The script value + * @param rContainer reference to the script container to add to + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + const char* szScript, + XMLScripts& rContainer); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szScript The script + * @param szInterpreter The interpreter to use for script execution + * @param szDir Directory to execute the script in + * @return none + **/ + XMLScript(const char* szScript, + const char* szInterpreter, + const char* szDir); + + /** + * Copy constructor + * . + * @param rScript Script to copy + * @return none + **/ + XMLScript(const XMLScript& rScript); + + /** + * Destructor + * . + * @param none + * @return none + **/ + virtual ~XMLScript(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param script the script to copy + * @return the copied object + **/ + XMLScript operator=(XMLScript script); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec file + * . + * @param rOut Output stream + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @param szIndent Indent string + * @return none + **/ + void toXMLFile(ostream& rOut, + const char* szIndent = ""); + + /** + * Converts the object into an RPM structure + * . + * @param pSB Pointer to the string buffer + * @return none + **/ + virtual void toRPMStruct(StringBuf* pSB); + +// +// member variable get/set functions +// +public: + /** + * Gets the script value + * . + * @param none + * @return string containing the script + **/ + const char* getValue() + { + return m_sValue.c_str(); + } + + /** + * Checks if we have an interpreter + * . + * @param none + * @return true if we have an interpreter, false otherwise + **/ + bool hasInterpreter() + { + return m_sInterpreter.length() ? true : false; + } + + /** + * Gets the interpreter + * . + * @param none + * @return string contating the interpreter + **/ + const char* getInterpreter() + { + return m_sInterpreter.c_str(); + } + + /** + * Checks if we have a direcory + * . + * @param none + * @return true if we have a directory, false otherwise + **/ + bool hasDirectory() + { + return m_sDir.length() ? true : false; + } + + /** + * Gets the directory + * . + * @param none + * @return string contating the directory + **/ + const char* getDirectory() + { + return m_sDir.c_str(); + } + + /** + * Gets the length of the directory string + * . + * @param none + * @return length of the description string + **/ + unsigned int getDirectoryLen() + { + return m_sDir.length(); + } + +// +// member variables +// +public: + string m_sValue; + string m_sInterpreter; + string m_sDir; +}; + +// +class XMLScripts : public XMLBase +{ +// +// factory functions +// +public: + static bool addPrepScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + static bool addBuildScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + static bool addInstallScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + static bool addCleanScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param none + * @return none + **/ + XMLScripts(); + + /** + * Copy constructor + * . + * @param rContainer the object to copy + * @return none + **/ + XMLScripts(const XMLScripts& rContainer); + + /** + * Destructor + * . + * @param none + * @return none + **/ + virtual ~XMLScripts(); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec file + * . + * @param rOut Output stream + * @param szTag The tag name + * @return none + **/ + virtual void toSpecFile(ostream& rOut, + const char* szTag); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @param szTag The tag name + * @return none + **/ + void toXMLFile(ostream& rOut, + const char* szTag); + +// +// member variable get/set functions +// +public: + /** + * Checks if we have an interpreter + * . + * @param none + * @return true if we have an interpreter, false otherwise + **/ + bool hasInterpreter() + { + return m_sInterpreter.length() ? true : false; + } + + /** + * Gets the interpreter + * . + * @param none + * @return string contatining the interpreter + **/ + const char* getInterpreter() + { + return m_sInterpreter.c_str(); + } + + /** + * Sets the script interpreter + * . + * @param szInterpreter The interpreter + * @return none + **/ + void setInterpreter(const char* szInterpreter) + { + if (szInterpreter) + m_sInterpreter.assign(szInterpreter); + } + + /** + * Gets the number of script entries + * . + * @param none + * @return the number of scripts + **/ + unsigned int numScripts() + { + return m_vScripts.size(); + } + + /** + * Gets a specific script entry + * . + * @param nNum The entry number + * @return Reference to the script entry + **/ + XMLScript& getScript(unsigned int nNum) + { + return m_vScripts[nNum]; + } + + /** + * Adds an script entry + * . + * @param szScript the script to add + * @return none + **/ + void add(XMLScript& rScript) + { + m_vScripts.push_back(rScript); + } + +// +// member variables +// +protected: + string m_sInterpreter; + vector m_vScripts; +}; + +// +class XMLPackageScripts : public XMLScripts +{ +// +// factory functions +// +public: + /** + * Adds a pre script + * . + * @param pAttrs The XML attributes + * @param szScript The script to add + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool addPreScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + /** + * Adds a post script + * . + * @param pAttrs The XML attributes + * @param szScript The script to add + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool addPostScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + /** + * Adds a preun script + * . + * @param pAttrs The XML attributes + * @param szScript The script to add + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool addPreUnScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + /** + * Adds a postun script + * . + * @param pAttrs The XML attributes + * @param szScript The script to add + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool addPostUnScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + /** + * Adds a verify script + * . + * @param pAttrs The XML attributes + * @param szScript The script to add + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool addVerifyScript(XMLAttrs* pAttrs, + const char* szScript, + XMLSpec* pSpec); + + /** + * Initialises a pre script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPreScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a post script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPostScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a preun script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPreUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a postun script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createPostUnScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + + /** + * Initialises a verify script container + * . + * @param pAttrs The XML attributes + * @param pSpec The spec to which we are adding + * @return true on success, false otherwise + **/ + static bool createVerifyScripts(XMLAttrs* pAttrs, + XMLSpec* pSpec); + +// +// constructors/destructors +// +public: + /** + * Default constructor + * . + * @param none + * @return none + **/ + XMLPackageScripts(); + + /** + * Copy constructor + * . + * @param rScripts Reference to the object to copy + * @return none + **/ + XMLPackageScripts(const XMLPackageScripts& rScripts); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLPackageScripts(); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec + * . + * @param rOut Output stream + * @param szTag The tag name + * @return none + **/ + virtual void toSpecFile(ostream& rOut, + const char* szTag); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @param szTag The tag name + * @return none + **/ + virtual void toXMLFile(ostream& rOut, + const char* szTag); + +}; + +#endif Index: xmlspec/XMLSource.cpp =================================================================== RCS file: xmlspec/XMLSource.cpp diff -N xmlspec/XMLSource.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLSource.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,339 @@ +// standard includes +#include + +// our includes +#include "XMLSource.h" +#include "XMLSpec.h" + +// rpm includes +#include + +using namespace std; + +bool XMLSource::structCreate(Source* pSource, + Spec pSpec, + XMLSpec* pXSpec) +{ + if (!pXSpec || !pSpec || !pSource) + return false; + + // create our mirror + XMLMirror *pMirror = NULL; + if (pSource->source != pSource->fullSource) { + unsigned int nLen = pSource->source-pSource->fullSource; + char szPath[nLen+1]; + strncpy(szPath, pSource->fullSource, nLen); + szPath[nLen] = '\0'; + pMirror = new XMLMirror(szPath, NULL, NULL); + } + + // generate the source, nosource, patch + XMLSource* pXSource = NULL; + XMLNoSource* pXNoSource = NULL; + XMLPatch* pXPatch = NULL; + switch (pSource->flags) { + case RPMBUILD_ISSOURCE: + pXSource = new XMLSource(pSource->source, pSource->num, + NULL, NULL, NULL); + pXSpec->addSource(*pXSource); + if (pMirror) + pXSpec->lastSource().addMirror(*pMirror); + delete pXSource; + break; + case RPMBUILD_ISNO: + pXNoSource = new XMLNoSource(pSource->source, pSource->num, + NULL, NULL, NULL); + pXSpec->addNoSource(*pXNoSource); + if (pMirror) + pXSpec->lastNoSource().addMirror(*pMirror); + delete pXNoSource; + break; + case RPMBUILD_ISPATCH: + pXPatch = new XMLPatch(pSource->source, pSource->num, NULL, NULL); + pXSpec->addPatch(*pXPatch); + if (pMirror) + pXSpec->lastPatch().addMirror(*pMirror); + delete pXPatch; + break; + default: + break; + } + if (pMirror) + delete pMirror; + + // do the next source and return + XMLSource::structCreate(pSource->next, pSpec, pXSpec); + return true; +} + +// attribute structure for XMLSource +structValidAttrs g_paSourceAttrs[] = +{ + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "num", XATTRTYPE_INTEGER, {NULL}}, + {0x0002, false, false, "dir", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "size", XATTRTYPE_INTEGER, {NULL}}, + {0x0004, false, false, "md5", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLSource::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + // validate the attributes + if (!pAttrs->validate(g_paSourceAttrs, (XMLBase*)pSpec)) + return false; + + XMLSource source(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("dir"), pAttrs->asString("size"), + pAttrs->asString("md5")); + pSpec->addSource(source); + + return true; +} + +XMLSource::XMLSource(const char* szName, + unsigned int nNum, + const char* szDir, + const char* szSize, + const char* szMD5) + : XMLBase() +{ + if (szName) + m_sName.assign(szName); + m_nNum = nNum; + if (szDir) + m_sDir.assign(szDir); + if (szSize) + m_sSize.assign(szSize); + if (szMD5) + m_sMD5.assign(szMD5); +} + +XMLSource::XMLSource(const XMLSource& rSource) + : XMLBase() +{ + m_sName.assign(rSource.m_sName); + m_nNum = rSource.m_nNum; + m_sDir.assign(rSource.m_sDir); + m_sSize.assign(rSource.m_sSize); + m_sMD5.assign(rSource.m_sMD5); + m_vMirrors = rSource.m_vMirrors; +} + +XMLSource::~XMLSource() +{ +} + +XMLSource XMLSource::operator=(XMLSource source) +{ + m_sName.assign(source.m_sName); + m_nNum = source.m_nNum; + m_sDir.assign(source.m_sDir); + m_sSize.assign(source.m_sSize); + m_sMD5.assign(source.m_sMD5); + m_vMirrors = source.m_vMirrors; + return *this; +} + +void XMLSource::toSpecFile(ostream& rOut) +{ + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toSpecFile(rOut); + + rOut << endl << "source"; + rOut << getNum(); + rOut << ": "; + if (numMirrors()) + rOut << getMirror(0).getPath(); + rOut << getName(); +} + +void XMLSource::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t"; + + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toXMLFile(rOut); + + rOut << endl << "\t"; +} + +void XMLSource::toRPMStruct(Spec pRPMSpec) +{ + /*Source* pCurr = new Source; + unsigned int nNameLen = strlen(getName()); + unsigned int nMirrorLen = 0; + if (pPrev) + pPrev->next = pCurr; + pCurr->next = NULL; + if (numMirrors()) + nMirrorlen = strlen(getMirror(0).getPath()); + pCurr->fullSource = new char[nNamelen+nMirrorLen+1]; + pCurr->fullSources[0] = '\0'; + if (numMirrors()) + strcpy(pCurr->fullSource, getMirror(0).getPath()); + strcat(pCurr->fullSource, getName()); + pCurr->source = pCurr->fullSource+nMirrorLen; + pCurr->num = getNum(); + pCurr->flags = RPMBUILD_ISSOURCE; + return pCurr;*/ +} + +bool XMLNoSource::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + // validate the attributes + if (!pAttrs->validate(g_paSourceAttrs, (XMLBase*)pSpec)) + return false; + + XMLNoSource source(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("dir"), pAttrs->asString("size"), + pAttrs->asString("md5")); + pSpec->addNoSource(source); + return true; +} + +XMLNoSource::XMLNoSource(const char* szName, + unsigned int nNum, + const char* szDir, + const char* szSize, + const char* szMD5) + : XMLSource(szName, + nNum, + szDir, + szSize, + szMD5) +{ +} + +XMLNoSource::XMLNoSource(const XMLNoSource& rNoSource) + : XMLSource(rNoSource.m_sName.c_str(), + rNoSource.m_nNum, + rNoSource.m_sDir.c_str(), + rNoSource.m_sSize.c_str(), + rNoSource.m_sMD5.c_str()) +{ +} + +XMLNoSource::~XMLNoSource() +{ +} + +void XMLNoSource::toSpecFile(ostream& rOut) +{ + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toSpecFile(rOut); + + rOut << endl << "nosource"; + rOut << getNum(); + rOut << ": " << getName(); +} + +void XMLNoSource::toXMLFile(ostream& rOut) +{ + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toXMLFile(rOut); +} + +void XMLNoSource::toRPMStruct(Spec pRPMSpec) +{ + //Source* pCurr = XMLSource::toRPMStruct(pPrev); + //pCurr->flags = RPMBUILD_ISNO; + //return pCurr; +} + +// attribute structure for XMLPatch +structValidAttrs g_paPatchAttrs[] = +{ + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, false, false, "num", XATTRTYPE_INTEGER, {NULL}}, + {0x0002, false, false, "size", XATTRTYPE_INTEGER, {NULL}}, + {0x0003, false, false, "md5", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +bool XMLPatch::parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec) +{ + // validate the attributes + if (!pAttrs->validate(g_paPatchAttrs, (XMLBase*)pSpec)) + return false; + + XMLPatch patch(pAttrs->asString("name"), pAttrs->asInteger("num"), + pAttrs->asString("size"), pAttrs->asString("md5")); + pSpec->addPatch(patch); + return true; +} + +XMLPatch::XMLPatch(const char* szName, + unsigned int nNum, + const char* szSize, + const char* szMD5) + : XMLSource(szName, + nNum, + NULL, + szSize, + szMD5) +{ +} + +XMLPatch::XMLPatch(const XMLPatch& rPatch) + : XMLSource(rPatch.m_sName.c_str(), + rPatch.m_nNum, + NULL, + rPatch.m_sSize.c_str(), + rPatch.m_sMD5.c_str()) +{ +} + +XMLPatch::~XMLPatch() +{ +} + +void XMLPatch::toSpecFile(ostream& rOut) +{ + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toSpecFile(rOut); + rOut << endl << "patch"; + rOut << getNum(); + rOut << ": " << getName(); +} + +void XMLPatch::toXMLFile(ostream& rOut) +{ + rOut << endl << "\t"; + + for (unsigned int i = 0; i < numMirrors(); i++) + getMirror(i).toXMLFile(rOut); + + rOut << endl << "\t"; +} + +void XMLPatch::toRPMStruct(Spec pRPMSpec) +{ + + //Source* pCurr = XMLSource::toRPMStruct(pPrev); + //pCurr->flags = RPMBUILD_ISPATCH; + //return pCurr; +} Index: xmlspec/XMLSource.h =================================================================== RCS file: xmlspec/XMLSource.h diff -N xmlspec/XMLSource.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLSource.h 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,454 @@ +#ifndef _H_XMLSOURCE_ +#define _H_XMLSOURCE_ + +// standard C++ includes +#include +#include +#include + +// standard includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" +#include "XMLMirror.h" + +// rpm includes +#include + +// forward declaration +class XMLSpec; + +using namespace std; + +// +class XMLSource : public XMLBase +{ +// +// factory functions +// +public: + /** + * Static factory function for the creation of XMLSource, XMLPatch, ... + * objects from RPM Source* structure. + * . + * @param pSource Pointer to a list of sources + * @param pSpec pointer to the RPM spec + * @param pSpec pointer to our spec object + * @return true on success, false otherwise + **/ + static bool structCreate(Source* pSource, + Spec pSpec, + XMLSpec* pXSpec); + + /** + * Static factory function for the creation of an XMLSource + * object from details parsed from an XML spec. + * . + * @param pAttrs Pointer to an XML attribute object + * @param pspec Ponter to our spec object + * @param bPatch True if this source is a patch + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default contructor + * . + * @param szName The name + * @param szNum The source number + * @param szDir The unpack directory + * @param szSize The size of the source archive + * @param szMD5 The MD5 sum of the archive + * @return none + **/ + XMLSource(const char* szName, + unsigned int nNum, + const char* szDir, + const char* szSize, + const char* szMD5); + + /** + * Copy contructor + * . + * @param rSource The source that we are to copy + * @return none + **/ + XMLSource(const XMLSource& rSource); + + /** + * Destructor + * . + * @param none + * @return none + **/ + virtual ~XMLSource(); + +// +// operators +// +public: + /** + * Assignment operator + * . + * @param source The source to copy + * @return copied object + **/ + XMLSource operator=(XMLSource source); + +// +// Member functions +// +public: + /** + * Convert the object into an RPM spec file + * . + * @param rOut Output stream + * @return none + **/ + virtual void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @return none + **/ + virtual void toXMLFile(ostream& rOut); + + /** + * Converts the object into an RPM structure + * . + * @param spec the RPM structure to use + * @return none + **/ + virtual void toRPMStruct(Spec spec); + +// +// member variable get/set functions +// +public: + /** + * Checks if we have a source name + * . + * @param none + * @return true if we have a name, false otherwise + **/ + bool hasName() + { + return m_sName.length() ? true : false; + } + + /** + * Get the source name + * . + * @param none + * @return string containing the name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Get the length of the name + * . + * @param none + * @return the length of the name + **/ + unsigned int getNameLen() + { + return m_sName.length(); + } + + /** + * Get the source number + * . + * @param none + * @return the number + **/ + unsigned int getNum() + { + return m_nNum; + } + + /** + * Checks to see if we have an unpack directory + * . + * @param none + * @return true if we have a specified directory, false otherwise + **/ + bool hasDir() + { + return m_sDir.length() ? true : false; + } + + /** + * Gets the directory that we are to unpack this source to + * . + * @param none + * @return string contating the directory + **/ + const char* getDir() + { + return m_sDir.c_str(); + } + + /** + * Checks to see if we have a source size + * . + * @param none + * @return true if we have a size, false otherwise + **/ + bool hasSize() + { + return m_sSize.length() ? true : false; + } + + /** + * Gets the size of the source + * . + * @param none + * @return string contating the size + **/ + const char* getSize() + { + return m_sSize.c_str(); + } + + /** + * Checks to see if this source has an MD5 sum + * . + * @param none + * @return true if we have an MD5, false oterwise + **/ + bool hasMD5() + { + return m_sMD5.length() ? true : false; + } + + /** + * Gets the MD5 sum for this source + * . + * @param none + * @return string contating the MD5 + **/ + const char* getMD5() + { + return m_sMD5.c_str(); + } + + /** + * Add a mirror for this source + * . + * @param rMirror The mirror to add + * @return none + **/ + void addMirror(XMLMirror& rMirror) + { + m_vMirrors.push_back(rMirror); + } + + /** + * Gets the number of mirrors for this source + * . + * @param none + * @return the number oif mirrors + **/ + unsigned int numMirrors() + { + return m_vMirrors.size(); + } + + /** + * Gets a specific mirror by number + * . + * @param nNum The mirror to get + * @param the mirror + **/ + XMLMirror& getMirror(unsigned int nNum) + { + return m_vMirrors[nNum]; + } + +// +// member variables +// +protected: + string m_sName; + unsigned int m_nNum; + string m_sDir; + string m_sSize; + string m_sMD5; + vector m_vMirrors; +}; + +// +class XMLNoSource : public XMLSource +{ +// +// factory methods +// +public: + /** + * Create an XMLNoSource object + * . + * @param pAttrs XML attributes + * @param pSpec The spec to add the object o + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szName The name + * @param nNum source number + * @param szDir Thje director to extract to + * @param szSize size of the archive + * @param szMD5 the MD5 sum of the archive + * @return none + **/ + XMLNoSource(const char* szName, + unsigned int nNum, + const char* szDir, + const char* szSize, + const char* szMD5); + + /** + * Copy constructor + * . + * @param rNoSource Reference to the object ot copy + * @return none + **/ + XMLNoSource(const XMLNoSource& rNoSource); + + /** + * Destructor + * . + * @param none + * @return none + **/ + virtual ~XMLNoSource(); + +// +// public member functions +// +public: + /** + * Converts the object into an RPM spec file + * . + * @param rOut Output stream + * @param none + **/ + virtual void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @return none + **/ + virtual void toXMLFile(ostream& rOut); + + /** + * Converts the object into an RPM structure + * . + * @param spec The RPM spec structure + * @return none + **/ + virtual void toRPMStruct(Spec spec); +}; + +// +class XMLPatch : public XMLSource +{ +// +// factory methods +// +public: + /** + * Create an XMLPatch object + * . + * @param pAttrs XML attributes + * @param pSpec The spec to add the object o + * @return true on success, false otherwise + **/ + static bool parseCreate(XMLAttrs* pAttrs, + XMLSpec* pSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szName archive name + * @param nNum source number + * @param szSize size of the archive + * @param szMD5 MD5 sum + * @return none + **/ + XMLPatch(const char* szName, + unsigned int nNum, + const char* szSize, + const char* szMD5); + + /** + * Copy constructor + * . + * @param rPatch Reference to the object to copy + * @return none + **/ + XMLPatch(const XMLPatch& rPatch); + + /** + * Destructor + * . + * @param none + * @return nonew + **/ + virtual ~XMLPatch(); + +// +// member functions +// +public: + /** + * Converts the object into an RPM spec file + * . + * @param rOut Output stream + * @param none + **/ + virtual void toSpecFile(ostream& rOut); + + /** + * Converts the object into an XML spec + * . + * @param rOut Output stream + * @return none + **/ + virtual void toXMLFile(ostream& rOut); + + /** + * Converts the object into an RPM structure + * . + * @param spec The RPM spec structure + * @return none + **/ + virtual void toRPMStruct(Spec spec); +}; + +#endif Index: xmlspec/XMLSpec.cpp =================================================================== RCS file: xmlspec/XMLSpec.cpp diff -N xmlspec/XMLSpec.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLSpec.cpp 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,252 @@ +// 3rd party includes +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLRPMWrap.h" +#include "XMLSpec.h" + +// rpm includes +#include + +using namespace std; + +// attribute structure for XMLSpec +structValidAttrs g_paSpecAttrs[] = +{ + {0x0000, true, false, "name", XATTRTYPE_STRING, {"*", NULL}}, + {0x0001, true, false, "version", XATTRTYPE_STRING, {"*", NULL}}, + {0x0002, true, false, "release", XATTRTYPE_STRING, {"*", NULL}}, + {0x0003, false, false, "epoch", XATTRTYPE_INTEGER, {NULL}}, + {0x0004, false, false, "distribution", XATTRTYPE_STRING, {"*", NULL}}, + {0x0005, false, false, "vendor", XATTRTYPE_STRING, {"*", NULL}}, + {0x0006, false, false, "packager", XATTRTYPE_STRING, {"*", NULL}}, + {0x0007, false, false, "packager-email", XATTRTYPE_MAIL, {"*", NULL}}, + {0x0008, false, false, "copyright", XATTRTYPE_STRING, {"*", NULL}}, + {0x0009, false, false, "url", XATTRTYPE_STRING, {"*", NULL}}, + {0x000A, false, false, "buildroot", XATTRTYPE_STRING, {"*", NULL}}, + {XATTR_END, false, false, "end", XATTRTYPE_NONE, {NULL}} +}; + +XMLSpec* XMLSpec::parseCreate(XMLAttrs* pAttrs, + const char* szFilename) +{ + // verify the attributes + if (!pAttrs->validate(g_paSpecAttrs, (XMLBase*)pAttrs)) + return NULL; + + // create and return + return new XMLSpec(szFilename, + pAttrs->asString("name"), + pAttrs->asString("version"), + pAttrs->asString("release"), + pAttrs->asString("epoch"), + pAttrs->asString("distribution"), + pAttrs->asString("vendor"), + pAttrs->asString("packager"), + pAttrs->asString("packager-email"), + pAttrs->asString("copyright"), + pAttrs->asString("url"), + pAttrs->asString("buildroot")); +} + +XMLSpec* XMLSpec::structCreate(Spec pSpec) +{ + if (!pSpec || !pSpec->packages || !pSpec->packages->header) + return NULL; + + // create the spec with values from the RPM stuff + string sName, sVersion, sRelease, sEpoch, sDistro; + string sVendor, sPackager, sMail, sLicense, sURL; + if (!getRPMHeader(pSpec->packages->header, RPMTAG_NAME, sName) || + !getRPMMacro("PACKAGE_VERSION", sVersion) || + !getRPMMacro("PACKAGE_RELEASE", sRelease)) + return NULL; + getRPMHeader(pSpec->packages->header, RPMTAG_EPOCH, sEpoch); + getRPMHeader(pSpec->packages->header, RPMTAG_DISTRIBUTION, sDistro); + getRPMHeader(pSpec->packages->header, RPMTAG_VENDOR, sVendor); + getRPMHeader(pSpec->packages->header, RPMTAG_PACKAGER, sPackager); + getRPMHeader(pSpec->packages->header, RPMTAG_LICENSE, sLicense); + getRPMHeader(pSpec->packages->header, RPMTAG_URL, sURL); + XMLSpec* pXSpec = new XMLSpec(pSpec->specFile, sName.c_str(), sVersion.c_str(), + sRelease.c_str(), sEpoch.c_str(), sDistro.c_str(), + sVendor.c_str(), sPackager.c_str(), sMail.c_str(), + sLicense.c_str(), sURL.c_str(), pSpec->buildRootURL); + + // add sources, packages all kinds of funny stuff + XMLChangelog::structCreate(pSpec, pXSpec); + XMLSource::structCreate(pSpec->sources, pSpec, pXSpec); + XMLPackage::structCreate(pSpec->packages, pSpec, pXSpec); + + // return the created spec + return pXSpec; +} + +XMLSpec::XMLSpec(const char* szFilename, + const char* szName, + const char* szVersion, + const char* szRelease, + const char* szEpoch, + const char* szDistribution, + const char* szVendor, + const char* szPackager, + const char* szPkgrEmail, + const char* szCopyright, + const char* szURL, + const char* szBuildRoot) : XMLBase() +{ + if (szFilename) + m_sFilename.assign(szFilename); + if (szName) + m_sName.assign(szName); + if (szVersion) + m_sVersion.assign(szVersion); + if (szRelease) + m_sRelease.assign(szRelease); + if (szEpoch) + m_sEpoch.assign(szEpoch); + if (szDistribution) + m_sDistribution.assign(szDistribution); + if (szVendor) + m_sVendor.assign(szVendor); + if (szPackager) + m_sPackager.assign(szPackager); + if (szPkgrEmail) + m_sPkgrEmail.assign(szPkgrEmail); + if (szCopyright) + m_sCopyright.assign(szCopyright); + if (szURL) + m_sURL.assign(szURL); + if (szBuildRoot) + m_sBuildRoot.assign(szBuildRoot); +} + +XMLSpec::~XMLSpec() +{ +} + +void XMLSpec::toSpecFile(ostream& rOut) +{ + for (unsigned int i = 0; i < numXMacros(); i++) + getXMacro(i).toSpecFile(rOut); + + rOut << "name: " << getName() << endl; + rOut << "version: " << getVersion() << endl; + rOut << "release: " << getRelease() << endl; + if (hasEpoch()) + rOut << "epoch: " << getEpoch() << endl; + if (hasCopyright()) + rOut << "copyright: " << getCopyright() << endl; + if (hasURL()) + rOut << "url: " << getURL() << endl; + if (hasBuildRoot()) + rOut << "buildroot: " << getBuildRoot() << endl; + if (hasDistribution()) + rOut << "distribution: " << getDistribution() << endl; + if (hasVendor()) + rOut << "vendor: " << getVendor() << endl; + if (hasPackager()) { + rOut << "packager: " << getPackager(); + if (hasPkgrEmail()) + rOut << " <" << getPkgrEmail() << ">"; + rOut << endl; + } + + for (unsigned int i = 0; i < numSources(); i++) + getSource(i).toSpecFile(rOut); + //for (unsigned int i = 0; i < numNoSources(); i++) + // getNoSource(i).toSpecFile(rOut); + for (unsigned int i = 0; i < numPatches(); i++) + getPatch(i).toSpecFile(rOut); + for (unsigned int i = 0; i < numPackages(); i++) + getPackage(i).toSpecFile(rOut); + + getPrep().toSpecFile(rOut, "prep"); + getBuild().toSpecFile(rOut, "build"); + getInstall().toSpecFile(rOut, "install"); + getClean().toSpecFile(rOut, "clean"); + + for (unsigned int i = 0; i < numPackages(); i++) + getPackage(i).toScriptsSpecFile(rOut); + + for (unsigned int i = 0; i < numPackages(); i++) + getPackage(i).toFilesSpecFile(rOut); + + getChangelog().toSpecFile(rOut); +} + +void XMLSpec::toXMLFile(ostream& rOut) +{ + // spec start + rOut << ""; + rOut << endl << ""; + + for (unsigned int i = 0; i < numXMacros(); i++) + getXMacro(i).toXMLFile(rOut); + for (unsigned int i = 0; i < numSources(); i++) + getSource(i).toXMLFile(rOut); + for (unsigned int i = 0; i < numNoSources(); i++) + getNoSource(i).toXMLFile(rOut); + for (unsigned int i = 0; i < numPatches(); i++) + getPatch(i).toXMLFile(rOut); + for (unsigned int i = 0; i < numPackages(); i++) + getPackage(i).toXMLFile(rOut); + + getPrep().toXMLFile(rOut, "prep"); + getBuild().toXMLFile(rOut, "build"); + getInstall().toXMLFile(rOut, "install"); + getClean().toXMLFile(rOut, "clean"); + + getChangelog().toXMLFile(rOut); + + rOut << endl << ""; +} + +void XMLSpec::toRPMStruct(Spec* pRPMSpec) +{ + Spec spec = newSpec(); + if (hasBuildRoot()) { + spec->gotBuildRootURL = 1; + spec->buildRootURL = strdup(getBuildRoot()); + addMacro(spec->macros, "buildroot", NULL, getBuildRoot(), RMIL_SPEC); + } + addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC); + spec->timeCheck = rpmExpandNumeric("%{_timecheck}"); + + //getChangelog().toRPMStruct(spec); + /*for (unsigned int i = 0; i < numPackages(); i++) + getPackage(i).toRPMStruct(pRPMSpec); + for (unsigned int i = 0; i < numSources(); i++) + getSource(i).toRPMStruct(pRPMSpec); + for (unsigned int i = 0; i < numNoSources(); i++) + getNoSource(i).toRPMStruct(pRPMSpec); + for (unsigned int i = 0; i < numPatches(); i++) + getPatch(i).toRPMStruct(pRPMSpec);*/ + + //getPrep().toRPMStruct(spec); + //getBuild().toRPMStruct(spec); + //getInstall().toRPMStruct(spec); + //getClean().toRPMStruct(spec); + + *pRPMSpec = spec; +} Index: xmlspec/XMLSpec.h =================================================================== RCS file: xmlspec/XMLSpec.h diff -N xmlspec/XMLSpec.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLSpec.h 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,678 @@ +#ifndef _H_XMLSPEC_ +#define _H_XMLSPEC_ + +// standard C++ includes +#include +#include +#include + +// our includes +#include "XMLAttrs.h" +#include "XMLBase.h" +#include "XMLChangelog.h" +#include "XMLMacro.h" +#include "XMLPackage.h" +#include "XMLScript.h" +#include "XMLSource.h" + +// rpm includes +#include + +using namespace std; + +// +class XMLSpec : public XMLBase +{ +// +// static object creation functions +// +public: + /** + * Creates an XMLSpec from values parsed + * . + * @param pAttrs The XML attributes + * @param szFilename The XML spec filename + * @return Pointer to the created spec + **/ + static XMLSpec* parseCreate(XMLAttrs* pAttrs, + const char* szFilename); + + /** + * Creates and XMLSpec from an RPM Spec structure + * . + * @param pSpec The RPM spec structure + * @return Pointer to the created spec + **/ + static XMLSpec* structCreate(Spec pSpec); + +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szFilename Filename of the spec on disk + * @param szName spec name + * @param szVersion Spec version + * @param szRelease spec release + * @param szEpoch spec epoch + * @param szDistribution spec distribution + * @param szVendor spec vendor + * @param szPackage spec packager + * @param szPkgEmail email address for the packager + * @param szCopyright spec copyright/licence + * @param szURL main package url + * @param szBuildRoot buildroot + * @return none + **/ + XMLSpec(const char* szFilename, + const char* szName, + const char* szVersion, + const char* szRelease, + const char* szEpoch, + const char* szDistribution, + const char* szVendor, + const char* szPackager, + const char* szPkgrEmail, + const char* szCopyright, + const char* szURL, + const char* szBuildRoot); + + /** + * Destructor + * . + * @param none + * @return none + **/ + ~XMLSpec(); + +// +// public member functions +// +public: + /** + * Converts the spec object to a normal RPM spec file + * . + * @param rOut Reference to the stream to write the information to + * @return none + **/ + void toSpecFile(ostream& rOut); + + /** + * Converts the spec object to an XML spec file + * . + * @param rOut Reference to the stream to write the information to + * @return none + **/ + void toXMLFile(ostream& rOut); + + /** + * Converts the spec object to an internal RPM structure + * . + * @param none + * @return the created RPM structure + **/ + void toRPMStruct(Spec* pRPMSpec); + +// +// member variable get/set functions +// +public: + /** + * Adds a package to the internal list + * . + * @param rPkg Reference to the package to add + * @return none + **/ + void addPackage(XMLPackage& rPkg) + { + m_vPackages.push_back(rPkg); + } + + /** + * Gets the number of packages + * . + * @param none + * @return the number of packages + **/ + unsigned int numPackages() + { + return m_vPackages.size(); + } + + /** + * Gets a specific package + * . + * @param nNum The package number + * @return the required package + **/ + XMLPackage& getPackage(unsigned int nNum) + { + return m_vPackages[nNum]; + } + + /** + * Gets the last package added + * . + * @param none + * @return the last package added + **/ + XMLPackage& lastPackage() + { + return m_vPackages[numPackages()-1]; + } + + /** + * Adds a source to the internal list + * . + * @param rSource Reference to the source to add + * @return none + **/ + void addSource(XMLSource& rSource) + { + m_vSources.push_back(rSource); + } + + /** + * Gets the number of sources + * . + * @param none + * @return the number of sources + **/ + unsigned int numSources() + { + return m_vSources.size(); + } + + /** + * Gets a specific source + * . + * @param nNum The source number + * @return the required source + **/ + XMLSource& getSource(unsigned int nNum) + { + return m_vSources[nNum]; + } + + /** + * Gets the last source added + * . + * @param none + * @return the last source added + **/ + XMLSource& lastSource() + { + return m_vSources[numSources()-1]; + } + + /** + * Adds a source to the internal list + * . + * @param rSource Reference to the source to add + * @return none + **/ + void addNoSource(XMLNoSource& rSource) + { + m_vNoSources.push_back(rSource); + } + + /** + * Gets the number of nosources + * . + * @param none + * @return the number of nsources + **/ + unsigned int numNoSources() + { + return m_vNoSources.size(); + } + + /** + * Gets a specific nosource + * . + * @param nNum The nosource number + * @return the required nosource + **/ + XMLNoSource& getNoSource(unsigned int nNum) + { + return m_vNoSources[nNum]; + } + + /** + * Gets the last nosource added + * . + * @param none + * @return the last nosource added + **/ + XMLNoSource& lastNoSource() + { + return m_vNoSources[numNoSources()-1]; + } + + /** + * Adds a patch to the internal list + * . + * @param rSource Reference to the patch to add + * @return none + **/ + void addPatch(XMLPatch& rSource) + { + m_vPatches.push_back(rSource); + } + + /** + * Gets the number of patches + * . + * @param none + * @return the number of patches + **/ + unsigned int numPatches() + { + return m_vPatches.size(); + } + + /** + * Gets a specific patch + * . + * @param nNum The patch number + * @return the required patch + **/ + XMLPatch& getPatch(unsigned int nNum) + { + return m_vPatches[nNum]; + } + + /** + * Gets the last patch added + * . + * @param none + * @return the last patch added + **/ + XMLPatch& lastPatch() + { + return m_vPatches[numPatches()-1]; + } + + /** + * Adds a macro to the internal list + * . + * @param rMacro Reference to the macro to add + * @return none + **/ + void addXMacro(XMLMacro& rMacro) + { + m_vMacros.push_back(rMacro); + } + + /** + * Gets the number of macros + * . + * @param none + * @return the number of macros + **/ + unsigned int numXMacros() + { + return m_vMacros.size(); + } + + /** + * Gets a specific macro + * . + * @param nNum The macro number + * @return the required macro + **/ + XMLMacro& getXMacro(unsigned int nNum) + { + return m_vMacros[nNum]; + } + + /** + * Checks if we have a filename + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasFilename() + { + return m_sFilename.length() ? true : false; + } + + /** + * Gets the filename + * . + * @param none + * @return string containing the filename + **/ + const char* getFilename() + { + return m_sFilename.c_str(); + } + + /** + * Checks if we have a name + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasName() + { + return m_sName.length() ? true : false; + } + + /** + * Gets the name + * . + * @param none + * @return string containing the name + **/ + const char* getName() + { + return m_sName.c_str(); + } + + /** + * Checks if we have a version + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasVersion() + { + return m_sVersion.length() ? true : false; + } + + /** + * Gets the version + * . + * @param none + * @return string containing the version + **/ + const char* getVersion() + { + return m_sVersion.c_str(); + } + + /** + * Checks if we have a release + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasRelease() + { + return m_sRelease.length() ? true : false; + } + + /** + * Gets the release + * . + * @param none + * @return string containing the release + **/ + const char* getRelease() + { + return m_sRelease.c_str(); + } + + /** + * Checks if we have a epoch + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasEpoch() + { + return m_sEpoch.length() ? true : false; + } + + /** + * Gets the epoch + * . + * @param none + * @return string containing the epoch + **/ + const char* getEpoch() + { + return m_sEpoch.c_str(); + } + + /** + * Checks if we have a distribution + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasDistribution() + { + return m_sDistribution.length() ? true : false; + } + + /** + * Gets the distribution + * . + * @param none + * @return string containing the distribution + **/ + const char* getDistribution() + { + return m_sDistribution.c_str(); + } + + /** + * Checks if we have a vendor + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasVendor() + { + return m_sVendor.length() ? true : false; + } + + /** + * Gets the vendor + * . + * @param none + * @return string containing the vendor + **/ + const char* getVendor() + { + return m_sVendor.c_str(); + } + + /** + * Checks if we have a packager + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasPackager() + { + return m_sPackager.length() ? true : false; + } + + /** + * Gets the packager + * . + * @param none + * @return string containing the packager + **/ + const char* getPackager() + { + return m_sPackager.c_str(); + } + + /** + * Checks if we have a packager email + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasPkgrEmail() + { + return m_sPkgrEmail.length() ? true : false; + } + + /** + * Gets the packager's email address + * . + * @param none + * @return string containing the packager's email address + **/ + const char* getPkgrEmail() + { + return m_sPkgrEmail.c_str(); + } + + /** + * Checks if we have a copyright + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasCopyright() + { + return m_sCopyright.length() ? true : false; + } + + /** + * Gets the copyright + * . + * @param none + * @return string containing the copyright + **/ + const char* getCopyright() + { + return m_sCopyright.c_str(); + } + + /** + * Checks if we have an URL + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasURL() + { + return m_sURL.length() ? true : false; + } + + /** + * Gets the URL + * . + * @param none + * @return string containing the URL + **/ + const char* getURL() + { + return m_sURL.c_str(); + } + + /** + * Checks if we have a BuildRoot + * . + * @param none + * @return true if available, false otherwise + **/ + bool hasBuildRoot() + { + return m_sBuildRoot.length() ? true : false; + } + + /** + * Gets the buildroot + * . + * @param none + * @return string containing the buildroor + **/ + const char* getBuildRoot() + { + return m_sBuildRoot.c_str(); + } + + /** + * Gets the prep section + * . + * @param none + * @return reference to the prep section + **/ + XMLScripts& getPrep() + { + return m_Prep; + } + + /** + * Gets the build section + * . + * @param none + * @return reference to the build section + **/ + XMLScripts& getBuild() + { + return m_Build; + } + + /** + * Gets the install section + * . + * @param none + * @return reference to the install section + **/ + XMLScripts& getInstall() + { + return m_Install; + } + + /** + * Gets the clean section + * . + * @param none + * @return reference to the clean section + **/ + XMLScripts& getClean() + { + return m_Clean; + } + + /** + * Gets the changelog section + * . + * @param none + * @return reference to the changelog section + **/ + XMLChangelog& getChangelog() + { + return m_Changelog; + } + +// +// internal member variables +// +protected: + string m_sFilename; + string m_sName; + string m_sVersion; + string m_sRelease; + string m_sEpoch; + string m_sDistribution; + string m_sVendor; + string m_sPackager; + string m_sPkgrEmail; + string m_sCopyright; + string m_sURL; + string m_sBuildRoot; + vector m_vPackages; + vector m_vSources; + vector m_vNoSources; + vector m_vPatches; + vector m_vMacros; + XMLScripts m_Prep; + XMLScripts m_Build; + XMLScripts m_Install; + XMLScripts m_Clean; + XMLChangelog m_Changelog; +}; + +#endif Index: xmlspec/XMLText.cpp =================================================================== RCS file: xmlspec/XMLText.cpp diff -N xmlspec/XMLText.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLText.cpp 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,23 @@ +// our includes +#include "XMLText.h" + +using namespace std; + +XMLText::XMLText(const char* szText, + const char* szLang) + : XMLBase() +{ + setText(szText); + setLang(szLang); +} + +XMLText::XMLText(const XMLText& rText) + : XMLBase() +{ + setText(rText.m_sText.c_str()); + setLang(rText.m_sLang.c_str()); +} + +XMLText::~XMLText() +{ +} Index: xmlspec/XMLText.h =================================================================== RCS file: xmlspec/XMLText.h diff -N xmlspec/XMLText.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/XMLText.h 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,119 @@ +#ifndef _H_XMLTEXT_ +#define _H_XMLTEXT_ + +// standard c++ includes +#include + +// our includes +#include "XMLBase.h" + +using namespace std; + +class XMLText : public XMLBase +{ +// +// constructors/destructor +// +public: + /** + * Default constructor + * . + * @param szText The text to add + * @param szLang The text's language + * @return none + **/ + XMLText(const char* szText, + const char* szLang = NULL); + + /** + * Copy constructor + * . + * @param rText reference to the text to copy + * @return none + **/ + XMLText(const XMLText& rText); + + /** + * Default destructor + * . + * @param none + * @return none + **/ + ~XMLText(); + +// +// get/set methods for internal variables +// +public: + /** + * Sets the text + * . + * @param szText The text + * @return none + **/ + void setText(const char* szText) + { + if (szText) + m_sText.assign(szText); + } + + /** + * Gets the text + * . + * @param none + * @return string containing the text + **/ + const char* getText() + { + return m_sText.c_str(); + } + + /** + * Tests if we have a language for this description + * . + * @param none + * @return true if we have a language, false otherwise + **/ + bool hasLang() + { + return m_sLang.length() ? true : false; + } + + /** + * Sets the language + * . + * @param szLang The language + * @return none + **/ + void setLang(const char* szLang) + { + if (szLang) { + // FIXME: We need to get the actual default language as specified + // in one of the RPM headers (which I cannot find now) and + // substitute it here. (I know the value is "C", bu we should + // use the define.) + if (strcmp(szLang, "C") != 0) + m_sLang.assign(szLang); + } + } + + /** + * Gets the language + * . + * @param none + * @return string containing the language + **/ + const char* getLang() + { + return m_sLang.c_str(); + } + +// +// member variables +// +public: + string m_sText; + string m_sLang; +}; + +#endif Index: xmlspec/example.spec.xml =================================================================== RCS file: xmlspec/example.spec.xml diff -N xmlspec/example.spec.xml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/example.spec.xml 28 Aug 2002 10:52:43 -0000 1.3.2.1 @@ -0,0 +1,188 @@ + + + + + value is this + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This spec is just an example for some funny purpose. + Hierdie is net 'n toets vir i18n in die opsomming + %{summary} + Nog 'n toets, hierdie keer in die beskrywing + + + + + + + + /usr/lib/*.so* + + + + + + + + + + The libvorbis-devel package contains development headers. + %{summary} +
+			
+			
+		
+ + /usr/include/*.h + /usr/lib/*.la + /usr/share/aclocal/* + /usr/share/m4/* + /usr/share/man/* + +
+ + + + + + + + + The toys package contains toys + %{summary} + + + + + + + + /usr/doc/* + + + + + + + + + + + + + + + + + + + + + + + + + + Changed spec to make sure the output spec file can be understood by RPM + Added languages (description/summary) and a test in Afrikaans + + + Changed file attributes to mode, user and group + + + Added attribute "interpreter" to script + + + Moved <files> into <package> structure + Added <nosource> tag as example + Changed <shell> to <script> + + + Changed the formatting of the XML file to fit in with new implementation + Commented the spec to allow others to understand it as well + + + Converted spec file to .spec.xml file for illustrative purposes + + +
Index: xmlspec/spec2xml.cpp =================================================================== RCS file: xmlspec/spec2xml.cpp diff -N xmlspec/spec2xml.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/spec2xml.cpp 28 Aug 2002 10:52:43 -0000 1.1.2.1 @@ -0,0 +1,62 @@ +// standard C++ includes +#include + +// our includes +#include "XMLSpec.h" + +// rpm includes +#include + +// display some usage +int usage() +{ + printf("Usage: spec2xml input [output]\n"); + printf("Converts the input pkg.spec file to a pkg.spec.xml\n"); + printf("file for use in an rpmbuild command.\n\n"); + return 1; +} + +// program entry point +int main(int argc, + char** argv) +{ + printf("\nspec2xml, version 0.01\n"); + if (argc != 2 && argc != 3) { + usage(); + return 1; + } + + Spec pSpec = NULL; + printf("Parsing RPM spec %s:\n", argv[1]); + if (!parseSpec(&pSpec, argv[1], "/", "/var/tmp", 0, NULL, NULL, 1, 0)) { + printf("\tOk, spec parsed.\n"); + printf("Creating XML structures:\n"); + XMLSpec* pXSpec = XMLSpec::structCreate(pSpec); + if (pXSpec) { + printf("\tOk, structures created.\n"); + if (argc == 3) { + printf("Writing XML to %s ... ", argv[2]); + ofstream fOut(argv[2]); + if (fOut.is_open()) { + pXSpec->toXMLFile(fOut); + fOut.close(); + printf("Ok.\n"); + } + else { + delete pSpec; + printf("Failed.\n"); + return 2; + } + } + else if (argc == 2) { + pXSpec->toXMLFile(cout); + } + + delete pSpec; + return 0; + } + } + + printf("\tFailed.\n"); + return 3; +} Index: xmlspec/xml2rpm.c =================================================================== RCS file: rpm/xmlspec/xml2rpm.c,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 diff -u -u -r1.2.2.1 -r1.2.2.2 --- rpm/xmlspec/xml2rpm.c 28 Aug 2002 10:52:43 -0000 1.2.2.1 +++ rpm/xmlspec/xml2rpm.c 10 Oct 2002 22:47:59 -0000 1.2.2.2 @@ -8,6 +8,10 @@ #include "xml2rpm.h" #include "xmlstruct.h" +#ifdef XML_DEBUG +#include "header_internal.h" +#endif + // This is where our packaged scripts start (or the largest number // of the sources) int g_nMaxSourceNum = 511; @@ -304,8 +308,14 @@ createRPMSource(pScript->m_szScript, g_nMaxSourceNum+1, pSpec, RPMBUILD_ISSOURCE); } - if (pScript->m_szEntry) - appendLineStringBuf(pSb, pScript->m_szEntry); + if (pScript->m_szEntry) { + // we do a newStrEx to make sure we expand all + // macros, as is done in the case of the files + // (done as part of the fileToStr call) + newStrEx(pScript->m_szEntry, (char**)(&szTmp)); + appendLineStringBuf(pSb, szTmp); + freeStr(&(szTmp)); + } pScript = pScript->m_pNext; } } @@ -335,6 +345,32 @@ pScripts->m_szInterpreter, 1); } +void handleProvObsConf(Header pHeader, t_structXMLRequire* pReqs, rpmsenseFlags fSense) +{ + t_structXMLRequire* pReq = NULL; + int nFlags = 0; + int i = 0; + int nIndex = 0; + + pReq = pReqs; + while (pReq) { + if (pReq->m_szName) { + nFlags = 0; + if (pReq->m_szCompare && pReq->m_szVersion) { + for (i = 0; sReqComp[i].m_szCmp; i++) { + if (!strcasecmp(sReqComp[i].m_szCmp, + pReq->m_szCompare)) { + nFlags = (sReqComp[i].m_rpmCmp | RPMSENSE_ANY) & ~RPMSENSE_SENSEMASK; + } + } + } + addReqProv(NULL, pHeader, fSense | nFlags, + pReq->m_szName, pReq->m_szVersion, nIndex++); + } + pReq = pReq->m_pNext; + } +} + void convertXMLPackage(const t_structXMLPackage* pXMLPkg, const t_structXMLSpec* pXMLSpec, Spec pSpec) @@ -364,6 +400,11 @@ _free(szArch); _free(szOs); + // do the provides, obsoletes, conflicts + handleProvObsConf(pPkg->header, pXMLPkg->m_pProvides, RPMSENSE_PROVIDES); + handleProvObsConf(pPkg->header, pXMLPkg->m_pObsoletes, RPMSENSE_OBSOLETES); + handleProvObsConf(pPkg->header, pXMLPkg->m_pConflicts, RPMSENSE_CONFLICTS); + if (pXMLPkg->m_szName) headerAddOrAppendEntry(pPkg->header, RPMTAG_NAME, RPM_STRING_TYPE, pXMLPkg->m_szName, 1); @@ -514,7 +555,7 @@ pSpec->build = scriptsToStringBuf(pXMLSpec->m_pBuild, pSpec); pSpec->install = scriptsToStringBuf(pXMLSpec->m_pInstall, pSpec); pSpec->clean = scriptsToStringBuf(pXMLSpec->m_pClean, pSpec); - + convertXMLPackage(pXMLSpec->m_pPackages, pXMLSpec, pSpec); initSourceHeader(pSpec); Index: xmlspec/xml2spec.cpp =================================================================== RCS file: xmlspec/xml2spec.cpp diff -N xmlspec/xml2spec.cpp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ rpm/xmlspec/xml2spec.cpp 28 Aug 2002 10:52:43 -0000 1.2.2.1 @@ -0,0 +1,52 @@ +// standard C++ includes +#include + +// our includes +#include "XMLParser.h" +#include "XMLSpec.h" + +// display some usage +int usage() +{ + printf("Usage: xml2spec input [output]\n"); + printf("Converts the input pkg.spec.xml file to a pkg.spec\n"); + printf("file for use in an rpmbuild command.\n\n"); + return 1; +} + +// program entry point +int main(int argc, + char** argv) +{ + printf("\nxml2spec, version 0.01\n"); + if (argc != 2 && argc != 3) { + usage(); + return 1; + } + + XMLSpec* pSpec = NULL; + if (parseXMLSpec(argv[1], pSpec) == 0 && pSpec) { + if (argc == 3) { + printf("Writing spec to %s ... ", argv[2]); + ofstream fOut(argv[2]); + if (fOut.is_open()) { + pSpec->toSpecFile(fOut); + fOut.close(); + printf("Ok.\n"); + } + else { + delete pSpec; + printf("Failed.\n"); + return 2; + } + } + else if (argc == 2) { + pSpec->toSpecFile(cout); + } + + delete pSpec; + return 0; + } + + return 3; +} Index: xmlspec/xmlparse.c =================================================================== RCS file: rpm/xmlspec/xmlparse.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -u -r1.1.2.1 -r1.1.2.2 --- rpm/xmlspec/xmlparse.c 28 Aug 2002 10:52:43 -0000 1.1.2.1 +++ rpm/xmlspec/xmlparse.c 10 Oct 2002 22:47:59 -0000 1.1.2.2 @@ -43,7 +43,15 @@ addXMLMacro(pParse->m_pAttrs, &(pSpec->m_pMacros)); break; case TAGVAL_SOURCE: - addXMLSource(pParse->m_pAttrs, &(pSpec->m_pSources)); + if (pSpec->m_pSources) + addXMLSource(pParse->m_pAttrs, &(pSpec->m_pSources)); + else { + if ((addXMLSource(pParse->m_pAttrs, &(pSpec->m_pSources))) && + (pSpec->m_pSources->m_szDirectory)) { + newStr(pSpec->m_pSources->m_szDirectory, + (char**)&(pSpec->m_szBuildSubdir)); + } + } break; case TAGVAL_PATCH: addXMLSource(pParse->m_pAttrs, &(pSpec->m_pPatches)); @@ -178,6 +186,12 @@ appendStringBuf(pSb, szTmp); appendStringBuf(pSb, pSource->m_szName); } + else if (!strcasecmp(szTmp, "tgz")) { + szTmp = NULL; + newStrEx("%{_gzipbin} -dc ", &szTmp); + appendStringBuf(pSb, szTmp); + appendStringBuf(pSb, pSource->m_szName); + } else if (!strcasecmp(szTmp, "zip")) { szTmp = NULL; newStrEx("%{_unzipbin} ", &szTmp); @@ -265,8 +279,8 @@ appendStringBuf(pSb, pSource->m_szName); } freeStr(&szTmp); - szTmp = malloc(strlen(" > patch -p1234567890 -s ")+strlen(pSource->m_szName)+1); - sprintf(szTmp, " | patch -p%d -s", nLevel); + szTmp = malloc(strlen(" > patch -pN1234567890 -s ")+strlen(pSource->m_szName)+1); + sprintf(szTmp, " | patch -Np%d -s", nLevel); appendStringBuf(pSb, szTmp); appendLineStringBuf(pSb, ""); appendLineStringBuf(pSb, "STATUS=$?"); @@ -290,6 +304,9 @@ case TAGVAL_SUMMARY: case TAGVAL_DESCRIPTION: case TAGVAL_REQUIRES: + case TAGVAL_PROVIDES: + case TAGVAL_OBSOLETES: + case TAGVAL_CONFLICTS: // we don't need to do anything break; default: @@ -315,6 +332,18 @@ pPkg = getLastXMLPackage(pSpec->m_pPackages); addXMLRequire(pParse->m_pAttrs, &(pPkg->m_pRequires)); break; + case TAGVAL_PROVIDE: + pPkg = getLastXMLPackage(pSpec->m_pPackages); + addXMLRequire(pParse->m_pAttrs, &(pPkg->m_pProvides)); + break; + case TAGVAL_OBSOLETE: + pPkg = getLastXMLPackage(pSpec->m_pPackages); + addXMLRequire(pParse->m_pAttrs, &(pPkg->m_pObsoletes)); + break; + case TAGVAL_CONFLICT: + pPkg = getLastXMLPackage(pSpec->m_pPackages); + addXMLRequire(pParse->m_pAttrs, &(pPkg->m_pConflicts)); + break; case TAGVAL_CHANGE: pChanges = getLastXMLChanges(pSpec->m_pChangelog); addXMLChange(pParse->m_pAttrs, &(pChanges->m_pChanges)); @@ -544,32 +573,26 @@ int nLen) { t_structXMLParse* pParse = NULL; + char* szVal = NULL; char* szTmp = NULL; - char* szTmpValue = NULL; - char* szPos = NULL; if ((pParse = (t_structXMLParse*)pData)) { - szTmp = malloc(nLen+2); - szTmp[nLen] = '\0'; - snprintf(szTmp, nLen+1, "%s", szValue); - szPos = szTmp; - while ((*szPos == ' ') || - (*szPos == '\t') || - (*szPos == '\r') || - (*szPos == '\n')) - szPos++; - - if (strlen(szPos)) { + szVal = malloc(nLen+2); + szVal[nLen] = '\0'; + snprintf(szVal, nLen+1, "%s", szValue); + if (strlen(szVal)) { + while ((szTmp = strchr(szVal, '\t'))) + *szTmp = ' '; if (pParse->m_szValue) { - szTmpValue = malloc(strlen(szPos)+strlen(pParse->m_szValue)+1); - sprintf(szTmpValue, "%s%s", pParse->m_szValue, szPos); - newStr(szTmpValue, &(pParse->m_szValue)); - free(szTmpValue); + szTmp = malloc(strlen(szVal)+strlen(pParse->m_szValue)+1); + sprintf(szTmp, "%s%s", pParse->m_szValue, szVal); + newStr(szTmp, &(pParse->m_szValue)); + free(szTmp); } else - newStr(szPos, &(pParse->m_szValue)); + newStr(szVal, &(pParse->m_szValue)); } - free(szTmp); + free(szVal); } } Index: xmlspec/xmlstruct.c =================================================================== RCS file: rpm/xmlspec/xmlstruct.c,v retrieving revision 1.2.2.1 retrieving revision 1.2.2.2 diff -u -u -r1.2.2.1 -r1.2.2.2 --- rpm/xmlspec/xmlstruct.c 28 Aug 2002 10:52:43 -0000 1.2.2.1 +++ rpm/xmlspec/xmlstruct.c 10 Oct 2002 22:47:59 -0000 1.2.2.2 @@ -97,7 +97,7 @@ { while (pAttr && (strcasecmp(szName, pAttr->m_szName) != 0)) pAttr = pAttr->m_pNext; - + return pAttr; } @@ -236,7 +236,7 @@ attrSetInt(pAttr, "size", &(pSource->m_nSize)); attrSetStr(pAttr, "md5", &(pSource->m_szMD5)); attrSetStr(pAttr, "directory", &(pSource->m_szDirectory)); - attrSetInt(pAttr, "number", &(pSource->m_nNum)); + attrSetInt(pAttr, "id", &(pSource->m_nNum)); } while ((pAttr = pAttr->m_pNext)); } @@ -365,6 +365,8 @@ if ((pScript = malloc(sizeof(t_structXMLScript)))) { pScript->m_szInterpreter = NULL; + pScript->m_szArch = NULL; + pScript->m_szOS = NULL; pScript->m_szScript = NULL; pScript->m_szEntry = NULL; pScript->m_pNext = NULL; @@ -373,6 +375,10 @@ do { attrSetStr(pAttr, "interpreter", &(pScript->m_szInterpreter)); + attrSetStr(pAttr, "arch", + &(pScript->m_szArch)); + attrSetStr(pAttr, "os", + &(pScript->m_szOS)); attrSetStr(pAttr, "script", &(pScript->m_szScript)); } while ((pAttr = pAttr->m_pNext)); @@ -386,6 +392,8 @@ { if (*ppScript) { freeStr(&((*ppScript)->m_szInterpreter)); + freeStr(&((*ppScript)->m_szArch)); + freeStr(&((*ppScript)->m_szOS)); freeStr(&((*ppScript)->m_szScript)); freeStr(&((*ppScript)->m_szEntry)); freeXMLScript(&((*ppScript)->m_pNext)); @@ -485,6 +493,59 @@ return 0; } +t_structI18NStr* newI18NStr(const t_structXMLAttr* pAttrs) +{ + t_structI18NStr* pStr = NULL; + t_structXMLAttr* pAttr = NULL; + + if ((pStr = malloc(sizeof(t_structI18NStr)))) { + pStr->m_szLang = NULL; + pStr->m_szText = NULL; + pStr->m_pNext = NULL; + + pAttr = (t_structXMLAttr*)pAttrs; + do { + attrSetStr(pAttr, "lang", &(pStr->m_szLang)); + } while ((pAttr = pAttr->m_pNext)); + } + + return pStr; +} + +int freeI18NStr(t_structI18NStr** ppStr) +{ + if (*ppStr) { + freeStr(&((*ppStr)->m_szLang)); + freeStr(&((*ppStr)->m_szText)); + freeI18NStr(&((*ppStr)->m_pNext)); + free(*ppStr); + } + *ppStr = NULL; + + return 0; +} + +t_structI18NStr* addI18NStr(const t_structXMLAttr* pAttrs, + t_structI18NStr** ppStr) +{ + t_structI18NStr* pStr = NULL; + + if ((pStr = getLastI18NStr(*ppStr))) + pStr = (pStr->m_pNext = newI18NStr(pAttrs)); + else + pStr = (*ppStr = newI18NStr(pAttrs)); + + return pStr; +} + +t_structI18NStr* getLastI18NStr(t_structI18NStr* pStr) +{ + while (pStr && (pStr->m_pNext)) + pStr = pStr->m_pNext; + + return pStr; +} + t_structXMLPackage* newXMLPackage(const t_structXMLAttr* pAttrs) { t_structXMLPackage* pPackage = NULL; @@ -492,6 +553,7 @@ if ((pPackage = malloc(sizeof(t_structXMLPackage)))) { pPackage->m_szName = NULL; + pPackage->m_szVersion = NULL; pPackage->m_szGroup = NULL; pPackage->m_szSummary = NULL; pPackage->m_szDescription = NULL; @@ -507,15 +569,21 @@ pPackage->m_pRequires = NULL; pPackage->m_pSuggests = NULL; pPackage->m_pObsoletes = NULL; + pPackage->m_pConflicts = NULL; pPackage->m_pProvides = NULL; pPackage->m_pNext = NULL; pAttr = (t_structXMLAttr*)pAttrs; do { attrSetStr(pAttr, "name", &(pPackage->m_szName)); + attrSetStr(pAttr, "version", &(pPackage->m_szVersion)); attrSetStr(pAttr, "group", &(pPackage->m_szGroup)); attrSetBool(pAttr, "autorequire", &(pPackage->m_nAutoRequire)); + attrSetBool(pAttr, "autoreq", &(pPackage->m_nAutoRequire)); attrSetBool(pAttr, "autoprovide", &(pPackage->m_nAutoProvide)); + attrSetBool(pAttr, "autoprov", &(pPackage->m_nAutoProvide)); + attrSetBool(pAttr, "autoreqprov", &(pPackage->m_nAutoProvide)); + attrSetBool(pAttr, "autoreqprov", &(pPackage->m_nAutoRequire)); attrSetBool(pAttr, "autosuggest", &(pPackage->m_nAutoSuggest)); } while ((pAttr = pAttr->m_pNext)); } @@ -527,6 +595,7 @@ { if (*ppPackage) { freeStr(&((*ppPackage)->m_szName)); + freeStr(&((*ppPackage)->m_szVersion)); freeStr(&((*ppPackage)->m_szGroup)); freeStr(&((*ppPackage)->m_szSummary)); freeStr(&((*ppPackage)->m_szDescription)); @@ -539,6 +608,7 @@ freeXMLRequire(&((*ppPackage)->m_pRequires)); freeXMLRequire(&((*ppPackage)->m_pSuggests)); freeXMLRequire(&((*ppPackage)->m_pObsoletes)); + freeXMLRequire(&((*ppPackage)->m_pConflicts)); freeXMLRequire(&((*ppPackage)->m_pProvides)); freeXMLPackage(&((*ppPackage)->m_pNext)); free(*ppPackage); Index: xmlspec/xmlstruct.h =================================================================== RCS file: rpm/xmlspec/xmlstruct.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -u -r1.1.2.1 -r1.1.2.2 --- rpm/xmlspec/xmlstruct.h 28 Aug 2002 10:52:43 -0000 1.1.2.1 +++ rpm/xmlspec/xmlstruct.h 10 Oct 2002 22:47:59 -0000 1.1.2.2 @@ -52,6 +52,8 @@ typedef struct structXMLScript { char* m_szInterpreter; + char* m_szArch; + char* m_szOS; char* m_szScript; char* m_szEntry; struct structXMLScript* m_pNext; @@ -71,9 +73,17 @@ char* m_szGID; } t_structXMLFiles; +typedef struct structI18NStr +{ + char* m_szLang; + char* m_szText; + struct structI18NStr* m_pNext; +} t_structI18NStr; + typedef struct structXMLPackage { char* m_szName; + char* m_szVersion; char* m_szGroup; char* m_szSummary; char* m_szDescription; @@ -89,6 +99,7 @@ struct structXMLRequire* m_pRequires; struct structXMLRequire* m_pSuggests; struct structXMLRequire* m_pObsoletes; + struct structXMLRequire* m_pConflicts; struct structXMLRequire* m_pProvides; struct structXMLPackage* m_pNext; } t_structXMLPackage; @@ -200,6 +211,12 @@ t_structXMLFiles* newXMLFiles(const t_structXMLAttr* pAttrs); int freeXMLFiles(t_structXMLFiles** ppFiles); + +t_structI18NStr* newI18NStr(const t_structXMLAttr* pAttrs); +int freeI18NStr(t_structI18NStr** ppStr); +t_structI18NStr* addI18NStr(const t_structXMLAttr* pAttrs, + t_structI18NStr** ppStr); +t_structI18NStr* getLastI18NStr(t_structI18NStr* pStr); t_structXMLPackage* newXMLPackage(const t_structXMLAttr* pAttrs); int freeXMLPackage(t_structXMLPackage** ppPackage); Index: xmlspec/xmlverify.c =================================================================== RCS file: rpm/xmlspec/xmlverify.c,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -u -r1.1.2.1 -r1.1.2.2 --- rpm/xmlspec/xmlverify.c 28 Aug 2002 10:52:43 -0000 1.1.2.1 +++ rpm/xmlspec/xmlverify.c 10 Oct 2002 22:47:59 -0000 1.1.2.2 @@ -58,7 +58,7 @@ {"size", ATTRTYPE_NUMERIC, 0}, {"md5", ATTRTYPE_MD5, 0}, {"path", ATTRTYPE_ANY, 0}, - {"number", ATTRTYPE_NUMERIC, 0}, + {"id", ATTRTYPE_NUMERIC, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -89,7 +89,7 @@ {"size", ATTRTYPE_NUMERIC, 0}, {"md5", ATTRTYPE_MD5, 0}, {"path", ATTRTYPE_ANY, 0}, - {"number", ATTRTYPE_NUMERIC, 0}, + {"id", ATTRTYPE_NUMERIC, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -165,6 +165,7 @@ }, { {"name", ATTRTYPE_ANY, 0}, + {"version", ATTRTYPE_ANY, 0}, {"group", ATTRTYPE_ANY, 1}, {"autoreqprov", ATTRTYPE_BOOL, 0}, {"autoprov", ATTRTYPE_BOOL, 0}, @@ -219,6 +220,7 @@ }, { {"name", ATTRTYPE_ANY, 1}, + {"version", ATTRTYPE_ANY, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -243,6 +245,34 @@ }, { {"name", ATTRTYPE_ANY, 1}, + {"version", ATTRTYPE_ANY, 0}, + {"cmp", ATTRTYPE_CMP, 0}, + {NULL, ATTRTYPE_ANY, 1} + } + }, + { + "conflicts", TAGVAL_CONFLICTS, 2, + { + TAGVAL_SPEC, + TAGVAL_PACKAGE, + TAGVAL_LAST + }, + { + {NULL, ATTRTYPE_ANY, 1} + } + }, + { + "conflict", TAGVAL_CONFLICT, 3, + { + TAGVAL_SPEC, + TAGVAL_PACKAGE, + TAGVAL_CONFLICTS, + TAGVAL_LAST + }, + { + {"name", ATTRTYPE_ANY, 1}, + {"version", ATTRTYPE_ANY, 0}, + {"cmp", ATTRTYPE_CMP, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -280,6 +310,7 @@ TAGVAL_LAST }, { + {"lang", ATTRTYPE_ANY, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -291,6 +322,7 @@ TAGVAL_LAST }, { + {"lang", ATTRTYPE_ANY, 0}, {NULL, ATTRTYPE_ANY, 1} } }, @@ -317,6 +349,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -344,6 +378,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -371,6 +407,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -398,11 +436,14 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } }, - {"verify", TAGVAL_VERIFY, 2, + { + "verify", TAGVAL_VERIFY, 2, { TAGVAL_SPEC, TAGVAL_PACKAGE, @@ -424,6 +465,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -463,6 +506,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -476,6 +521,8 @@ }, { {"source", ATTRTYPE_NUMERIC, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"path", ATTRTYPE_ANY, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -489,6 +536,8 @@ }, { {"patch", ATTRTYPE_NUMERIC, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"level", ATTRTYPE_NUMERIC, 0}, {"path", ATTRTYPE_ANY, 0}, {NULL, ATTRTYPE_ANY, 1} @@ -515,6 +564,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -540,6 +591,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } @@ -565,6 +618,8 @@ }, { {"interpreter", ATTRTYPE_ANY, 0}, + {"arch", ATTRTYPE_ANY, 0}, + {"os", ATTRTYPE_ANY, 0}, {"script", ATTRTYPE_SCRIPT, 0}, {NULL, ATTRTYPE_ANY, 1} } Index: xmlspec/xmlverify.h =================================================================== RCS file: rpm/xmlspec/xmlverify.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -u -r1.1.2.1 -r1.1.2.2 --- rpm/xmlspec/xmlverify.h 28 Aug 2002 10:52:43 -0000 1.1.2.1 +++ rpm/xmlspec/xmlverify.h 10 Oct 2002 22:47:59 -0000 1.1.2.2 @@ -22,6 +22,8 @@ TAGVAL_REQUIRE, TAGVAL_OBSOLETES, TAGVAL_OBSOLETE, + TAGVAL_CONFLICTS, + TAGVAL_CONFLICT, TAGVAL_SUGGESTS, TAGVAL_SUGGEST, TAGVAL_SUMMARY,