home *** CD-ROM | disk | FTP | other *** search
- static char SccsId[] = "@(#)sybperl.c 1.14 4/6/93";
- /************************************************************************/
- /* Copyright 1991, 1992, 1993 by Michael Peppler */
- /* and ITF Management SA */
- /* */
- /* Full ownership of this software, and all rights pertaining to */
- /* the for-profit distribution of this software, are retained by */
- /* Michael Peppler and ITF Management SA. You are permitted to */
- /* use this software without fee. This software is provided "as */
- /* is" without express or implied warranty. You may redistribute */
- /* this software, provided that this copyright notice is retained, */
- /* and that the software is not distributed for profit. If you */
- /* wish to use this software in a profit-making venture, you must */
- /* first license this code and its underlying technology from */
- /* ITF Management SA. */
- /* */
- /* Bottom line: you can have this software, you can use it, you */
- /* can give it away. You just can't sell any or all parts of it */
- /* without prior permission from ITF Management SA. */
- /************************************************************************/
-
- /* sybperl.c
- *
- * Call Sybase DB-Library functions from Perl.
- * Written by Michael Peppler (mpeppler@itf.ch)
- * ITF Management SA, 13 rue de la Fontaine
- * CH-1204 Geneva, Switzerland
- * Tel: (+4122) 312 1311 Fax: (+4122) 312 1322
- */
-
-
- #include "EXTERN.h"
- #include "perl.h"
- #undef MAX
- #undef MIN
-
- #if defined(VERSION3)
- #define str_2mortal(s) str_2static(s)
- #endif
-
- #include <sybfront.h>
- #include <sybdb.h>
- #include <syberror.h>
-
- #include "patchlevel.h"
-
- extern int wantarray;
-
- /*
- * The variables that the Sybase routines set, and that you may want
- * to test in your Perl script. These variables are READ-ONLY.
- */
- static enum uservars
- {
- UV_SUCCEED, /* Returns SUCCEED */
- UV_FAIL, /* Returns FAIL */
- UV_NO_MORE_ROWS, /* Returns NO_MORE_ROWS */
- UV_NO_MORE_RESULTS, /* Returns NO_MORE_RESULTS */
- UV_ComputeId, /* Returns the compute id of the row (in dbnextrow()) */
- UV_SybperlVer, /* Returns Sybperl Version/Patchlevel */
- UV_DBstatus, /* The value status value of the last dbnextrow() call */
- };
-
- /*
- * User subroutines that we have implemented. I've found that I can do
- * all the stuff I want to with this subset of DB-Library. Let me know
- * if you implement further routines.
- * The names are self-explanatory.
- */
- static enum usersubs
- {
- US_dblogin, /* This also performs the first dbopen() */
- US_dbopen,
- US_dbclose,
- US_dbcmd,
- US_dbsqlexec,
- US_dbresults,
- US_dbnextrow,
- US_dbcancel,
- US_dbcanquery,
- US_dbexit,
- US_dbuse,
- #ifdef HAS_CALLBACK
- US_dberrhandle,
- US_dbmsghandle,
- #endif
- US_dbstrcpy,
- US_DBMORECMDS,
- US_DBCMDROW,
- US_DBROWS,
- US_DBCOUNT,
- US_DBCURCMD,
- US_dbhasretstat,
- US_dbretstatus,
- #if defined(DBLIB42)
- US_dbsafestr,
- #endif
- US_dbwritetext,
- };
-
- #ifndef MAX_DBPROCS
- #define MAX_DBPROCS 25 /* Change this if you really want your perl script to talk to */
- /* more than 25 dataserver connections at a time ...*/
- #endif
-
- static LOGINREC *login;
- static DBPROCESS *dbproc[MAX_DBPROCS];
- static int exitCalled = 0; /* Set to 1 if dbexit() has been called. */
- static int ComputeId;
- static int DBstatus; /* Set by dbnextrow() */
- static int DBReturnAssoc; /* If true, dbnextrow returns an associative array */
-
- /* Stack pointer for the error routines. This is set to the stack pointer
- when entering into the sybase subroutines. Error and message
- handling needs this. */
-
- static int perl_sp;
-
- /* Current error handler name. */
-
- static char *err_handler_sub;
-
- /* Current message handler subroutine name */
-
- static char *msg_handler_sub;
-
- /* Macro to access the stack. This is necessary since error handlers may
- call perl routines and thus the stack may change. I hope most compilers
- will optimize this reasonably. */
-
- #define STACK(SP) (stack->ary_array + (SP))
-
-
- static int usersub();
- static int userset();
- static int userval();
- static int err_handler(), msg_handler();
-
- int userinit()
- {
- init_sybase();
- }
-
- int
- init_sybase()
- {
- struct ufuncs uf;
- char *filename = "sybase.c";
-
- if (dbinit() == FAIL) /* initialize dblibrary */
- exit(ERREXIT);
- /*
- * Install the user-supplied error-handling and message-handling routines.
- * They are defined at the bottom of this source file.
- */
- dberrhandle(err_handler);
- dbmsghandle(msg_handler);
-
- if(MAX_DBPROCS > 25)
- dbsetmaxprocs(MAX_DBPROCS);
-
- uf.uf_set = userset;
- uf.uf_val = userval;
-
- #define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf)
-
- MAGICVAR("SUCCEED", UV_SUCCEED);
- MAGICVAR("FAIL",UV_FAIL);
- MAGICVAR("NO_MORE_ROWS", UV_NO_MORE_ROWS);
- MAGICVAR("NO_MORE_RESULTS", UV_NO_MORE_RESULTS);
- MAGICVAR("ComputeId", UV_ComputeId);
- MAGICVAR("SybperlVer", UV_SybperlVer);
-
- make_usub("dblogin", US_dblogin, usersub, filename);
- make_usub("dbopen", US_dbopen, usersub, filename);
- make_usub("dbclose", US_dbclose, usersub, filename);
- make_usub("dbcmd", US_dbcmd, usersub, filename);
- make_usub("dbsqlexec", US_dbsqlexec, usersub, filename);
- make_usub("dbresults", US_dbresults, usersub, filename);
- make_usub("dbnextrow", US_dbnextrow, usersub, filename);
- make_usub("dbcancel", US_dbcancel, usersub, filename);
- make_usub("dbcanquery", US_dbcanquery, usersub, filename);
- make_usub("dbexit", US_dbexit, usersub, filename);
- make_usub("dbuse", US_dbuse, usersub, filename);
- #ifdef HAS_CALLBACK
- make_usub("dberrhandle", US_dberrhandle, usersub, filename);
- make_usub("dbmsghandle", US_dbmsghandle, usersub, filename);
- #endif
- make_usub("dbstrcpy", US_dbstrcpy, usersub, filename);
- make_usub("DBCURCMD", US_DBCURCMD, usersub, filename);
- make_usub("DBMORECMDS", US_DBMORECMDS, usersub, filename);
- make_usub("DBCMDROW", US_DBCMDROW, usersub, filename);
- make_usub("DBROWS", US_DBROWS, usersub, filename);
- make_usub("DBCOUNT", US_DBCOUNT, usersub, filename);
- make_usub("dbhasretstat", US_dbhasretstat, usersub, filename);
- make_usub("dbretstatus", US_dbretstatus, usersub, filename);
- #if defined(DBLIB42)
- make_usub("dbsafestr", US_dbsafestr, usersub, filename);
- #endif
- make_usub("dbwritetext", US_dbwritetext, usersub, filename);
- }
-
- static int
- usersub(ix, sp, items)
- int ix;
- register int sp;
- register int items;
- {
- STR **st = stack->ary_array + sp;
- ARRAY *ary = stack;
- register STR *Str; /* used in str_get and str_gnum macros */
- int inx = -1; /* Index into dbproc[] array. Passed as first parameter to nearly all &dbxxx() calls */
-
-
- if(exitCalled)
- fatal("&dbexit() has been called. Access to Sybase impossible.");
-
- perl_sp = sp + items;
-
- /*
- * We're calling some dblib function, but dblogin has not been
- * called. Two actions are possible: either fail the call, or call
- * dblogin/dbopen with the default info. The second option is used
- * to keep backwards compatibility with an older version of
- * sybperl. A call to fatal(msg) is probably better.
- */
- if(!login && (ix != US_dblogin) && (ix != US_dbmsghandle) && (ix != US_dberrhandle))
- { /* You can call &dbmsghandle/errhandle before calling &dblogin */
- #ifdef OLD_SYBPERL
- login = dblogin();
- dbproc[0] = dbopen(login, NULL);
- #else
- fatal("&dblogin has not been called yet!");
- #endif
- }
-
- switch (ix)
- {
- case US_dblogin:
- if (items > 3)
- fatal("Usage: &dblogin([user[,pwd[,server]]])");
- else
- {
- int j = 0;
- char *server = NULL, *user = NULL, *pwd = NULL;
-
- if (!login)
- login = dblogin();
- switch(items)
- {
- case 3:
- server = (char *)str_get(STACK(sp)[3]);
- case 2:
- if(STACK(sp)[2] != &str_undef)
- {
- pwd = (char *)str_get(STACK(sp)[2]);
- if(pwd && strlen(pwd))
- DBSETLPWD(login, pwd);
- }
- case 1:
- if(STACK(sp)[1] != &str_undef)
- {
- user = (char *)str_get(STACK(sp)[1]);
- if(user && strlen(user))
- DBSETLUSER(login, user);
- }
- }
-
- for(j = 0; j < MAX_DBPROCS; ++j)
- if(dbproc[j] == NULL)
- break;
- if(j == MAX_DBPROCS)
- fatal ("&dblogin: No more dbprocs available.");
- if((dbproc[j] = dbopen(login, server)) == NULL)
- j = -1;
-
- str_numset(STACK(sp)[0], (double) j);
- }
- break;
- case US_dbopen:
- if (items > 1)
- fatal("Usage: $dbproc = &dbopen([server]);");
- else
- {
- int j;
- char *server = NULL;
-
- for(j = 0; j < MAX_DBPROCS; ++j)
- if(dbproc[j] == NULL)
- break;
- if(j == MAX_DBPROCS)
- fatal("&dbopen: No more dbprocs available.");
- if(items == 1)
- server = (char *)str_get(STACK(sp)[1]);
-
- dbproc[j] = dbopen(login, server);
- str_numset(STACK(sp)[0], (double) j);
- }
- break;
- case US_dbclose:
- if (items != 1)
- fatal("Usage: $ret = &dbclose($dbproc);");
- else
- {
- inx = getDbProc(STACK(sp)[1]);
-
- dbclose(dbproc[inx]);
- dbproc[inx] = (DBPROCESS *)NULL;
- }
- break;
- case US_dbcancel:
- if (items > 1)
- fatal("Usage: &dbcancel($dbproc)");
- else
- {
- int retval;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- retval = dbcancel(dbproc[inx]);
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbcanquery:
- if (items > 1)
- fatal("Usage: &dbcanquery($dbproc)");
- else
- {
- int retval;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- retval = dbcanquery(dbproc[inx]);
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbexit:
- if (items != 0)
- fatal("Usage: &dbexit()");
- else
- {
- dbexit(dbproc[0]);
- exitCalled++;
- str_numset(STACK(sp)[0], (double) 1);
- }
- break;
-
- case US_dbuse:
- if (items > 2)
- fatal("Usage: &dbuse($dbproc, $database)");
- else
- {
- int retval, off;
- char str[255];
-
- if(items == 2)
- {
- inx = getDbProc(STACK(sp)[1]);
- off = 2;
- }
- else
- inx = 0, off = 1;
-
- strcpy(str, (char *)str_get(STACK(sp)[off]));
-
-
- retval = dbuse(dbproc[inx], str);
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbsqlexec:
- if (items > 1)
- fatal("Usage: &dbsqlexec($dbproc)");
- else
- {
- int retval;
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- retval = dbsqlexec(dbproc[inx]);
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbresults:
- if (items > 1)
- fatal("Usage: &dbresults($dbproc)");
- else
- {
- int retval;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- retval = dbresults(dbproc[inx]);
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbcmd:
- if (items > 2)
- fatal("Usage: &dbcmd($dbproc, $str)");
- else
- {
- int retval, off;
-
- if(items == 2)
- {
- inx = getDbProc(STACK(sp)[1]);
- off = 2;
- }
- else
- inx = 0, off = 1;
- retval = dbcmd(dbproc[inx], (char *)str_get(STACK(sp)[off]));
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
-
- case US_dbnextrow:
- if (items > 2)
- fatal("Usage: @arr = &dbnextrow([$dbproc [, $returnAssoc]])");
- else
- {
- int retval;
- char buff[1024], *p = NULL, *t;
- BYTE *data;
- int col, type, numcols;
- int len;
- int doAssoc = 0;
- DBFLT8 tmp;
- char *colname;
- char cname[64];
-
- inx = 0;
- switch(items)
- {
- case 2:
- doAssoc = (int)str_gnum(STACK(sp)[2]);
- case 1:
- inx = getDbProc(STACK(sp)[1]);
- break;
- }
-
- --sp; /* otherwise you get an empty element at the beginning of the results array! */
-
- DBstatus = retval = dbnextrow(dbproc[inx]);
- if(retval == REG_ROW)
- {
- ComputeId = 0;
- numcols = dbnumcols(dbproc[inx]);
- }
- else
- {
- ComputeId = retval;
- numcols = dbnumalts(dbproc[inx], ComputeId);
- }
- for(col = 1, buff[0] = 0; col <= numcols; ++col)
- {
- colname = NULL;
- if(!ComputeId)
- {
- type = dbcoltype(dbproc[inx], col);
- len = dbdatlen(dbproc[inx],col);
- data = (BYTE *)dbdata(dbproc[inx],col);
- colname = dbcolname(dbproc[inx], col);
- if(!colname || !colname[0])
- {
- sprintf(cname, "Col %d", col);
- colname = cname;
- }
- }
- else
- {
- int colid = dbaltcolid(dbproc[inx], ComputeId, col);
- type = dbalttype(dbproc[inx], ComputeId, col);
- len = dbadlen(dbproc[inx], ComputeId, col);
- data = (BYTE *)dbadata(dbproc[inx], ComputeId, col);
- if(colid > 0)
- colname = dbcolname(dbproc[inx], colid);
- if(!colname || !colname[0])
- {
- sprintf(cname, "Col %d", col);
- colname = cname;
- }
- }
- t = &buff[0];
- if(!data && !len)
- {
- #if defined(NULL_IS_UNDEF)
- t = &str_undef;
- #else
- strcpy(buff,"NULL");
- #endif
- }
- else
- {
- switch(type)
- {
- case SYBCHAR:
- strncpy(buff,data,len);
- buff[len] = 0;
- break;
- case SYBTEXT:
- New(902, p, len + 1, char);
- strncpy(p, data, len);
- p[len] = 0;
- t = p;
- break;
- case SYBINT1:
- case SYBBIT: /* a bit is at least a byte long... */
- sprintf(buff,"%u",*(unsigned char *)data);
- break;
- case SYBINT2:
- sprintf(buff,"%d",*(short *)data);
- break;
- case SYBINT4:
- sprintf(buff,"%d",*(long *)data);
- break;
- case SYBFLT8:
- sprintf(buff,"%.6f",*(double *)data);
- break;
- case SYBMONEY:
- dbconvert(dbproc[inx], SYBMONEY, data, len, SYBFLT8, &tmp, -1);
- sprintf(buff,"%.6f",tmp);
- break;
- case SYBDATETIME:
- dbconvert(dbproc[inx], SYBDATETIME, data, len, SYBCHAR, buff, -1);
- break;
- case SYBBINARY:
- dbconvert(dbproc[inx], type, data, len, SYBCHAR, buff, -1);
- break;
- #if defined(DBLIB42)
- case SYBREAL:
- sprintf(buff, "%.6f", *(float *)data);
- break;
- case SYBDATETIME4:
- dbconvert(dbproc[inx], SYBDATETIME4, data, len, SYBCHAR, buff, -1);
- break;
- #endif
- case SYBIMAGE:
- fatal ("&dbnextrow: SYBIMAGE datatypes are not handled at the moment!");
- break;
-
- default:
- /*
- * WARNING!
- *
- * We convert unknown data types to SYBCHAR
- * without checking to see if the resulting
- * string will fit in the 'buff' variable.
- * This isn't very pretty...
- */
- dbconvert(dbproc[inx], type, data, len, SYBCHAR, buff, -1);
- break;
- }
- }
- if(doAssoc)
- (void)astore(ary,++sp,str_2mortal(str_make(colname, 0)));
-
- (void)astore(ary,++sp,str_2mortal(str_make(t, 0)));
- /*
- * If we've allocated some space to retrieve a
- * SYBTEXT field, then free it now.
- */
- if(t == p)
- {
- Safefree(p);
- p = NULL;
- }
- }
- }
- break;
- #ifdef HAS_CALLBACK
- case US_dberrhandle:
- if (items > 1)
- fatal ("Usage: &dberrhandle($handler)");
- else
- {
- char *old = err_handler_sub;
- if (items == 1)
- {
- if (STACK (sp)[1] == &str_undef)
- err_handler_sub = 0;
- else
- {
- char *sub = (char *) str_get (STACK (sp)[1]);
- New (902, err_handler_sub, strlen (sub) + 1, char);
- strcpy (err_handler_sub, sub);
- }
- }
-
- if (old)
- {
- STACK (sp)[0] = str_2mortal (str_make (old, strlen (old)));
- if (items == 1)
- Safefree (old);
- }
- else
- STACK (sp)[0] = &str_undef;
- }
- break;
- case US_dbmsghandle:
- if (items > 1)
- fatal ("Usage: &dbmsghandle($handler)");
- else
- {
- char *old = msg_handler_sub;
- if (items == 1)
- {
- if (STACK (sp)[1] == &str_undef)
- msg_handler_sub = 0;
- else
- {
- char *sub = (char *) str_get (STACK (sp)[1]);
- New (902, msg_handler_sub, strlen (sub) + 1, char);
- strcpy (msg_handler_sub, sub);
- }
- }
-
- if (old)
- {
- STACK (sp)[0] = str_2mortal (str_make (old, strlen (old)));
- if (items == 1)
- Safefree (old);
- }
- else
- STACK (sp)[0] = &str_undef;
- }
- break;
- #endif /* HAS_CALLBACK */
- case US_dbstrcpy:
- if (items > 1)
- fatal("Usage: $string = &dbstrcpy($dbproc)");
- else
- {
- int retval, len;
- char *buff;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx] && (len = dbstrlen(dbproc[inx])))
- {
- New(902, buff, len+1, char);
- retval = dbstrcpy(dbproc[inx], 0, -1, buff);
- str_set(STACK(sp)[0], buff);
- Safefree(buff);
- }
- else
- str_set(STACK(sp)[0], "");
- }
- break;
-
- case US_DBCURCMD:
- if (items > 1)
- fatal("Usage: $num = &DBCURCMD($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = DBCURCMD(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_DBMORECMDS:
- if (items > 1)
- fatal("Usage: $rc = &DBMORECMDS($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = DBMORECMDS(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_DBCMDROW:
- if (items > 1)
- fatal("Usage: $rc = &DBCMDROW($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = DBCMDROW(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_DBROWS:
- if (items > 1)
- fatal("Usage: $rc = &DBROWS($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = DBROWS(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_DBCOUNT:
- if (items > 1)
- fatal("Usage: $ret = &DBCOUNT($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = DBCOUNT(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_dbhasretstat:
- if (items > 1)
- fatal("Usage: $rc = &dbhasretstat($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = dbhasretstat(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- case US_dbretstatus:
- if (items > 1)
- fatal("Usage: $rc = &dbretstatus($dbproc)");
- else
- {
- int retval = 0;
-
- if(items)
- inx = getDbProc(STACK(sp)[1]);
- else
- inx = 0;
-
- if(dbproc[inx])
- retval = dbretstatus(dbproc[inx]);
-
- str_numset(STACK(sp)[0], (double) retval);
- }
- break;
- #if defined(DBLIB42)
- case US_dbsafestr:
- if (items > 3 || items != 2)
- fatal ("Usage: $string = &dbsafestr($dbproc,$instring[,$quote_char])");
- else
- {
- int retval, len, quote;
- char *buff, *instr;
-
- inx = getDbProc (STACK (sp)[1]);
-
- instr = (char *) str_get (STACK (sp)[2]);
- if (items != 3)
- quote = DBBOTH;
- else
- {
- char *quote_char = (char *) str_get (STACK (sp)[3]);
- if (*quote_char == '\"')
- quote = DBDOUBLE;
- else if (*quote_char == '\'')
- quote = DBSINGLE;
- else
- { /* invalid */
- str_set (STACK (sp)[0], "");
- break;
- }
- }
- if (dbproc[inx] && (len = strlen (instr)))
- {
- /* twice as much space needed worst case */
- New (902, buff, len * 2 + 1, char);
- retval = dbsafestr (dbproc[inx], instr, -1, buff, -1, quote);
- str_set (STACK (sp)[0], buff);
- Safefree (buff);
- }
- }
- break;
- #endif
- case US_dbwritetext:
- if (items != 5)
- fatal ("Usage: dbwritetext($dbproc1,$column,$dbproc2,$col,$text");
- else
- {
- int inx2, wcolnum;
- char *wcolname, *wtext;
- int ret;
-
- inx = getDbProc(STACK(sp)[1]);
- wcolname = str_get(STACK(sp)[2]);
- inx2 = getDbProc(STACK(sp)[3]);
- wcolnum = (int)str_gnum(STACK(sp)[4]);
- wtext = str_get(STACK(sp)[5]);
- ret = dbwritetext (dbproc[inx], wcolname, dbtxptr(dbproc[inx2], wcolnum),
- DBTXPLEN, dbtxtimestamp(dbproc[inx2], wcolnum), 0,
- strlen(wtext), wtext);
- str_numset(STACK(sp)[0], (double) ret);
- }
- break;
-
- default:
- fatal("Unimplemented user-defined subroutine");
- }
- return sp;
- }
-
- /*
- * Return the value of a userdefined variable. These variables are all
- * READ-ONLY in Perl.
- */
- static int
- userval(ix, str)
- int ix;
- STR *str;
- {
- char buff[24];
-
- switch (ix)
- {
- case UV_SUCCEED:
- str_numset(str, (double)SUCCEED);
- break;
- case UV_FAIL:
- str_numset(str, (double)FAIL);
- break;
- case UV_NO_MORE_ROWS:
- str_numset(str, (double)NO_MORE_ROWS);
- break;
- case UV_NO_MORE_RESULTS:
- str_numset(str, (double)NO_MORE_RESULTS);
- break;
- case UV_ComputeId:
- str_numset(str, (double)ComputeId);
- break;
- case UV_SybperlVer:
- sprintf(buff, "%d.%3.3d", VERSION, PATCHLEVEL);
- str_set(str, buff);
- break;
- case UV_DBstatus:
- str_numset(str, (double)DBstatus);
- break;
- }
- return 0;
- }
-
- static int
- userset(ix, str)
- int ix;
- STR *str;
- {
- #if defined(USERVAL_SET_FATAL)
- fatal("sybperl: trying to write to a read-only variable.");
- #else
- return 0;
- #endif
- }
-
-
- /*ARGSUSED*/
- static int err_handler(db, severity, dberr, oserr, dberrstring, oserrstr)
- DBPROCESS *db;
- int severity;
- int dberr;
- int oserr;
- char *dberrstring;
- char *oserrstr;
- {
- #ifdef HAS_CALLBACK
- /* If we have error handler subroutine, use it. */
- if (err_handler_sub)
- {
- int sp = perl_sp;
- int j;
-
- for(j = 0; j < MAX_DBPROCS; ++j)
- if(db == dbproc[j])
- break;
- if(j == MAX_DBPROCS)
- j = 0;
-
- /* Reserve spot for return value. */
- astore (stack, ++ sp, Nullstr);
-
- /* Set up arguments. */
- astore (stack, ++ sp,
- str_2mortal (str_nmake ((double) j)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) severity)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) dberr)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) oserr)));
- if (dberrstring && *dberrstring)
- astore (stack, ++ sp, str_2mortal (str_make (dberrstring, 0)));
- else
- astore (stack, ++ sp, &str_undef);
- if (oserrstr && *oserrstr)
- astore (stack, ++ sp, str_2mortal (str_make (oserrstr, 0)));
- else
- astore (stack, ++ sp, &str_undef);
-
- /* Call it. */
- sp = callback (err_handler_sub, sp, 0, 1, 6);
-
- /* Return whatever it returned. */
- return (int) str_gnum (STACK (sp)[0]);
- }
- #endif /* HAS_CALLBACK */
- if ((db == NULL) || (DBDEAD(db)))
- return(INT_EXIT);
- else
- {
- fprintf(stderr,"DB-Library error:\n\t%s\n", dberrstring);
-
- if (oserr != DBNOERR)
- fprintf(stderr,"Operating-system error:\n\t%s\n", oserrstr);
-
- return(INT_CANCEL);
- }
- }
-
- /*ARGSUSED*/
-
- static int msg_handler(db, msgno, msgstate, severity, msgtext, srvname, procname, line)
- DBPROCESS *db;
- DBINT msgno;
- int msgstate;
- int severity;
- char *msgtext;
- char *srvname;
- char *procname;
- DBUSMALLINT line;
- {
- #ifdef HAS_CALLBACK
- /* If we have message handler subroutine, use it. */
- if (msg_handler_sub)
- {
- int sp = perl_sp;
- int j;
-
- for(j = 0; j < MAX_DBPROCS; ++j)
- if(db == dbproc[j])
- break;
- if(j == MAX_DBPROCS)
- j = 0;
-
- /* Reserve spot for return value. */
- astore (stack, ++ sp, Nullstr);
-
- /* Set up arguments. */
- astore (stack, ++ sp,
- str_2mortal (str_nmake ((double) j)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) msgno)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) msgstate)));
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) severity)));
- if (msgtext && *msgtext)
- astore (stack, ++ sp, str_2mortal (str_make (msgtext, 0)));
- else
- astore (stack, ++ sp, &str_undef);
- if (srvname && *srvname)
- astore (stack, ++ sp, str_2mortal (str_make (srvname, 0)));
- else
- astore (stack, ++ sp, &str_undef);
- if (procname && *procname)
- astore (stack, ++ sp, str_2mortal (str_make (procname, 0)));
- else
- astore (stack, ++ sp, &str_undef);
- astore (stack, ++ sp, str_2mortal (str_nmake ((double) line)));
-
- /* Call it. */
- sp = callback (msg_handler_sub, sp, 0, 1, 8);
-
- /* Return whatever it returned. */
- return (int) str_gnum (STACK (sp)[0]);
- }
- #endif /* HAS_CALLBACK */
- #ifdef OLD_SYBPERL
- if(!severity)
- return 0;
- #endif
- fprintf (stderr,"Msg %ld, Level %d, State %d\n",
- msgno, severity, msgstate);
- if (strlen(srvname) > 0)
- fprintf (stderr,"Server '%s', ", srvname);
- if (strlen(procname) > 0)
- fprintf (stderr,"Procedure '%s', ", procname);
- if (line > 0)
- fprintf (stderr,"Line %d", line);
-
- fprintf(stderr,"\n\t%s\n", msgtext);
-
- return(0);
- }
-
- /*
- * Get the index into the dbproc[] array from a Perl STR datatype.
- * Check that the index is reasonably valid...
- */
- int getDbProc(Str)
- STR *Str;
- {
- int ix = (int)str_gnum(Str);
-
- if(ix < 0 || ix >= MAX_DBPROCS)
- fatal("$dbproc parameter is out of range.");
- if(dbproc[ix] == NULL || DBDEAD(dbproc[ix]))
- fatal("$dbproc parameter is NULL or the connection to the server has been closed.");
- return ix;
- }
-
- #ifdef HAS_CALLBACK
-
- /* Taken from Perl 4.018 usub/usersub.c. mp. */
-
- /* Be sure to refetch the stack pointer after calling these routines. */
-
- int
- callback(subname, sp, gimme, hasargs, numargs)
- char *subname;
- int sp; /* stack pointer after args are pushed */
- int gimme; /* called in array or scalar context */
- int hasargs; /* whether to create a @_ array for routine */
- int numargs; /* how many args are pushed on the stack */
- {
- static ARG myarg[3]; /* fake syntax tree node */
- int arglast[3];
-
- arglast[2] = sp;
- sp -= numargs;
- arglast[1] = sp--;
- arglast[0] = sp;
-
- if (!myarg[0].arg_ptr.arg_str)
- myarg[0].arg_ptr.arg_str = str_make("",0);
-
- myarg[1].arg_type = A_WORD;
- myarg[1].arg_ptr.arg_stab = stabent(subname, FALSE);
-
- myarg[2].arg_type = hasargs ? A_EXPR : A_NULL;
-
- return do_subr(myarg, gimme, arglast);
- }
-
- #endif /* HAS_CALLBACK */
-
-