/***************************************************************************** ** File: API.xs ** Type: interface library (for Perl and friends) ** Author: David Oberholtzer, (daveo@obernet.com) ** Copyright (c)2005, David Oberholtzer ** Date: 2001/03/23 ** Rev: $Id: API.xs,v 1.1 2003/06/18 02:01:57 daveo Exp daveo $ ** Use: Access to FAME functions in other platforms. ** Mod: 2005/03/15 daveo: modified the Missing Value functions to ** return HBCNTX and don't even try to implement them. ****************************************************************************** ** This library is an abstraction layer for FAME C-HLI functions ** ** NOTE: The most obvious difference between CHLI functions and FameHLI::API ** functions is moving 'status' from 'argument' status to being the ** 'return value' of the function. ** ** The second difference is in the handling of missing values. In 'C' ** there are special values with some rather odd properties. In Perl ** missing values are handled as references to the strings "NA", "NC" ** and "ND" (with the standard meanings). ** ** The last major difference is that 'length' attributes have been ** let fall by the wayside. To be really Perl-ish, the library takes ** care of the lengths incoming and outgoing. ** ****************************************************************************** ** To Do? ** Reads & Writes: fix translation tables. ** *****************************************************************************/ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "hli.h" #include "API.h" //*************************************************************************** // This may not be a good idea, but everybody has at least one vice... #define DEF_CENT 1900 //*************************************************************************** //*************************************************************************** // G L O B A L V A R I A B L E S //*************************************************************************** //*************************************************************************** static int status = 0; static int cfmini_status = 0; //*************************************************************************** //*************************************************************************** // E x t e n s i o n F u n c t i o n ( s ) //*************************************************************************** //*************************************************************************** //=========================================================================== // N E W S T R I N G //=========================================================================== char *newString(char *src) { int len; char *ptr; if (src) { len = strlen(src) + 1; New(0, ptr, len, char); strcpy(ptr, src); } else { New(0, ptr, 1, char); *ptr = '\0'; } return(ptr); } //*************************************************************************** //*************************************************************************** // P E R L - H L I M O D U L E S T A R T S //*************************************************************************** //**************************************************************************/ MODULE = FameHLI::API PACKAGE = FameHLI::API PREFIX = perl_ BOOT: status = HSUCC; cfmini_status = HSUCC; cfmini(&cfmini_status); ## ## ## P U B L I C F U N C T I O N S ## ## ##*************************************************************************** ##*************************************************************************** ## P E R L H E L P E R F U N C T I O N S ##*************************************************************************** ##*************************************************************************** ##*************************************************************************** ##*************************************************************************** ## U s i n g t h e H L I ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmini F A M E L I B R A R Y I N I T I A L I Z A T I O N ##=========================================================================== ## This function allows people to re-initialize the HLI if necessary ## (e.g. FAME environment variable needs setting inside the perl ## script) but also so that it isn't necessary to call cfmini in the ## common case of having everything set up first. ##=========================================================================*/ int perl_Cfmini() CODE: if (cfmini_status != HSUCC) { cfmini(&cfmini_status); } RETVAL = cfmini_status; OUTPUT: RETVAL ##=========================================================================== ## cfmver ##=========================================================================== ## Tested 2000/10/10 ##=========================================================================*/ int perl_Cfmver(sv_ver) SV *sv_ver PREINIT: float version; CODE: cfmver(&status, &version); sv_setnv(sv_ver, version); RETVAL = status; OUTPUT: RETVAL sv_ver ##=========================================================================== ## cfmfin F A M E L I B R A R Y C L O S E / T E R M I N A T I O N ##=========================================================================== ## Tested 2000/10/10 ##=========================================================================*/ int perl_Cfmfin() CODE: cfmfin(&status); RETVAL = status; OUTPUT: RETVAL ##*************************************************************************** ##*************************************************************************** ## S e t t i n g O p t i o n s i n t h e H L I ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmsopt ##=========================================================================== ## Tested 2000/10/17 ##=========================================================================== int perl_Cfmsopt(optname, optval) char *optname char *optval CODE: cfmsopt(&status, optname, optval); RETVAL = status; OUTPUT: RETVAL ##*************************************************************************** ##*************************************************************************** ## S e t t i n g R a n g e s ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmsrng ##=========================================================================== int perl_Cfmsrng(freq, sv_syear, sv_sprd, sv_eyear, sv_eprd, range, sv_numobs) int freq SV *sv_syear SV *sv_sprd SV *sv_eyear SV *sv_eprd SV *range SV *sv_numobs PREINIT: int syear; int sprd; int eyear; int eprd; int rng[3]; int numobs; int i; I32 ix; AV *rngarray; SV *sv; CODE: ## ---------------------------------------------------------------------- ## Check to see if we have been given anything valid. If so, use it. ## ---------------------------------------------------------------------- if (SvROK(range) && (SvTYPE(SvRV(range)) == SVt_PVAV)) { rngarray = (AV *)SvRV(range); av_clear(rngarray); ## ---------------------------------------------------------------------- ## It isn't a refrence or an array. For now, blow away the old thing ## and create a new reference. ## ---------------------------------------------------------------------- } else { rngarray = newAV(); SvREFCNT_dec(range); range = newRV_inc((SV *)rngarray); } syear = SvIV(sv_syear); sprd = SvIV(sv_sprd); eyear = SvIV(sv_eyear); eprd = SvIV(sv_eprd); numobs = SvIV(sv_numobs); cfmsrng(&status, freq, &syear, &sprd, &eyear, &eprd, rng, &numobs); if (status == HSUCC) { sv_setiv(sv_syear, syear); sv_setiv(sv_sprd, sprd); sv_setiv(sv_eyear, eyear); sv_setiv(sv_eprd, eprd); for (i=0; i<3; i++) { sv = newSViv(rng[i]); av_push(rngarray, sv); } sv_setiv(sv_numobs, numobs); } RETVAL = status; OUTPUT: RETVAL sv_syear sv_sprd sv_eyear sv_eprd range sv_numobs ##=========================================================================== ## cfmsfis ##=========================================================================== int perl_Cfmsfis(freq, sv_syear, sv_sprd, sv_eyear, sv_eprd, range, sv_numobs, fmonth=HDEC, flabel=HFYFST) int freq SV *sv_syear SV *sv_sprd SV *sv_eyear SV *sv_eprd SV *range SV *sv_numobs int fmonth int flabel PREINIT: int syear; int sprd; int eyear; int eprd; int rng[3]; int numobs; int i; I32 ix; AV *rngarray; SV *sv; CODE: ## ---------------------------------------------------------------------- ## Check to see if we have been given anything valid. If so, use it. ## ---------------------------------------------------------------------- if (SvROK(range) && (SvTYPE(SvRV(range)) == SVt_PVAV)) { rngarray = (AV *)SvRV(range); av_clear(rngarray); ## ---------------------------------------------------------------------- ## It isn't a refrence or an array. For now, blow away the old thing ## and create a new reference. ## ---------------------------------------------------------------------- } else { rngarray = newAV(); SvREFCNT_dec(range); range = newRV_inc((SV *)rngarray); } syear = SvIV(sv_syear); sprd = SvIV(sv_sprd); eyear = SvIV(sv_eyear); eprd = SvIV(sv_eprd); numobs = SvIV(sv_numobs); cfmsfis(&status, freq, &syear, &sprd, &eyear, &eprd, rng, &numobs, fmonth, flabel); if (status == HSUCC) { sv_setiv(sv_syear, syear); sv_setiv(sv_sprd, sprd); sv_setiv(sv_eyear, eyear); sv_setiv(sv_eprd, eprd); for (i=0; i<3; i++) { sv = newSViv(rng[i]); av_push(rngarray, sv); } sv_setiv(sv_numobs, numobs); } RETVAL = status; OUTPUT: RETVAL sv_syear sv_sprd sv_eyear sv_eprd range sv_numobs ##*************************************************************************** ##*************************************************************************** ## H a n d l i n g C o n n e c t i o n s ##*************************************************************************** ##**************************************************************************/ ##=========================================================================== ## cfmopcn Open connection ##=========================================================================== ## Tested ##=========================================================================*/ int perl_Cfmopcn(sv_connkey, service="mcadbs", hostname="localhost", username="", password="") SV *sv_connkey char *service char *hostname char *username char *password PREINIT: int connkey; CODE: cfmopcn(&status, &connkey, service, hostname, username, password); if (status == HSUCC) { sv_setiv(sv_connkey, connkey); } RETVAL = status; OUTPUT: RETVAL sv_connkey ##=========================================================================== ## cfmgcid Get channel id ##=========================================================================*/ int perl_Cfmgcid(dbkey, sv_connkey) int dbkey SV *sv_connkey PREINIT: int connkey; CODE: cfmgcid(&status, dbkey, &connkey); if (status == HSUCC) { sv_setiv(sv_connkey, connkey); } RETVAL = status; OUTPUT: RETVAL sv_connkey ##=========================================================================== ## cfmcmmt Commit unit of work ##=========================================================================*/ int perl_Cfmcmmt(connkey) int connkey CODE: cfmcmmt(&status, connkey); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmabrt Abort unit of work ##=========================================================================*/ int perl_Cfmabrt(connkey) int connkey CODE: cfmabrt(&status, connkey); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmclcn ##=========================================================================== int perl_Cfmclcn(connkey) int connkey CODE: cfmclcn(&status, connkey); RETVAL = status; OUTPUT: RETVAL ##*************************************************************************** ##*************************************************************************** ## H a n d l i n g D a t a b a s e s ##*************************************************************************** ##**************************************************************************/ ##=========================================================================== ## cfmopdb O P E N F A M E D A T A B A S E ##=========================================================================== ## Tested HCMODE, HUMODE ##=========================================================================*/ int perl_Cfmopdb(sv_dbkey, dbname, mode=HRMODE) SV *sv_dbkey char *dbname int mode PREINIT: int dbkey; char name[SMALLBUF]; int key; CODE: strcpy(name, dbname); cfmopdb(&status, &dbkey, name, mode); if (status == HSUCC) { sv_setiv(sv_dbkey, dbkey); } RETVAL = status; OUTPUT: RETVAL sv_dbkey ##=========================================================================== ## cfmspos P O S T / R E S T O R E S W I T C H ##=========================================================================== ## Enable/Disable the post/restore mechanism for databases. Use with ## extreme caution. If a process dies without posting or closing a ## database, the result will be a corrupt and unusable database. ##=========================================================================== ##=========================================================================== int perl_Cfmspos(flag) int flag CODE: cfmspos(&status, flag); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmcldb C L O S E F A M E D A T A B A S E ##=========================================================================== ## Tested ##=========================================================================*/ int perl_Cfmcldb(key) int key CODE: cfmcldb(&status, key); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmpodb P O S T D A T A B A S E ##=========================================================================== ## Tested ##=========================================================================*/ int perl_Cfmpodb(dbkey) int dbkey CODE: cfmpodb(&status, dbkey); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmrsdb R E S T O R E D A T A B A S E ##=========================================================================*/ int perl_Cfmrsdb(dbkey) int dbkey CODE: cfmrsdb(&status, dbkey); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmpack P A C K D A T A B A S E ##=========================================================================*/ int perl_Cfmpack(dbkey) int dbkey CODE: cfmpack(&status, dbkey); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmopdc O P E N D A T A B A S E C O N N E C T I O N ##=========================================================================*/ int perl_Cfmopdc(sv_dbkey, dbname, mode, connkey) SV *sv_dbkey char *dbname int mode int connkey PREINIT: int dbkey; CODE: cfmopdc(&status, &dbkey, dbname, mode, connkey); if (status == HSUCC) { sv_setiv(sv_dbkey, dbkey); } RETVAL = status; OUTPUT: RETVAL sv_dbkey ##*************************************************************************** ##*************************************************************************** ## H a n d l i n g D a t a b a s e I n f o r m a t i o n ## A n d A t t r i b u t e s ##*************************************************************************** ##**************************************************************************/ ##=========================================================================== ## cfmddes ##=========================================================================== int perl_Cfmddes(dbkey, desc) int dbkey char *desc CODE: cfmddes(&status, dbkey, desc); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmddoc ##=========================================================================== int perl_Cfmddoc(dbkey, doc) int dbkey char *doc CODE: cfmddoc(&status, dbkey, doc); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmgdba ##=========================================================================== ## Tested ##=========================================================================*/ int perl_Cfmgdba(dbkey, sv_cyear, sv_cmonth, sv_cday, sv_myear, sv_mmonth, sv_mday, sv_desc, sv_doc) int dbkey SV *sv_cyear SV *sv_cmonth SV *sv_cday SV *sv_myear SV *sv_mmonth SV *sv_mday SV *sv_desc SV *sv_doc PREINIT: int cyear; int cmonth; int cday; int myear; int mmonth; int mday; char *desc; char *doc; int deslen, doclen, i; CODE: cfmglen(&status, dbkey, &deslen, &doclen); if (status == HSUCC) { New(0, desc, deslen+1, char); for (i=0; idata), tmiss, (float *)tbl->tbl); RETVAL = status; OUTPUT: RETVAL syear sprd gotobs data ##=========================================================================== ## cfmgtnl G e t N a m e l i s t ( E l e m e n t o r A l l ) ##=========================================================================== ##=========================================================================== int perl_Cfmgtnl(dbkey, objnam, index, sv_str, xinlen=0, xoutlen=0) int dbkey char *objnam int index SV *sv_str int xinlen int xoutlen PREINIT: int inlen; int outlen; int worked = TRUE; char *buffer; CODE: cfmnlen(&status, dbkey, objnam, index, &inlen); worked = status == HSUCC; if (worked) { New(0, buffer, inlen+1, char); cfmgtnl(&status, dbkey, objnam, index, buffer, inlen, &outlen); worked = status == HSUCC; sv_setpv(sv_str, buffer); Safefree(buffer); } RETVAL = status; OUTPUT: RETVAL sv_str ##=========================================================================== ## cfmrrng R e a d R a n g e o f D a t a ##=========================================================================== ## Tested ## 2001/04/17 ## Missing values passed, but not missing table values. ##=========================================================================== int perl_Cfmrrng(dbkey, objnam, range, data, miss, table) int dbkey char *objnam SV *range SV *data int miss SV *table PREINIT: int i; int worked = TRUE; SV **svptr; SV *sv; SV *sv2; I32 ix; int len; int rlen = 0; int rng[3]; AV *datarray; AV *rngarray; AV *tblarray; int *iptr; float *fptr; void *vptr; int *mitbl = NULL; float *mftbl = NULL; double *mdtbl = NULL; void *tbl = NULL; int class; int type; int freq; int fyear; int fprd; int lyear; int lprd; double *dptr; double dtmp; int ii = 0; CODE: ## ---------------------------------------------------------------------- ## First, let's see what type of data object we are reading. This will ## affect what we do with the DATA set and the MISSING TABLE stuff. ## ---------------------------------------------------------------------- cfmosiz(&status, dbkey, objnam, &class, &type, &freq, &fyear, &fprd, &lyear, &lprd); if (status != HSUCC) { worked = FALSE; } ## ---------------------------------------------------------------------- ## See if we were given a real variable in which to save data. If so, ## clear it out. ## ---------------------------------------------------------------------- if (worked) { if (SvROK(data)) { if (SvTYPE(SvRV(data)) == SVt_PVAV) { datarray = (AV *)SvRV(data); av_clear(datarray); } ## ---------------------------------------------------------------------- ## ---------------------------------------------------------------------- } else { datarray = newAV(); SvREFCNT_dec(data); data = newRV_inc((SV *)datarray); } } ## ---------------------------------------------------------------------- ## Check to see if we have been given a valid RANGE. ## ---------------------------------------------------------------------- if (SvROK(range) && (SvTYPE(SvRV(range)) == SVt_PVAV)) { rngarray = (AV *)SvRV(range); if (av_len(rngarray) == 2) { for (ix=0; ix<3; ix++) { svptr = av_fetch(rngarray, ix, 0); rng[ix] = SvIV(*svptr); } ## ---------------------------------------------------------- ## This might be cheating but I believe it is correct... ## [0]=freq, [1]=start, [2]=end so [2]-[1] should be nobs - 1. ## ---------------------------------------------------------- rlen = rng[2] - rng[1] + 1; } ## ---------------------------------------------------------------------- ## If there is no frequency then this is a SCALAR and needs to be handled ## as such. FAME will ignore the 'range' object but we need a length. ## ---------------------------------------------------------------------- } else if (freq == HUNDFX) { rlen = 1; ## ---------------------------------------------------------------------- ## Not much we can do here... ## ---------------------------------------------------------------------- } else { status = HBRNG; worked = FALSE; } ## ---------------------------------------------------------------------- ## Next, depending on the type of data that we will be reading... ## ---------------------------------------------------------------------- if (worked) { switch (type) { case HNUMRC: New(0, fptr, rlen, float); vptr = (void *)fptr; break; case HPRECN: New(0, dptr, rlen, double); vptr = (void *)dptr; break; case HSTRNG: case HNAMEL: worked = FALSE; status = -1; break; case HBOOLN: default: New(0, iptr, rlen, int); vptr = (void *)iptr; break; } } ## ---------------------------------------------------------------------- ## We now know that data type is one of the valid types. 'default' ## now takes on the meaning "date frequency" type. ## ---------------------------------------------------------------------- if (worked) { cfmrrng(&status, dbkey, objnam, rng, (float *)vptr, miss, tbl); if (status != HSUCC) { worked = FALSE; } } ## ---------------------------------------------------------------------- ## Copy the data into the array that is to be returned. ## ---------------------------------------------------------------------- if (worked) { ## ---------------------------------------------------------------------- ## If there is no frequency, it is a scalar. For now, however, it is ## returned as the first element of an array (which is consistent with ## the Fame C-HLI documentation). ## ---------------------------------------------------------------------- ## ---------------------------------------------------------------------- ## F I X T H I S ## F I X T H I S ## Missing values need to be set as references to strings. ## F I X T H I S ## F I X T H I S ## ---------------------------------------------------------------------- if (freq == HUNDFX) { switch(type) { case HNUMRC: if (fptr[0] == FNUMNA) { sv = newSVpv("NA", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (fptr[0] == FNUMNC) { sv = newSVpv("NC", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (fptr[0] == FNUMND) { sv = newSVpv("ND", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else { ## fprintf(stderr, "\n\t'%s'%g'\n", objnam, fptr[0]); sv = newSVnv(fptr[0]); av_push(datarray, sv); } break; case HBOOLN: if (iptr[0] == FBOONA) { sv = newSVpv("NA", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (iptr[0] == FBOONC) { sv = newSVpv("NC", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (iptr[0] == FBOOND) { sv = newSVpv("ND", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else { ## fprintf(stderr, "\n\t'%d'\n", iptr[0]); sv = newSViv(iptr[0]); av_push(datarray, sv); } break; case HPRECN: if (dptr[0] == FPRCNA) { sv = newSVpv("NA", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (dptr[0] == FPRCNC) { sv = newSVpv("NC", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (dptr[0] == FPRCND) { sv = newSVpv("ND", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else { ## fprintf(stderr, "\n\t'%g'\n", dptr[0]); sv = newSVnv(dptr[0]); av_push(datarray, sv); } break; default: if (iptr[0] == FDATNA) { sv = newSVpv("NA", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (iptr[0] == FDATNC) { sv = newSVpv("NC", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else if (iptr[0] == FDATND) { sv = newSVpv("ND", 0); sv2 = newRV_noinc(sv); av_push(datarray, sv2); } else { ## fprintf("\n\t'%d'\n", iptr[0]); sv = newSViv(iptr[0]); av_push(datarray, sv); } break; } ## ---------------------------------------------------------------------- ## Otherwise this is an array so set all the values. ## ---------------------------------------------------------------------- } else { for (i=0; idata), miss, (float *)tbl->tbl); RETVAL = status; OUTPUT: RETVAL ##*************************************************************************** ##*************************************************************************** ## C o n v e r t i n g D a t e s ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmtdat ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmtdat(freq, sv_date, hour, minute, second, ddate) int freq SV *sv_date int hour int minute int second int ddate PREINIT: int date; CODE: cfmtdat(&status, freq, &date, hour, minute, second, ddate); if (status == HSUCC) { sv_setiv(sv_date, date); } RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdatt ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmdatt(freq, date, sv_hour, sv_minute, sv_second, sv_ddate) int freq int date SV *sv_hour SV *sv_minute SV *sv_second SV *sv_ddate PREINIT: int hour; int minute; int second; int ddate; CODE: cfmdatt(&status, freq, date, &hour, &minute, &second, &ddate); if (status == HSUCC) { sv_setiv(sv_hour, hour); sv_setiv(sv_minute, minute); sv_setiv(sv_second, second); sv_setiv(sv_ddate, ddate); } RETVAL = status; OUTPUT: RETVAL sv_hour sv_minute sv_second sv_ddate ##=========================================================================== ## cfmddat ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmddat(freq, sv_date, year, month, day) int freq SV *sv_date int year int month int day PREINIT: int date; CODE: cfmddat(&status, freq, &date, year, month, day); if (status == HSUCC) { sv_setiv(sv_date, date); } RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdatd ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmdatd(freq, date, sv_year, sv_month, sv_day) int freq int date SV *sv_year SV *sv_month SV *sv_day PREINIT: int year; int month; int day; CODE: cfmdatd(&status, freq, date, &year, &month, &day); if (status == HSUCC) { sv_setiv(sv_year, year); sv_setiv(sv_month, month); sv_setiv(sv_day, day); } RETVAL = status; OUTPUT: RETVAL sv_year sv_month sv_day ##=========================================================================== ## cfmpdat ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmpdat(freq, sv_date, year, period) int freq SV *sv_date int year int period PREINIT: int date; CODE: cfmpdat(&status, freq, &date, year, period); if (status == HSUCC) { sv_setiv(sv_date, date); } RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdatp ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmdatp(freq, date, sv_year, sv_period) int freq int date SV *sv_year SV *sv_period PREINIT: int year; int period; CODE: cfmdatp(&status, freq, date, &year, &period); if (status == HSUCC) { sv_setiv(sv_year, year); sv_setiv(sv_period, period); } RETVAL = status; OUTPUT: RETVAL sv_year sv_period ##=========================================================================== ## cfmfdat ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmfdat(freq, sv_date, year, period, fmonth=HDEC, flabel=HFYFST) int freq SV *sv_date int year int period int fmonth int flabel PREINIT: int date; CODE: cfmfdat(&status, freq, &date, year, period, fmonth=HDEC, flabel=HFYFST); if (status == HSUCC) { sv_setiv(sv_date, date); } RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdatf ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmdatf(freq, date, sv_year, sv_period, fmonth, flabel) int freq int date SV *sv_year SV *sv_period int fmonth int flabel PREINIT: int year; int period; CODE: cfmdatf(&status, freq, date, &year, &period, fmonth=HDEC,flabel=HFYFST); if (status == HSUCC) { sv_setiv(sv_year, year); sv_setiv(sv_period, period); } RETVAL = status; OUTPUT: RETVAL sv_year sv_period ##=========================================================================== ## cfmldat ##=========================================================================== ## Tested ##=========================================================================== int perl_Cfmldat(freq, sv_date, datestr, month=HDEC, label=HFYFST, century=DEF_CENT) int freq SV *sv_date char *datestr int month int label int century PREINIT: int date; CODE: cfmldat(&status, freq, &date, datestr, month, label, century); sv_setiv(sv_date, date); RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdatl ##=========================================================================== int perl_Cfmdatl(freq, date, sv_datestr, month=HDEC, label=HFYFST) int freq int date SV *sv_datestr int month int label PREINIT: char buf[SMALLBUF]; CODE: cfmdatl(&status, freq, date, buf, month, label); if (status == HSUCC) { sv_setpv(sv_datestr, buf); } RETVAL = status; OUTPUT: RETVAL sv_datestr ##=========================================================================== ## cfmidat ##=========================================================================== int perl_Cfmidat(freq, sv_date, datestr, image="//", month=HDEC, label=HFYFST, century=DEF_CENT) int freq SV *sv_date char *datestr char *image int month int label int century PREINIT: int date; CODE: cfmidat(&status, freq, &date, datestr, image, month, label, century); sv_setiv(sv_date, date); RETVAL = status; OUTPUT: RETVAL sv_date ##=========================================================================== ## cfmdati ##=========================================================================== int perl_Cfmdati(freq, date, sv_datestr, image="//", month=HDEC, label=HFYFST) int freq int date SV *sv_datestr char *image int month int label PREINIT: char buf[SMALLBUF]; CODE: cfmdati(&status, freq, date, buf, image, month, label); if (status == HSUCC) { sv_setpv(sv_datestr, buf); } RETVAL = status; OUTPUT: RETVAL sv_datestr ##*************************************************************************** ##*************************************************************************** ## U s i n g t h e F A M E / S e r v e r ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmfame ##=========================================================================== int perl_Cfmfame(command) char *command CODE: cfmfame(&status, command); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmopwk ##=========================================================================== int perl_Cfmopwk(sv_dbkey) SV *sv_dbkey PREINIT: int dbkey; CODE: cfmopwk(&status, &dbkey); sv_setiv(sv_dbkey, dbkey); RETVAL = status; OUTPUT: RETVAL sv_dbkey ##=========================================================================== ## cfmsinp ##=========================================================================== int perl_Cfmsinp(cmd) char *cmd CODE: char **dcmd = (char **)cmd; char buffer[HMAXSCMD]; cfmsinp(&status, buffer); Safefree(*dcmd); *dcmd = newString(buffer); RETVAL = status; OUTPUT: RETVAL ##*************************************************************************** ##*************************************************************************** ## U s i n g a n A n a l y t i c a l C h a n n e l ##*************************************************************************** ##*************************************************************************** ##=========================================================================== ## cfmoprc ##=========================================================================== int perl_Cfmoprc(sv_dbkey, connkey) SV *sv_dbkey int connkey PREINIT: int dbkey; CODE: cfmoprc(&status, &dbkey, connkey); sv_setiv(sv_dbkey, dbkey); RETVAL = status; OUTPUT: RETVAL sv_dbkey ##=========================================================================== ## cfmopre ##=========================================================================== int perl_Cfmopre(sv_dbkey, svname) SV *sv_dbkey char *svname PREINIT: int dbkey; CODE: cfmopre(&status, &dbkey, svname); sv_setiv(sv_dbkey, dbkey); RETVAL = status; OUTPUT: RETVAL sv_dbkey ##=========================================================================== ## cfmrmev ##=========================================================================== int perl_Cfmrmev(dbkey, expr, optns, wdbkey, objnam) int dbkey char *expr char *optns int wdbkey char *objnam CODE: cfmrmev(&status, dbkey, expr, optns, wdbkey, objnam); RETVAL = status; OUTPUT: RETVAL ##=========================================================================== ## cfmferr ##=========================================================================== ## ##=========================================================================== int perl_Cfmferr(sv_errtxt) SV *sv_errtxt PREINIT: int i; char buf[BIGBUF+1]; CODE: for (i=0; i