Wide-range changes and bugfixing. Commit to sync w/ desktop
CVS patchset: 4249 CVS date: 2000/11/10 08:49:57
This commit is contained in:
parent
843e9e7763
commit
011f727bbf
|
@ -1,6 +1,6 @@
|
|||
#!/bin/perl
|
||||
|
||||
# $Id: Makefile.PL,v 1.13 2000/10/13 08:42:32 rjray Exp $
|
||||
# $Id: Makefile.PL,v 1.14 2000/11/10 08:49:57 rjray Exp $
|
||||
|
||||
use Config;
|
||||
use ExtUtils::MakeMaker;
|
||||
|
@ -95,8 +95,9 @@ WriteMakefile(
|
|||
XS => \%XS,
|
||||
EXE_FILES => [ @SAMPLES ],
|
||||
OBJECT => $OBJECT,
|
||||
INC => "-I. -I$rpm_libdir",
|
||||
INC => "-Wunused -I. -I$rpm_libdir",
|
||||
DIR => [],
|
||||
XSOPT => '-nolinenumbers',
|
||||
dist => { COMPRESS => 'gzip -9f' },
|
||||
clean => { FILES => $CLEAN }
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: RPM.h,v 1.12 2000/10/10 08:37:20 rjray Exp $
|
||||
* $Id: RPM.h,v 1.13 2000/11/10 08:49:57 rjray Exp $
|
||||
*
|
||||
* Various C-specific decls/includes/etc. for the RPM linkage
|
||||
*/
|
||||
|
@ -51,9 +51,33 @@
|
|||
#define RPM_HEADER_READONLY 0x01
|
||||
#define RPM_HEADER_FROM_REF 0x02
|
||||
|
||||
#define RPM_PACKAGE_MASK 0xf0
|
||||
#define RPM_PACKAGE_READONLY 0x10
|
||||
#define RPM_PACKAGE_NOREAD 0x20
|
||||
#define RPM_PACKAGE_MASK 0x0f00
|
||||
#define RPM_PACKAGE_READONLY 0x0100
|
||||
#define RPM_PACKAGE_NOREAD 0x0200
|
||||
|
||||
/*
|
||||
Use this define for deriving the saved underlying struct, rather than coding
|
||||
it a dozen places.
|
||||
*/
|
||||
#define struct_from_object_ret(type, header, object, err_ret) \
|
||||
{ \
|
||||
MAGIC* mg = mg_find((SV *)(object), '~'); \
|
||||
if (mg) \
|
||||
(header) = (type *)SvIV(mg->mg_obj); \
|
||||
else \
|
||||
return (err_ret); \
|
||||
}
|
||||
/* And a no-return version: */
|
||||
#define struct_from_object(type, header, object) \
|
||||
{ \
|
||||
MAGIC* mg = mg_find((SV *)(object), '~'); \
|
||||
if (mg) \
|
||||
(header) = (type *)SvIV(mg->mg_obj); \
|
||||
else \
|
||||
(header) = Null(type *); \
|
||||
}
|
||||
|
||||
#define new_RPM_storage(type) (type *)safemalloc(sizeof(type))
|
||||
|
||||
/*
|
||||
* Perl complement: RPM::Database
|
||||
|
@ -61,9 +85,7 @@
|
|||
|
||||
/*
|
||||
This is the underlying struct that implements the interface to the RPM
|
||||
database. Since we need the actual object to be a hash, the struct will
|
||||
be stored as an SV (actually, a pointer to a struct) on a special key
|
||||
defined below.
|
||||
database.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
@ -76,12 +98,12 @@ typedef struct {
|
|||
int offx;
|
||||
int* offsets;
|
||||
#endif
|
||||
/* This HV will be used to cache key/value pairs to avoid re-computing */
|
||||
HV* storage;
|
||||
} RPM_Database;
|
||||
|
||||
typedef HV* RPM__Database;
|
||||
|
||||
#define new_RPM__Database(x) x = newHV()
|
||||
|
||||
|
||||
/*
|
||||
* Perl complement: RPM::Header
|
||||
|
@ -89,9 +111,7 @@ typedef HV* RPM__Database;
|
|||
|
||||
/*
|
||||
This is the underlying struct that implements the interface to the RPM
|
||||
headers. As above, we need the actual object to be a hash, so the struct
|
||||
will be stored as an SV on the same sort of special key as RPM__Database
|
||||
uses.
|
||||
headers.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
|
@ -104,6 +124,8 @@ typedef struct {
|
|||
int isSource; /* If this header is for a source RPM (SRPM) */
|
||||
int major; /* Major and minor rev numbers of package's format */
|
||||
int minor;
|
||||
/* This HV will be used to cache key/value pairs to avoid re-computing */
|
||||
HV* storage;
|
||||
/* Keep a per-header iterator for things like FIRSTKEY and NEXTKEY */
|
||||
HeaderIterator iterator;
|
||||
int read_only;
|
||||
|
@ -114,8 +136,6 @@ typedef struct {
|
|||
|
||||
typedef HV* RPM__Header;
|
||||
|
||||
#define new_RPM__Header(x) x = newHV()
|
||||
|
||||
|
||||
/*
|
||||
* Perl complement: RPM::Package
|
||||
|
@ -139,34 +159,12 @@ typedef struct {
|
|||
int readonly;
|
||||
/* The current notify/callback function associated with this package */
|
||||
CV* callback;
|
||||
/* Any data they want to have passed to the callback */
|
||||
SV* cb_data;
|
||||
} RPM_Package;
|
||||
|
||||
typedef RPM_Package* RPM__Package;
|
||||
|
||||
#define new_RPM__Package(x) x = (RPM__Package)safemalloc(sizeof(RPM_Package))
|
||||
|
||||
|
||||
/*
|
||||
Because our HV* are going to be set magical, the following is needed for
|
||||
explicit fetch and store calls that are done within the tied FETCH/STORE
|
||||
methods.
|
||||
*/
|
||||
#define hv_fetch_nomg(SVP, h, k, kl, f) \
|
||||
SvMAGICAL_off((SV *)(h)); \
|
||||
(SVP) = hv_fetch((h), (k), (kl), (f)); \
|
||||
SvMAGICAL_on((SV *)(h))
|
||||
#define hv_store_nomg(h, k, kl, v, f) \
|
||||
SvMAGICAL_off((SV *)(h)); \
|
||||
hv_store((h), (k), (kl), (v), (f)); \
|
||||
SvMAGICAL_on((SV *)(h))
|
||||
|
||||
/*
|
||||
This silly-looking key is what will be used on the RPM::Header and
|
||||
RPM::Database objects to stash the underlying struct.
|
||||
*/
|
||||
#define STRUCT_KEY "<<<struct>>>"
|
||||
/* This must match! */
|
||||
#define STRUCT_KEY_LEN 13
|
||||
|
||||
/*
|
||||
These represent the various interfaces that are allowed for use outside
|
||||
|
@ -184,11 +182,11 @@ extern void rpm_error(pTHX_ int, const char *);
|
|||
|
||||
/* RPM/Header.xs: */
|
||||
extern const char* sv2key(pTHX_ SV *);
|
||||
extern RPM__Header rpmhdr_TIEHASH(pTHX_ SV *, SV *, int);
|
||||
extern RPM__Header rpmhdr_TIEHASH(pTHX_ char *, SV *, int);
|
||||
extern SV* rpmhdr_FETCH(pTHX_ RPM__Header, SV *, const char *, int, int);
|
||||
extern int rpmhdr_STORE(pTHX_ RPM__Header, SV *, SV *);
|
||||
extern int rpmhdr_DELETE(pTHX_ RPM__Header, SV *);
|
||||
extern int rpmhdr_EXISTS(pTHX_ RPM__Header, SV *);
|
||||
extern bool rpmhdr_EXISTS(pTHX_ RPM__Header, SV *);
|
||||
extern unsigned int rpmhdr_size(pTHX_ RPM__Header);
|
||||
extern int rpmhdr_tagtype(pTHX_ RPM__Header, SV *);
|
||||
extern int rpmhdr_write(pTHX_ RPM__Header, SV *, int);
|
||||
|
@ -199,7 +197,7 @@ extern int rpmhdr_scalar_tag(pTHX_ SV*, int);
|
|||
/* RPM/Database.xs: */
|
||||
extern RPM__Database rpmdb_TIEHASH(pTHX_ char *, SV *);
|
||||
extern RPM__Header rpmdb_FETCH(pTHX_ RPM__Database, SV *);
|
||||
extern int rpmdb_EXISTS(pTHX_ RPM__Database, SV *);
|
||||
extern bool rpmdb_EXISTS(pTHX_ RPM__Database, SV *);
|
||||
|
||||
/* RPM/Package.xs: */
|
||||
extern RPM__Package rpmpkg_new(pTHX_ char *, SV *, int);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#include "RPM.h"
|
||||
|
||||
static char * const rcsid = "$Id: RPM.xs,v 1.8 2000/10/13 09:24:05 rjray Exp $";
|
||||
static char * const rcsid = "$Id: RPM.xs,v 1.9 2000/11/10 08:49:57 rjray Exp $";
|
||||
|
||||
extern XS(boot_RPM__Constants);
|
||||
extern XS(boot_RPM__Header);
|
||||
|
@ -59,7 +59,6 @@ const char* num2tag(pTHX_ int num)
|
|||
{
|
||||
SV** svp;
|
||||
char str_num[8];
|
||||
SV* tmp;
|
||||
|
||||
Zero(str_num, 1, 8);
|
||||
snprintf(str_num, 8, "%d", num);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
###############################################################################
|
||||
#
|
||||
# $Id: Database.pm,v 1.11 2000/10/13 08:47:26 rjray Exp $
|
||||
# $Id: Database.pm,v 1.12 2000/11/10 08:49:57 rjray Exp $
|
||||
#
|
||||
# Description: The RPM::Database class provides access to the RPM database
|
||||
# as a tied hash, whose keys are taken as the names of
|
||||
|
@ -36,7 +36,7 @@ require RPM;
|
|||
require RPM::Header;
|
||||
|
||||
$VERSION = '0.291';
|
||||
$revision = do { my @r=(q$Revision: 1.11 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
|
||||
$revision = do { my @r=(q$Revision: 1.12 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
|
||||
|
||||
1;
|
||||
|
||||
|
@ -46,7 +46,6 @@ sub new
|
|||
my %hash = ();
|
||||
|
||||
tie %hash, $class;
|
||||
return (tied %hash);
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -5,22 +5,7 @@
|
|||
#include <fcntl.h>
|
||||
#include "RPM.h"
|
||||
|
||||
static char * const rcsid = "$Id: Database.xs,v 1.8 2000/10/05 04:48:59 rjray Exp $";
|
||||
|
||||
/*
|
||||
Use this define for deriving the saved rpmdb struct, rather than coding
|
||||
it a dozen places. Note that the hv_fetch call is the no-magic one defined
|
||||
in RPM.h
|
||||
*/
|
||||
#define dbstruct_from_object_ret(s_ptr, rdb, object, err_ret) \
|
||||
hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
|
||||
(rdb) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Database *)SvIV(*(s_ptr)) : NULL; \
|
||||
if (! (rdb)) return (err_ret);
|
||||
/* And a no-return-value version: */
|
||||
#define dbstruct_from_object(s_ptr, rdb, object) \
|
||||
hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
|
||||
(rdb) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Database *)SvIV(*(s_ptr)) : NULL; \
|
||||
if (! (rdb)) return;
|
||||
static char * const rcsid = "$Id: Database.xs,v 1.9 2000/11/10 08:49:57 rjray Exp $";
|
||||
|
||||
/*
|
||||
rpmdb_TIEHASH
|
||||
|
@ -36,10 +21,10 @@ RPM__Database rpmdb_TIEHASH(pTHX_ char* class, SV* opts)
|
|||
int mode = O_RDONLY;
|
||||
mode_t perms = 0;
|
||||
HV* opt_hash;
|
||||
SV* value;
|
||||
SV* t_magic;
|
||||
SV** svp;
|
||||
RPM_Database* dbstruct;
|
||||
RPM__Database TIEHASH;
|
||||
RPM_Database* retvalp; /* For "private" */
|
||||
RPM__Database RETVAL;
|
||||
|
||||
if (opts)
|
||||
{
|
||||
|
@ -68,29 +53,31 @@ RPM__Database rpmdb_TIEHASH(pTHX_ char* class, SV* opts)
|
|||
}
|
||||
|
||||
/* With that all processed, attempt to open the actual RPM DB */
|
||||
/* The dbstruct is used for the C-level rpmlib information on databases */
|
||||
dbstruct = safemalloc(sizeof(RPM_Database));
|
||||
Zero(dbstruct, 1, RPM_Database);
|
||||
if (rpmdbOpen(root, &dbstruct->dbp, mode, perms) != 0)
|
||||
/* The retvalp is used for the C-level rpmlib information on databases */
|
||||
retvalp = new_RPM_storage(RPM_Database);
|
||||
if (rpmdbOpen(root, &retvalp->dbp, mode, perms) != 0)
|
||||
/* rpm lib will have set the error already */
|
||||
return (Null(RPM__Database));
|
||||
else
|
||||
{
|
||||
dbstruct->current_rec = 0;
|
||||
retvalp->current_rec = 0;
|
||||
#if RPM_MAJOR < 4
|
||||
dbstruct->index_set = (void *)NULL;
|
||||
retvalp->index_set = (void *)NULL;
|
||||
#else
|
||||
dbstruct->noffs = dbstruct->offx = 0;
|
||||
dbstruct->offsets = (int *)NULL;
|
||||
retvalp->noffs = retvalp->offx = 0;
|
||||
retvalp->offsets = (int *)NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
new_RPM__Database(TIEHASH);
|
||||
/* STRUCT_KEY is used to stash the C-level struct on the TIEHASH obj */
|
||||
hv_store_nomg(TIEHASH,
|
||||
STRUCT_KEY, STRUCT_KEY_LEN, newSViv((unsigned)dbstruct),
|
||||
FALSE);
|
||||
return TIEHASH;
|
||||
RETVAL = newHV();
|
||||
retvalp->storage = newHV();
|
||||
t_magic = newSViv((unsigned)retvalp);
|
||||
|
||||
sv_magic((SV *)RETVAL, Nullsv, 'P', Nullch, 0);
|
||||
sv_magic((SV *)RETVAL, t_magic, '~', Nullch, 0);
|
||||
SvREFCNT_dec(t_magic);
|
||||
|
||||
return RETVAL;
|
||||
}
|
||||
|
||||
RPM__Header rpmdb_FETCH(pTHX_ RPM__Database self, SV* key)
|
||||
|
@ -109,7 +96,7 @@ RPM__Header rpmdb_FETCH(pTHX_ RPM__Database self, SV* key)
|
|||
/* Any successful operation will re-assign this */
|
||||
FETCH = Null(RPM__Header);
|
||||
|
||||
dbstruct_from_object_ret(svp, dbstruct, self, FETCH);
|
||||
struct_from_object_ret(RPM_Database, dbstruct, self, FETCH);
|
||||
/* De-reference key, if it is a reference */
|
||||
if (SvROK(key))
|
||||
key = SvRV(key);
|
||||
|
@ -124,10 +111,10 @@ RPM__Header rpmdb_FETCH(pTHX_ RPM__Database self, SV* key)
|
|||
|
||||
/* Step 1: Check to see if this has already been requested and is
|
||||
thus cached on the hash itself */
|
||||
hv_fetch_nomg(svp, self, (char *)name, namelen, FALSE);
|
||||
if (svp && SvOK(*svp))
|
||||
svp = hv_fetch(dbstruct->storage, (char *)name, namelen, FALSE);
|
||||
if (svp && SvROK(*svp))
|
||||
{
|
||||
FETCH = (RPM__Header)SvIV(*svp);
|
||||
FETCH = (RPM__Header)SvRV(*svp);
|
||||
return FETCH;
|
||||
}
|
||||
|
||||
|
@ -201,15 +188,16 @@ RPM__Header rpmdb_FETCH(pTHX_ RPM__Database self, SV* key)
|
|||
#if RPM_MAJOR >= 4
|
||||
hdr = headerLink(hdr);
|
||||
#endif
|
||||
FETCH = rpmhdr_TIEHASH(aTHX_ sv_2mortal(newSVpv("RPM::Header", 12)),
|
||||
sv_2mortal(newRV((SV *)hdr)),
|
||||
FETCH = rpmhdr_TIEHASH(aTHX_ "RPM::Header",
|
||||
sv_2mortal(newSViv((unsigned)hdr)),
|
||||
RPM_HEADER_FROM_REF | RPM_HEADER_READONLY);
|
||||
/* If name is no longer NULL, it means our vector in was a string
|
||||
(key), so put the result back into the hash-cache. */
|
||||
if (name != NULL)
|
||||
{
|
||||
hv_store_nomg(self, (char *)name, namelen,
|
||||
newSViv((unsigned)FETCH), FALSE);
|
||||
hv_store(dbstruct->storage, (char *)name, namelen,
|
||||
newRV((SV *)FETCH), FALSE);
|
||||
SvREFCNT_inc((SV *)FETCH);
|
||||
}
|
||||
}
|
||||
#if RPM_MAJOR >= 4
|
||||
|
@ -219,13 +207,12 @@ RPM__Header rpmdb_FETCH(pTHX_ RPM__Database self, SV* key)
|
|||
return FETCH;
|
||||
}
|
||||
|
||||
int rpmdb_EXISTS(pTHX_ RPM__Database self, SV* key)
|
||||
bool rpmdb_EXISTS(pTHX_ RPM__Database self, SV* key)
|
||||
{
|
||||
SV* tmp;
|
||||
|
||||
tmp = (SV *)rpmdb_FETCH(aTHX_ self, key);
|
||||
/* There is probably a cleaner test for (SV *)tmp == PL_sv_undef */
|
||||
return (SvANY(tmp) != NULL);
|
||||
return (tmp != Nullsv);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -237,9 +224,8 @@ int rpmdb_EXISTS(pTHX_ RPM__Database self, SV* key)
|
|||
int rpmdb_FIRSTKEY(pTHX_ RPM__Database self, SV** key, RPM__Header* value)
|
||||
{
|
||||
RPM_Database* dbstruct;
|
||||
SV** svp;
|
||||
|
||||
dbstruct_from_object_ret(svp, dbstruct, self, 0);
|
||||
struct_from_object_ret(RPM_Database, dbstruct, self, 0);
|
||||
#if RPM_MAJOR < 4
|
||||
/* This more or less resets our "iterator" */
|
||||
dbstruct->current_rec = 0;
|
||||
|
@ -285,9 +271,8 @@ int rpmdb_NEXTKEY(pTHX_ RPM__Database self, SV* key,
|
|||
SV** nextkey, RPM__Header* nextvalue)
|
||||
{
|
||||
RPM_Database* dbstruct;
|
||||
SV** svp;
|
||||
|
||||
dbstruct_from_object_ret(svp, dbstruct, self, 0);
|
||||
struct_from_object_ret(RPM_Database, dbstruct, self, 0);
|
||||
|
||||
#if RPM_MAJOR < 4
|
||||
if (! (dbstruct->current_rec = rpmdbNextRecNum(dbstruct->dbp,
|
||||
|
@ -311,10 +296,9 @@ int rpmdb_NEXTKEY(pTHX_ RPM__Database self, SV* key,
|
|||
|
||||
void rpmdb_DESTROY(pTHX_ RPM__Database self)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Database* dbstruct; /* This is the struct used to hold C-level data */
|
||||
|
||||
dbstruct_from_object(svp, dbstruct, self);
|
||||
struct_from_object(RPM_Database, dbstruct, self);
|
||||
|
||||
rpmdbClose(dbstruct->dbp);
|
||||
#if RPM_MAJOR < 4
|
||||
|
@ -323,10 +307,10 @@ void rpmdb_DESTROY(pTHX_ RPM__Database self)
|
|||
#else
|
||||
if (dbstruct->offsets)
|
||||
safefree(dbstruct->offsets);
|
||||
dbstruct->noffs = dbstruct->offx = 0;
|
||||
dbstruct->offsets = NULL;
|
||||
#endif
|
||||
|
||||
hv_undef(dbstruct->storage);
|
||||
safefree(dbstruct);
|
||||
hv_undef(self);
|
||||
}
|
||||
|
||||
|
@ -349,7 +333,6 @@ AV* rpmdb_find_by_whatever(pTHX_ RPM__Database self, SV* string, int idx)
|
|||
{
|
||||
const char* str = NULL; /* For the actual string out of (SV *)string */
|
||||
STRLEN len; /* Arg for SvPV(..., len) */
|
||||
SV** svp;
|
||||
RPM_Database* dbstruct; /* This is the struct used to hold C-level data */
|
||||
AV* return_val;
|
||||
int result, loop;
|
||||
|
@ -357,11 +340,11 @@ AV* rpmdb_find_by_whatever(pTHX_ RPM__Database self, SV* string, int idx)
|
|||
#if RPM_MAJOR >= 4
|
||||
rpmdbMatchIterator mi;
|
||||
#endif
|
||||
|
||||
|
||||
/* Any successful operation will store items on this */
|
||||
return_val = newAV();
|
||||
|
||||
dbstruct_from_object_ret(svp, dbstruct, self, return_val);
|
||||
struct_from_object_ret(RPM_Database, dbstruct, self, return_val);
|
||||
/* De-reference key, if it is a reference */
|
||||
if (SvROK(string))
|
||||
string = SvRV(string);
|
||||
|
@ -418,6 +401,7 @@ AV* rpmdb_find_by_whatever(pTHX_ RPM__Database self, SV* string, int idx)
|
|||
return return_val;
|
||||
}
|
||||
|
||||
|
||||
MODULE = RPM::Database PACKAGE = RPM::Database PREFIX = rpmdb_
|
||||
|
||||
|
||||
|
@ -442,8 +426,8 @@ rpmdb_FETCH(self, key)
|
|||
RETVAL
|
||||
|
||||
int
|
||||
rpmdb_STORE(self, key, value)
|
||||
RPM::Database self;
|
||||
rpmdb_STORE(self=NULL, key=NULL, value=NULL)
|
||||
SV* self;
|
||||
SV* key;
|
||||
SV* value;
|
||||
PROTOTYPE: $$$
|
||||
|
@ -455,22 +439,22 @@ rpmdb_STORE(self, key, value)
|
|||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
int
|
||||
rpmdb_DELETE(self, key)
|
||||
RPM::Database self;
|
||||
SV*
|
||||
rpmdb_DELETE(self=NULL, key=NULL)
|
||||
SV* self;
|
||||
SV* key;
|
||||
PROTOTYPE: $$
|
||||
CODE:
|
||||
{
|
||||
rpm_error(aTHX_ RPMERR_NOCREATEDB, "DELETE: operation not permitted");
|
||||
RETVAL = 0;
|
||||
RETVAL = Nullsv;
|
||||
}
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
RETVAL
|
||||
|
||||
int
|
||||
rpmdb_CLEAR(self)
|
||||
RPM::Database self;
|
||||
rpmdb_CLEAR(self=NULL)
|
||||
SV* self;
|
||||
PROTOTYPE: $
|
||||
CODE:
|
||||
{
|
||||
|
@ -478,9 +462,9 @@ rpmdb_CLEAR(self)
|
|||
RETVAL = 0;
|
||||
}
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
RETVAL
|
||||
|
||||
int
|
||||
bool
|
||||
rpmdb_EXISTS(self, key)
|
||||
RPM::Database self;
|
||||
SV* key;
|
||||
|
@ -492,13 +476,12 @@ rpmdb_EXISTS(self, key)
|
|||
|
||||
void
|
||||
rpmdb_FIRSTKEY(self)
|
||||
RPM::Header self;
|
||||
RPM::Database self;
|
||||
PROTOTYPE: $
|
||||
PREINIT:
|
||||
SV* key;
|
||||
SV* value;
|
||||
PPCODE:
|
||||
{
|
||||
SV* key;
|
||||
SV* value;
|
||||
RPM__Header hvalue;
|
||||
|
||||
if (! rpmdb_FIRSTKEY(aTHX_ self, &key, &hvalue))
|
||||
|
@ -519,17 +502,16 @@ rpmdb_NEXTKEY(self, key=NULL)
|
|||
RPM::Database self;
|
||||
SV* key;
|
||||
PROTOTYPE: $;$
|
||||
PREINIT:
|
||||
SV* nextkey;
|
||||
SV* nextvalue;
|
||||
PPCODE:
|
||||
{
|
||||
SV* nextkey;
|
||||
SV* nextvalue;
|
||||
RPM__Header hvalue;
|
||||
|
||||
if (! rpmdb_NEXTKEY(aTHX_ self, key, &nextkey, &hvalue))
|
||||
{
|
||||
nextkey = newSVsv(&PL_sv_undef);
|
||||
nextvalue = newRV(&PL_sv_undef);
|
||||
nextvalue = newSVsv(&PL_sv_undef);
|
||||
}
|
||||
else
|
||||
nextvalue = newRV((SV *)hvalue);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#
|
||||
###############################################################################
|
||||
#
|
||||
# $Id: Header.pm,v 1.14 2000/10/13 08:47:26 rjray Exp $
|
||||
# $Id: Header.pm,v 1.15 2000/11/10 08:49:57 rjray Exp $
|
||||
#
|
||||
# Description: The RPM::Header class provides access to the RPM Header
|
||||
# structure as a tied hash, allowing direct access to the
|
||||
|
@ -39,7 +39,7 @@ use RPM::Error;
|
|||
use RPM::Constants ':rpmerr';
|
||||
|
||||
$VERSION = '0.291';
|
||||
$revision = do { my @r=(q$Revision: 1.14 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
|
||||
$revision = do { my @r=(q$Revision: 1.15 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r };
|
||||
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = ();
|
||||
|
@ -69,7 +69,6 @@ sub new
|
|||
my %hash = ();
|
||||
|
||||
tie %hash, $class, @_;
|
||||
return (tied %hash);
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
|
|
|
@ -4,24 +4,30 @@
|
|||
|
||||
#include "RPM.h"
|
||||
|
||||
static char * const rcsid = "$Id: Header.xs,v 1.19 2000/10/12 05:09:16 rjray Exp $";
|
||||
static char * const rcsid = "$Id: Header.xs,v 1.20 2000/11/10 08:49:57 rjray Exp $";
|
||||
static int scalar_tag(pTHX_ SV *, int);
|
||||
|
||||
/*
|
||||
Use this define for deriving the saved Header struct, rather than coding
|
||||
it a dozen places. Note that the hv_fetch call is the no-magic one defined
|
||||
in RPM.h
|
||||
it a dozen places.
|
||||
*/
|
||||
#define header_from_object_ret(s_ptr, header, object, err_ret) \
|
||||
hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
|
||||
(header) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Header *)SvIV(*(s_ptr)) : NULL; \
|
||||
if (! (header)) \
|
||||
return (err_ret);
|
||||
#define header_from_object_ret(header, object, err_ret) \
|
||||
{ \
|
||||
MAGIC* mg = mg_find((SV *)(object), '~'); \
|
||||
if (mg) \
|
||||
(header) = (RPM_Header *)SvIV(mg->mg_obj); \
|
||||
else \
|
||||
return (err_ret); \
|
||||
}
|
||||
/* And a no-return version: */
|
||||
#define header_from_object(s_ptr, header, object) \
|
||||
hv_fetch_nomg((s_ptr), (object), STRUCT_KEY, STRUCT_KEY_LEN, FALSE); \
|
||||
(header) = ((s_ptr) && SvOK(*(s_ptr))) ? (RPM_Header *)SvIV(*(s_ptr)) : NULL;
|
||||
|
||||
#define header_from_object(header, object) \
|
||||
{ \
|
||||
MAGIC* mg = mg_find((SV *)(object), '~'); \
|
||||
if (mg) \
|
||||
(header) = (RPM_Header *)SvIV(mg->mg_obj); \
|
||||
else \
|
||||
(header) = Null(RPM_Header *); \
|
||||
}
|
||||
|
||||
/* Any constants that are specific to the RPM::Header class will be exported
|
||||
from here, via this C-level constant() routine */
|
||||
|
@ -75,11 +81,6 @@ SV* key2sv(pTHX_ const char* key)
|
|||
return (sv_2mortal(newSVpv((char *)key, PL_na)));
|
||||
}
|
||||
|
||||
static SV* ikey2sv(pTHX_ int key)
|
||||
{
|
||||
return (sv_2mortal(newSViv(key)));
|
||||
}
|
||||
|
||||
/* This creates a header data-field from the passed-in data */
|
||||
static SV* rpmhdr_create(pTHX_ const char* data, int type, int size,
|
||||
int scalar)
|
||||
|
@ -250,7 +251,7 @@ static int new_from_fname(pTHX_ const char* source, RPM_Header* new_hdr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (retval = new_from_fd_t(fd, new_hdr))
|
||||
if ((retval = new_from_fd_t(fd, new_hdr)))
|
||||
{
|
||||
Fclose(fd);
|
||||
new_hdr->source_name = safemalloc(strlen(source) + 1);
|
||||
|
@ -260,19 +261,20 @@ static int new_from_fname(pTHX_ const char* source, RPM_Header* new_hdr)
|
|||
return retval;
|
||||
}
|
||||
|
||||
RPM__Header rpmhdr_TIEHASH(pTHX_ SV* class, SV* source, int flags)
|
||||
RPM__Header rpmhdr_TIEHASH(pTHX_ char* class, SV* source, int flags)
|
||||
{
|
||||
char* fname;
|
||||
int fname_len;
|
||||
RPM__Header TIEHASH;
|
||||
RPM_Header* hdr_struct; /* Use this to store the actual C-level data */
|
||||
RPM__Header RETVAL;
|
||||
RPM_Header* retvalp; /* Use this to store the actual C-level data */
|
||||
SV* t_magic;
|
||||
|
||||
hdr_struct = safemalloc(sizeof(RPM_Header));
|
||||
Zero(hdr_struct, 1, RPM_Header);
|
||||
TIEHASH = Null(RPM__Header);
|
||||
retvalp = new_RPM_storage(RPM_Header);
|
||||
Zero(retvalp, 1, RPM_Header);
|
||||
RETVAL = Nullhv;
|
||||
|
||||
if (! source)
|
||||
hdr_struct->hdr = headerNew();
|
||||
retvalp->hdr = headerNew();
|
||||
else if (! (flags & RPM_HEADER_FROM_REF))
|
||||
{
|
||||
/* If we aren't starting out with a pointer to a Header
|
||||
|
@ -282,52 +284,59 @@ RPM__Header rpmhdr_TIEHASH(pTHX_ SV* class, SV* source, int flags)
|
|||
if (SvPOK(source))
|
||||
{
|
||||
fname = SvPV(source, fname_len);
|
||||
if (! new_from_fname(aTHX_ fname, hdr_struct))
|
||||
if (! new_from_fname(aTHX_ fname, retvalp))
|
||||
{
|
||||
return TIEHASH;
|
||||
return RETVAL;
|
||||
}
|
||||
}
|
||||
else if (IoIFP(sv_2io(source)))
|
||||
{
|
||||
if (! new_from_fd(PerlIO_fileno(IoIFP(sv_2io(source))),
|
||||
hdr_struct))
|
||||
retvalp))
|
||||
{
|
||||
return TIEHASH;
|
||||
return RETVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rpm_error(aTHX_ RPMERR_BADARG,
|
||||
"Argument 2 must be filename or GLOB");
|
||||
return TIEHASH;
|
||||
return RETVAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hdr_struct->hdr = (Header)SvRV(source);
|
||||
retvalp->hdr = (Header)SvIV(source);
|
||||
/* We simply don't know these three settings at this point */
|
||||
hdr_struct->isSource = 0;
|
||||
hdr_struct->major = 0;
|
||||
hdr_struct->minor = 0;
|
||||
retvalp->isSource = 0;
|
||||
retvalp->major = 0;
|
||||
retvalp->minor = 0;
|
||||
}
|
||||
|
||||
/* These three are likely to be most of the data requests, anyway */
|
||||
headerNVR(hdr_struct->hdr,
|
||||
&hdr_struct->name, &hdr_struct->version, &hdr_struct->release);
|
||||
headerNVR(retvalp->hdr,
|
||||
&retvalp->name, &retvalp->version, &retvalp->release);
|
||||
/* This defaults to false, but RPM::Database will set it true */
|
||||
hdr_struct->read_only = flags & RPM_HEADER_READONLY;
|
||||
retvalp->read_only = flags & RPM_HEADER_READONLY;
|
||||
|
||||
hdr_struct->iterator = (HeaderIterator)NULL;
|
||||
retvalp->iterator = (HeaderIterator)NULL;
|
||||
|
||||
new_RPM__Header(TIEHASH);
|
||||
retvalp->storage = newHV();
|
||||
RETVAL = newHV();
|
||||
t_magic = newSViv((unsigned)retvalp);
|
||||
/* With the actual HV*, store the type-keys for the three cached values: */
|
||||
hv_store_nomg(TIEHASH, "NAME_t", 7, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
hv_store_nomg(TIEHASH, "VERSION_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
hv_store_nomg(TIEHASH, "RELEASE_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
hv_store_nomg(TIEHASH,
|
||||
STRUCT_KEY, STRUCT_KEY_LEN,
|
||||
newSViv((unsigned)hdr_struct), FALSE);
|
||||
return TIEHASH;
|
||||
hv_store(retvalp->storage,
|
||||
"NAME_t", 7, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
hv_store(retvalp->storage,
|
||||
"VERSION_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
hv_store(retvalp->storage,
|
||||
"RELEASE_t", 10, newSViv(RPM_STRING_TYPE), FALSE);
|
||||
|
||||
sv_magic((SV *)RETVAL, Nullsv, 'P', Nullch, 0);
|
||||
sv_magic((SV *)RETVAL, t_magic, '~', Nullch, 0);
|
||||
SvREFCNT_dec(t_magic);
|
||||
|
||||
return RETVAL;
|
||||
}
|
||||
|
||||
SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
||||
|
@ -344,7 +353,7 @@ SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
|||
|
||||
FETCH = newSVsv(&PL_sv_undef);
|
||||
|
||||
header_from_object_ret(svp, hdr, self, FETCH);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, FETCH);
|
||||
|
||||
name = sv2key(aTHX_ key);
|
||||
if (! (name && (namelen = strlen(name))))
|
||||
|
@ -375,7 +384,7 @@ SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
|||
{
|
||||
/* If it wasn't one of those three, then we have to explicitly fetch
|
||||
it, either from the store in cache or via the headerGetEntry call */
|
||||
hv_fetch_nomg(svp, self, uc_name, namelen, FALSE);
|
||||
svp = hv_fetch(hdr->storage, uc_name, namelen, FALSE);
|
||||
if (svp && SvOK(*svp))
|
||||
{
|
||||
FETCH = newSVsv(*svp);
|
||||
|
@ -389,10 +398,10 @@ SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
|||
SV* new_item = rpmhdr_create(aTHX_ data_in, type_in, size_in,
|
||||
scalar_tag(aTHX_ Nullsv, tag_by_num));
|
||||
|
||||
hv_store_nomg(self, uc_name, namelen, newRV((SV *)new_item),
|
||||
FALSE);
|
||||
hv_store_nomg(self, strcat(uc_name, "_t"), (namelen + 2),
|
||||
newSViv(type_in), FALSE);
|
||||
hv_store(hdr->storage, uc_name, namelen, newRV((SV *)new_item),
|
||||
FALSE);
|
||||
hv_store(hdr->storage, strcat(uc_name, "_t"), (namelen + 2),
|
||||
newSViv(type_in), FALSE);
|
||||
|
||||
FETCH = new_item;
|
||||
}
|
||||
|
@ -402,7 +411,6 @@ SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
|||
char* new_item_p;
|
||||
int new_item_type;
|
||||
int size;
|
||||
char urk[2];
|
||||
|
||||
/* Pull the tag by the int value we now have */
|
||||
if (! headerGetEntry(hdr->hdr, tag_by_num,
|
||||
|
@ -417,10 +425,10 @@ SV* rpmhdr_FETCH(pTHX_ RPM__Header self, SV* key,
|
|||
new_item = rpmhdr_create(aTHX_ new_item_p, new_item_type, size,
|
||||
scalar_tag(aTHX_ Nullsv, tag_by_num));
|
||||
|
||||
hv_store_nomg(self, uc_name, namelen, newRV((SV *)new_item),
|
||||
FALSE);
|
||||
hv_store_nomg(self, strcat(uc_name, "_t"), (namelen + 2),
|
||||
newSViv(new_item_type), FALSE);
|
||||
hv_store(hdr->storage, uc_name, namelen, newRV((SV *)new_item),
|
||||
FALSE);
|
||||
hv_store(hdr->storage, strcat(uc_name, "_t"), (namelen + 2),
|
||||
newSViv(new_item_type), FALSE);
|
||||
FETCH = new_item;
|
||||
}
|
||||
}
|
||||
|
@ -441,12 +449,12 @@ int rpmhdr_STORE(pTHX_ RPM__Header self, SV* key, SV* value)
|
|||
char errmsg[256];
|
||||
STRLEN namelen;
|
||||
int size, i, is_scalar;
|
||||
I32 num_ent, data_type, data_key;
|
||||
I32 num_ent, data_type;
|
||||
void* data;
|
||||
AV* a_value = Nullav;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
if (hdr->read_only)
|
||||
return 0;
|
||||
|
||||
|
@ -562,7 +570,8 @@ int rpmhdr_STORE(pTHX_ RPM__Header self, SV* key, SV* value)
|
|||
{
|
||||
/* This will permanently concat "_t" to uc_name. But we'll craftily
|
||||
manipulate that later on with namelen. */
|
||||
hv_fetch_nomg(svp, self, strcat(uc_name, "_t"), (namelen + 2), FALSE);
|
||||
svp = hv_fetch(hdr->storage, strcat(uc_name, "_t"), (namelen + 2),
|
||||
FALSE);
|
||||
if (! (svp && SvOK(*svp)))
|
||||
{
|
||||
/*
|
||||
|
@ -771,9 +780,9 @@ int rpmhdr_STORE(pTHX_ RPM__Header self, SV* key, SV* value)
|
|||
/* Store the new data */
|
||||
headerAddEntry(hdr->hdr, num_ent, data_type, data, size);
|
||||
/* Store on the hash */
|
||||
hv_store_nomg(self, uc_name, namelen,
|
||||
(is_scalar) ? newSVsv(value) : newRV_noinc((SV *)a_value),
|
||||
FALSE);
|
||||
hv_store(hdr->storage, uc_name, namelen,
|
||||
(is_scalar) ? newSVsv(value) : newRV_noinc((SV *)a_value),
|
||||
FALSE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -784,10 +793,9 @@ int rpmhdr_DELETE(pTHX_ RPM__Header self, SV* key)
|
|||
int namelen; /* Arg for SvPV(..., len) */
|
||||
char* uc_name; /* UC'd version of name */
|
||||
RPM_Header* hdr; /* Pointer to C-level struct */
|
||||
SV** svp;
|
||||
int retval, num, i;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
if (hdr->read_only)
|
||||
return 0;
|
||||
|
||||
|
@ -821,11 +829,8 @@ int rpmhdr_DELETE(pTHX_ RPM__Header self, SV* key)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Remove magic long enough to do two hv_delete() calls */
|
||||
SvMAGICAL_off((SV *)self);
|
||||
hv_delete(self, uc_name, namelen, G_DISCARD);
|
||||
hv_delete(self, strcat(uc_name, "_t"), namelen + 2, G_DISCARD);
|
||||
SvMAGICAL_on((SV *)self);
|
||||
hv_delete(hdr->storage, uc_name, namelen, G_DISCARD);
|
||||
hv_delete(hdr->storage, strcat(uc_name, "_t"), namelen + 2, G_DISCARD);
|
||||
retval = 1;
|
||||
}
|
||||
|
||||
|
@ -833,15 +838,14 @@ int rpmhdr_DELETE(pTHX_ RPM__Header self, SV* key)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int rpmhdr_EXISTS(pTHX_ RPM__Header self, SV* key)
|
||||
bool rpmhdr_EXISTS(pTHX_ RPM__Header self, SV* key)
|
||||
{
|
||||
const char* name;
|
||||
char* uc_name;
|
||||
int namelen, tag_by_num, i;
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
name = sv2key(aTHX_ key);
|
||||
if (! (name && (namelen = strlen(name))))
|
||||
return 0;
|
||||
|
@ -856,21 +860,27 @@ int rpmhdr_EXISTS(pTHX_ RPM__Header self, SV* key)
|
|||
tag_by_num = tag2num(aTHX_ uc_name);
|
||||
Safefree(uc_name);
|
||||
if (! tag_by_num)
|
||||
/* Later we need to set some sort of error message */
|
||||
{
|
||||
char errmsg[256];
|
||||
|
||||
snprintf(errmsg, 256,
|
||||
"RPM::Header::EXISTS: unknown (to rpm) tag %s", uc_name);
|
||||
rpm_error(aTHX_ RPMERR_BADARG, errmsg);
|
||||
Safefree(uc_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (headerIsEntry(hdr->hdr, tag_by_num));
|
||||
}
|
||||
|
||||
int rpmhdr_FIRSTKEY(pTHX_ RPM__Header self, SV** key, SV** value)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
int tag, type, size;
|
||||
char* ptr;
|
||||
const char* tagname;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
/* If there is an existing iterator attached to the struct, free it */
|
||||
if (hdr->iterator)
|
||||
headerFreeIterator(hdr->iterator);
|
||||
|
@ -897,13 +907,12 @@ int rpmhdr_FIRSTKEY(pTHX_ RPM__Header self, SV** key, SV** value)
|
|||
int rpmhdr_NEXTKEY(pTHX_ RPM__Header self, SV* key,
|
||||
SV** nextkey, SV** nextvalue)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
int tag, type, size;
|
||||
char* ptr;
|
||||
const char* tagname;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
/* If there is not an existing iterator, we can't continue */
|
||||
if (! hdr->iterator)
|
||||
return 0;
|
||||
|
@ -932,10 +941,9 @@ int rpmhdr_NEXTKEY(pTHX_ RPM__Header self, SV* key,
|
|||
|
||||
void rpmhdr_DESTROY(pTHX_ RPM__Header self)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object(svp, hdr, self);
|
||||
struct_from_object(RPM_Header, hdr, self);
|
||||
if (! hdr) return;
|
||||
|
||||
if (hdr->iterator)
|
||||
|
@ -943,15 +951,16 @@ void rpmhdr_DESTROY(pTHX_ RPM__Header self)
|
|||
if (hdr->hdr)
|
||||
headerFree(hdr->hdr);
|
||||
|
||||
hv_undef(hdr->storage);
|
||||
Safefree(hdr);
|
||||
hv_undef(self);
|
||||
}
|
||||
|
||||
unsigned int rpmhdr_size(pTHX_ RPM__Header self)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
|
||||
if (! hdr->hdr)
|
||||
return 0;
|
||||
|
@ -966,6 +975,9 @@ int rpmhdr_tagtype(pTHX_ RPM__Header self, SV* key)
|
|||
char* uc_name;
|
||||
SV** svp;
|
||||
int i, retval;
|
||||
RPM_Header* hdr;
|
||||
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
|
||||
name = sv2key(aTHX_ key);
|
||||
if (! (name && (namelen = strlen(name))))
|
||||
|
@ -979,7 +991,7 @@ int rpmhdr_tagtype(pTHX_ RPM__Header self, SV* key)
|
|||
|
||||
retval = RPM_NULL_TYPE;
|
||||
|
||||
hv_fetch_nomg(svp, self, uc_name, strlen(uc_name) + 1, FALSE);
|
||||
svp = hv_fetch(hdr->storage, uc_name, strlen(uc_name), FALSE);
|
||||
if (svp && SvOK(*svp))
|
||||
{
|
||||
/* The base tag has already been fetched and thus we have a type */
|
||||
|
@ -995,12 +1007,14 @@ int rpmhdr_tagtype(pTHX_ RPM__Header self, SV* key)
|
|||
|
||||
if (sub_fetch)
|
||||
{
|
||||
hv_fetch_nomg(svp, self, uc_name, strlen(uc_name), FALSE);
|
||||
svp = hv_fetch(hdr->storage, uc_name, strlen(uc_name), FALSE);
|
||||
if (svp && SvOK(*svp))
|
||||
{
|
||||
/* The base tag has now been fetched */
|
||||
retval = SvIV(*svp);
|
||||
}
|
||||
SvREFCNT_dec(*svp);
|
||||
SvREFCNT_dec(sub_fetch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1015,12 +1029,11 @@ int rpmhdr_write(pTHX_ RPM__Header self, SV* gv_in, int magicp)
|
|||
FD_t fd;
|
||||
RPM_Header* hdr;
|
||||
GV* gv;
|
||||
SV** svp;
|
||||
int written = 0;
|
||||
|
||||
gv = (SvPOK(gv_in) && (SvTYPE(gv_in) == SVt_PVGV)) ?
|
||||
(GV *)SvRV(gv_in) : (GV *)gv_in;
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
|
||||
if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io)))
|
||||
return written;
|
||||
|
@ -1036,10 +1049,9 @@ int rpmhdr_write(pTHX_ RPM__Header self, SV* gv_in, int magicp)
|
|||
/* T/F test whether the header references a SRPM */
|
||||
int rpmhdr_is_source(pTHX_ RPM__Header self)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object_ret(svp, hdr, self, 0);
|
||||
struct_from_object_ret(RPM_Header, hdr, self, 0);
|
||||
|
||||
if (! hdr->hdr)
|
||||
return 0;
|
||||
|
@ -1055,16 +1067,15 @@ int rpmhdr_cmpver(pTHX_ RPM__Header self, RPM__Header other)
|
|||
{
|
||||
RPM_Header* one;
|
||||
RPM_Header* two;
|
||||
SV** svp;
|
||||
|
||||
header_from_object(svp, one, self);
|
||||
struct_from_object(RPM_Header, one, self);
|
||||
if (! one)
|
||||
{
|
||||
rpm_error(aTHX_ RPMERR_BADARG,
|
||||
"RPM::Header::rpmhdr_cmpver: Arg 1 has no header data");
|
||||
return 0;
|
||||
}
|
||||
header_from_object(svp, two, other);
|
||||
struct_from_object(RPM_Header, two, other);
|
||||
if (! two)
|
||||
{
|
||||
rpm_error(aTHX_ RPMERR_BADARG,
|
||||
|
@ -1081,10 +1092,9 @@ int rpmhdr_cmpver(pTHX_ RPM__Header self, RPM__Header other)
|
|||
*/
|
||||
char* rpmhdr_source_name(RPM__Header self)
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object(svp, hdr, self);
|
||||
struct_from_object(RPM_Header, hdr, self);
|
||||
|
||||
return hdr->source_name;
|
||||
}
|
||||
|
@ -1146,7 +1156,7 @@ MODULE = RPM::Header PACKAGE = RPM::Header PREFIX = rpmhdr_
|
|||
|
||||
RPM::Header
|
||||
rpmhdr_TIEHASH(class, source=NULL, flags=0)
|
||||
SV* class;
|
||||
char* class;
|
||||
SV* source;
|
||||
int flags;
|
||||
PROTOTYPE: $;$$
|
||||
|
@ -1171,8 +1181,6 @@ rpmhdr_STORE(self, key, value)
|
|||
SV* key;
|
||||
SV* value;
|
||||
PROTOTYPE: $$$
|
||||
PREINIT:
|
||||
AV* avalue;
|
||||
CODE:
|
||||
RETVAL = rpmhdr_STORE(aTHX_ self, key, value);
|
||||
OUTPUT:
|
||||
|
@ -1189,8 +1197,8 @@ rpmhdr_DELETE(self, key)
|
|||
RETVAL
|
||||
|
||||
int
|
||||
rpmhdr_CLEAR(self)
|
||||
RPM::Header self;
|
||||
rpmhdr_CLEAR(self=NULL)
|
||||
SV* self;
|
||||
PROTOTYPE: $
|
||||
CODE:
|
||||
{
|
||||
|
@ -1200,7 +1208,7 @@ rpmhdr_CLEAR(self)
|
|||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
int
|
||||
bool
|
||||
rpmhdr_EXISTS(self, key)
|
||||
RPM::Header self;
|
||||
SV* key;
|
||||
|
@ -1214,12 +1222,11 @@ void
|
|||
rpmhdr_FIRSTKEY(self)
|
||||
RPM::Header self;
|
||||
PROTOTYPE: $
|
||||
PREINIT:
|
||||
SV* key;
|
||||
SV* value;
|
||||
int i;
|
||||
PPCODE:
|
||||
{
|
||||
SV* key;
|
||||
SV* value;
|
||||
|
||||
if (! rpmhdr_FIRSTKEY(aTHX_ self, &key, &value))
|
||||
{
|
||||
key = newSVsv(&PL_sv_undef);
|
||||
|
@ -1235,12 +1242,11 @@ rpmhdr_NEXTKEY(self, key=NULL)
|
|||
RPM::Header self;
|
||||
SV* key;
|
||||
PROTOTYPE: $;$
|
||||
PREINIT:
|
||||
SV* nextkey;
|
||||
SV* nextvalue;
|
||||
int i;
|
||||
PPCODE:
|
||||
{
|
||||
SV* nextkey;
|
||||
SV* nextvalue;
|
||||
|
||||
if (! rpmhdr_NEXTKEY(aTHX_ self, key, &nextkey, &nextvalue))
|
||||
{
|
||||
nextkey = newSVsv(&PL_sv_undef);
|
||||
|
@ -1322,10 +1328,9 @@ rpmhdr_NVR(self)
|
|||
PROTOTYPE: $
|
||||
PPCODE:
|
||||
{
|
||||
SV** svp;
|
||||
RPM_Header* hdr;
|
||||
|
||||
header_from_object(svp, hdr, self);
|
||||
struct_from_object(RPM_Header, hdr, self);
|
||||
|
||||
if (hdr->name)
|
||||
{
|
||||
|
|
|
@ -5,10 +5,28 @@ use RPM::Database;
|
|||
$SIG{__WARN__} = sub { $@ = shift; };
|
||||
$SIG{__DIE__} = sub { $@ = shift; };
|
||||
|
||||
print "1..12\n";
|
||||
print "1..13\n";
|
||||
$count = 1;
|
||||
|
||||
#
|
||||
# Prior to starting up, we need to do some less-direct queries of the RPM
|
||||
# database, so that we have baseline data to test against.
|
||||
#
|
||||
@all_packs = `rpm -q -a --queryformat "\%{NAME}\\n"`;
|
||||
chomp(@all_packs);
|
||||
$all_packs{$_}++ for (@all_packs);
|
||||
|
||||
#
|
||||
# With a full list of packages now known, find one to use for package existence
|
||||
# testing.
|
||||
#
|
||||
for (qw(rpm kernel bash file passwd))
|
||||
{
|
||||
$test_pack = $_, last if (exists $all_packs{$_});
|
||||
}
|
||||
|
||||
tie %DB, "RPM::Database" or print "not ";
|
||||
print "ok 1\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
unless (tied %DB)
|
||||
{
|
||||
|
@ -16,28 +34,31 @@ unless (tied %DB)
|
|||
exit -1;
|
||||
}
|
||||
|
||||
# This package must exist, obviously
|
||||
$rpm = $DB{rpm};
|
||||
# Start with the test package
|
||||
$rpm = $DB{$test_pack};
|
||||
print "not " unless (defined $rpm and ref $rpm);
|
||||
print "ok 2\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# Verify that STORE, DELETE and CLEAR operations are blocked
|
||||
# STORE
|
||||
eval { $DB{foo_package} = 'baz'; print "not " if ($DB{foo_package} eq 'baz') };
|
||||
print "ok 3\n";
|
||||
eval {
|
||||
$DB{foo_package} = 'baz';
|
||||
print "not " if (exists $DB{foo_package} and ($DB{foo_package} eq 'baz'));
|
||||
};
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# DELETE
|
||||
eval { delete $DB{foo_package} and print "not " };
|
||||
print "ok 4\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# CLEAR
|
||||
eval { %DB = () and print "not " };
|
||||
print "ok 5\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# Test the untying
|
||||
eval { untie %DB };
|
||||
print "not " if ($@);
|
||||
print "ok 6\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# That should cover the basic TIEHASH operands sufficiently.
|
||||
|
||||
|
@ -49,29 +70,33 @@ print "ok 6\n";
|
|||
# Test the non-tie approach
|
||||
$rpm = new RPM::Database;
|
||||
print "not " unless (defined $rpm and ref $rpm);
|
||||
print "ok 7\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# Ensure that the same test package is visible
|
||||
print "not " unless (exists $rpm->{$test_pack} and ref($rpm->{$test_pack}));
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
@matches = $rpm->find_by_file('/bin/rpm');
|
||||
# There should be exactly one match:
|
||||
print "not " unless (@matches == 1);
|
||||
print "ok 8\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
print "not " unless ($matches[0]->{name} eq 'rpm');
|
||||
print "ok 9\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# There may be more than one package that depends on rpm
|
||||
@matches = $rpm->find_by_required_by('rpm');
|
||||
for (@matches) { $_ = $_->{name} }
|
||||
# As long as we see this one (it has to be present to build this package)
|
||||
print "not " unless (grep 'rpm-devel', @matches);
|
||||
print "ok 10\n";
|
||||
print "not " unless (grep($_ eq 'rpm-devel', @matches));
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
# Try to fetch a bogus package
|
||||
$hdr = $rpm->{i_hope_no_one_makes_a_package_by_this_name};
|
||||
print "not " if $hdr;
|
||||
print "ok 11\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
undef $rpm;
|
||||
print "ok 12\n";
|
||||
print "ok $count\n"; $count++;
|
||||
|
||||
exit 0;
|
||||
|
|
|
@ -3,35 +3,18 @@
|
|||
TYPEMAP
|
||||
|
||||
const char * T_PTROBJ
|
||||
RPM::Database O_RPM_Database
|
||||
RPM::Header O_RPM_Header
|
||||
RPM::Database O_RPM_Tied
|
||||
RPM::Header O_RPM_Tied
|
||||
RPM::Package O_RPM_Blessed
|
||||
RPM::Transaction O_RPM_Blessed
|
||||
|
||||
#
|
||||
# The following mappings for O_HvRV are taken directly from Dean Roehrich's
|
||||
# excellent XS Cookbook, vol. A.
|
||||
#
|
||||
|
||||
OUTPUT
|
||||
O_RPM_Database
|
||||
O_RPM_Tied
|
||||
if ($var)
|
||||
{
|
||||
$arg = sv_bless(newRV_noinc((SV*)$var),
|
||||
gv_stashpv("RPM::Database", TRUE));
|
||||
hv_magic($var, (GV *)Nullhv, 'P');
|
||||
}
|
||||
else
|
||||
{
|
||||
$arg = newSVsv(&PL_sv_undef);
|
||||
}
|
||||
|
||||
O_RPM_Header
|
||||
if ($var)
|
||||
{
|
||||
$arg = sv_bless(newRV_noinc((SV*)$var),
|
||||
gv_stashpv("RPM::Header", TRUE));
|
||||
hv_magic($var, (GV *)Nullhv, 'P');
|
||||
$arg = sv_bless(sv_2mortal(newRV_noinc((SV*)$var)),
|
||||
gv_stashpv(\"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\",
|
||||
TRUE));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -50,17 +33,7 @@ O_RPM_Blessed
|
|||
}
|
||||
|
||||
INPUT
|
||||
O_RPM_Database
|
||||
if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVHV))
|
||||
$var = (HV*)SvRV($arg);
|
||||
else
|
||||
{
|
||||
rpm_error(aTHX_ RPMERR_BADARG,
|
||||
\"${Package}::$func_name: not a blessed HV reference\");
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
O_RPM_Header
|
||||
O_RPM_Tied
|
||||
if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVHV))
|
||||
$var = (HV*)SvRV($arg);
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue