: "%W% %E%" #!/bin/sh # shar: Shell Archiver (v1.22) # # This is a shell archive. # Remove everything above this line and run sh on the resulting file # If this archive is complete, you will see this message at the end # "All files extracted" # # Created: Wed Apr 27 20:50:17 1994 by johnl at Sphinx Ltd. # Files archived in this archive: # checkint.4gl # dbexpln.4gl # dbtype.4gl # dlist.c # dlist.h # dlist.man # dliststr.c # dliststr.man # helpfile.4gl # incdec.4gl # interr.4gl # ldint.c # msgtext.c # nxtfield.4gl # openlog.4gl # repdest.4gl # repdest.per # reptype.4gl # translog.4gl # uname.c # popstr.c # scrndump.4gl # scrndump.per # security.4gl # shell.4gl # stdopt.4gl # spi.msg # spi.sql # if test -f checkint.4gl; then echo "File checkint.4gl exists"; else echo "x - checkint.4gl" sed 's/^X//' << 'SHAR_EOF' > checkint.4gl && X{ X @(#)checkint.4gl 2.4 90/04/05 X @(#)Sphinx Informix Tools: General Library X @(#)Interrupt checker X @(#)Author: JL X} X X{ Warn about ignored interrupt if interrupt has occurred } XFUNCTION check_interrupt() X X DEFINE X sccs CHAR(1) X X IF int_flag != 0 THEN X LET sccs = "@(#)checkint.4gl 2.4 90/04/05" X ERROR "Interrupt detected -- ignored" X LET int_flag = 0 X END IF X XEND FUNCTION {check_interrupt} SHAR_EOF chmod 0444 checkint.4gl || echo "$0: failed to restore checkint.4gl" fi if test -f dbexpln.4gl; then echo "File dbexpln.4gl exists"; else echo "x - dbexpln.4gl" sed 's/^X//' << 'SHAR_EOF' > dbexpln.4gl && X{ X @(#)dbexpln.4gl 1.2 91/05/09 X @(#)JLSS Informix Tools: General Library X @(#)Handle SET EXPLAIN mode X} X XDEFINE X expl_mode INTEGER, X sccs CHAR(1) X X{ Set explain mode from DBEXPLAIN environment variable } XFUNCTION set_dbexplain() X X DEFINE X dbexpl CHAR(3) X X LET dbexpl = fgl_getenv("DBEXPLAIN") X LET dbexpl = DOWNSHIFT(dbexpl) X IF dbexpl = "on" THEN X SET EXPLAIN ON X LET expl_mode = 1 X ELSE X SET EXPLAIN OFF X LET expl_mode = 0 X LET sccs = "@(#)dbexpln.4gl 1.2 91/05/09" X END IF X XEND FUNCTION {set_dbexplain} X X{ Set explain mode } XFUNCTION set_explain(dbexpl) X X DEFINE X dbexpl CHAR(3) X X LET dbexpl = DOWNSHIFT(dbexpl) X IF dbexpl = "on" THEN X SET EXPLAIN ON X LET expl_mode = 1 X ELSE X SET EXPLAIN OFF X LET expl_mode = 0 X END IF X XEND FUNCTION {set_explain} X X{ Get current explain mode } XFUNCTION get_explain() X X RETURN expl_mode X XEND FUNCTION {get_explain} SHAR_EOF chmod 0664 dbexpln.4gl || echo "$0: failed to restore dbexpln.4gl" fi if test -f dbtype.4gl; then echo "File dbtype.4gl exists"; else echo "x - dbtype.4gl" sed 's/^X//' << 'SHAR_EOF' > dbtype.4gl && X{ X @(#)dbtype.4gl 1.2 91/05/09 X @(#)JLSS Informix Tools: General Library X @(#)Determine type of database X @(#)Author: JL X} X X{ XThe set_databasetype() function should be called after a database is opened Xand before the next operation that alters the SQLCA record. It will try Xto determine whether the database is Version 4.00 or earlier than Version 4.00, Xwhether it is OnLine or Standard Engine, whether the database has logging Xenabled, and whether the database is mode ANSI. X XThe other routines are used to interrogate the database type. X Xget_databasemode() returns true if the database is mode ANSI. Xget_databasetype() returns true if the database is OnLine Xget_databasevers() returns true if the database is Version 4.00 or later Xget_databaselogs() returns true if the database is logged. X} X XDEFINE X db_init INTEGER, X db_mode INTEGER, X db_type INTEGER, X db_vers INTEGER, X db_logs INTEGER, X db_sccs CHAR(1) X X{ Establish characteristics of database } X{ It is assumed that the last statement was a DATABASE statement } XFUNCTION set_databasetype() X X DEFINE X counter INTEGER X X IF SQLCA.SQLAWARN[1] != 'W' THEN X { Damn; could be version 4.00 unlogged SE database in non-ANSI mode } X { Could be earlier version with or without logs } X WHENEVER ERROR CONTINUE X SELECT COUNT(*) INTO counter X FROM Informix.Systables WHERE Tabid = 1 X IF STATUS < 0 THEN X LET db_vers = FALSE { It clearly isn't a Version 4.00 database } X LET db_mode = FALSE { It cannot therefore be mode ANSI } X LET db_type = FALSE { It is assumed to be Standard Engine } X SELECT COUNT(*) INTO counter X FROM Systables WHERE Tabtype = 'L' X LET db_logs = (counter = 1) X LET db_sccs = "@(#)dbtype.4gl 1.2 91/05/09" X ELSE X LET db_vers = TRUE { It must be Version 4.00 or later } X SELECT COUNT(*) INTO counter X FROM Informix.Syscolumns WHERE Tabid = 1 X IF counter >= 18 THEN X LET db_type = TRUE { OnLine } X LET db_logs = TRUE { Assumed to be logged! } X LET db_mode = FALSE { Assumed to be non-ANSI mode } X ELSE X LET db_type = FALSE { Standard Engine } X SELECT COUNT(*) INTO counter X FROM Informix.Systables WHERE Tabtype = 'L' X IF counter = 1 THEN X LET db_logs = TRUE { It has a transaction log } X SELECT COUNT(*) INTO counter X FROM Informix.Systables WHERE Tabname = "ANSI" X LET db_mode = (counter = 1) X END IF X END IF X END IF X ELSE X { Must be a version 4.00 database with all information at hand } X LET db_vers = TRUE X LET db_logs = (SQLCA.SQLAWARN[2] = "W") X LET db_mode = (SQLCA.SQLAWARN[3] = "W") X LET db_type = (SQLCA.SQLAWARN[4] = "W") X END IF X LET db_init = TRUE X XEND FUNCTION {set_databasetype} X XFUNCTION get_databasetype() X X IF db_init = FALSE THEN X LET SQLCA.SQLAWARN[1] = ' ' X CALL set_databasetype() X END IF X X RETURN db_type X XEND FUNCTION {get_databasetype} X XFUNCTION get_databaselogs() X X IF db_init = FALSE THEN X LET SQLCA.SQLAWARN[1] = ' ' X CALL set_databasetype() X END IF X X RETURN db_logs X XEND FUNCTION {get_databaselogs} X XFUNCTION get_databasevers() X X IF db_init = FALSE THEN X LET SQLCA.SQLAWARN[1] = ' ' X CALL set_databasetype() X END IF X X RETURN db_vers X XEND FUNCTION {get_databasevers} X XFUNCTION get_databasemode() X X IF db_init = FALSE THEN X LET SQLCA.SQLAWARN[1] = ' ' X CALL set_databasetype() X END IF X X RETURN db_mode X XEND FUNCTION {get_databasemode} SHAR_EOF chmod 0444 dbtype.4gl || echo "$0: failed to restore dbtype.4gl" fi if test -f dlist.c; then echo "File dlist.c exists"; else echo "x - dlist.c" sed 's/^X//' << 'SHAR_EOF' > dlist.c && X/* X@(#) File: dlist.c X@(#) Version: 3.3 X@(#) Last changed: 89/06/28 X@(#) Purpose: Maintain multiple D-lists of arbitrary data X@(#) Author: J Leffler X*/ X X/* -- Configuration */ X X/* #define FIXEDALLOCATION to use a fixed number of lists */ X/* #define VARIABLEALLOCATION to use a variable number of lists */ X/* #define PARANOID to scrutinise each dlist before each use */ X X#if defined(FIXEDALLOCATION) && defined(VARIABLEALLOCATION) X#undef FIXEDALLOCATION X#endif X X#if !defined(FIXEDALLOCATION) && !defined(VARIABLEALLOCATION) X#define VARIABLEALLOCATION X#endif X X/* -- Include Files */ X X#include "dlist.h" X#if defined(PARANOID) X#include X#endif X X/* -- Constant Definitions */ X X#define GLOBAL X#if defined(FIXEDALLOCATION) && !defined(MAXDLIST) X#define MAXDLIST 30 X#endif X X/* -- Type Definitions */ X Xstruct ditem X{ X struct ditem *next; X struct ditem *prev; X char *key; X int len; X}; Xtypedef struct ditem Ditem; X Xstruct dlist X{ X Ditem *head; X Ditem *curr; X int listlength; X Ditem item; X int inuse; X}; Xtypedef struct dlist Dlist; Xtypedef unsigned long ulong; X X/* -- Declarations */ X X#if !defined(lint) Xstatic char sccs[] = "@(#)dlist.c 3.3 89/06/28"; X#endif X X#if defined(FIXEDALLOCATION) Xstatic Dlist master[MAXDLIST]; Xstatic int nalloc = MAXDLIST; X#endif X X#if defined(VARIABLEALLOCATION) Xstatic Dlist *master = NIL(Dlist *); Xstatic int nalloc = 0; Xextern char *malloc(); Xextern Dlist *dalloc(); Xextern void free(); X#endif X XGLOBAL int sc_error; Xstatic int nused = 0; Xstatic Dlist *d = NIL(Dlist *); X X/* Initialise new or emptied list */ Xstatic void initialise(index) Xint index; X{ X Dlist *dp = &master[index-1]; X X dp->head = &dp->item; X dp->curr = dp->head; X dp->head->next = dp->head; X dp->head->prev = dp->head; X dp->listlength = 0; X} X X/* Check that list is valid, reset sc_error, set d */ Xstatic int check(index) Xint index; X{ X X#ifdef PARANOID X chk_key(index); X#endif X X sc_error = ENOERROR; X if (index < 1 || index > nalloc || master[index-1].inuse != 1) X sc_error = EINVARG; X else X d = &master[index-1]; X X return(sc_error); X} X X/* Create new list */ Xint mk_key() X{ X int index; X X sc_error = ENOERROR; X if (nalloc == nused) X { X /* No space left in current list */ X#if defined(FIXEDALLOCATION) X sc_error = ENOMEM; X return(sc_error); X#endif X#if defined(VARIABLEALLOCATION) X if (master == NIL(Dlist *)) X { X master = (Dlist *)malloc(sizeof(Dlist)); X } X else X { X master = dalloc(master, nalloc, (nalloc+1)); X } X if (master == NIL(Dlist *)) X { X /* Failure -- no memory */ X /* NB: old lists have not been lost */ X sc_error = ENOMEM; X return(sc_error); X } X index = ++nalloc; X master[index-1].inuse = 1; X nused++; X#endif X } X else X { X for (index = 0; index < nalloc; index++) X if (master[index].inuse == 0) X break; X if (index >= nalloc) X { X /* Lists are scrambled -- core dump imminent */ X sc_error = ENOMEM; X return(sc_error); X } X master[index++].inuse = 1; X nused++; X } X initialise(index); X return(index); X} X X/* Remove list -- make it inactive */ Xint rm_key(index) Xint index; X{ X if (check(index)) X return(sc_error); X (void)zap_key(index); X nused--; X master[index-1].inuse = 0; X return(sc_error); X} X X/* Add new item with key value at end of list */ Xint ins_key(index, keyval, keylen) Xint index; Xchar *keyval; Xint keylen; X{ X Ditem *new; X ulong alloclen; X X if (check(index)) X return(sc_error); X X /* Allocate new Ditem item */ X alloclen = sizeof(Ditem) + keylen; X if ((new = (Ditem *)malloc(alloclen)) == NIL(Ditem *)) X { X sc_error = ENOMEM; X return(sc_error); X } X X /* Insert new item */ X new->key = ((char *)new) + sizeof(Ditem); X memcpy(new->key, keyval, keylen); X new->len = keylen; X X#if defined(INSERT_AT_END) X new->prev = d->head->prev; X new->next = d->head; X new->prev->next = new; X d->head->prev = new; X#else X /* Relies on d->curr being set to d->head for empty list */ X new->prev = d->curr; X new->next = d->curr->next; X d->curr->next->prev = new; X d->curr->next = new; X#endif X X d->listlength++; X d->curr = new; X X return(sc_error); X} X X/* Update current key */ Xupd_key(index, keyval, keylen) Xint index; Xchar *keyval; Xint keylen; X{ X if (check(index)) X return(sc_error); X X if (d->listlength <= 0) X sc_error = ENOLIST; X else X { X (void)del_key(index); X (void)ins_key(index, keyval, keylen); X } X return(sc_error); X} X X/* Delete current key */ Xdel_key(index) Xint index; X{ X Ditem *old; X X if (check(index)) X return(sc_error); X if (d->listlength <= 0) X sc_error = ENOLIST; X else X { X old = d->curr; X old->prev->next = old->next; X old->next->prev = old->prev; X d->listlength--; X if (old->next != d->head) X d->curr = old->next; X else if (old->prev != d->head) X d->curr = old->prev; X else X d->curr = d->head; X X free((char *)old); X } X return(sc_error); X} X X/* Get current/next/previous/first/last/relative/absolute key */ Xchar *get_key(index, flag, offset) Xint index; /* List to work on */ Xint flag; /* Type of move */ Xint offset; /* Distance to move */ X{ X register Ditem *curr; X int i; X X if (check(index)) X return(NIL(char *)); X X if (d->listlength <= 0) X { X sc_error = ENOLIST; X return(NIL(char *)); X } X X /* SC_RELATIVE gets mapped into NEXT, PREVIOUS or CURRENT */ X if (flag == SC_RELATIVE) X { X if (offset == 0) X flag = SC_CURRENT; X else if (offset > 0) X flag = SC_NEXT; X else X { X flag = SC_PREVIOUS; X offset = -offset; X } X } X X /* Only non-negative offsets */ X if (offset < 0) X { X sc_error = EINVARG; X return(NIL(char *)); X } X X /* Fetch absolute 0 should not produce an error */ X if (flag == SC_ABSOLUTE && offset == 0) X { X return(NIL(char *)); X } X X if (offset == 0) X offset++; X X /* Absolute maps into SC_NEXT from first */ X if (flag == SC_ABSOLUTE) X { X flag = SC_NEXT; X d->curr = d->head->next; X offset--; X } X X /* Find relevant row -- overshoot is not an error */ X curr = d->curr; X switch (flag) X { X case SC_CURRENT: X /* curr = curr; */ X break; X case SC_FIRST: X curr = d->head->next; X break; X case SC_LAST: X curr = d->head->prev; X break; X case SC_NEXT: X for (i = 0; i < offset; i++) X { X if (curr->next == d->head) X break; X curr = curr->next; X } X break; X case SC_PREVIOUS: X for (i = 0; i < offset; i++) X { X if (curr->prev == d->head) X break; X curr = curr->prev; X } X break; X#if defined(PARANOID) X default: X err_key("Impossible case in get_key", flag, 1); X break; X#endif X } X X d->curr = curr; X return(curr->key); X} X X/* Delete complete list */ Xint zap_key(index) Xint index; X{ X Ditem *curr; X Ditem *old; X X if (check(index)) X return(sc_error); X X curr = d->head->next; X while (curr != d->head) X { X old = curr; X curr = curr->next; X free((char *)old); X } X d->listlength = 0; X initialise(index); X return(sc_error); X} X X/* Number of keys in list */ Xint cnt_key(index) Xint index; X{ X if (check(index)) X return(sc_error); X X return(d->listlength); X} X X/* Number of current key */ Xint num_key(index) Xint index; X{ X Ditem *p; X int i; X X if (check(index)) X return(sc_error); X X i = 0; X if (d->listlength > 0) X { X for (p = d->head->next, i = 1; p != d->curr; p = p->next) X i++; X } X return(i); X} X X#if defined(VARIABLEALLOCATION) X#define MIN(a,b) (((a)<(b))?(a):(b)) X XDlist *dalloc(old, old_size, new_size) XDlist *old; Xulong old_size; Xulong new_size; X{ X Dlist *new; X Dlist *op; X Dlist *np; X int i; X int n; X X new = (Dlist *)malloc(new_size*sizeof(Dlist)); X if (new == NIL(Dlist *)) X return(new); X X /* Transfer old lists -- adjust pointers galore */ X n = MIN(old_size, new_size); X for (i = 0, op = old, np = new; i < n; i++, op++, np++) X { X np->head = &np->item; X if (op->listlength > 0) X { X np->head->next = op->head->next; X np->head->prev = op->head->prev; X np->head->next->prev = np->head; X np->head->prev->next = np->head; X } X else X { X np->head->next = np->head; X np->head->prev = np->head; X } X np->listlength = op->listlength; X np->inuse = op->inuse; X if (op->curr == op->head) X np->curr = np->head; X else X np->curr = op->curr; X } X X free((char *)old); X return(new); X} X#endif X X#ifdef PARANOID X/* X This code is never necessary. On the other hand, it does a X fairly thorough scrutiny of the data in the named dlist. X Against that though, the one time it was needed (debugging X realloc on a SUN), it didn't detect the problem in time. X*/ Xstatic int err_count = 0; X Xchk_key(index) Xint index; X{ X Ditem *p; X Ditem *o; X int i; X X i = 0; X sc_error = ENOERROR; X if (index < 1) X err_key("index under bounds", index, i, 1); X if (index > nalloc) X err_key("index over bounds", index, i, 1); X if (master == NIL(Dlist *)) X err_key("nil master pointer", index, i, 1); X if (master[index-1].inuse != 1) X err_key("list not in use", index, i, 1); X d = &master[index-1]; X X if (d == NIL(Dlist *)) X err_key("nil list ptr", index, i, 1); X o = d->head; X if (o == NIL(Ditem *)) X err_key("nil head ptr", index, i, 1); X if (o != &d->item) X err_key("invalid head ptr", index, i, 1); X if (o->next == NIL(Ditem *)) X err_key("nil frwd ptr from head", index, i, 1); X if (o->prev == NIL(Ditem *)) X err_key("nil back ptr from head", index, i, 1); X if (d->curr == NIL(Ditem *)) X err_key("nil curr ptr", index, i, 0); /* Not fatal immediately */ X X p = d->head->next; X while (p != d->head) X { X i++; X if (o != p->prev) X err_key("back link error", index, i, 0); /* Not fatal immediately */ X if (p->next == NIL(Ditem *)) X err_key("nil frwd link", index, i, 1); X if (p->key == NIL(char *)) X err_key("nil data item", index, i, 0); /* Not fatal immediately */ X o = p; X p = p->next; X } X X if (i != d->listlength) X err_key("list length error", index, i, 1); X if (err_count) X err_key("too many errors", index, i, 1); X return(sc_error); X} X Xstatic FILE *fp = NIL(FILE *); Xstatic err_key(s, ix, inum, mode) Xchar *s; Xint ix; Xint inum; Xint mode; X{ X if (fp == NIL(FILE *)) X fp = fopen("key.errors", "w"); X fprintf(fp, " %s in dlist %d item %d\n", s, ix, inum); X fflush(fp); X err_count++; X if (mode == 1) X { X dmp_list(d); X fclose(fp); X abort(); X } X} X Xstatic dmp_list(p) XDlist *p; X{ X Ditem *s; X int i; X X if (fp == NIL(FILE *)) X fp = fopen("key.errors", "w"); X X if (p == NIL(Dlist *)) X fprintf(fp, "Nil list ptr\n"); X else X { X fprintf(fp, "Dump of list at 0x%08X\n", p); X fprintf(fp, "Head = 0x%08X (cf. 0x%08X)\n", p->head, &p->item); X fprintf(fp, "Current item = 0x%08X\n", p->curr); X fprintf(fp, "List length = %d\n", p->listlength); X fprintf(fp, "Use state = %d\n", p->inuse); X fprintf(fp, "Address Next Previous Key Length\n"); X fflush(fp); X s = p->head; X dmp_item(s); X for (i = 0; i < p->listlength; i++) X { X s = s->next; X dmp_item(s); X } X dmp_item(s->next); X } X} X Xstatic dmp_item(s) XDitem *s; X{ X if (s == NIL(Ditem *)) X fprintf(fp, " pointer to item"); X fprintf(fp, "0x%08X 0x%08X 0x%08X 0x%08X %d\n", X s, s->next, s->prev, s->key, s->len); X fflush(fp); X} X#endif /* PARANOID */ SHAR_EOF chmod 0444 dlist.c || echo "$0: failed to restore dlist.c" fi if test -f dlist.h; then echo "File dlist.h exists"; else echo "x - dlist.h" sed 's/^X//' << 'SHAR_EOF' > dlist.h && X/* X @(#)dlist.h 3.3 89/06/28 X @(#)Header file for D-list handling X*/ X#define SC_CURRENT 'C' X#define SC_NEXT 'N' X#define SC_PREVIOUS 'P' X#define SC_FIRST 'F' X#define SC_LAST 'L' X#define SC_RELATIVE 'R' X#define SC_ABSOLUTE 'A' X X#define ENOERROR 0 X#define ENOLIST -1 X#define EINVARG -2 X#define ENOMEM -3 X X#define NIL(x) ((x)0) X Xextern int mk_key(/* void */); Xextern int rm_key(/* index */); Xextern int ins_key(/* int, int, int */); Xextern int upd_key(/* int, int, int */); Xextern int del_key(/* index */); Xextern char *get_key(/* int, int, int */); Xextern int zap_key(/* index */); Xextern int cnt_key(/* index */); Xextern int num_key(/* index */); X Xextern int sc_error; SHAR_EOF chmod 0444 dlist.h || echo "$0: failed to restore dlist.h" fi if test -f dlist.man; then echo "File dlist.man exists"; else echo "x - dlist.man" sed 's/^X//' << 'SHAR_EOF' > dlist.man && X'\" @(#)dlist.man 3.2 X'\" @(#)Manual page: DLIST -- Double-linked list support routines X.ds fC "Version: 3.2 (88/11/16) X.TH DLIST 3S "Sphinx Informix Tools" X.SH NAME Xdlist \(em Doubly-linked list maintenance in C X.SH SYNOPSIS Xmk_key() X.sp Xrm_key(index) X.br Xint index; X.sp Xins_key(index, keyval, keylen) X.br Xint index; X.br Xchar *keyval; X.br Xint keylen; X.sp Xdel_key(index) X.br Xint index; X.br X.sp Xupd_key(index, keyval, keylen) X.br Xint index; X.br Xchar *keyval; X.br Xint keylen; X.sp Xchar *get_key(index, flag, offset) X.br Xint index; X.br Xint flag; X.br Xint offset; X.sp Xcnt_key(index) X.br Xint index; X.sp Xnum_key(index) X.br Xint index; X.SH DESCRIPTION XThere are 9 routines in this package which provide a fairly Xcomplete service for handling doubly-linked lists (Dlists) Xof an arbitrary data type (which could be of variable length items). XLists are created (\fBmk_key\fP) and destroyed (\fBrm_key\fP). XItems can be inserted (\fBins_key\fP), deleted (\fBdel_key\fP) Xand changed (\fBupd_key\fP). XItems can be retrieved by position in the list (\fBget_key\fP), Xand the size of the list can be determined by \fBcnt_key\fP, and Xthe current position discovered by \fBnum_key\fP. XEach list has a current position recorded (provided there are any Xitems in the list). XThe routines are described in the sections below. X.SH MK_KEY XThis routine either returns the index number of a new Dlist (Dlist#) Xor a negative number indicating an error. XThis routine must be called before any of the other routines are used. X.SH RM_KEY XThis routine is given a Dlist# and deletes all the records in the Xlist and then removes the list. XFurther calls using this Dlist# will fail with EINVARG. XThe Dlist# may be re-used by the Dlist package after another call Xto \fBmk_key\fP. X.SH INS_KEY XThis routine is given three arguments; a Dlist#, a character Xpointer to a data item to be inserted in the list and the length Xof the data item. XIf the data item is a string, do not forget to count the Xterminating null in the length of the item. XThe item will be inserted into the list after the current position, Xand becomes the current item. X.SH DEL_KEY XThis routine is given a Dlist# and deletes the current item. X.SH UPD_KEY XThis routine expects a Dlist#, a character pointer and a length. XThe current item is deleted and the item passed is inserted in Xits place. X.SH ZAP_KEY XThis routine is given a Dlist# and deletes all the items in the Xlist; the list remains active but is empty. X.SH GET_KEY XThis routine is given three arguments; the Dlist#, a flag Xindicating the action and an offset qualifying the action. XThe flag may take any of the following values: X.sp X`F' \(em relative position X.br X`L' \(em last position X.br X`N' \(em next position X.br X`P' \(em previous position X.br X`C' \(em current position X.br X`A' \(em absolute position X.br X`R' \(em relative position X.sp XThe first, last and current options ignore the offset. XThe relative option takes a signed offset and moves forward (if Xpositive) or backward (if negative) through the list. XA zero offset fetches the current item. XThe other options expect a positive offset. XThe next option moves forward by the relevant number of steps, Xthe previous option moves back; Xif the offset is zero, the move is by one item. XThe absolute option moves from the start of the list to the Xspecified offset. XIf this offset is zero, no row is returned (it returns a null Xpointer), but no error is indicated either. XThis behaviour is useful when repositioning the current item Xafter inserting some data into what was an empty list. XIf the offset would go beyond the end of the list (either Xforwards or backwards), the first or last item is fetched as Xappropriate; no error is signalled unless the list is empty. X.P XThe routine returns a character pointer to the item data; Xthere is no record of the length available, so the calling Xroutine must know what was stored. X.SH CNT_KEY XThis routine expects a Dlist# and returns the number of items on Xthe Dlist. X.SH NUM_KEY XThis routine expects a Dlist# and returns the number of the Xcurrent item in the list. X.SH "ERROR RETURN VALUES" XThe interfaces for these routines and some useful constants are Xdefined in ``dlist.h''. XThe error values returned are: X.sp X\00 \(em ENOERROR no error X.br X\-1 \(em ENOLIST no items in the list X.br X\-2 \(em EINVARG invalid argument X.br X\-3 \(em ENOMEM no more memory X.sp XException: \fBget_key\fP returns a null character pointer if Xthere is an error. X.P XAdditionally, there is a global variable \fBsc_error\fP declared Xin ``dlist.h'' which also contains the value of the error Xcondition. XThis variable is set to ENOERROR when each routine is called, so Xit only indicates the error state of the last Dlist routine which Xwas called. X.SH CONFIGURATION XThere are five configuration parameters which can be used when Xcompiling the Dlist code. X.sp XFIXEDALLOCATION \(em use a fixed number of Dlists, default 30. X.br XVARIABLEALLOCATION \(em use a variable number of Dlists, no limit. X.br XMAXDLIST \(em maximum number of Dlists if FIXEDALLOCATION X.br XPARANOID \(em run through some stringent (but not necessarily Xfool-proof) validation before using any Dlist. X.br XINSERT_AT_END \(em insert all values at end of list instead of Xcurrent position (not recommended). X.sp XPARANOID may possibly useful if you have a problem with memory allocation Xelsewhere \(em the code was used to debug an allocation problem Xwith Dlists \(em but it is also a considerable overhead. X.P XIf you do not specify any of these, or if you specify a Xconflicting set of values, the program supplies reasonable defaults. X.SH FILES Xdlist.h \(em interfaces and constants X.br Xdlist.c \(em code X.br Xdltest.c \(em a verification test program X.SH BUGS XNone known. X.sp XThe code uses `#if defined(PARANOID)' rather than `#ifdef'. X.SH DEFICIENCIES XThere is no mechanism for searching by value rather than by Xposition in list. X.SH AUTHOR XJonathan Leffler X.br XSphinx Ltd. X.br X30th June 1988 SHAR_EOF chmod 0444 dlist.man || echo "$0: failed to restore dlist.man" fi if test -f dliststr.c; then echo "File dliststr.c exists"; else echo "x - dliststr.c" sed 's/^X//' << 'SHAR_EOF' > dliststr.c && X/* X @(#)dliststr.c 3.3 89/06/28 X @(#)C code to maintain multiple D-lists of arbitrary data X @(#)I4GL interface code -- SQL CHAR types X*/ X X#include "dlist.h" X X#if !defined(lint) Xstatic char sccs[] = "@(#)dliststr.c 3.3 89/06/28"; X#endif X X#define I4GL_C /* Informix-4GL interface routine */ X X/* Long enough for longest I4GL string that could be Primary Key only */ Xtypedef char String[121]; X X/* Create new D-list (nominally of strings) */ XI4GL_C int sc_mkstr(n) Xint n; X{ X int retval; X X if (n != 0) X { X sc_error = EINVARG; X retval = sc_error; X } X else X retval = mk_key(); X retint(retval); X return(1); X} X X/* Remove list (nominally of strings) */ XI4GL_C int sc_rmstr(n) Xint n; X{ X int index; X X if (n != 1) X sc_error = EINVARG; X else X { X popint(&index); X (void)rm_key(index); X } X retint(sc_error); X return(1); X} X X/* Insert new key */ XI4GL_C int sc_insstr(n) Xint n; X{ X String value; X int index; X X if (n != 2) X sc_error = EINVARG; X else X { X popstring(value, sizeof(String)); X popint(&index); X (void)ins_key(index, (char *)value, strlen(value)+1); X } X X retint(sc_error); X return(1); X} X X/* Update current key */ XI4GL_C int sc_updstr(n) Xint n; X{ X String value; X int index; X X if (n != 2) X sc_error = EINVARG; X else X { X popstring(value, sizeof(String)); X popint(&index); X (void)upd_key(index, (char *)value, strlen(value)+1); X } X retint(sc_error); X return(1); X} X X/* Delete current key */ XI4GL_C int sc_delstr(n) Xint n; X{ X int index; X X if (n != 1) X sc_error = EINVARG; X else X { X popint(&index); X (void)del_key(index); X } X retint(sc_error); X return(1); X} X X/* Get current/next/previous/first/last/absolute/relative key */ XI4GL_C int sc_getstr(n) Xint n; X{ X int index; X int offset; /* Distance to move */ X char string[2]; /* Type of move */ X char *value; /* Key found */ X X value = ""; X X if (n != 3) X sc_error = EINVARG; X else X { X popint(&offset); X popquote(string, 2); X popint(&index); X value = get_key(index, string[0], offset); X if (value == NIL(char *)) X value = ""; X } X retint(sc_error); X retquote(value); X return(2); X} X X/* Delete complete list */ XI4GL_C int sc_zapstr(n) Xint n; X{ X int index; X X if (n != 1) X sc_error = EINVARG; X else X { X popint(&index); X (void)zap_key(index); X } X retint(sc_error); X return(1); X} X X/* Number of keys in list */ XI4GL_C int sc_cntstr(n) Xint n; X{ X int index; X int retval; X X if (n != 1) X { X sc_error = EINVARG; X retval = sc_error; X } X else X { X popint(&index); X retval = cnt_key(index); X } X retint(retval); X return(1); X} X X/* Number of current key */ XI4GL_C int sc_numstr(n) Xint n; X{ X int index; X int retval; X X if (n != 1) X { X sc_error = EINVARG; X retval = sc_error; X } X else X { X popint(&index); X retval = num_key(index); X } X retint(retval); X return(1); X} SHAR_EOF chmod 0444 dliststr.c || echo "$0: failed to restore dliststr.c" fi if test -f dliststr.man; then echo "File dliststr.man exists"; else echo "x - dliststr.man" sed 's/^X//' << 'SHAR_EOF' > dliststr.man && X'\" @(#)dliststr.man 3.1 X'\" @(#)Manual page: DLISTSTR -- Double-linked list support routines X.ds fC "Version: 3.1 (88/11/16) X.TH DLISTSTR 3S "Sphinx Informix Tools" X.SH NAME Xdliststr \(em Doubly-linked list maintenance in I4GL (\s-2CHAR\s0) X.SH SYNOPSIS Xdefine sc_error integer { Not available in calling code } X.sp Xfunction sc_mkstr() X define index integer X ... X return index X.br Xend function X.sp Xfunction sc_rmstr(index) X define index integer X ... X return sc_error X.br Xend function X.sp Xfunction sc_insstr(index, keyval) X define index integer X define keyval char(512) X ... X return sc_error X.br Xend function X.sp Xfunction sc_delstr(index) X.br Xdefine index integer X ... X return sc_error X.br Xend function X.br X.sp Xfunction sc_updstr(index, keyval) X define index integer X define keyval char(512) X ... X return sc_error X.br Xend function X.sp Xfunction sc_getstr(index, flag, offset) X define index integer X define flag integer X define offset integer X ... X return sc_error, value X.br Xend function X.sp Xfunction sc_cntstr(index) X define index integer X ... X return sc_error X.br Xend function X.sp Xfunction sc_numstr(index) X define index integer X ... X return sc_error X.br Xend function X.SH DESCRIPTION XThere are 9 routines in this package which provide a fairly Xcomplete service for handling doubly-linked lists (Dlists) Xof the I4GL \s-2CHAR\s0 data type. XLists are created (\fBsc_mkstr\fP) and destroyed (\fBsc_rmstr\fP). XItems can be inserted (\fBsc_insstr\fP), deleted (\fBsc_delstr\fP) Xand changed (\fBsc_updstr\fP). XItems can be retrieved by position in the list (\fBsc_getstr\fP), Xand the size of the list can be determined by \fBsc_cntstr\fP, and Xthe current position discovered by \fBsc_numstr\fP. XEach list has a current position recorded (provided there are any Xitems in the list). XThe routines are described in the sections below. X.SH SC_MKSTR XThis routine either returns the index number of a new Dlist (Dlist#) Xor a negative number indicating an error. XThis routine must be called before any of the other routines are used. X.SH SC_RMSTR XThis routine is given a Dlist# and deletes all the records in the Xlist and then removes the list. XFurther calls using this Dlist# will fail with EINVARG. XThe Dlist# may be re-used by the Dlist package after another call Xto \fBsc_mkstr\fP. X.SH SC_INSSTR XThis routine is given two arguments, a Dlist# and an string value. XThe value will be inserted into the list after the current position, Xand becomes the current item. X.SH SC_DELSTR XThis routine is given a Dlist# and deletes the current item. X.SH SC_UPDSTR XThis routine expects a Dlist# and an string value. XThe current item is deleted and the value passed is inserted in Xits place. X.SH SC_ZAPSTR XThis routine is given a Dlist# and deletes all the items in the Xlist; the list remains active but is empty. X.SH SC_GETSTR XThis routine is given three arguments; the Dlist#, a flag Xindicating the action and an offset qualifying the action. XThe flag may take any of the following values: X.sp X`F' \(em relative position X.br X`L' \(em last position X.br X`N' \(em next position X.br X`P' \(em previous position X.br X`C' \(em current position X.br X`A' \(em absolute position X.br X`R' \(em relative position X.sp XThe first, last and current options ignore the offset. XThe relative option takes a signed offset and moves forward (if Xpositive) or backward (if negative) through the list. XA zero offset fetches the current item. XThe other options expect a positive offset. XThe next option moves forward by the relevant number of steps, Xthe previous option moves back; Xif the offset is zero, the move is by one item. XThe absolute option moves from the start of the list to the Xspecified offset. XIf this offset is zero, no row is returned (it returns a null Xvalue), but no error is indicated either. XThis behaviour is useful when repositioning the current item Xafter inserting some data into what was an empty list. XIf the offset would go beyond the end of the list (either Xforwards or backwards), the first or last item is fetched as Xappropriate; no error is signalled unless the list is empty. X.P XThe routine returns the error status and the value from the list. XIf there is an error status returned, the contents of the value Xvariable is indeterminate. X.SH SC_CNTSTR XThis routine expects a Dlist# and returns the number of items on Xthe Dlist. X.SH SC_NUMSTR XThis routine expects a Dlist# and returns the number of the Xcurrent item in the list. X.SH "ERROR RETURN VALUES" XThe error values returned are: X.sp X\00 \(em ENOERROR no error X.br X\-1 \(em ENOLIST no items in the list X.br X\-2 \(em EINVARG invalid argument X.br X\-3 \(em ENOMEM no more memory X.SH FILES Xdlist.h \(em interfaces and constants X.br Xdliststr.c \(em code X.br Xdltststr.4gl \(em a verification test program X.sp XThis code is purely interface code and uses the routine provided Xby the Dlist package (DLIST(3S)) to actually store the data. X.SH BUGS XNone known. X.SH DEFICIENCIES XThere is no mechanism for searching by value rather than by Xposition in list. X.SH AUTHOR XJonathan Leffler X.br XSphinx Ltd. X.br X16th November 1988 SHAR_EOF chmod 0444 dliststr.man || echo "$0: failed to restore dliststr.man" fi if test -f helpfile.4gl; then echo "File helpfile.4gl exists"; else echo "x - helpfile.4gl" sed 's/^X//' << 'SHAR_EOF' > helpfile.4gl && X-- @(#)helpfile.4gl 1.4 93/11/02 X-- @(#)JLSS Informix Tools: General Library X-- @(#)Maintain stack of helpfile names X-- @(#)Author: JL X X X{ XThis code maintains a stack of help file names. Whenever a new file Xis pushed onto the stack, the stack pointer is incremented. If there Xis still space on the stack, the name is put onto the stack; in any Xcase, it is made into the current help file. The pop function Xrecogises whether it has a record of the correct help file name, and Xif it has, the current help file is changed; in any case, the stack Xpointer is decremented unless it would then go negative. X} X XDEFINE X stack ARRAY[10] OF CHAR(64), X sp INTEGER X X{ Push helpfile on to stack and make it the current help file } XFUNCTION psh_helpfile(filename) X X DEFINE X filename CHAR(64) X X LET sp = sp + 1 X IF sp <= 10 THEN X LET stack[sp] = filename X END IF X X OPTIONS HELP FILE filename X XEND FUNCTION {psh_helpfile} X X{ Pop helpfile off stack and make it the current help file } XFUNCTION pop_helpfile() X X DEFINE X filename CHAR(64) X X IF sp > 0 AND sp <= 10 THEN X LET filename = stack[sp] X OPTIONS HELP FILE filename X END IF X X IF sp > 0 THEN X LET sp = sp - 1 X END IF X XEND FUNCTION {pop_helpfile} X X{ Return name of current help file } XFUNCTION cur_helpfile() X X DEFINE X filename CHAR(64), X sccs CHAR(1) X X IF sp > 0 AND sp <= 10 THEN X LET filename = stack[sp] X ELSE X LET filename = NULL X LET sccs = "@(#)helpfile.4gl 1.4 93/11/02" X END IF X X RETURN filename X XEND FUNCTION {cur_helpfile} X X{ Return text of message number from help file } XFUNCTION help_message(msgnum) X X DEFINE X msgnum INTEGER, X s CHAR(512) X X IF sp > 0 AND sp <= 10 THEN X LET s = fgl_msgtext(stack[sp], msgnum) X ELSE X LET s = NULL X END IF X X RETURN s X XEND FUNCTION {help_message} X XFUNCTION fgl_msgtext(fname, msgnum) X X DEFINE X fname CHAR(30), X msgnum INTEGER, X msgtxt CHAR(512) X X IF fgl_msgopen(fname) != 0 THEN X LET msgtxt = NULL X ELSE X LET msgtxt = fgl_msgread(msgnum) X CALL fgl_msgclose() X END IF X XEND FUNCTION {fgl_msgtext} SHAR_EOF chmod 0444 helpfile.4gl || echo "$0: failed to restore helpfile.4gl" fi if test -f incdec.4gl; then echo "File incdec.4gl exists"; else echo "x - incdec.4gl" sed 's/^X//' << 'SHAR_EOF' > incdec.4gl && X{ X @(#)incdec.4gl 7.1 90/08/23 X @(#)Built by: FGLBLD Version 6.08 (01/12/1989) X @(#)Modular arithmetic functions X} X XFUNCTION inc_modulo(i, n) X X DEFINE X i INTEGER, X n INTEGER X X { i unconstrained } X LET i = (i + 1) MOD n X { i in range -n:n-1 } X IF i <= 0 THEN X LET i = i + n X END IF X { i in range 1:n } X X RETURN i X XEND FUNCTION {inc_modulo} X XFUNCTION dec_modulo(i, n) X X DEFINE X i INTEGER, X n INTEGER X X { i unconstrained } X LET i = (i - 1) MOD n X { i in range -n:n-1 } X IF i <= 0 THEN X LET i = i + n X END IF X { i in range 1:n } X X RETURN i X XEND FUNCTION {dec_modulo} SHAR_EOF chmod 0444 incdec.4gl || echo "$0: failed to restore incdec.4gl" fi if test -f interr.4gl; then echo "File interr.4gl exists"; else echo "x - interr.4gl" sed 's/^X//' << 'SHAR_EOF' > interr.4gl && X{ X @(#)interr.4gl 7.1 90/08/23 X @(#)Sphinx informix Tools: Error handling X @(#)Record internal and fatal errors X @(#)Assumes use of std_options X @(#)Author: JL X} X X{ Record irrecoverable error } XFUNCTION fatal_error(s) X X DEFINE X s CHAR(512), X sccs CHAR(1) X X LET sccs = "@(#)interr.4gl 7.1 90/08/23" X CALL logerror(s) X ERROR "A serious internal error has occurred -- please report to DBA" X SLEEP 5 X EXIT PROGRAM 1 X XEND FUNCTION {fatal_error} X X{ Record error which can be survived } XFUNCTION internal_error(s) X X DEFINE X s CHAR(512) X X CALL logerror(s) X ERROR "An internal error has been detected -- please report to DBA" X SLEEP 3 X XEND FUNCTION {internal_error} SHAR_EOF chmod 0444 interr.4gl || echo "$0: failed to restore interr.4gl" fi if test -f ldint.c; then echo "File ldint.c exists"; else echo "x - ldint.c" sed 's/^X//' << 'SHAR_EOF' > ldint.c && X/* X@(#)File: ldint.c X@(#)Version: 1.4 X@(#)Last changed: 91/12/22 X@(#)Purpose: C-ISAM style LDINT(3) X@(#)Author: J Leffler X@(#)Product: :PRODUCT: X*/ X X/*TABSTOP=4*/ X/*LINTLIBRARY*/ X X#ifndef lint Xstatic char sccs[] = "@(#)ldint.c 1.4 91/12/22"; X#endif X Xtypedef unsigned short ushort; X X/* X** Convert 2-byte character array into real short integer X** Works on both 680x0 and 80x86 type machines. X** Slows 680x0 type machines up as it is then a no-op. X*/ Xint ldint(s) Xregister char *s; X{ X register int i; X register ushort j; X X for (i = j = 0; i < 2; i++) X { X j = (j << 8) | (*s++ & 0xFF); X } X return(j); X} X X#ifdef TEST X X#include X X#define DIM(x) (sizeof(x)/sizeof(*(x))) X Xchar values[][2] = X{ X "\002\003", X "\017\017" X}; X Xmain() X{ X int i; X X for (i = 0; i < DIM(values); i++) X printf("0x%02X%02X => 0x%04X\n", X (unsigned char)values[i][0], (unsigned char)values[i][1], X ldint(values[i])); X return(0); X} X X#endif /* TEST */ SHAR_EOF chmod 0444 ldint.c || echo "$0: failed to restore ldint.c" fi if test -f msgtext.c; then echo "File msgtext.c exists"; else echo "x - msgtext.c" sed 's/^X//' << 'SHAR_EOF' > msgtext.c && X/* X@(#)File: msgtext.c X@(#)Version: 2.4 X@(#)Last changed: 91/11/02 X@(#)Purpose: Open, Read, Close Informix Error Message Files X@(#)Author: J Leffler X*/ X X/* -- Include Files */ X X#include X#include X X/* -- Constant Definitions */ X X#define I4GL_C int /* C callable from I4GL */ X#define MAGIC1 ((ushort)0xFE68) X#define MAXBUFF 4096 X#define NIL(x) ((x)0) X X/* -- Type Definitions */ X Xtypedef unsigned short ushort; Xtypedef unsigned long ulong; X Xtypedef struct X{ X ushort magic; X short n_entries; X} Header; X Xtypedef struct X{ X short err_number; X short err_length; X long err_seek; X} Entry; X X/* -- Declarations */ X Xstatic char buff[MAXBUFF]; Xstatic char header[sizeof(Header)]; Xstatic char entry[sizeof(Entry)]; Xstatic Header hdr; Xstatic FILE *fp; Xstatic Entry *elist; X Xextern char *malloc(); Xextern void free(); X X#if !defined(lint) Xstatic char sccs[] = "@(#)msgtext.c 2.4 91/11/02"; X#endif X X/* Close an already open error message file */ X/* Does not fail if no file open */ Xvoid iem_close() X{ X if (fp != NIL(FILE *)) X { X fclose(fp); X if (elist != NIL(Entry *)) X free(elist); X elist = NIL(Entry *); X fp = NIL(FILE *); X } X} X Xint iem_open(fname) Xchar *fname; X{ X iem_close(); X if ((fp = fopen(fname, "r")) == NIL(FILE *)) X return (-1); X if (fread(header, sizeof(header), 1, fp) == EOF) X return (-1); X hdr.magic = ldint(&header[0]); X hdr.n_entries = ldint(&header[2]); X#ifdef DEBUG X fprintf(stderr, "Magic: %04X; entries = %d\n", hdr.magic, hdr.n_entries); X#endif /* DEBUG */ X if (hdr.magic != MAGIC1) X return (-1); X return (0); X} X X/* Compare two error message entries */ Xstatic int iem_comp(cp1, cp2) Xchar *cp1; Xchar *cp2; X{ X register Entry *ep1 = (Entry *) cp1; X register Entry *ep2 = (Entry *) cp2; X X return (ep1->err_number - ep2->err_number); X} X Xchar *iem_read(msg) Xint msg; X{ X Entry hunt; X Entry *ent; X char *entry; X long org_seek; X int i; X int n; X X if (elist == NIL(Entry *)) X { X /* Read array of message headers into memory */ X n = hdr.n_entries; X if ((elist = (Entry *) malloc(n * sizeof(Entry))) == NIL(Entry *)) X return(NIL(char *)); X if (fread((char *) elist, sizeof(Entry), n, fp) != n) X { X /* Failed to read header records */ X free(elist); X elist = NIL(Entry *); X return (NIL(char *)); X } X /* Convert numbers from canonical form to host form */ X for (i = 0; i < n; i++) X { X ent = &elist[i]; X entry = (char *) ent; X ent->err_number = ldint(&entry[0]); X ent->err_length = ldint(&entry[2]); X ent->err_seek = ldlong(&entry[4]); X } X } X X hunt.err_number = msg; X ent = (Entry *) bsearch((char *) &hunt, (char *) elist, hdr.n_entries, X sizeof(Entry), iem_comp); X X if (ent == NIL(Entry *)) X return (NIL(char *)); X else X { X#ifdef DEBUG X fprintf(stderr, "%4d: %6d: %4d @ 0x%08X\n", msg, ent->err_number, X ent->err_length, ent->err_seek); X#endif /* DEBUG */ X fseek(fp, ent->err_seek, 0); X if (ent->err_length > MAXBUFF) X ent->err_length = MAXBUFF - 1; X if (fread(buff, ent->err_length, 1, fp) != 1) X return (NIL(char *)); X buff[ent->err_length] = '\0'; X if (buff[ent->err_length - 1] == '\n') X buff[ent->err_length - 1] = '\0'; X } X return (buff); X} X X/* I4GL calling sequence: LET i = fgl_msgopen(msgfile) */ X/* (i = 0 => OK; i = -1 => fail) */ X/* I4GL calling sequence: LET s = fgl_msgread(msgnum) */ X/* I4GL calling sequence: CALL fgl_msgclose() */ X XI4GL_C fgl_msgopen(n) Xint n; X{ X char msgfile[512]; X int r; X X if (n != 1) X r = -1; X else X { X popstring(msgfile, sizeof(msgfile)); X r = iem_open(msgfile); X } X retint(r); X return (1); X} X XI4GL_C fgl_msgread(n) Xint n; X{ X char *s; X int msgnum; X char buffer[50]; X X if (n != 1) X s = ""; X else X { X popint(&msgnum); X if ((s = iem_read(msgnum)) == NIL(char *)) X { X sprintf(buffer, "<>", msgnum); X s = buffer; X } X } X retquote(s); X return (1); X} X X/* ARGSUSED */ XI4GL_C fgl_msgclose(n) Xint n; X{ X iem_close(); X return (0); X} X X#ifdef TEST X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X int i; X int n; X char *s; X X if (argc <= 2) X { X fprintf(stderr, "Usage: %s iemfile msg [...]\n", argv[0]); X exit(1); X } X X if (iem_open(argv[1]) != 0) X { X fprintf(stderr, "%s: failed to open message file %s\n", argv[0], argv[1]); X exit(1); X } X X for (i = 2; i < argc; i++) X { X n = atoi(argv[i]); X s = iem_read(n); X if (s != NIL(char *)) X printf("%d: %s\n", n, s); X else X printf("%d: \n", n); X } X X iem_close(); X return (0); X} X X#endif /* TEST */ SHAR_EOF chmod 0444 msgtext.c || echo "$0: failed to restore msgtext.c" fi if test -f nxtfield.4gl; then echo "File nxtfield.4gl exists"; else echo "x - nxtfield.4gl" sed 's/^X//' << 'SHAR_EOF' > nxtfield.4gl && X{ X @(#)nxtfield.4gl 7.1 90/08/23 X @(#)Sphinx Informix Tools X @(#)Calculate which field to go next X} X XFUNCTION next_field(c, p, mn, mx) X X DEFINE X c INTEGER, { Current field number } X p INTEGER, { Previous field number } X mn INTEGER, { Minimum field number } X mx INTEGER, { Maximum field number } X n INTEGER, { Number of fields } X df INTEGER, { Difference forwards } X db INTEGER, { Difference backwards } X nxt INTEGER { Next field number } X X LET n = mx - mn + 1 X X { Normalise c } X IF c IS NULL OR c = 0 THEN X { This should not happen } X LET c = mn X END IF X LET c = c - mn + 1 X IF c < 0 OR c >= n THEN X LET c = (n + (c MOD n)) MOD n X END IF X X { Normalise p } X IF p IS NULL OR p = 0 THEN X LET p = mn X END IF X LET p = p - mn + 1 X IF p < 0 OR p >= n THEN X LET p = (n + (p MOD n)) MOD n X END IF X X LET df = (n + (c - p)) MOD n X LET db = (n - df) MOD n X X IF df <= db THEN X LET nxt = (c + 1) MOD n X ELSE X LET nxt = (n + c - 1) MOD n X END IF X X IF nxt = 0 THEN X LET nxt = n X END IF X X LET nxt = nxt + mn - 1 X X RETURN nxt X XEND FUNCTION {next_field} SHAR_EOF chmod 0444 nxtfield.4gl || echo "$0: failed to restore nxtfield.4gl" fi if test -f openlog.4gl; then echo "File openlog.4gl exists"; else echo "x - openlog.4gl" sed 's/^X//' << 'SHAR_EOF' > openlog.4gl && X-- @(#)openlog.4gl 1.2 91/05/09 X-- @(#)JLSS Informix Tools: General Library X-- @(#)Open log file reasonably reliably X-- @(#)Author: JL X XFUNCTION open_logfile(filename) X X DEFINE X filename CHAR(64), X cmd CHAR(90), X sccs CHAR(1) X X WHENEVER ERROR CONTINUE X CALL STARTLOG(filename) X WHENEVER ERROR STOP X X IF STATUS != 0 THEN X LET sccs = "@(#)openlog.4gl 1.2 91/05/09" X ERROR "Failed to open log file ", filename X SLEEP 3 X EXIT PROGRAM 1 X END IF X X LET cmd = "sh -c 'exec chmod 666 ", filename CLIPPED, " 2>&1'" X RUN cmd X XEND FUNCTION {open_logfile} SHAR_EOF chmod 0444 openlog.4gl || echo "$0: failed to restore openlog.4gl" fi if test -f repdest.4gl; then echo "File repdest.4gl exists"; else echo "x - repdest.4gl" sed 's/^X//' << 'SHAR_EOF' > repdest.4gl && X{ X @(#)repdest.4gl 2.8 91/05/17 X @(#)JLSS Informix Tools: General Library X @(#)Select destination for report X @(#)Author: JL X} X X{ X Return values of destination: X NULL => abandon report X 0 => send to screen X 1 => send to printer X 2 => send to file X 3 => send to pipe X} X XDEFINE X old_name CHAR(42) { old program/filename for CONTROL-P } XDEFINE X prv_opt CHAR(1), { Was previous option `View' } X prv_file CHAR(40) { Name of file to be viewed } X X{ Select destination for report } XFUNCTION report_destination() X X DEFINE X wrow INTEGER, X pipe_or_file CHAR(80), X destination INTEGER X X LET wrow = 2 X OPEN WINDOW w_repdest1 AT wrow, 2 X WITH 2 ROWS, 78 COLUMNS X ATTRIBUTE (BORDER) X X LET prv_opt = NULL X IF prv_file IS NOT NULL THEN X LET pipe_or_file = "rm -f ", prv_file X RUN pipe_or_file WITHOUT WAITING X LET prv_file = NULL X END IF X X MENU "REPORT DESTINATION" X X COMMAND "Screen" X "Send the report to standard output" X LET pipe_or_file = "@(#)repdest.4gl 2.8 91/05/17" { SCCS ID only } X LET destination = 0 X LET pipe_or_file = NULL X CALL set_plength(23) X CALL set_tmargin(0) X CALL set_bmargin(0) X CALL set_lmargin(0) X EXIT MENU X X COMMAND "Printer" X "Send output of report to default printer" X LET pipe_or_file = NULL X LET destination = 1 X EXIT MENU X X COMMAND KEY(F) X -- "File" X -- "Send the report to a new file (over-writes existing file)" X CALL get_pipe_or_fn(2, "F", wrow) X RETURNING pipe_or_file, destination X EXIT MENU X X COMMAND KEY(A) X -- "Append" X -- "Append the report to the end of a file (creates new file)" X CALL get_pipe_or_fn(3, "F", wrow) X RETURNING pipe_or_file, destination X LET pipe_or_file = "cat >>", pipe_or_file CLIPPED X EXIT MENU X X COMMAND "View" X "Place the report in a file and run editor on file afterwards" X LET destination = 2 X LET pipe_or_file = mkfilename("/tmp/view.XXXXXX") X LET prv_file = pipe_or_file X LET prv_opt = 'V' X EXIT MENU X X COMMAND KEY('|') X { "Pipe" "Pipe the report to a program (or pipeline)" } X CALL get_pipe_or_fn(3, "P", wrow) X RETURNING pipe_or_file, destination X EXIT MENU X X COMMAND "Exit" X "Exit without specifying destination -- abandon report" X LET destination = NULL X LET pipe_or_file = NULL X EXIT MENU X X COMMAND KEY(F9) X CALL do_screen_dump() X X COMMAND KEY(CONTROL-Y) X CALL do_screen_dump() X X END MENU X X CLOSE WINDOW w_repdest1 X X RETURN destination, pipe_or_file X XEND FUNCTION {report_destination} X X{ Get name of file or program to which report should be sent } XFUNCTION get_pipe_or_fn(dest, code, wrow) X X DEFINE X wrow integer, X dest INTEGER, X code CHAR(1), X msg CHAR(25), X fn CHAR(42) X X CASE X WHEN code = "F" X LET msg = "Enter name of print-file" X WHEN code = "P" X LET msg = "Enter name of program" X END CASE X X LET fn = NULL X OPEN WINDOW w_repdest2 AT wrow, 2 X WITH FORM "repdest" X ATTRIBUTE(FORM LINE FIRST, COMMENT LINE LAST) X DISPLAY msg AT 1,1 X X OPTIONS INPUT NO WRAP X INPUT BY NAME fn X X ON KEY (INTERRUPT) X LET dest = NULL X LET fn = NULL X EXIT INPUT X X ON KEY (CONTROL-P) X IF old_name IS NOT NULL THEN X LET fn = old_name X DISPLAY BY NAME fn X END IF X X ON KEY(F9, CONTROL-Y) X CALL do_screen_dump() X X END INPUT X OPTIONS INPUT WRAP X X LET INT_FLAG = FALSE X LET old_name = fn X CLOSE WINDOW w_repdest2 X X RETURN fn, dest X XEND FUNCTION {get_pipe_or_fn} X X{ View saved report } XFUNCTION view_report() X X DEFINE X cmd CHAR(80), X ed CHAR(20) X X IF prv_opt = 'V' THEN X LET ed = fgl_getenv("DBEDIT") X IF ed IS NULL THEN X LET ed = "vi" X END IF X LET cmd = ed clipped, " ", prv_file CLIPPED X RUN cmd X LET cmd = "rm -f ", prv_file CLIPPED X RUN cmd WITHOUT WAITING X LET prv_opt = NULL X LET prv_file = NULL X END IF X XEND FUNCTION {view_report} SHAR_EOF chmod 0664 repdest.4gl || echo "$0: failed to restore repdest.4gl" fi if test -f repdest.per; then echo "File repdest.per exists"; else echo "x - repdest.per" sed 's/^X//' << 'SHAR_EOF' > repdest.per && X{ X @(#)repdest.4gf 2.3 90/02/08 X @(#)Sphinx Informix Tools: General Library X @(#)Form for specifying destination of report X @(#)Author: DMR X} X XDATABASE FORMONLY X XSCREEN X{ X : [f001 ] X} X XATTRIBUTES Xf001 = FORMONLY.fn TYPE CHAR, REQUIRED, X COMMENTS = "Use CONTROL-P to use the same name as last time"; XEND X XINSTRUCTIONS XDELIMITERS " " XEND SHAR_EOF chmod 0444 repdest.per || echo "$0: failed to restore repdest.per" fi if test -f reptype.4gl; then echo "File reptype.4gl exists"; else echo "x - reptype.4gl" sed 's/^X//' << 'SHAR_EOF' > reptype.4gl && X-- @(#)reptype.4gl 7.1 91/05/09 X-- @(#)JLSS Informix Tools: FGLBLD Support Library X-- @(#)Allow user to select data set for report X-- @(#)Author: J Leffler X X{ Choose report option } XFUNCTION report_type(mqdone, rqdone, nrows) X X DEFINE X mqdone INTEGER, { Boolean: main query done } X rqdone INTEGER, { Boolean: report query done } X nrows INTEGER, { Number of rows in current data } X sccs CHAR(1), { SCCS ID string } X choice CHAR(1) X X LET sccs = "@(#)reptype.4gl 7.1 91/05/09" X LET INT_FLAG = FALSE X X MENU "REPORT DATA" X X COMMAND "Current-List" X "Print all the data in the current list" X HELP 30 X IF nrows <= 0 THEN X ERROR "No current list" X NEXT OPTION "Query" X ELSE X LET choice = 'C' X EXIT MENU X END IF X X COMMAND KEY(S) X { "Same Query" } X { "Re-execute the main query and report the data" } X { HELP 31 } X IF NOT mqdone THEN X ERROR "No query to repeat" X NEXT OPTION "Query" X ELSE X LET choice = 'S' X EXIT MENU X END IF X X COMMAND "Query" X "Specify a new enquiry and report the results" X HELP 32 X LET choice = 'Q' { Re-use enquiry just set up } X EXIT MENU X X COMMAND KEY(R) X { "Re-use Query" } X { "Re-use the report query specified previously" } X { HELP 33 } X IF NOT rqdone THEN X ERROR "No report query to re-use" X NEXT OPTION "Query" X ELSE X LET choice = 'R' X EXIT MENU X END IF X X COMMAND "All" X "Report on all the data in the table" X HELP 34 X LET choice = 'A' X EXIT MENU X X COMMAND "Exit" X "Leave the REPORT DATA menu" X HELP 35 X LET choice = 'E' X EXIT MENU X X COMMAND KEY(F9) X CALL do_screen_dump() X X COMMAND KEY(CONTROL-Y) X CALL do_screen_dump() X X END MENU X X IF INT_FLAG THEN X LET choice = 'E' X LET INT_FLAG = FALSE X END IF X X RETURN choice X XEND FUNCTION {report_type} SHAR_EOF chmod 0444 reptype.4gl || echo "$0: failed to restore reptype.4gl" fi if test -f translog.4gl; then echo "File translog.4gl exists"; else echo "x - translog.4gl" sed 's/^X//' << 'SHAR_EOF' > translog.4gl && X{ X @(#)translog.4gl 1.6 90/11/16 X @(#)Sphinx Informix Tools: General Library X @(#)Handle transactions whether database has log or not X @(#)Author: JL X} X X{ Global to this file -- not accessible outside } XDEFINE X logstatus INTEGER X { 0 => State of log unknown, 1 => Log absent, 2 => Log present } X X{ Determine whether there is a transaction log } XFUNCTION translog() X X DEFINE X sccs CHAR(1), X logs INTEGER X X IF logstatus = 0 THEN X LET logs = get_databaselogs() X IF logs = FALSE THEN X LET logstatus = 1 { Log absent } X ELSE X LET logstatus = 2 { Log present } X LET sccs = "@(#)translog.4gl 1.6 90/11/16" X END IF X END IF X X RETURN (logstatus = 2) X XEND FUNCTION {translog} X X{ Begin a transaction if there is a log } XFUNCTION begin_work() X X IF translog() THEN X BEGIN WORK X END IF X XEND FUNCTION {begin_work} X X{ Commit a transaction if there is a log } XFUNCTION commit_work() X X IF translog() THEN X COMMIT WORK X END IF X XEND FUNCTION {commit_work} X X{ Rollback transaction if there is a log } XFUNCTION rollback_work() X X IF translog() THEN X ROLLBACK WORK X END IF X XEND FUNCTION {rollback_work} X X{ Terminate a transaction } XFUNCTION end_work(state) X X DEFINE X state INTEGER X X IF state != 0 THEN X CALL rollback_work() X ELSE X CALL commit_work() X END IF X XEND FUNCTION {end_work} SHAR_EOF chmod 0444 translog.4gl || echo "$0: failed to restore translog.4gl" fi if test -f uname.c; then echo "File uname.c exists"; else echo "x - uname.c" sed 's/^X//' << 'SHAR_EOF' > uname.c && X/* X@(#) File: uname.c X@(#) Version: 1.2 X@(#) Last changed: 91/05/09 X@(#) Purpose: I4GL: Find user name -- no reference to database X@(#) Author: J Leffler X*/ X X/* -- Include Files */ X X#include X#include X Xstruct passwd *getpwuid(); Xstatic char u_name[10]; X X#ifndef lint Xstatic char sccs[] = "@(#)uname.c 1.2 91/05/09"; X#endif X X/* username: return name of user */ X/* I4GL: LET uname = username() */ X Xint username(i) Xint i; X{ X struct passwd *p; X X if (u_name[0] == '\0') X { X p = getpwuid(getuid()); X strncpy(u_name, p->pw_name, sizeof(u_name)); X } X retquote(u_name); X return(1); X} SHAR_EOF chmod 0444 uname.c || echo "$0: failed to restore uname.c" fi if test -f popstr.c; then echo "File popstr.c exists"; else echo "x - popstr.c" sed 's/^X//' << 'SHAR_EOF' > popstr.c && X/* X@(#)File: popstr.c X@(#)Version: 1.2 X@(#)Last changed: 90/04/05 X@(#)Purpose: Pop string and strip trailing blanks X@(#)Author: J Leffler X*/ X X/* -- Declarations */ X X#ifndef lint Xstatic char sccs[] = "@(#)popstr.c 1.2 90/04/05"; X#endif X X/* -- Routine: popstring */ X Xvoid popstring(s, l) Xchar *s; /* InOut: String to be stripped */ Xint l; /* In: Length of string */ X{ X register char *p = s + l - 1; X X popquote(s,l); X X if (l <= 1) X return; /* Length 1 => "" */ X X while (p > s) X if (*--p != ' ') X break; X *(p+1) = '\0'; X} SHAR_EOF chmod 0444 popstr.c || echo "$0: failed to restore popstr.c" fi if test -f scrndump.4gl; then echo "File scrndump.4gl exists"; else echo "x - scrndump.4gl" sed 's/^X//' << 'SHAR_EOF' > scrndump.4gl && X{ X @(#)scrndump.4gl 1.5 90/04/05 X @(#)Interface to Screen Dump Utility X} X XFUNCTION do_screen_dump() X X DEFINE X sccs CHAR(1), X filename CHAR(64), X ans CHAR(1) X X LET INT_FLAG = FALSE X X OPEN WINDOW w_screen_dump AT 2, 2 X WITH 2 ROWS, 78 COLUMNS X ATTRIBUTE (BORDER, FORM LINE FIRST, COMMENT LINE LAST) X OPEN FORM f_screen_dump FROM "scrndump" X DISPLAY FORM f_screen_dump X X OPTIONS INPUT NO WRAP X INPUT BY NAME filename X OPTIONS INPUT WRAP X X IF INT_FLAG THEN X ERROR "Not doing screen dump" X LET sccs = "@(#)scrndump.4gl 1.5 90/04/05" X LET INT_FLAG = FALSE X CLOSE WINDOW w_screen_dump X CLOSE FORM f_screen_dump X RETURN X END IF X X IF filename IS NULL THEN X LET filename = mkfilename("/tmp/scrdumpXXXXXX") X DISPLAY "Your dump file is: ", filename X PROMPT "Hit return to continue" FOR CHAR ans X END IF X X CLOSE WINDOW w_screen_dump X CLOSE FORM f_screen_dump X X CALL screendump(filename) X XEND FUNCTION {do_screen_dump} SHAR_EOF chmod 0444 scrndump.4gl || echo "$0: failed to restore scrndump.4gl" fi if test -f scrndump.per; then echo "File scrndump.per exists"; else echo "x - scrndump.per" sed 's/^X//' << 'SHAR_EOF' > scrndump.per && X{ X @(#)scrndump.4gf 1.2 90/02/09 X @(#)Form for Screen Dump Utility X} X XDATABASE FORMONLY X XSCREEN X{ XFilename [f000 ] X} X XEND X XATTRIBUTES Xf000 = FORMONLY.filename TYPE CHAR, X COMMENTS = "Enter name of file. Leave blank to have name generated"; XEND SHAR_EOF chmod 0444 scrndump.per || echo "$0: failed to restore scrndump.per" fi if test -f security.4gl; then echo "File security.4gl exists"; else echo "x - security.4gl" sed 's/^X//' << 'SHAR_EOF' > security.4gl && X-- @(#)security.4gl 2.6 91/05/09 X-- @(#)JLSS Informix Tools: General Library X-- @(#)See whether user is entitled to perform an action X-- @(#)Author: JL X XDEFINE X name_set INTEGER, { Has user name been set? } X user_name CHAR(8) { Name of user } X XFUNCTION allowed_to_do(action) X X DEFINE X action CHAR(12), { Action code } X sccs CHAR(1), { SCCS ID only } X stmt CHAR(110), { Statement to prepare } X ostatus INTEGER, { Status of OPEN } X number INTEGER X X IF name_set = 0 THEN X LET user_name = "@(#)security.4gl 2.6 91/05/09" { SCCS ID only } X LET user_name = username() X LET name_set = 1 X LET stmt = " SELECT COUNT(*)", X " FROM Sec_actuser", X " WHERE Sec_actuser.Sau_username = ?", X " AND Sec_actuser.Sau_action = ?" X WHENEVER ERROR CONTINUE X PREPARE s_security FROM stmt X LET ostatus = STATUS X IF ostatus = -349 THEN { -349: database not selected yet } X LET name_set = 2 X LET STATUS = 0 X ELSE X DECLARE c_security CURSOR FOR s_security X END IF X WHENEVER ERROR STOP X END IF X X IF action = "NONE" OR name_set = 2 THEN X LET number = 1 X LET ostatus = 0 X ELSE X WHENEVER ERROR CONTINUE X OPEN c_security USING user_name, action X LET ostatus = STATUS X IF ostatus = 0 THEN X FETCH c_security INTO number X CLOSE c_security X END IF X WHENEVER ERROR STOP X IF ostatus != 0 THEN X { No security system present } X LET name_set = 2 X LET number = 1 X LET ostatus = 0 X END IF X END IF X X LET STATUS = 0 -- Crucial X LET SQLCA.SQLCODE = 0 -- Crucial X X RETURN (number > 0 AND ostatus = 0) X XEND FUNCTION {allowed_to_do} SHAR_EOF chmod 0664 security.4gl || echo "$0: failed to restore security.4gl" fi if test -f shell.4gl; then echo "File shell.4gl exists"; else echo "x - shell.4gl" sed 's/^X//' << 'SHAR_EOF' > shell.4gl && X{ X @(#)shell.4gl 1.6 90/08/19 X @(#)Sphinx Informix Tools: General Library X @(#)Provide shell escape -- allow user to run commands X @(#)Author: JL X} X XFUNCTION shell_escape() X X DEFINE X sccs CHAR(1), X cmd CHAR(80), X ans CHAR(1) X X LET INT_FLAG = FALSE X LET ans = '!' X WHILE ans = '!' X PROMPT "! " FOR cmd X IF INT_FLAG THEN X LET INT_FLAG = FALSE X EXIT WHILE X END IF X RUN cmd X PROMPT "Hit any key to continue" FOR CHAR ans X IF INT_FLAG THEN X LET sccs = "@(#)shell.4gl 1.6 90/08/19" X LET INT_FLAG = FALSE X EXIT WHILE X END IF X END WHILE X XEND FUNCTION {shell_escape} SHAR_EOF chmod 0444 shell.4gl || echo "$0: failed to restore shell.4gl" fi if test -f stdopt.4gl; then echo "File stdopt.4gl exists"; else echo "x - stdopt.4gl" sed 's/^X//' << 'SHAR_EOF' > stdopt.4gl && X-- @(#)stdopt.4gl 4.7 91/05/09 X-- @(#)JLSS Informix Tools: General Library X-- @(#)Set standard options; log messages and errors X-- @(#)Author: JL X XDEFINE X sccs CHAR(1), { SCCS version number } X basedir CHAR(64), { Base Directory of application } X uname CHAR(8), { User name } X pname CHAR(8) { Program name } X X{ Set standard options, specify help file, open error log } XFUNCTION std_options(progname) X X DEFINE X progname CHAR(8), # Name of program recorded in log files X lprogname CHAR(8), # Lower-case version of progname X hlpfile CHAR(76), # Name of help file X logfile CHAR(76) # Name of log file X X { Determine type of database which has been opened -- must be first } X CALL set_databasetype() X X { Set explain mode from DBEXPLAIN } X CALL set_dbexplain() X X { Set module variables for reuse } X LET basedir = get_base() X LET sccs = "@(#)stdopt.4gl 4.7 91/05/09" X LET uname = username() X LET pname = UPSHIFT(progname) X LET lprogname = DOWNSHIFT(progname) X X IF basedir = "." THEN X LET logfile = basedir CLIPPED, "/", lprogname CLIPPED, ".log" X LET hlpfile = basedir CLIPPED, "/", lprogname CLIPPED, ".iem" X ELSE X LET logfile = basedir CLIPPED, "/log/", lprogname CLIPPED, ".log" X LET hlpfile = basedir CLIPPED, "/msg/", lprogname CLIPPED, ".iem" X END IF X CALL open_logfile(logfile) X CALL psh_helpfile(hlpfile) X X { Security clearance } X IF allowed_to_do(pname) = FALSE THEN X CALL logerror("Unauthorised use") X ERROR "Sorry!" X SLEEP 3 X EXIT PROGRAM 1 X ELSE X CALL logmessage("Started") X END IF X X OPTIONS X PROMPT LINE LAST, X ERROR LINE LAST, X MESSAGE LINE LAST - 1, X COMMENT LINE LAST, X HELP KEY CONTROL-W, { Standard } X INSERT KEY F1, { Standard } X DELETE KEY F2, { Standard } X NEXT KEY F3, { Standard } X PREVIOUS KEY F4, { Standard } X #ACCEPT KEY ESCAPE, { Standard } X INPUT WRAP X XEND FUNCTION {std_options} X X{ Return name of program } XFUNCTION get_progname() X X RETURN pname CLIPPED X XEND FUNCTION {get_progname} X X{ Log a message on log file } XFUNCTION logmessage(msg) X X DEFINE X msg CHAR(460), X fullmsg CHAR(512) X X { ERRORLOG records Date and Time anyway } X LET fullmsg = pname CLIPPED, ": ", uname CLIPPED, ": ", msg X WHENEVER ERROR CONTINUE X CALL ERRORLOG(fullmsg CLIPPED) X WHENEVER ERROR STOP X X IF STATUS != 0 THEN X ERROR "Failed to write to log file" X SLEEP 3 X EXIT PROGRAM 1 X END IF X XEND FUNCTION {logmessage} X X{ Log an error message on log file } XFUNCTION logerror(msg) X X DEFINE X msg CHAR(460), X fullmsg CHAR(512) X X { ERRORLOG records Date and Time anyway } X LET fullmsg = pname CLIPPED, ": ", uname CLIPPED, ": ", msg X WHENEVER ERROR CONTINUE X CALL ERRORLOG(fullmsg CLIPPED) X WHENEVER ERROR STOP X X IF STATUS != 0 THEN X ERROR "Failed to write to log file" X SLEEP 3 X EXIT PROGRAM 1 X END IF X XEND FUNCTION {logerror} X X{ Is user allowed to do a update } XFUNCTION allowed_to_update() X X DEFINE X action CHAR(12) X X LET action = pname CLIPPED, "_UPD" X X RETURN allowed_to_do(action) X XEND FUNCTION {allowed_to_update} X X{ Is user allowed to do a insert } XFUNCTION allowed_to_insert() X X DEFINE X action CHAR(12) X X LET action = pname CLIPPED, "_INS" X X RETURN allowed_to_do(action) X XEND FUNCTION {allowed_to_insert} X X{ Is user allowed to do a delete } XFUNCTION allowed_to_delete() X X DEFINE X action CHAR(12) X X LET action = pname CLIPPED, "_DEL" X X RETURN allowed_to_do(action) X XEND FUNCTION {allowed_to_delete} SHAR_EOF chmod 0444 stdopt.4gl || echo "$0: failed to restore stdopt.4gl" fi if test -f spi.msg; then echo "File spi.msg exists"; else echo "x - spi.msg" sed 's/^X//' << 'SHAR_EOF' > spi.msg && X# @(#)spi.msg 7.1 90/08/23 X# @(#)Built by: FGLBLD Version 6.08 (01/12/1989) X# @(#)Help messages X.1 X XThe "Query" option allows you to select one or more rows and to display Xtheir data on the screen by using query-by-example input. X XUse the RETURN or arrow keys to move through the form. Enter the criteria you Xwant the program to use in searching for rows. Your options include: X X o literal values X o a range of values (separated by :) X o relational operators (for example "> 105") X o to choose a null field, use = X o wild cards like * to match any number of characters X o a selection of values (separated by |) X o etc. X X.2 X XThe "Next" option allows you to display the next row of the current list. X X.3 X XThe "Previous" option allows you to display the previous row of the current Xlist. X X.4 X XThe "Add" option enables you to enter new rows into the table. X XYou may get assistance on what input is appropriate for each field by pressing Xthe control-w key when the cursor is in the field. When you have entered Xall the data you want for a given row, press ESC to enter the row in the Xtable. If you want to abort a given row and not write it to the table, Xpress the INTERRUPT key (usually DEL or CTRL-C). X X.5 X XThe "Delete" option enables you to remove rows from the table. X XYou must first select a current row to delete by using the "Query" option. XFor your protection, you will be asked to confirm that the row should be Xdeleted. Once deleted, it cannot be restored. X X.6 X XThe "Update" option enables you to alter data on existing rows in the table. X XYou must first select a current row to update by using the "Query" option. XYou may get assistance on what input is appropriate for each field by pressing Xthe CONTROL-F key when the cursor is in the field. When you have altered Xall the data you want for a given row, press ESC to enter the data in the Xtable. If you want to abort the changes and not write them to the table, press Xthe INTERRUPT key (usually DEL or CTRL-C). X X.7 X XThe "Report" option enables you to produce a report to the screen. X X.8 X XThe "Exit" option leaves the program and returns you to the operating system. X X.10 X XNo, I don't really want to delete this row. X X.11 X XYes, I really want this row to be deleted. X X.20 X XUse control-F to obtain detailed help information for each field. X XEnter the data appropriate to the new row of data, or edit what Xis already there. You will probably not be able to edit the Xprimary key column of this table. X X X.30 X XThe "Curent-List" option will produce a report which will contain Xjust the rows in the current list -- i.e. those you could see by Xusing Next and Previous repeatedly. X XThis does not affect the current list. X X.31 X XThe "Same-Query" option will produce a report which will contain Xjust the rows you would be able to see if you re-executed the last Xenquiry you specified on the data now in the database. X XThis does not affect the current list. X X.32 X XThe "New-Query" option allows you to specify a new enquiry X(completely unrelated to the main enquiry) which specifies the rows Xyou wish to have included in the report. X XThis does not affect the current list. X X.33 X XThe "Reuse-Query" option is only avaliable if you have previously Xexecuted a "New-Query" report; it will produce the report by Xre-executing the same query as last time on the data now in the Xdatabase. X XThis does not affect the current list. X X.34 X XThe "All" option prints all the data from the database. X XThis does not affect the current list. X X.35 X XThe "Exit" option takes you back to the main menu. X X.100 X XThis is the default help for "Spi.tabname" X X.101 X XThis is the default help for "Spi.pkcol" X X.102 X XThis is the default help for "Spi.menuname" X X.103 X XThis is the default help for "Spi.basename" X X.104 X XThis is the default help for "Spi.opt_ins" X X.105 X XThis is the default help for "Spi.afterfield" X X.106 X XThis is the default help for "Spi.beforefield" X X.107 X XThis is the default help for "Spi.controlb" X X.108 X XThis is the default help for "Spi.controlp" X X.109 X XThis is the default help for "Spi.opt_del" X X.110 X XThis is the default help for "Spi.opt_upd" X X.111 X XThis is the default help for "Spi.opt_rep" X X.112 X XThis is the default help for "Spi.opt_sh" X SHAR_EOF chmod 0444 spi.msg || echo "$0: failed to restore spi.msg" fi if test -f spi.sql; then echo "File spi.sql exists"; else echo "x - spi.sql" sed 's/^X//' << 'SHAR_EOF' > spi.sql && X-- @(#)spi.sql 1.1 94/04/24 X-- @(#)Table used for demonstrating multi-screen input X XCREATE DATABASE fglbld; X XCREATE TABLE spi X( X tabname CHAR(18) NOT NULL, X pkcol CHAR(18) NOT NULL, X menuname CHAR(18) NOT NULL, X basename CHAR(7) NOT NULL, X opt_ins CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (opt_ins IN ('Y', 'N')) CONSTRAINT c1_spi, X afterfield CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (afterfield IN ('Y', 'N')) CONSTRAINT c2_spi, X beforefield CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (beforefield IN ('Y', 'N')) CONSTRAINT c3_spi, X controlb CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (controlb IN ('Y', 'N')) CONSTRAINT c4_spi, X controlp CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (controlp IN ('Y', 'N')) CONSTRAINT c5_spi, X opt_del CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (opt_del IN ('Y', 'N')) CONSTRAINT c6_spi, X opt_upd CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (opt_upd IN ('Y', 'N')) CONSTRAINT c7_spi, X opt_rep CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (opt_rep IN ('Y', 'N')) CONSTRAINT c8_spi, X opt_sh CHAR(1) DEFAULT 'Y' NOT NULL X CHECK (opt_sh IN ('Y', 'N')) CONSTRAINT c9_spi X); SHAR_EOF chmod 0444 spi.sql || echo "$0: failed to restore spi.sql" fi echo All files extracted exit 0