/* openisis - an open implementation of the CDS/ISIS database Version 0.8.x (patchlevel see file Version) Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA see README for more information EOH */ /* $Id: OpenIsis.xs,v 1.5 2003/04/08 00:20:53 kripke Exp $ the openisis XSUB */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #ifdef assert #undef assert /* perl.h assert doesn't really assert */ #endif #include /* XSUB.h: #if (defined(PERL_CAPI) || defined(PERL_IMPLICIT_SYS)) && !defined(PERL_CORE) # define malloc PerlMem_malloc # define free PerlMem_free but we need to free memory that was acquired by real malloc I don't now wether these should be defined or not, they are on some Serhij's windows box and aren't on my linux !?? However, we will have to move to OpenIsisMFree, anyway ... */ #ifdef free #define PERLFREE PerlMem_free #undef free #else #define PERLFREE free #endif #define OPENISIS_NOPRE09 #include "openisis.h" /* turn negative error codes in nice little numbers */ static int sherr ( int x ) { return -(1<> OPENISIS_ERR_SHIFT); } MODULE = OpenIsis PACKAGE = OpenIsis PROTOTYPES: ENABLE VERSIONCHECK: ENABLE void log( level, file ) int level char* file CODE: openIsisCLog( level, *file ? file : 0 ); int open( name, ... ) char* name CODE: { const char **argv = 0; int argc = 0; if ( 1 < items ) { STRLEN n_a; int i; argv = (const char **)malloc( (items-1) * sizeof(argv[0]) ); for ( i=1; irowid ), 0 ); if ( items > 2 ) { #ifdef SvPV_nolen /* 5.6.x has this. see man perlguts for why it's useful. */ char *fmt = (char *)SvPV_nolen( ST(2) ); #else STRLEN unused; char *fmt = (char *)SvPV( ST(2), unused ); #endif OpenIsisRec *q; OPENISIS_INITBUF(x); q = openIsisRFmt( &x.r, fmt, r ); free( r ); r = q; } for ( i=0; i < r->len; i++ ) { char buf[7]; AV *ar; SV *ref, **entry; SV *val; val = newSVpv( (char*)r->field[i].val, r->field[i].len ); snprintf( buf, sizeof(buf), "%hu", r->field[i].tag ); buf[sizeof(buf)-1] = 0; entry = hv_fetch( hv, buf, strlen(buf), 1 ); assert ( entry ); /* out of memory */ if ( ! *entry || ! SvROK(*entry) ) { ar = newAV(); *entry = newRV_noinc((SV*)ar); } else { ar = (AV*)SvRV(*entry); assert( SVt_PVAV == SvTYPE(ar) ); } av_push( ar, val ); } if ( r != &x.r ) free( r ); } RETVAL = newRV_noinc( (SV*)hv ); } OUTPUT: RETVAL SV* subfields( field ) char *field CODE: { OpenIsisField f; OpenIsisRec *r; HV *hv = newHV(); f.tag = 0; f.val = field; f.len = strlen(field); r = openIsisRSplitf( 0, &f ); if ( r ) { int i; char buf[2]; buf[sizeof(buf)-1] = 0; for ( i=0; i < r->len; i++ ) { buf[0] = (char)r->field[i].tag; hv_store( hv, buf, buf[0] ? 1 : 0, newSVpv( (char*)r->field[i].val, r->field[i].len ), 0 ); } free( r ); } RETVAL = newRV_noinc( (SV*)hv ); } OUTPUT: RETVAL void query( db, key, ... ) int db char *key PPCODE: { int mode = OPENISIS_QRY_SIMPLE; int skip = 0; int got; OpenIsisSet set; set.len = 0; got = (int)openIsisDQuery( &set, db, key, mode, skip ); if ( 0 < got ) { int i; EXTEND(SP,got); for ( i=0; i