Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/5/84; site yetti.UUCP Path: utzoo!utcs!mnetor!yetti!oz From: oz@yetti.UUCP (Ozan Yigit) Newsgroups: net.sources Subject: a small dbms - part 2 Message-ID: <241@yetti.UUCP> Date: Mon, 26-Aug-85 15:44:42 EDT Article-I.D.: yetti.241 Posted: Mon Aug 26 15:44:42 1985 Date-Received: Mon, 26-Aug-85 18:46:10 EDT Reply-To: oz@yetti.UUCP (Ozan Yigit) Organization: York University Computer Science Lines: 5091 Keywords: dbms This is the last part of the dbms: all the source files. This stuff compiles under 4.2 BSD and VENIX (vers. 7) just fine. Oz ------------ SNIP SNIP SNIP ------------------------------- #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # cmd.c # com.c # cre.c # err.c # iex.c # int.c # io.c # mth.c # pcjunk.c # scn.c # sdb.c # sel.c # srt.c # tbl.c # sdbio.h # This archive created: Mon Aug 26 15:39:01 1985 export PATH; PATH=/bin:$PATH echo shar: extracting "'cmd.c'" '(20167 characters)' if test -f 'cmd.c' then echo shar: over-writing existing file "'cmd.c'" fi sed 's/^X//' << \SHAR_EOF > 'cmd.c' X/* SDB - command parser */ X X#include "stdio.h" X#include "sdbio.h" X Xextern int dbv_token; Xextern char dbv_tstring[]; Xextern int dbv_tvalue; Xextern struct ifile *dbv_ifp; Xextern struct macro *dbv_macros; Xextern int dbv_fold; X X#ifdef Lattice Xint _fmode = 0; /*dns*/ X#endif X X/* db_parse - parse a command */ Xint db_parse(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X int sts; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* determine the statement type */ X switch (db_ntoken()) { X case ';': sts = TRUE; X break; X case COMPRESS: X sts = db_squeeze(NULL); X break; X case CREATE: X sts = create(); X break; X case DEFINE: X sts = mc_define(); X break; X case DELETE: X sts = delete(); X break; X case EXIT: X exit(); X case EXPORT: X sts = db_export(NULL); X break; X case EXTRACT: X sts = db_extract(NULL); X break; X case HELP: X sts = help(); X break; X case IMPORT: X sts = db_import(NULL); X break; X case INSERT: X sts = insert(); X break; X case PRINT: X sts = print(); X break; X case SELECT: X sts = select(); X break; X case SET: X sts = set(); X break; X case SHOW: X sts = mc_show(); X break; X case SORT: X sts = db_sort(NULL); X break; X case UPDATE: X sts = update(); X break; X default: X return (db_ferror(SYNTAX)); X } X X return (sts); X} X X/* help - print a short help message */ Xstatic int help() X{ X FILE *fp; X int ch; X X if ((fp = fopen("sdb.hlp","r")) != NULL) { X /* while ((ch = agetc(fp)) != EOF) dns */ X while ((ch = getc(fp)) != EOF) X putchar(ch); X fclose(fp); X } X else X printf("No online help available. Read the manual\n"); X X /* return successfully */ X return (TRUE); X} X X/* create - create a new relation */ Xstatic int create() X{ X struct relation *rptr; X char aname[STRINGMAX+1]; X int atype; X X /* get relation name */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X X /* start relation creation */ X if ((rptr = db_rcreate(dbv_tstring)) == NULL) X return (FALSE); X X /* check for attribute list */ X if (db_ntoken() != '(') { X free(rptr); X return (db_ferror(SYNTAX)); X } X X /* parse the attributes */ X while (TRUE) { X X /* get the attribute name */ X if (db_ntoken() != ID) { X free(rptr); X return (db_ferror(SYNTAX)); X } X strcpy(aname,dbv_tstring); X X /* get the attribute type */ X db_ntoken(); X if (dbv_token == CHAR) X atype = TCHAR; X else if (dbv_token == NUM) X atype = TNUM; X else { X free(rptr); X return (db_ferror(SYNTAX)); X } X X /* get the attribute size */ X if (db_ntoken() != NUMBER) { X free(rptr); X return (db_ferror(SYNTAX)); X } X X /* add the attribute */ X if (!db_rcattr(rptr,aname,atype,dbv_tvalue)) { X free(rptr); X return (FALSE); X } X X /* check for end of attributes */ X if (db_token() != ID) X break; X } X X /* check for attribute list end */ X if (db_ntoken() != ')') { X free(rptr); X return (db_ferror(SYNTAX)); X } X X /* check for relation size */ X if (db_ntoken() != NUMBER) { X free(rptr); X return (db_ferror(SYNTAX)); X } X X /* finish relation creation */ X if (!db_rcheader(rptr)) X return (FALSE); X if (!db_rctuples(rptr,dbv_tvalue)) X return (FALSE); X if (!db_rcdone(rptr)) X return (FALSE); X X /* return successfully */ X return (TRUE); X} X X/* insert - insert a tuple into a relation */ Xstatic int insert() X{ X struct scan *sptr; X struct attribute *aptr; X char aname[ANSIZE+1],avalue[STRINGMAX+1]; X int tcnt,astart,i; X X /* get relation name */ X if (db_token() == ID) X db_ntoken(); X else X strcpy(dbv_tstring,"sdbcur"); X X /* make sure that the rest of the line is blank */ X if (!db_flush()) X return (FALSE); X X /* open the relation */ X if ((sptr = db_ropen(dbv_tstring)) == NULL) X return (FALSE); X X /* insert tuples */ X for (tcnt = 0; ; tcnt++) { X X /* print separator if not the first tuple */ X if (tcnt != 0) X printf("----\n"); X X /* get attribute values */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &sptr->sc_relation->rl_header.hd_attrs[i]; X X /* check for the last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* get the attribute name */ X strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0; X X /* setup null prompt strings */ X db_prompt(NULL,NULL); X X /* prompt and input attribute value */ X while (TRUE) { X if (dbv_ifp == NULL) X if (strlen(aname) < 8) X printf("%s\t\t: ",aname); X else X printf("%s\t: ",aname); X if (db_gline(avalue) != NULL) X break; X } X X /* check for last insert */ X if (i == 0 && avalue[0] == EOS) X break; X X /* store the attribute value */ X db_aput(aptr,&sptr->sc_tuple[astart],avalue); X X /* update the attribute start */ X astart += aptr->at_size; X } X X /* check for last insert */ X if (avalue[0] == EOS) X break; X X /* store the new tuple */ X if (!db_rstore(sptr)) { X db_rclose(sptr); X return (FALSE); X } X } X X /* close the relation */ X db_rclose(sptr); X X /* check number of tuples inserted */ X if (tcnt != 0) { X X /* print tuple count */ X printf("[ %d inserted ]\n",tcnt); X } X else X printf("[ none inserted ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* delete - delete tuples from a relation */ Xstatic int delete() X{ X struct sel *slptr; X struct srel *srptr; X int tcnt; X X /* parse the retrieval clause */ X if ((slptr = db_retrieve(NULL)) == NULL) X return (FALSE); X X /* loop through the retrieved tuples */ X for (tcnt = 0; db_fetch(slptr); tcnt++) X X /* delete the retrieved tuples */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) X if (!db_rdelete(srptr->sr_scan)) { X db_done(slptr); X return (FALSE); X } X X /* finish the retrieval */ X db_done(slptr); X X /* check number of tuples deleted */ X if (tcnt != 0) { X X /* print tuple count */ X printf("[ %d deleted ]\n",tcnt); X } X else X printf("[ none deleted ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* update - update tuples from a relation */ Xstatic int update() X{ X struct sel *slptr; X struct sattr *saptr; X struct attribute *aptr; X char aname[ANSIZE+1],avalue[STRINGMAX+1],*ap; X int tcnt; X X /* parse the selection clause */ X if ((slptr = db_select(NULL)) == NULL) X return (FALSE); X X /* make sure that the rest of the line is blank */ X if (!db_flush()) { X db_done(slptr); X return (FALSE); X } X X /* loop through the selected tuples */ X for (tcnt = 0; db_fetch(slptr); tcnt++) { X X /* print separator if not the first tuple */ X if (tcnt != 0) X printf("----\n"); X X /* loop through the selected attributes */ X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X X /* get the attribute pointer */ X aptr = saptr->sa_attr; X X /* get the attribute name */ X strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0; X X /* get the attribute value */ X db_aget(aptr,saptr->sa_aptr,avalue); X for (ap = avalue; isspace(*ap); ap++) X ; X X /* print it */ X if (strlen(aname) < 8) X printf("%s\t\t: %s\n",aname,ap); X else X printf("%s\t: %s\n",aname,ap); X X /* setup null prompt strings */ X db_prompt(NULL,NULL); X X /* prompt and input attribute value */ X while (TRUE) { X if (strlen(aname) < 8) X printf("%s\t\t: ",aname); X else X printf("%s\t: ",aname); X if (db_gline(avalue) != NULL) X break; X } X X /* store the attribute value */ X if (avalue[0] != EOS) { X db_aput(aptr,saptr->sa_aptr,avalue); X saptr->sa_srel->sr_update = TRUE; X } X } X X /* update the tuples */ X db_update(slptr); X } X X /* finish the selection */ X db_done(slptr); X X /* check number of tuples updated */ X if (tcnt != 0) { X X /* print tuple count */ X printf("[ %d updated ]\n",tcnt); X } X else X printf("[ none updated ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* print - print tuples from a set of relations */ Xstatic int print() X{ X struct sel *slptr; X FILE *ffp,*ofp; X int tcnt; X X /* parse the using clause */ X if (!using(&ffp,".frm")) X return (FALSE); X X /* parse the select clause */ X if ((slptr = db_select(NULL)) == NULL) X return (FALSE); X X /* parse the into clause */ X if (!db_to(&ofp,".txt")) { X db_done(slptr); X return (FALSE); X } X X /* check for normal or formated output */ X if (ffp == NULL) X tcnt = table(ofp,slptr); X else X tcnt = form(ofp,slptr,ffp); X X /* finish the selection */ X db_done(slptr); X X /* close the form definition file */ X if (ffp != NULL) X fclose(ffp); X X /* close the output file */ X if (ofp != stdout) X fclose(ofp); X X /* check number of tuples selected */ X if (tcnt != 0) X printf("[ %d found ]\n",tcnt); X else X printf("[ none found ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* select - select tuples from a set of relations */ Xstatic int select() X{ X struct sel *slptr; X struct relation *rptr; X struct sattr *saptr; X char *aname,*tbuf; X int tcnt,abase,i; X X /* parse the select clause */ X if ((slptr = db_select(NULL)) == NULL) X return (FALSE); X X /* create a new relation */ X if ((rptr = db_rcreate("sdbcur")) == NULL) { X db_done(slptr); X return (FALSE); X } X X /* create the selected attributes */ X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X X /* decide which attribute name to use */ X if ((aname = saptr->sa_name) == NULL) X aname = saptr->sa_aname; X X /* add the attribute */ X if (!db_rcattr(rptr,aname,saptr->sa_attr->at_type, X saptr->sa_attr->at_size)) { X free(rptr); X db_done(slptr); X return (FALSE); X } X } X X /* create the relation header */ X if (!db_rcheader(rptr)) { X db_done(slptr); X return (FALSE); X } X X /* allocate and initialize a tuple buffer */ X if ((tbuf = calloc(1,rptr->rl_size)) == NULL) { X db_rcdone(rptr); X return (db_ferror(INSMEM)); X } X tbuf[0] = ACTIVE; X X /* loop through the selected tuples */ X for (tcnt = 0; db_fetch(slptr); tcnt++) { X X /* create the tuple from the selected attributes */ X abase = 1; X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X for (i = 0; i < saptr->sa_attr->at_size; i++) X tbuf[abase + i] = saptr->sa_aptr[i]; X abase += i; X } X X /* write the tuple */ X if (write(rptr->rl_fd,tbuf,rptr->rl_size) != rptr->rl_size) { X db_rcdone(rptr); X free(tbuf); X return (db_ferror(INSBLK)); X } X rptr->rl_tcnt++; X rptr->rl_tmax++; X } X X /* finish the selection */ X db_done(slptr); X X /* finish relation creation */ X if (!db_rcdone(rptr)) X return (FALSE); X X /* check number of tuples selected */ X if (tcnt != 0) X printf("[ %d found ]\n",tcnt); X else X printf("[ none found ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* mc_define - define a macro */ Xstatic int mc_define() X{ X struct macro *mptr,*mlast; X struct mtext *tptr,*tlast; X char textline[LINEMAX+1]; X X /* get macro name */ X if (db_xntoken() != ID) X return (db_ferror(SYNTAX)); X X /* make sure that the rest of the line is blank */ X if (!db_flush()) X return (FALSE); X X /* find the macro in the macro table and free it */ X for (mptr = dbv_macros, mlast = NULL; mptr != NULL; mlast = mptr, mptr = mptr->mc_next) X if (db_scmp(mptr->mc_name,dbv_tstring) == 0) { X if (mlast == NULL) X dbv_macros = mptr->mc_next; X else X mlast->mc_next = mptr->mc_next; X mc_free(mptr); X } X X /* allocate and initialize a macro structure */ X if ((mptr = malloc(sizeof(struct macro))) == NULL) X return (db_ferror(INSMEM)); X if ((mptr->mc_name = malloc(strlen(dbv_tstring)+1)) == NULL) { X free(mptr); X return (db_ferror(INSMEM)); X } X strcpy(mptr->mc_name,dbv_tstring); X mptr->mc_mtext = NULL; X X /* setup null prompt strings */ X db_prompt(NULL,"SDB-DEF> "); X X /* get definition text */ X for (tlast = NULL; ; tlast = tptr) { X X /* get a line */ X db_gline(textline); X if (textline[0] == EOS || textline[0] == '\n') X break; X X /* allocate a macro text structure */ X if ((tptr = malloc(sizeof(struct mtext))) == NULL) { X mc_free(mptr); X return (db_ferror(INSMEM)); X } X if ((tptr->mt_text = malloc(strlen(textline)+1)) == NULL) { X mc_free(mptr); X return (db_ferror(INSMEM)); X } X strcpy(tptr->mt_text,textline); X tptr->mt_next = NULL; X X /* link it into the macro list */ X if (tlast == NULL) X mptr->mc_mtext = tptr; X else X tlast->mt_next = tptr; X } X X /* link the new macro into the macro list */ X if (tlast == NULL) X mc_free(mptr); X else { X mptr->mc_next = dbv_macros; X dbv_macros = mptr; X } X X /* return successfully */ X return (TRUE); X} X X/* mc_show - show a macro */ Xstatic int mc_show() X{ X struct macro *mptr; X struct mtext *tptr; X X /* get macro name */ X if (db_xntoken() != ID) X return (db_ferror(SYNTAX)); X X /* find the macro in the macro table */ X for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next) X if (db_scmp(mptr->mc_name,dbv_tstring) == 0) { X for (tptr = mptr->mc_mtext; tptr != NULL; tptr = tptr->mt_next) X printf("\t%s\n",tptr->mt_text); X break; X } X X /* check for successful search */ X if (mptr == NULL) X printf("*** no macro named: %s ***\n",dbv_tstring); X X /* return successfully */ X return (TRUE); X} X X/* mc_free - free a macro definition */ Xstatic mc_free(mptr) X struct macro *mptr; X{ X struct mtext *tptr; X X while ((tptr = mptr->mc_mtext) != NULL) { X mptr->mc_mtext = tptr->mt_next; X free(tptr->mt_text); X free(tptr); X } X free(mptr->mc_name); X free(mptr); X} X X/* db_to - redirect output into a file */ Xint db_to(pfp,ext) X FILE **pfp; char *ext; X{ X#ifdef vms X int fd; X#endif X X /* assume no into clause */ X *pfp = stdout; X X /* check for "into " */ X if (db_token() != INTO) X return (TRUE); X db_ntoken(); X if (db_ntoken() == ID) X strcat(dbv_tstring,ext); X else if (dbv_token != STRING) X return (db_ferror(SYNTAX)); X X /* open the output file */ X#ifdef vms X if ((fd = creat(dbv_tstring,0,"rfm=var","rat=cr")) == -1) X return (db_ferror(OUTCRE)); X *pfp = fdopen(fd,"w"); X#else X#ifdef Lattice X _fmode = 0x8000; /*dns*/ X#endif X *pfp = fopen(dbv_tstring,"w"); /*dns*/ X#ifdef Lattice X _fmode = 0; /*dns*/ X#endif X if (*pfp == NULL) /*dns*/ X return (db_ferror(OUTCRE)); /*dns*/ X#endif X X /* return successfully */ X return (TRUE); X} X X/* using - get form definition file spec */ Xstatic int using(pfp,ext) X FILE **pfp; char *ext; X{ X /* assume no using clause */ X *pfp = NULL; X X /* check for "using " */ X if (db_token() != USING) X return (TRUE); X db_ntoken(); X if (db_ntoken() == ID) X strcat(dbv_tstring,ext); X else if (dbv_token != STRING) X return (db_ferror(SYNTAX)); X X /* open the input file */ X if ((*pfp = fopen(dbv_tstring,"r")) == NULL) X return (db_ferror(INPFNF)); X X /* return successfully */ X return (TRUE); X} X X/* table - output a relation table */ Xstatic int table(fp,slptr) X FILE *fp; struct sel *slptr; X{ X int tcnt; X X /* loop through the selected tuples */ X for (tcnt = 0; db_fetch(slptr); tcnt++) { X X /* print table head on first tuple selected */ X if (tcnt == 0) X db_thead(fp,slptr); X X /* print the tuple */ X db_tentry(fp,slptr); X } X X /* print table foot */ X if (tcnt != 0) X db_tfoot(fp,slptr); X X /* return the tuple count */ X return (tcnt); X} X X/* form - process a form */ Xstatic int form(ofp,slptr,ffp) X FILE *ofp; struct sel *slptr; FILE *ffp; X{ X char aname[ANSIZE+1]; X int ch,tcnt; X X /* loop through the selected tuples */ X for (tcnt = 0; db_fetch(slptr); tcnt++) { X X /* reposition the form definition file */ X fseek(ffp,0L,0); X X /* process the form */ X while ((ch = getc(ffp)) != -1) X if (ch == '<') { X get_aname(ffp,aname); X put_avalue(ofp,slptr,aname); X } X else X putc(ch,ofp); X } X X /* return the tuple count */ X return (tcnt); X} X X/* get_aname - get an attribute name */ Xstatic get_aname(fp,aname) X FILE *fp; char *aname; X{ X int ch; X X while ((ch = getc(fp)) != '>') X if (!isspace(ch)) X *aname++ = ch; X *aname = 0; X} X X/* put_avalue - output attribute value */ Xstatic put_avalue(fp,slptr,aname) X FILE *fp; struct sel *slptr; char *aname; X{ X struct sattr *saptr; X char *saname; X int i; X X /* loop through the selected attributes */ X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X X /* check the selected attribute name */ X if ((saname = saptr->sa_name) == NULL) X saname = saptr->sa_aname; X if (db_scmp(saname,aname) == 0) X break; X } X X if (saptr == NULL) { X fprintf(fp,""); X return; X } X X /* get the attribute value */ X for (i = 0; i < saptr->sa_attr->at_size; i++) X if (saptr->sa_aptr[i] != 0) X putc(saptr->sa_aptr[i],fp); X else X putc(' ',fp); X} X X/* set - set internal parameters */ Xstatic int set() X{ X int value; X X /* process each set request */ X while (db_token() == ID) { X X /* skip the identifier */ X db_ntoken(); X X /* check for "no" */ X if (db_scmp(dbv_tstring,"no") == 0) { X value = FALSE; X if (db_token() != ID) X return (db_ferror(BADSET)); X db_ntoken(); X } X else X value = TRUE; X X /* check for parameter to set */ X if (db_scmp(dbv_tstring,"fold") == 0) X dbv_fold = value; X else X return (db_ferror(BADSET)); X } X X /* return successfully */ X return (TRUE); X} X SHAR_EOF if test 20167 -ne "`wc -c 'cmd.c'`" then echo shar: error transmitting "'cmd.c'" '(should have been 20167 characters)' fi echo shar: extracting "'com.c'" '(9887 characters)' if test -f 'com.c' then echo shar: over-writing existing file "'com.c'" fi sed 's/^X//' << \SHAR_EOF > 'com.c' X/* SDB - expression compiler X syntax: X ::= X ::= { '|' } X ::= { '&' } X ::= { } X ::= | X ::= | | '(' ')' X ::= | X ::= '"' '"' X ::= nil | X ::= '=' | '<>' | '<' | '>' | '<=' | '>=' X ::= '+' | '-' | '~' X*/ X X#include "sdbio.h" X Xextern int dbv_token; Xextern char dbv_tstring[]; Xextern int dbv_tvalue; X Xextern int db_xand(); Xextern int db_xor(); Xextern int db_xnot(); Xextern int db_xlss(); Xextern int db_xleq(); Xextern int db_xeql(); Xextern int db_xgeq(); Xextern int db_xgtr(); Xextern int db_xneq(); Xextern int db_xpush(); Xextern int db_xstop(); X Xstatic union codecell code[CODEMAX+1]; Xstatic int cndx; Xstatic struct sel *selptr; X X/* compile - compile a boolean expression */ Xint db_compile(slptr) X struct sel *slptr; X{ X int result,i; X union codecell *cptr; X#ifdef Lattice X int (*dns)(); /*dns*/ X#endif X X /* save the selection structure pointer */ X selptr = slptr; X X /* initialize the code array index */ X cndx = 0; X X /* parse the boolean expression */ X if (!expr(&result)) { X code[cndx++].c_operator = db_xstop; X freelit(code); X return (FALSE); X } X X /* terminate the code */ X code[cndx++].c_operator = db_xstop; X X /* allocate space for the code array */ X if ((cptr = malloc(sizeof(union codecell) * cndx)) == NULL) { X freelit(code); X return (FALSE); X } X X /* store the code into the code array */ X slptr->sl_where = cptr; X for (i = 0; i < cndx; i++) { X (*cptr++).c_operator = code[i].c_operator; X#ifndef Lattice X if (code[i].c_operator == db_xpush) X#else X if ( code[i].c_operator == (dns=db_xpush) ) /*dns*/ X#endif X (*cptr++).c_operand = code[++i].c_operand; X } X X /* return successfully */ X return (TRUE); X} X X/* db_fcode - free a code array */ Xdb_fcode(slptr) X struct sel *slptr; X{ X /* make sure there is a where clause */ X if (slptr->sl_where == NULL) X return; X X /* free the literals */ X freelit(slptr->sl_where); X X /* free the code array */ X free(slptr->sl_where); X} X X/* operator - insert an operator into the code array */ Xstatic int operator(opr) X int (*opr)(); X{ X /* insert the operator */ X if (cndx < CODEMAX) X code[cndx++].c_operator = opr; X else X return (db_ferror(CDSIZE)); X X /* return successfully */ X return (TRUE); X} X X/* operand - insert an operand into the code array */ Xstatic int operand(opr) X struct operand *opr; X{ X /* insert the push operator */ X if (!operator(db_xpush)) X return (FALSE); X X /* insert the operand */ X if (cndx < CODEMAX) X code[cndx++].c_operand = opr; X else X return (db_ferror(CDSIZE)); X X /* return successfully */ X return (TRUE); X} X X/* expr - compile an expression */ Xstatic int expr(result) X int *result; X{ X int lval,rval; X X if (!land(&lval)) X return (FALSE); X while (db_token() == '|') { X db_ntoken(); X if (!land(&rval)) X return (FALSE); X if (!operator(db_xor)) X return (FALSE); X } X *result = lval; X return (TRUE); X} X Xstatic int land(result) X int *result; X{ X int lval,rval; X X if (!relat(&lval)) X return (FALSE); X while (db_token() == '&') { X db_ntoken(); X if (!relat(&rval)) X return (FALSE); X if (!operator(db_xand)) X return (FALSE); X } X *result = lval; X return (TRUE); X} X Xstatic int relat(result) X int *result; X{ X int lval,rval; X int tkn; X X if (!primary(&lval)) X return (FALSE); X while (db_token() <= LSS && dbv_token >= GTR) { X tkn = db_ntoken(); X if (!primary(&rval)) X return (FALSE); X switch (tkn) { X case LSS: X if (!operator(db_xlss)) X return (FALSE); X break; X case LEQ: X if (!operator(db_xleq)) X return (FALSE); X break; X case EQL: X if (!operator(db_xeql)) X return (FALSE); X break; X case NEQ: X if (!operator(db_xneq)) X return (FALSE); X break; X case GEQ: X if (!operator(db_xgeq)) X return (FALSE); X break; X case GTR: X if (!operator(db_xgtr)) X return (FALSE); X break; X } X } X *result = lval; X return (TRUE); X} X Xstatic int primary(result) X int *result; X{ X int val; X int tkn; X X if (db_token() == '~') { X tkn = db_ntoken(); X if (!primary(&val)) X return (FALSE); X switch (tkn) { X case '~': X if (!operator(db_xnot)) X return (FALSE); X break; X } X } X else X if (!factor(&val)) X return (FALSE); X *result = val; X return (TRUE); X} X Xstatic int factor(result) X int *result; X{ X int val; X X if (db_token() == '(') { X db_ntoken(); X if (!expr(&val)) X return (FALSE); X if (db_token() != ')') X return (db_ferror(SYNTAX)); X db_ntoken(); X } X else X if (!get_operand(&val)) X return (FALSE); X *result = val; X return (TRUE); X} X X/* get_operand - get an operand (number, string, or attribute) */ Xstatic int get_operand(result) X int *result; X{ X /* determine operand type */ X if (db_ntoken() == NUMBER) X return (get_number(result)); X else if (dbv_token == ID) X return (get_attr(result)); X else if (dbv_token == STRING) X return (get_string(result)); X else X return (db_ferror(SYNTAX)); X} X X/* get_attr - get an attribute argument */ Xstatic int get_attr(result) X int *result; X{ X struct operand *opr; X char rname[RNSIZE+1],aname[ANSIZE+1]; X char *aptr; int atype,alen; X X /* save the attribute name */ X strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS; X X /* check for a "." indicating a qualified attribute name */ X if (db_token() == '.') { X db_ntoken(); X X /* the previous ID was really a relation name */ X strcpy(rname,aname); X X /* check for the real attribute name */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X X /* save the attribute name */ X strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS; X X /* lookup the attribute name */ X if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen)) X return (FALSE); X } X else X if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen)) X return (FALSE); X X /* get a new operand structure */ X if ((opr = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the new operand structure */ X opr->o_type = ATTR; X opr->o_value.ov_char.ovc_type = atype; X opr->o_value.ov_char.ovc_string = aptr; X opr->o_value.ov_char.ovc_length = alen; X X /* insert the operand into the code array */ X if (!operand(opr)) { X free(opr); X return (FALSE); X } X X /* store operand type */ X *result = atype; X X /* return successfully */ X return (TRUE); X} X X/* get_number - get a numeric operand */ Xstatic int get_number(result) X int *result; X{ X struct operand *opr; X X /* get a new operand structure */ X if ((opr = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the new operand structure */ X opr->o_type = LITERAL; X if ((opr->o_value.ov_char.ovc_string = X malloc(strlen(dbv_tstring)+1)) == NULL) { X free(opr); X return (db_ferror(INSMEM)); X } X opr->o_value.ov_char.ovc_type = TNUM; X strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring); X opr->o_value.ov_char.ovc_length = strlen(dbv_tstring); X X /* insert the operand into the code array */ X if (!operand(opr)) { X free(opr->o_value.ov_char.ovc_string); free(opr); X return (FALSE); X } X X /* operand type is number */ X *result = TNUM; X X /* return successfully */ X return (TRUE); X} X X/* get_string - get a string operand */ Xstatic int get_string(result) X int *result; X{ X struct operand *opr; X X /* get a new operand structure */ X if ((opr = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the new operand structure */ X opr->o_type = LITERAL; X if ((opr->o_value.ov_char.ovc_string = X malloc(strlen(dbv_tstring)+1)) == NULL) { X free(opr); X return (db_ferror(INSMEM)); X } X opr->o_value.ov_char.ovc_type = TCHAR; X strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring); X opr->o_value.ov_char.ovc_length = strlen(dbv_tstring); X X /* insert the operand into the code array */ X if (!operand(opr)) { X free(opr->o_value.ov_char.ovc_string); free(opr); X return (FALSE); X } X X /* operand type is character */ X *result = TCHAR; X X /* return successfully */ X return (TRUE); X} X X/* freelit - free the literals in a code array */ Xstatic freelit(cptr) X union codecell *cptr; X{ X#ifdef Lattice X int (*dns)(); /*dns*/ X for (; (*cptr).c_operator != (dns=db_xstop); cptr++) /*dns*/ X if ((*cptr).c_operator == (dns=db_xpush) ) /*dns*/ X#else X for (; (*cptr).c_operator != db_xstop; cptr++) X if ((*cptr).c_operator == db_xpush ) X#endif X if ((*++cptr).c_operand->o_type == LITERAL) X free((*cptr).c_operand->o_value.ov_char.ovc_string); X} X SHAR_EOF if test 9887 -ne "`wc -c 'com.c'`" then echo shar: error transmitting "'com.c'" '(should have been 9887 characters)' fi echo shar: extracting "'cre.c'" '(3881 characters)' if test -f 'cre.c' then echo shar: over-writing existing file "'cre.c'" fi sed 's/^X//' << \SHAR_EOF > 'cre.c' X/* SDB - relation creation routines */ X X#include "sdbio.h" X X/* db_rcreate(rname) - begin the creation of a new relation */ Xstruct relation *db_rcreate(rname) X char *rname; X{ X struct relation *rptr; X X /* allocate the relation structure */ X if ((rptr = calloc(1,sizeof(struct relation))) == NULL) X return (db_nerror(INSMEM)); X X /* initialize the relation structure */ X strncpy(rptr->rl_name,rname,RNSIZE); X rptr->rl_tcnt = 0; X rptr->rl_tmax = 0; X rptr->rl_data = 512; X rptr->rl_size = 1; X rptr->rl_header.hd_attrs[0].at_name[0] = 0; X X /* return the new relation structure pointer */ X return (rptr); X} X X/* db_rcheader - create the relation header */ Xint db_rcheader(rptr) X struct relation *rptr; X{ X char rname[RNSIZE+1],filename[RNSIZE+13]; X X /* initialize the relation file header */ X db_cvbytes(rptr->rl_tcnt,rptr->rl_header.hd_tcnt); X db_cvbytes(rptr->rl_tmax,rptr->rl_header.hd_tmax); X db_cvbytes(rptr->rl_data,rptr->rl_header.hd_data); X db_cvbytes(rptr->rl_size,rptr->rl_header.hd_size); X X /* create the relation file name */ X strncpy(rname,rptr->rl_name,RNSIZE); rname[RNSIZE] = 0; X sprintf(filename,"%s.sdb",rname); X X /* create the relation file */ X if ((rptr->rl_fd = creat(filename,0)) == -1) { X free(rptr); X return (db_ferror(RELCRE)); X } X X /* write the header to the relation file */ X if (write(rptr->rl_fd,&rptr->rl_header,512) != 512) { X close(rptr->rl_fd); X free(rptr); X return (db_ferror(BADHDR)); X } X X /* return successfully */ X return (TRUE); X} X X/* db_rctuples - create the relation tuples */ Xint db_rctuples(rptr,tcnt) X struct relation *rptr; unsigned int tcnt; X{ X unsigned int i; X char *tbuf; X X /* store the number of tuples */ X rptr->rl_tmax = tcnt; X X /* allocate a tuple buffer */ X if ((tbuf = calloc(1,rptr->rl_size)) == NULL) X return (db_ferror(INSMEM)); X X /* write null tuples into the file */ X for (i = 0; i < tcnt; i++) X if (write(rptr->rl_fd,tbuf,rptr->rl_size) != rptr->rl_size) { X free(tbuf); X return (db_ferror(INSBLK)); X } X X /* free the tuple buffer */ X free(tbuf); X X /* return successfully */ X return (TRUE); X} X X/* db_rcdone(rptr) - finish the creation of a new relation */ Xint db_rcdone(rptr) X struct relation *rptr; X{ X /* initialize the relation file header */ X db_cvbytes(rptr->rl_tcnt,rptr->rl_header.hd_tcnt); X db_cvbytes(rptr->rl_tmax,rptr->rl_header.hd_tmax); X X /* write the header to the relation file */ X lseek(rptr->rl_fd,0L,0); X if (write(rptr->rl_fd,&rptr->rl_header,512) != 512) { X close(rptr->rl_fd); X free(rptr); X return (db_ferror(BADHDR)); X } X X /* close the relation file */ X close(rptr->rl_fd); X X /* free the relation structure */ X free(rptr); X X /* return successfully */ X return (TRUE); X} X X/* db_rcattr(rptr,aname,type,size) - add an attribute to relation being created */ Xint db_rcattr(rptr,aname,type,size) X struct relation *rptr; char *aname; int type,size; X{ X int i; X X /* look for attribute name */ X for (i = 0; i < NATTRS; i++) X if (rptr->rl_header.hd_attrs[i].at_name[0] == 0) X break; X else if (db_sncmp(aname,rptr->rl_header.hd_attrs[i].at_name,ANSIZE) == 0) X return (db_ferror(DUPATT)); X X /* check for too many attributes */ X if (i == NATTRS) X return (db_ferror(MAXATT)); X X /* store the new attribute */ X strncpy(rptr->rl_header.hd_attrs[i].at_name,aname,ANSIZE); X rptr->rl_header.hd_attrs[i].at_type = type; X rptr->rl_header.hd_attrs[i].at_size = size; X X /* terminate the attribute table */ X if (++i != NATTRS) X rptr->rl_header.hd_attrs[i].at_name[0] = 0; X X /* update the tuple size */ X rptr->rl_size += size; X X /* return successfully */ X return (TRUE); X} X SHAR_EOF if test 3881 -ne "`wc -c 'cre.c'`" then echo shar: error transmitting "'cre.c'" '(should have been 3881 characters)' fi echo shar: extracting "'err.c'" '(1630 characters)' if test -f 'err.c' then echo shar: over-writing existing file "'err.c'" fi sed 's/^X//' << \SHAR_EOF > 'err.c' X/* SDB - error messages */ X X#include "sdbio.h" X Xchar *db_ertxt(msg) X int msg; X{ X char *txt; X X /* select the appropriate message text */ X switch (msg) { X case INSMEM: X txt = "insufficient memory"; X break; X case RELFNF: X txt = "relation file not found"; X break; X case BADHDR: X txt = "bad relation header"; X break; X case TUPINP: X txt = "tuple input error"; X break; X case TUPOUT: X txt = "tuple output error"; X break; X case RELFUL: X txt = "relation file full"; X break; X case RELCRE: X txt = "error creating relation file"; X break; X case DUPATT: X txt = "duplicate attribute"; X break; X case MAXATT: X txt = "too many attributes"; X break; X case INSBLK: X txt = "insufficient disk space"; X break; X case SYNTAX: X txt = "syntax error"; X break; X case ATUNDF: X txt = "undefined attribute"; X break; X case ATAMBG: X txt = "ambiguous attribute"; X break; X case RLUNDF: X txt = "undefined relation"; X break; X case CDSIZE: X txt = "boolean expression too complex"; X break; X case INPFNF: X txt = "input file not found"; X break; X case OUTCRE: X txt = "error creating output file"; X break; X case INDFNF: X txt = "indirect command file not found"; X break; X case BADSET: X txt = "bad set parameter"; X break; X default: X txt = "undefined error"; X break; X } X X /* return the message text */ X return (txt); X} X SHAR_EOF if test 1630 -ne "`wc -c 'err.c'`" then echo shar: error transmitting "'err.c'" '(should have been 1630 characters)' fi echo shar: extracting "'iex.c'" '(6728 characters)' if test -f 'iex.c' then echo shar: over-writing existing file "'iex.c'" fi sed 's/^X//' << \SHAR_EOF > 'iex.c' X/* SDB - import/export command routines */ X X#include "stdio.h" X#include "sdbio.h" X Xextern int dbv_token; Xextern char dbv_tstring[]; Xextern int dbv_tvalue; X X/* db_import - import tuples from a file */ Xint *db_import(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct scan *sptr; X struct attribute *aptr; X char fname[STRINGMAX+1],avalue[STRINGMAX+1]; X int tcnt,astart,i,eofile; X FILE *fp; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* checks for " into " */ X if (db_ntoken() == ID) X strcat(dbv_tstring,".dat"); X else if (dbv_token != STRING) X return (db_ferror(SYNTAX)); X strcpy(fname,dbv_tstring); X if (db_ntoken() != INTO) X return (db_ferror(SYNTAX)); X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X X /* open the relation */ X if ((sptr = db_ropen(dbv_tstring)) == NULL) X return (FALSE); X X /* open the input file */ X if ((fp = fopen(fname,"r")) == NULL) X return (db_ferror(INPFNF)); X X /* import tuples */ X eofile = FALSE; X for (tcnt = 0; ; tcnt++) { X X /* get attribute values */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &sptr->sc_relation->rl_header.hd_attrs[i]; X X /* check for the last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* input the tuple */ X if (fgets(avalue,STRINGMAX,fp) == 0) { X eofile = TRUE; X break; X } X avalue[strlen(avalue)-1] = EOS; X X /* store the attribute value */ X db_aput(aptr,&sptr->sc_tuple[astart],avalue); X X /* update the attribute start */ X astart += aptr->at_size; X } X X /* store the new tuple */ X if (!eofile) { X if (!db_rstore(sptr)) { X db_rclose(sptr); X return (FALSE); X } X } X else X break; X } X X /* close the relation */ X db_rclose(sptr); X X /* close the input file */ X fclose(fp); X X /* check number of tuples imported */ X if (tcnt != 0) { X X /* print tuple count */ X printf("[ %d imported ]\n",tcnt); X } X else X printf("[ none imported ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* db_export - export tuples to a file */ Xint *db_export(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct scan *sptr; X struct attribute *aptr; X char rname[STRINGMAX+1],avalue[STRINGMAX+1]; X int tcnt,astart,i; X FILE *fp; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* checks for " [ into ]" */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X strcpy(rname,dbv_tstring); X if (!db_to(&fp,".dat")) X return (FALSE); X X /* open the relation */ X if ((sptr = db_ropen(rname)) == NULL) X return (FALSE); X X /* export tuples */ X for (tcnt = 0; db_rfetch(sptr); tcnt++) { X X /* get attribute values */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &sptr->sc_relation->rl_header.hd_attrs[i]; X X /* check for the last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* get the attribute value */ X db_aget(aptr,&sptr->sc_tuple[astart],avalue); X X /* output the tuple */ X fprintf(fp,"%s\n",avalue); X X /* update the attribute start */ X astart += aptr->at_size; X } X } X X /* close the relation */ X db_rclose(sptr); X X /* close the output file */ X if (fp != stdout) X fclose(fp); X X /* check number of tuples exported */ X if (tcnt != 0) { X X /* print tuple count */ X printf("[ %d exported ]\n",tcnt); X } X else X printf("[ none exported ]\n"); X X /* return successfully */ X return (TRUE); X} X X/* db_squeeze - squeeze deleted tuples from a relation file */ Xint *db_squeeze(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct scan *sptr; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* checks for "" */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X X /* open the relation */ X if ((sptr = db_ropen(dbv_tstring)) == NULL) X return (FALSE); X X /* compress the relation file */ X if (!db_rcompress(sptr)) { X db_rclose(sptr); X return (FALSE); X } X X /* close the relation */ X db_rclose(sptr); X X /* return successfully */ X return (TRUE); X} X X/* db_extract - extract a relation definition */ Xint *db_extract(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct scan *sptr; X struct attribute *aptr; X char rname[STRINGMAX+1],aname[ANSIZE+1],*atype; X int i; X FILE *fp; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* checks for " [ into ]" */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X strcpy(rname,dbv_tstring); X if (!db_to(&fp,".def")) X return (FALSE); X X /* open the relation */ X if ((sptr = db_ropen(rname)) == NULL) X return (FALSE); X X /* output the relation definition */ X fprintf(fp,"create %s (\n",rname); X X /* get attribute values */ X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &sptr->sc_relation->rl_header.hd_attrs[i]; X X /* check for the last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* get the attribute name */ X strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0; X X /* determine the attribute type */ X switch (aptr->at_type) { X case TCHAR: X atype = "char"; X break; X case TNUM: X atype = "num"; X break; X default: X atype = ""; X break; X } X X /* output the attribute definition */ X if (strlen(aname) < 8) X fprintf(fp,"\t%s\t\t%s\t%d\n",aname,atype,aptr->at_size); X else X fprintf(fp,"\t%s\t%s\t%d\n",aname,atype,aptr->at_size); X } X X /* output the relation size */ X fprintf(fp,") %d\n",sptr->sc_relation->rl_tmax); X X /* close the relation */ X db_rclose(sptr); X X /* close the output file */ X if (fp != stdout) X fclose(fp); X X /* return successfully */ X return (TRUE); X} X SHAR_EOF if test 6728 -ne "`wc -c 'iex.c'`" then echo shar: error transmitting "'iex.c'" '(should have been 6728 characters)' fi echo shar: extracting "'int.c'" '(4388 characters)' if test -f 'int.c' then echo shar: over-writing existing file "'int.c'" fi sed 's/^X//' << \SHAR_EOF > 'int.c' X/* SDB - boolean expression evaluator */ X X#include "sdbio.h" X Xstatic struct operand *stack[STACKMAX],**sptr; Xstatic union codecell *cptr; X X/* db_interpret - interpret a boolean expression */ Xint db_interpret(slptr) X struct sel *slptr; X{ X struct operand *result; X int r; X X /* check for empty where clause */ X if ((cptr = slptr->sl_where) == NULL) X return (TRUE); X X /* setup stack */ X sptr = stack; X X /* execute the code */ X while ((*(*cptr++).c_operator)()) X ; X X /* get the result from the top of stack */ X result = *--sptr; X r = result->o_value.ov_boolean; X if (result->o_type == TEMP) X free(result); X X /* make sure the stack is empty */ X while (sptr != stack) { X if ((*sptr)->o_type == TEMP) X free(*sptr); X sptr -= 1; X } X X /* return result */ X return (r); X} X Xint db_xstop() X{ X return (FALSE); X} X Xint db_xpush() X{ X *sptr++ = (*cptr++).c_operand; X} X Xint db_xand() X{ X return (boolean('&')); X} X Xint db_xor() X{ X return (boolean('|')); X} X Xstatic int boolean(opr) X{ X struct operand *lval,*rval,*result; X int lv,rv,r; X X rval = *--sptr; lval = *--sptr; X lv = lval->o_value.ov_boolean; X rv = rval->o_value.ov_boolean; X X if ((result = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X result->o_type = TEMP; X switch (opr) { X case '&': r = (lv && rv); X break; X case '|': r = (lv || rv); X break; X } X result->o_value.ov_boolean = r; X *sptr++ = result; X if (lval->o_type == TEMP) X free(lval); X if (rval->o_type == TEMP) X free(rval); X return (TRUE); X} X Xint db_xnot() X{ X struct operand *val,*result; X X val = *--sptr; X if ((result = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X result->o_type = TEMP; X result->o_value.ov_boolean = !val->o_value.ov_boolean; X *sptr++ = result; X if (val->o_type == TEMP) X free(val); X return (TRUE); X} X Xint db_xlss() X{ X return (compare(LSS)); X} X Xint db_xleq() X{ X return (compare(LEQ)); X} X Xint db_xeql() X{ X return (compare(EQL)); X} X Xint db_xgeq() X{ X return (compare(GEQ)); X} X Xint db_xgtr() X{ X return (compare(GTR)); X} X Xint db_xneq() X{ X return (compare(NEQ)); X} X Xstatic int compare(cmp) X{ X struct operand *lval,*rval,*result; X int i; X X rval = *--sptr; lval = *--sptr; X if ((result = malloc(sizeof(struct operand))) == NULL) X return (db_ferror(INSMEM)); X result->o_type = TEMP; X X if (lval->o_value.ov_char.ovc_type == TCHAR) X i = comp(lval,rval); X else X i = ncomp(lval,rval); X X switch (cmp) { X case LSS: i = (i < 0); X break; X case LEQ: i = (i <= 0); X break; X case EQL: i = (i == 0); X break; X case GEQ: i = (i >= 0); X break; X case GTR: i = (i > 0); X break; X case NEQ: i = (i != 0); X break; X } X result->o_value.ov_boolean = i; X *sptr++ = result; X if (lval->o_type == TEMP) X free(lval); X if (rval->o_type == TEMP) X free(rval); X return (TRUE); X} X Xstatic int comp(lval,rval) X struct operand *lval,*rval; X{ X char *lptr,*rptr; int lctr,rctr; X int len; X X lptr = lval->o_value.ov_char.ovc_string; X lctr = lval->o_value.ov_char.ovc_length; X rptr = rval->o_value.ov_char.ovc_string; X rctr = rval->o_value.ov_char.ovc_length; X X while (lctr > 0 && (lptr[lctr-1] == 0 || lptr[lctr-1] == ' ')) X lctr--; X while (rctr > 0 && (rptr[rctr-1] == 0 || rptr[rctr-1] == ' ')) X rctr--; X X if (lctr < rctr) X len = lctr; X else X len = rctr; X X while ((len--) > 0) { X if (*lptr++ != *rptr++) X if (*--lptr < *--rptr) X return (-1); X else X return (1); X } X X if (lctr == rctr) X return (0); X else if (lctr < rctr) X return (-1); X else X return (1); X} X Xstatic int ncomp(lval,rval) X struct operand *lval,*rval; X{ X char lstr[NUMBERMAX+1],rstr[NUMBERMAX+1]; X int len; X X strncpy(lstr,lval->o_value.ov_char.ovc_string, X (len = lval->o_value.ov_char.ovc_length)); lstr[len] = EOS; X strncpy(rstr,rval->o_value.ov_char.ovc_string, X (len = rval->o_value.ov_char.ovc_length)); rstr[len] = EOS; X X return (db_cmp(lstr,rstr)); X} X SHAR_EOF if test 4388 -ne "`wc -c 'int.c'`" then echo shar: error transmitting "'int.c'" '(should have been 4388 characters)' fi echo shar: extracting "'io.c'" '(10454 characters)' if test -f 'io.c' then echo shar: over-writing existing file "'io.c'" fi sed 's/^X//' << \SHAR_EOF > 'io.c' X/* SDB - relation file I/O routines */ X X#include "stdio.h" X#include "sdbio.h" X X/* global error code variable */ Xint dbv_errcode; X X/* list of currently loaded relation definitions */ Xstatic struct relation *relations = NULL; X X/* rfind - find the specified relation */ Xstatic struct relation *rfind(rname) X char *rname; X{ X int fd; X char filename[RNSIZE+5]; X struct relation *rptr; X X /* look for relation in list currently loaded */ X for (rptr = relations; rptr != NULL; rptr = rptr->rl_next) X if (db_sncmp(rname,rptr->rl_name,RNSIZE) == 0) X return (rptr); X X /* create a file name */ X make_fname(filename,rname); X X /* lookup the relation file */ X#ifdef Lattice X if ((fd = open(filename,0x8000)) == -1) /*dns*/ X#else X if ((fd = open(filename,0)) == -1) X#endif X return (db_nerror(RELFNF)); X X /* allocate a new relation structure */ X if ((rptr = malloc(sizeof(struct relation))) == NULL) { X close(fd); X return (db_nerror(INSMEM)); X } X X /* initialize the relation structure */ X rptr->rl_scnref = 0; X X /* read the header block */ X if ( read(fd,&rptr->rl_header,512) != 512) { X free(rptr); X close(fd); X return (db_nerror(BADHDR)); X } X X /* close the relation file */ X close(fd); X X /* extract header information */ X rptr->rl_tcnt = db_cvword(rptr->rl_header.hd_tcnt); X rptr->rl_tmax = db_cvword(rptr->rl_header.hd_tmax); X rptr->rl_data = db_cvword(rptr->rl_header.hd_data); X rptr->rl_size = db_cvword(rptr->rl_header.hd_size); X X /* store the relation name */ X strncpy(rptr->rl_name,rname,RNSIZE); X X /* link new relation into relation list */ X rptr->rl_next = relations; X relations = rptr; X X /* return the new relation structure pointer */ X return (rptr); X} X X/* db_ropen - open a relation file */ Xstruct scan *db_ropen(rname) X char *rname; X{ X struct relation *rptr; X struct scan *sptr; X char filename[RNSIZE+5]; X X /* find the relation definition */ X if ((rptr = rfind(rname)) == NULL) X return (NULL); X X /* allocate a new scan structure */ X if ((sptr = malloc(sizeof(struct scan))) == NULL) X return (db_nerror(INSMEM)); X X /* allocate a tuple buffer */ X if ((sptr->sc_tuple = malloc(rptr->rl_size)) == NULL) { X free(sptr); X return (db_nerror(INSMEM)); X } X X /* initialize the scan structure */ X sptr->sc_relation = rptr; /* store the relation struct addrs */ X sptr->sc_dtnum = 0; /* desired tuple (non-existant) */ X sptr->sc_atnum = 0; /* actual tuple (non-existant) */ X sptr->sc_store = FALSE; /* no store done since open */ X X /* open relation file if necessary */ X if (rptr->rl_scnref++ == 0) { X X /* create the relation file name */ X make_fname(filename,rname); X X /* open the relation file */ X#ifdef Lattice X if ((rptr->rl_fd = open(filename,0x8002)) == -1) { /*dns*/ X#else X if ((rptr->rl_fd = open(filename,2)) == -1) { X#endif X rptr->rl_scnref--; X free(sptr->sc_tuple); free(sptr); X return (db_nerror(RELFNF)); X } X } X X /* return the new scan structure pointer */ X return (sptr); X} X X/* db_rclose - close the relation file */ Xint db_rclose(sptr) X struct scan *sptr; X{ X struct relation *rptr,*lastrptr; X X /* close relation file if this is the last reference */ X if (--sptr->sc_relation->rl_scnref == 0) { X X /* rewrite header if any stores took place */ X if (sptr->sc_store) { X X /* store the tuple count back in the header */ X db_cvbytes(sptr->sc_relation->rl_tcnt, X sptr->sc_relation->rl_header.hd_tcnt); X X /* write the header block */ X lseek(sptr->sc_relation->rl_fd,0L,0); X if (write(sptr->sc_relation->rl_fd, X &sptr->sc_relation->rl_header,512) != 512) { X close(sptr->sc_relation->rl_fd); X free(sptr->sc_tuple); free(sptr); X return (db_ferror(BADHDR)); X } X } X X /* close the relation file */ X close(sptr->sc_relation->rl_fd); X X /* free the relation header */ X lastrptr = NULL; X for (rptr = relations; rptr != NULL; rptr = rptr->rl_next) { X if (rptr == sptr->sc_relation) { X if (lastrptr == NULL) X relations = rptr->rl_next; X else X lastrptr->rl_next = rptr->rl_next; X } X lastrptr = rptr; X } X free(sptr->sc_relation); X } X X /* free the scan structure */ X free(sptr->sc_tuple); free(sptr); X X /* return successfully */ X return (TRUE); X} X X/* db_rcompress - compress a relation file */ Xint db_rcompress(sptr) X struct scan *sptr; X{ X unsigned int next,nextfree,tcnt; X X /* get the last used tuple */ X tcnt = sptr->sc_relation->rl_tcnt; X X /* loop through all of the tuples */ X for (next = nextfree = 1; next <= tcnt; next++) { X X /* read the tuple */ X seek(sptr,next); X if (read(sptr->sc_relation->rl_fd, X sptr->sc_tuple,sptr->sc_relation->rl_size) X != sptr->sc_relation->rl_size) X return (db_ferror(TUPINP)); X X /* rewrite the tuple if it is active */ X if (sptr->sc_tuple[0] == ACTIVE) { X X /* rewrite it only if it must move */ X if (next != nextfree) { X X /* write the tuple */ X seek(sptr,nextfree); X if (write(sptr->sc_relation->rl_fd, X sptr->sc_tuple,sptr->sc_relation->rl_size) X != sptr->sc_relation->rl_size) X return (db_ferror(TUPOUT)); X } X X /* update the next free tuple number */ X nextfree += 1; X } X } X X /* update the tuple count */ X sptr->sc_relation->rl_tcnt = nextfree - 1; X X /* remember which tuple is in the buffer */ X sptr->sc_atnum = sptr->sc_relation->rl_tcnt; X X /* reset the desired tuple */ X sptr->sc_dtnum = 0; X X /* remember that the index needs rewriting */ X sptr->sc_store = TRUE; X X /* return successfully */ X return (TRUE); X} X X/* db_rbegin - begin scan at first tuple in relation */ Xdb_rbegin(sptr) X struct scan *sptr; X{ X /* begin with the first tuple in the file */ X sptr->sc_dtnum = 0; X} X X/* db_rfetch - fetch the next tuple from the relation file */ Xint db_rfetch(sptr) X struct scan *sptr; X{ X /* look for an active tuple */ X while (TRUE) { X X /* check for this being the last tuple */ X if (!db_rget(sptr,sptr->sc_dtnum + 1)) X return (FALSE); X X /* increment the tuple number */ X sptr->sc_dtnum += 1; X X /* return if the tuple found is active */ X if (sptr->sc_tuple[0] == ACTIVE) X return (TRUE); X } X} X X/* db_rupdate - update the current tuple */ Xint db_rupdate(sptr) X struct scan *sptr; X{ X /* make sure the status byte indicates an active tuple */ X sptr->sc_tuple[0] = ACTIVE; X X /* write the tuple */ X return (db_rput(sptr,sptr->sc_atnum)); X} X X/* db_rdelete - delete the current tuple */ Xint db_rdelete(sptr) X struct scan *sptr; X{ X /* make sure the status byte indicates a deleted tuple */ X sptr->sc_tuple[0] = DELETED; X X /* write the tuple */ X return (db_rput(sptr,sptr->sc_atnum)); X} X X/* db_rstore - store a new tuple */ Xint db_rstore(sptr) X struct scan *sptr; X{ X /* make sure there's room for this tuple */ X if (sptr->sc_relation->rl_tcnt == sptr->sc_relation->rl_tmax) X return (db_ferror(RELFUL)); X X /* make sure the status byte indicates an active tuple */ X sptr->sc_tuple[0] = ACTIVE; X X /* write the tuple */ X if (!db_rput(sptr,sptr->sc_relation->rl_tcnt + 1)) X return (FALSE); X X /* update the tuple count */ X sptr->sc_relation->rl_tcnt += 1; X X /* remember that a tuple was stored */ X sptr->sc_store = TRUE; X X /* return successfully */ X return (TRUE); X} X X/* db_rget - get a tuple from the relation file */ Xint db_rget(sptr,tnum) X struct scan *sptr; unsigned int tnum; X{ X /* check to see if the tuple is already in the buffer */ X if (tnum == sptr->sc_atnum) X return (TRUE); X X /* check for this being beyond the last tuple */ X if (tnum > sptr->sc_relation->rl_tcnt) X return (db_ferror(TUPINP)); X X /* read the tuple */ X seek(sptr,tnum); X if (read(sptr->sc_relation->rl_fd, X sptr->sc_tuple,sptr->sc_relation->rl_size) X != sptr->sc_relation->rl_size) X return (db_ferror(TUPINP)); X X /* remember which tuple is in the buffer */ X sptr->sc_atnum = tnum; X X /* return successfully */ X return (TRUE); X} X X/* db_rput - put a tuple to a relation file */ Xint db_rput(sptr,tnum) X struct scan *sptr; unsigned int tnum; X{ X /* check for this being beyond the maximum tuple */ X if (tnum > sptr->sc_relation->rl_tmax) X return (db_ferror(TUPOUT)); X X /* write the tuple */ X seek(sptr,tnum); X if (write(sptr->sc_relation->rl_fd, X sptr->sc_tuple,sptr->sc_relation->rl_size) X != sptr->sc_relation->rl_size) X return (db_ferror(TUPOUT)); X X /* remember which tuple is in the buffer */ X sptr->sc_atnum = tnum; X X /* return successfully */ X return (TRUE); X} X X/* seek - seek a tuple in a relation file */ Xstatic seek(sptr,tnum) X struct scan *sptr; unsigned int tnum; X{ X long offset; X X offset = (long) sptr->sc_relation->rl_data + X ((long) (tnum - 1) * (long) sptr->sc_relation->rl_size); X lseek(sptr->sc_relation->rl_fd,offset,0); X} X X/* make_fname - make a relation name into a file name */ Xstatic make_fname(fname,rname) X char *fname,*rname; X{ X strncpy(fname,rname,RNSIZE); fname[RNSIZE] = 0; X strcat(fname,".sdb"); X} X X/* db_nerror - store the error code and return NULL */ Xint db_nerror(errcode) X int errcode; X{ X dbv_errcode = errcode; X return (NULL); X} X X/* db_ferror - store the error code and return FALSE */ Xint db_ferror(errcode) X int errcode; X{ X dbv_errcode = errcode; X return (FALSE); X} X X/* db_cvword - convert 2 bytes to a word */ Xint db_cvword(bytes) X char bytes[2]; X{ X return (((bytes[1] & 0377) << 8) + (bytes[0] & 0377)); X} X X/* db_cvbytes - convert a word to 2 bytes */ Xdb_cvbytes(word,bytes) X int word; char bytes[2]; X{ X bytes[0] = word; X bytes[1] = word >> 8; X} X SHAR_EOF if test 10454 -ne "`wc -c 'io.c'`" then echo shar: error transmitting "'io.c'" '(should have been 10454 characters)' fi echo shar: extracting "'mth.c'" '(7647 characters)' if test -f 'mth.c' then echo shar: over-writing existing file "'mth.c'" fi sed 's/^X//' << \SHAR_EOF > 'mth.c' X/* SDB - string arithmetic routines */ X X#include "ctype.h" /*dns*/ X X/* useful definitions */ X#define TRUE 1 X#define FALSE 0 X#define NUMBERMAX 99 X#define EOS 0 X X/* db_cmp - compare two signed numeric strings */ Xint db_cmp(arg1,arg2) X char *arg1,*arg2; X{ X int sign1,sign2; X X /* get the signs of the arguments */ X sign1 = getsign(&arg1); X sign2 = getsign(&arg2); X X /* compute the result */ X if (sign1 == sign2) { X if (sign1 == 1) X return (compare(arg1,arg2)); X else X return (compare(arg2,arg1)); X } X X /* signs are different */ X return (sign1); X} X X/* db_add - add two signed numeric strings */ Xdb_add(result,arg1,arg2) X char *result,*arg1,*arg2; X{ X int signr,sign1,sign2; X char rtmp[NUMBERMAX+2],*rptr; X X /* get the signs of the arguments */ X sign1 = getsign(&arg1); X sign2 = getsign(&arg2); X X /* compute the result */ X if (sign1 == sign2) { X signr = sign1; X add(rtmp,arg1,arg2); X } X else X switch (compare(arg1,arg2)) { X case -1: X signr = sign2; X sub(rtmp,arg2,arg1); X break; X case 0: X strcpy(result,"0"); X return; X case 1: X signr = sign1; X sub(rtmp,arg1,arg2); X break; X } X X /* insert the sign */ X if (signr == -1) X strcpy(result,"-"); X else X result[0] = EOS; X X /* eliminate possible leading zeros */ X for (rptr = rtmp; *rptr == '0'; rptr++) X ; X X /* copy the result */ X if (*rptr != EOS) X strcat(result,rptr); X else X strcat(result,"0"); X} X X/* db_sub - subtract two signed numeric strings */ Xdb_sub(result,arg1,arg2) X char *result,*arg1,*arg2; X{ X int signr,sign1,sign2; X char rtmp[NUMBERMAX+2],*rptr; X X /* get the signs of the arguments */ X sign1 = getsign(&arg1); X sign2 = getsign(&arg2); X X /* invert the sign of arg2 */ X sign2 = -sign2; X X /* compute the result */ X if (sign1 == sign2) { X signr = sign1; X add(rtmp,arg1,arg2); X } X else X switch (compare(arg1,arg2)) { X case -1: X signr = sign2; X sub(rtmp,arg2,arg1); X break; X case 0: X strcpy(result,"0"); X return; X case 1: X signr = sign1; X sub(rtmp,arg1,arg2); X break; X } X X /* insert the sign */ X if (signr == -1) X strcpy(result,"-"); X else X result[0] = EOS; X X /* eliminate a possible leading zero */ X for (rptr = rtmp; *rptr == '0'; rptr++) X ; X X /* copy the result */ X if (*rptr != EOS) X strcat(result,rptr); X else X strcat(result,"0"); X} X X/* add - add two unsigned numeric strings */ Xstatic add(result,arg1,arg2) X char *result,*arg1,arg2; X{ X char *vr,*v1,*v2,*vx; X int carry,i,nmin,nmax,nd1,nd2; X X X /* get number of digits in each argument */ X nd1 = getlen(arg1); X nd2 = getlen(arg2); X X /* compute the address of the last digit + 1 */ X v1 = arg1 + nd1; X v2 = arg2 + nd2; X X /* compute minimum and maximum of nd1 and nd2 */ X if (nd1 < nd2) { X nmin = -nd1; X nmax = -nd2; X vx = v2; X } X else { X nmin = -nd2; X nmax = -nd1; X vx = v1; X } X X /* compute the address of the last result digit + 1 */ X vr = result - nmax; vr[0] = EOS; X X /* initialize the carry */ X carry = 0; X X /* add the digits */ X for (i = -1; i >= nmin; i--) { X X /* check for decimal point */ X if (v1[i] == '.') X vr[i] = '.'; X else { X X /* add the current pair of digits with the carry */ X vr[i] = v1[i] + v2[i] + carry - '0'; X X /* check for carry */ X if (vr[i] > '9') { X vr[i] -= 10; X carry = 1; X } X else X carry = 0; X } X } X X /* add the remaining digits */ X for (; i >= nmax; i--) { X X /* add the current digit with the carry */ X vr[i] = vx[i] + carry; X X /* check for carry */ X if (vr[i] > '9') { X vr[i] -= 10; X carry = 1; X } X else X carry = 0; X } X X /* check for a carry out and shift digits if necessary */ X if (carry == 1) { X X /* shift the digits */ X for (i = -nmax; i >= 0; i--) X result[i+1] = result[i]; X result[0] = '1'; X } X} X X/* sub - subtract two unsigned numeric strings */ Xstatic sub(result,arg1,arg2) X char *result,*arg1,arg2; X{ X char *vr,*v1,*v2,*vx; X int borrow,i,nmin,nmax,nd1,nd2; X X /* get number of digits in each argument */ X nd1 = getlen(arg1); X nd2 = getlen(arg2); X X /* compute the address of the last digit + 1 */ X v1 = arg1 + nd1; X v2 = arg2 + nd2; X X /* compute minimum and maximum of nd1 and nd2 */ X if (nd1 < nd2) { X nmin = -nd1; X nmax = -nd2; X vx = v2; X } X else { X nmin = -nd2; X nmax = -nd1; X vx = v1; X } X X /* compute the address of the last result digit + 1 */ X vr = result - nmax; vr[0] = EOS; X X /* initialize the borrow */ X borrow = 0; X X /* subtract the digits */ X for (i = -1; i >= nmin; i--) { X X /* check for decimal point */ X if (v1[i] == '.') X vr[i] = '.'; X else { X X /* subtract the current pair of digits with the borrow */ X vr[i] = v1[i] - v2[i] - borrow + '0'; X X /* check for borrow */ X if (vr[i] < '0') { X vr[i] += 10; X borrow = 1; X } X else X borrow = 0; X } X } X X /* subtract the remaining digits */ X for (; i >= nmax; i--) { X X /* subtract the current digit with the borrow */ X vr[i] = vx[i] - borrow; X X /* check for borrow */ X if (vr[i] < '0') { X vr[i] += 10; X borrow = 1; X } X else X borrow = 0; X } X} X X/* getsign - get the sign of a numeric string */ Xstatic int getsign(parg) X char **parg; X{ X int sign; X char *p; X X /* eliminate leading spaces */ X while (isspace(**parg)) X *parg += 1; X X /* get the sign */ X switch (**parg) { X case '+': *parg += 1; X sign = 1; X break; X case '-': *parg += 1; X sign = -1; X break; X default: sign = 1; X break; X } X X /* eliminate leading spaces and zeros */ X while (isspace(**parg) || **parg == '0') X *parg += 1; X X /* if the value is zero, make sure that the sign is positive */ X switch (**parg) { X case EOS: sign = 1; X break; X case '.': for (p = *parg + 1; *p == '0'; p++) X ; X if (*p == EOS) X sign = 1; X break; X } X X /* return the sign */ X return (sign); X} X X/* getlen - get the length of a numeric string */ Xstatic int getlen(arg) X char *arg; X{ X int len; X X /* get the length of the string */ X len = strlen(arg); X X /* eliminate trailing spaces */ X while (isspace(arg[len-1])) X len -= 1; X X /* return the length */ X return (len); X} X X/* compare - compare two unsigned numeric strings */ Xstatic int compare(arg1,arg2) X char *arg1,*arg2; X{ X int len1,len2; X X /* compare lengths */ X if ((len1 = getlen(arg1)) != (len2 = getlen(arg2))) X if (len1 < len2) X return (-1); X else X return (1); X X /* compare strings */ X return (strcmp(arg1,arg2)); X} X SHAR_EOF if test 7647 -ne "`wc -c 'mth.c'`" then echo shar: error transmitting "'mth.c'" '(should have been 7647 characters)' fi echo shar: extracting "'pcjunk.c'" '(1360 characters)' if test -f 'pcjunk.c' then echo shar: over-writing existing file "'pcjunk.c'" fi sed 's/^X//' << \SHAR_EOF > 'pcjunk.c' X/* PCJUNK.C Misc. procedures */ X X#include "stdio.h" X#include "sdbio.h" X X/* Replaces JUNK.C for the IBM/PC version dns */ X X Xchar *alloc(n) Xint n; X{ X return (char*) malloc(n); X} X X Xint getcx(fp) X FILE *fp; X{ X static char buf[LINEMAX] = {0}; X static char *pbuf = buf; X int ch, i; X X if (fp!=stdin) X if ((ch = getc(fp)) == '\r') X return getc(fp); X else X return ch; X X if (*pbuf > 0) X return *pbuf++; X X pbuf = buf; X for (i = 0; (ch = getc(fp)) != -1; ) X if (i < LINEMAX) { X if (ch == ESC) { i=0; putchar('\n'); fflush(stdout); } else X if (ch == BS) { if (i>0) i--; } else X buf[i++] = ch; X if (ch == '\n') break; X } X else { X printf("*** line too long ***\nRetype> "); X i = 0; X } X buf[i] = EOS; X return getcx(fp); X} X X X X/* string copy up to n characters */ Xstrncpy(to, from, n) Xchar *to, *from; Xint n; X{ X char *cp; X X for( cp=to; n-- && (*cp++ = *from++); ) ; X if( n<0 ) *cp = 0; X return to; X} X X X/* string compare up to n characters */ Xstrncmp(s1, s2, n) Xchar *s1, *s2; Xint n; X{ X X for( ;n-- && (*s1==*s2); s2++ ) X if( !*s1++ ) X return 0; X if( n < 0 ) X return 0; X if( *s1 < *s2 ) X return -1; X return 1; X} SHAR_EOF if test 1360 -ne "`wc -c 'pcjunk.c'`" then echo shar: error transmitting "'pcjunk.c'" '(should have been 1360 characters)' fi echo shar: extracting "'scn.c'" '(14358 characters)' if test -f 'scn.c' then echo shar: over-writing existing file "'scn.c'" fi sed 's/^X//' << \SHAR_EOF > 'scn.c' X/* SDB - token scanning routines */ X X#include "stdio.h" X#include "sdbio.h" X Xint dbv_token; /* current token */ Xint dbv_tvalue; /* integer token value */ Xchar dbv_tstring[STRINGMAX+1]; /* string token value */ Xstruct ifile *dbv_ifp; /* indirect file context */ Xstruct macro *dbv_macros; /* macro definitions */ Xint dbv_fold; /* case fold alpha comparisons */ X Xstatic char *iprompt,*cprompt; /* input prompts */ Xstatic char cmdline[LINEMAX+2],*lptr; /* current line and pointer */ Xstatic int atbol; /* flag indicating at bol */ Xstatic int savech; /* lookahead character */ Xstatic int savetkn; /* lookahead token */ Xstatic char *keywords[] = { /* keyword table */ X "ascending", X "by", X "char", X "compress", X "create", X "define", X "delete", X "descending", X "exit", X "export", X "extract", X "from", X "help", X "insert", X "import", X "into", X "num", X "print", X "select", X "set", X "show", X "sort", X "update", X "using", X "where", X NULL X}; Xstatic int keytokens[] = { /* token values for each keyword */ X ASCENDING, X BY, X CHAR, X COMPRESS, X CREATE, X DEFINE, X DELETE, X DESCENDING, X EXIT, X EXPORT, X EXTRACT, X FROM, X HELP, X INSERT, X IMPORT, X INTO, X NUM, X PRINT, X SELECT, X SET, X SHOW, X SORT, X UPDATE, X USING, X WHERE, X NULL X}; X X/* db_sinit - initialize the scanner */ Xdb_sinit() X{ X /* at beginning of line */ X atbol = TRUE; X X /* make the command line null */ X lptr = NULL; X X /* no lookahead yet */ X savech = EOS; X savetkn = NULL; X X /* no indirect command files */ X dbv_ifp = NULL; X X /* no macros defined */ X dbv_macros = NULL; X X /* fold alpha comparisons */ X dbv_fold = TRUE; X} X X/* db_prompt(ip,cp) - initialize prompt strings */ Xdb_prompt(ip,cp) X char *ip,*cp; X{ X /* save initial and continuation prompt strings */ X iprompt = ip; X cprompt = cp; X} X X/* db_scan(fmt,args) - initiate line scan command parsing */ Xdb_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) X{ X /* convert the command line and arguments */ X sprintf(cmdline,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); X X /* start at the beginning of the command line */ X lptr = cmdline; X iprompt = NULL; X dbv_ifp = NULL; X X /* no lookahead yet */ X savech = EOS; X savetkn = NULL; X X /* fold alpha comparisons */ X dbv_fold = TRUE; X} X X/* db_flush - flush the current input line */ Xint db_flush() X{ X while (savech != '\n') X if (savech > ' ') X return (db_ferror(SYNTAX)); X else X savech = getchx(); X X savech = EOS; X atbol = TRUE; X return (TRUE); X} X X/* db_gline - get a line from the current input */ Xchar *db_gline(buf) X char *buf; X{ X int ch,i; X X for (i = 0; (ch = getch()) != '\n' && ch != -1; ) X if (i < LINEMAX) X buf[i++] = ch; X else { X printf("*** line too long ***\nRetype> "); X i = 0; X } X buf[i] = EOS; X X return (buf); X} X X/* db_ifile - setup an indirect command file */ Xint db_ifile(fname) X char *fname; X{ X struct ifile *new_ifp; X X if ((new_ifp = malloc(sizeof(struct ifile))) == NULL) X return (db_ferror(INSMEM)); X else if ((new_ifp->if_fp = fopen(fname,"r")) == NULL) { X free(new_ifp); X return (db_ferror(INDFNF)); X } X new_ifp->if_mtext = NULL; X new_ifp->if_savech = savech; X new_ifp->if_lptr = lptr; X new_ifp->if_next = dbv_ifp; X dbv_ifp = new_ifp; X X /* return successfully */ X return (TRUE); X} X X/* db_kill - kill indirect command file input */ Xdb_kill() X{ X struct ifile *old_ifp; X X while ((old_ifp = dbv_ifp) != NULL) { X dbv_ifp = old_ifp->if_next; X if (old_ifp->if_fp != NULL) X fclose(old_ifp->if_fp); X savech = old_ifp->if_savech; X lptr = old_ifp->if_lptr; X free(old_ifp); X } X X while (savech != '\n') X savech = getchx(); X X savech = EOS; X savetkn = NULL; X atbol = TRUE; X} X X/* db_token - return the current input token */ Xint db_token() X{ X struct macro *mptr; X struct ifile *new_ifp; X X /* find a token that's not a macro call */ X while (db_xtoken() == ID) { X X /* check for a macro call */ X for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next) X if (db_scmp(dbv_tstring,mptr->mc_name) == 0) { X if ((new_ifp = malloc(sizeof(struct ifile))) == NULL) X printf("*** error expanding macro: %s ***\n",dbv_tstring); X else { X new_ifp->if_fp = NULL; X new_ifp->if_mtext = mptr->mc_mtext->mt_next; X new_ifp->if_lptr = lptr; lptr = mptr->mc_mtext->mt_text; X new_ifp->if_savech = savech; savech = EOS; X new_ifp->if_next = dbv_ifp; X dbv_ifp = new_ifp; X } X savetkn = NULL; X break; X } X X if (mptr == NULL) X break; X } X X return (dbv_token); X} X X/* db_xtoken - return the current input token */ Xint db_xtoken() X{ X int ch; X X /* check for a saved token */ X if ((dbv_token = savetkn) != NULL) X return (dbv_token); X X /* get the next non-blank character */ X ch = nextch(); X X /* check type of character */ X if (isalpha(ch)) /* identifier or keyword */ X get_id(); X else if (isdigit(ch)) /* number */ X get_number(); X else if (ch == '"') /* string */ X get_string(); X else if (get_rel()) /* relational operator */ X ; X else /* single character token */ X dbv_token = getch(); X X /* save the lookahead token */ X savetkn = dbv_token; X X /* return the token */ X return (dbv_token); X} X X/* db_ntoken - get next token (after skipping the current one) */ Xint db_ntoken() X{ X /* get the current token */ X db_token(); X X /* make sure another is read on next call */ X savetkn = NULL; X X /* return the current token */ X return (dbv_token); X} X X/* db_xntoken - get next token (after skipping the current one) */ Xint db_xntoken() X{ X /* get the current token */ X db_xtoken(); X X /* make sure another is read on next call */ X savetkn = NULL; X X /* return the current token */ X return (dbv_token); X} X X/* db_scmp - compare two strings */ Xint db_scmp(str1,str2) X char *str1,*str2; X{ X if (dbv_fold) X return (scmp(str1,str2)); X else X return (strcmp(str1,str2)); X} X X/* db_sncmp - compare two strings with a maximum length */ Xint db_sncmp(str1,str2,len) X char *str1,*str2; int len; X{ X if (dbv_fold) X return (sncmp(str1,str2,len)); X else X return (strncmp(str1,str2,len)); X} X X/* scmp - compare two strings with alpha case folding */ Xstatic int scmp(str1,str2) X char *str1,*str2; X{ X int ch1,ch2; X X /* compare each character */ X while (*str1 && *str2) { X X /* fold the character from the first string */ X if (isupper(*str1)) X ch1 = tolower(*str1++); X else X ch1 = *str1++; X X /* fold the character from the second string */ X if (isupper(*str2)) X ch2 = tolower(*str2++); X else X ch2 = *str2++; X X /* compare the characters */ X if (ch1 != ch2) X if (ch1 < ch2) X return (-1); X else X return (1); X } X X /* check for strings of different lengths */ X if (*str1 == *str2) X return (0); X else if (*str1 == 0) X return (-1); X else X return (1); X} X X/* sncmp - compare two strings with alpha case folding and a maximum length */ Xstatic int sncmp(str1,str2,len) X char *str1,*str2; int len; X{ X int ch1,ch2; X X /* compare each character */ X while (*str1 && *str2 && len > 0) { X X /* fold the character from the first string */ X if (isupper(*str1)) X ch1 = tolower(*str1++); X else X ch1 = *str1++; X X /* fold the character from the second string */ X if (isupper(*str2)) X ch2 = tolower(*str2++); X else X ch2 = *str2++; X X /* compare the characters */ X if (ch1 != ch2) X if (ch1 < ch2) X return (-1); X else X return (1); X X /* decrement the string length */ X len--; X } X X /* check for strings of different lengths */ X if (len == 0 || *str1 == *str2) X return (0); X else if (*str1 == 0) X return (-1); X else X return (1); X} X X/* get_id - get a keyword or a user identifier */ Xstatic get_id() X{ X int ch,nchars,i; X X /* input letters and digits */ X ch = nextch(); X nchars = 0; X while (isalpha(ch) || isdigit(ch)) { X if (nchars < KEYWORDMAX) X dbv_tstring[nchars++] = ch; X getch(); ch = thisch(); X } X X /* terminate the keyword */ X dbv_tstring[nchars] = EOS; X X /* assume its an identifier */ X dbv_token = ID; X X /* check for keywords */ X for (i = 0; keywords[i] != NULL; i++) X if (db_scmp(dbv_tstring,keywords[i]) == 0) X dbv_token = keytokens[i]; X} X X/* get_number - get a number */ Xstatic get_number() X{ X int ch,ndigits,nodot; X X /* read digits and at most one decimal point */ X ch = nextch(); X ndigits = 0; nodot = TRUE; X while (isdigit(ch) || (nodot && ch == '.')) { X if (ch == '.') X nodot = FALSE; X if (ndigits < NUMBERMAX) X dbv_tstring[ndigits++] = ch; X getch(); ch = thisch(); X } X X /* terminate the number */ X dbv_tstring[ndigits] = EOS; X X /* get the value of the number */ X sscanf(dbv_tstring,"%d",&dbv_tvalue); X X /* token is a number */ X dbv_token = NUMBER; X} X X/* get_string - get a string */ Xstatic get_string() X{ X int ch,nchars; X X /* skip the opening quote */ X getch(); X X /* read characters until a closing quote is found */ X ch = thisch(); X nchars = 0; X while (ch && ch != '"') { X if (nchars < STRINGMAX) X dbv_tstring[nchars++] = ch; X getch(); ch = thisch(); X } X X /* terminate the string */ X dbv_tstring[nchars] = EOS; X X /* skip the closing quote */ X getch(); X X /* token is a string */ X dbv_token = STRING; X} X X/* get_rel - get a relational operator */ Xstatic int get_rel() X{ X int ch; X X switch (ch = nextch()) { X case '=': X getch(); X dbv_token = EQL; X return (TRUE);; X case '<': X getch(); ch = nextch(); X if (ch == '>') { X getch(); X dbv_token = NEQ; X } X else if (ch == '=') { X getch(); X dbv_token = LEQ; X } X else X dbv_token = LSS; X return (TRUE);; X case '>': X getch(); ch = nextch(); X if (ch == '=') { X getch(); X dbv_token = GEQ; X } X else X dbv_token = GTR; X return (TRUE);; X default: X return (FALSE); X } X} X X/* getch - get the next character */ Xstatic int getch() X{ X char fname[STRINGMAX+1]; X int ch,i; X X /* return the lookahead character if there is one */ X if (savech != EOS) { X ch = savech; X savech = EOS; X return (ch); X } X X /* get a character */ X ch = getchx(); X X /* skip spaces at the beginning of a command */ X if (atbol && iprompt != NULL) X while (ch <= ' ') X ch = getchx(); X X /* use continuation prompt next time */ X iprompt = NULL; X X /* check for indirect command file */ X while (ch == '@') { X for (i = 0; (savech = getchx()) > ' '; ) X if (i < STRINGMAX) X fname[i++] = savech; X fname[i] = 0; X if (db_ifile(fname) != TRUE) X printf("*** error opening command file: %s ***\n",fname); X ch = getchx(); X } X X /* return the character */ X return (ch); X} X X/* getchx - get the next character */ Xstatic int getchx() X{ X struct ifile *old_ifp; X int ch; X X /* check for input from buffer */ X if (lptr != NULL) { X while (*lptr == EOS) X if (dbv_ifp != NULL) X if (dbv_ifp->if_mtext == NULL) { X old_ifp = dbv_ifp; X ch = dbv_ifp->if_savech; savech = EOS; X lptr = dbv_ifp->if_lptr; X dbv_ifp = dbv_ifp->if_next; X free(old_ifp); X if (ch != EOS) X return (ch); X if (lptr == NULL) X break; X } X else { X lptr = dbv_ifp->if_mtext->mt_text; X dbv_ifp->if_mtext = dbv_ifp->if_mtext->mt_next; X } X else X return (EOS); X X if (lptr != NULL) X return (*lptr++); X } X X /* print prompt if necessary */ X if (atbol && dbv_ifp == NULL) { /*dns*/ X if (iprompt != NULL) X printf("%s",iprompt); X else if (cprompt != NULL) X printf("%s",cprompt); X#ifdef Lattice X fflush(stdout); /*dns*/ X#endif X } /*dns*/ X X if (dbv_ifp == NULL) X if ((ch = getcx(stdin)) == '\n') X atbol = TRUE; X else X atbol = FALSE; X else { X if ((ch = getcx(dbv_ifp->if_fp)) == -1) { X old_ifp = dbv_ifp; X ch = dbv_ifp->if_savech; savech = EOS; X lptr = dbv_ifp->if_lptr; X dbv_ifp = dbv_ifp->if_next; X fclose(old_ifp->if_fp); X free(old_ifp); X } X } X X /* return the character */ X return (ch); X} X X/* thisch - get the current character */ Xstatic int thisch() X{ X /* get a lookahead character */ X if (savech == EOS) X savech = getch(); X X /* return lookahead character */ X return (savech); X} X X/* nextch - get the next non-blank character */ Xstatic int nextch() X{ X int ch; X X /* skip blank characters */ X while ((ch = thisch()) <= ' ' && ch != EOS) X getch(); X X /* return the first non-blank */ X return (ch); X} X SHAR_EOF if test 14358 -ne "`wc -c 'scn.c'`" then echo shar: error transmitting "'scn.c'" '(should have been 14358 characters)' fi echo shar: extracting "'sdb.c'" '(367 characters)' if test -f 'sdb.c' then echo shar: over-writing existing file "'sdb.c'" fi sed 's/^X//' << \SHAR_EOF > 'sdb.c' X/* SDB - main routine */ X X#include "stdio.h" X#include "sdbio.h" X Xextern int dbv_errcode; X Xmain() X{ X printf("SDB - version 2.0\n"); X db_sinit(); X db_ifile("sdb.ini"); X X while (TRUE) { X db_prompt("SDB> ","\t> "); X if (!db_parse(NULL)) { X printf("** error: %s ***\n",db_ertxt(dbv_errcode)); X db_kill(); X } X } X} X SHAR_EOF if test 367 -ne "`wc -c 'sdb.c'`" then echo shar: error transmitting "'sdb.c'" '(should have been 367 characters)' fi echo shar: extracting "'sel.c'" '(20482 characters)' if test -f 'sel.c' then echo shar: over-writing existing file "'sel.c'" fi sed 's/^X//' << \SHAR_EOF > 'sel.c' X/* SDB - select data from the database */ X X#include "sdbio.h" X Xextern int dbv_token; Xextern char dbv_tstring[]; Xextern int dbv_tvalue; X X/* db_select - select a set of tuples from a set of relations */ Xstruct sel *db_select(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct sel *slptr; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* allocate a sel structure */ X if ((slptr = malloc(sizeof(struct sel))) == NULL) X return (db_nerror(INSMEM)); X X /* initialize the structure */ X slptr->sl_rels = NULL; X slptr->sl_attrs = NULL; X slptr->sl_where = NULL; X slptr->sl_bindings = NULL; X X /* parse the list of selected attributes */ X if (!get_sattrs(slptr)) { X db_done(slptr); X return (NULL); X } X X /* check for "from" clause */ X if (db_token() == FROM) { X db_ntoken(); X if (!get_srels(slptr)) { X db_done(slptr); X return (NULL); X } X } X else { X if (!srelation(slptr,"sdbcur",NULL)) { X db_done(slptr); X return (NULL); X } X } X X /* check the list of selected attributes */ X if (!check_attrs(slptr)) { X db_done(slptr); X return (NULL); X } X X /* check for the existance of a "where" clause */ X if (db_token() == WHERE) { X db_ntoken(); X X /* parse the boolean expression */ X if (!db_compile(slptr)) { X db_done(slptr); X return (FALSE); X } X } X X /* return the new selection structure */ X return (slptr); X} X X/* db_retrieve - retrieve a set of tuples from a set of relations */ Xstruct sel *db_retrieve(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct sel *slptr; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* allocate a sel structure */ X if ((slptr = malloc(sizeof(struct sel))) == NULL) X return (db_nerror(INSMEM)); X X /* initialize the structure */ X slptr->sl_rels = NULL; X slptr->sl_attrs = NULL; X slptr->sl_where = NULL; X slptr->sl_bindings = NULL; X X /* check for selected relations clause */ X if (db_token() == ID) { X if (!get_srels(slptr)) { X db_done(slptr); X return (NULL); X } X } X else { X if (!srelation(slptr,"sdbcur",NULL)) { X db_done(slptr); X return (NULL); X } X } X X /* check the list of selected attributes */ X if (!check_attrs(slptr)) { X db_done(slptr); X return (NULL); X } X X /* check for the existance of a "where" clause */ X if (db_token() == WHERE) { X db_ntoken(); X X /* parse the boolean expression */ X if (!db_compile(slptr)) { X db_done(slptr); X return (FALSE); X } X } X X /* return the new selection structure */ X return (slptr); X} X X/* db_done(slptr) - finish a selection */ Xdb_done(slptr) X struct sel *slptr; X{ X struct sattr *saptr,*nxtsa; X struct srel *srptr,*nxtsr; X struct binding *bdptr,*nxtbd; X X /* free the selected attribute blocks */ X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = nxtsa) { X nxtsa = saptr->sa_next; X if (saptr->sa_rname != NULL) X free(saptr->sa_rname); X free(saptr->sa_aname); X if (saptr->sa_name != NULL) X free(saptr->sa_name); X free(saptr); X } X X /* close the scans and free the selected relation blocks */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = nxtsr) { X nxtsr = srptr->sr_next; X if (srptr->sr_name != NULL) X free(srptr->sr_name); X db_rclose(srptr->sr_scan); X free(srptr); X } X X /* free the where clause */ X db_fcode(slptr); X X /* free the user bindings */ X for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = nxtbd) { X nxtbd = bdptr->bd_next; X free(bdptr); X } X X /* free the selection structure */ X free(slptr); X} X X/* db_fetch(slptr) - fetch the next tuple from a selection */ Xint db_fetch(slptr) X struct sel *slptr; X{ X struct srel *srptr; X struct binding *bdptr; X X /* clear the update flags */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) X srptr->sr_update = FALSE; X X /* find a matching tuple */ X while (process(slptr->sl_rels)) X if (db_interpret(slptr)) { X for (bdptr = slptr->sl_bindings; bdptr != NULL; bdptr = bdptr->bd_next) X db_aget(bdptr->bd_attr,bdptr->bd_vtuple,bdptr->bd_vuser); X return (TRUE); X } X X /* no matches, failure return */ X return (FALSE); X} X X/* db_update - update modified tuples */ Xint db_update(slptr) X struct sel *slptr; X{ X struct srel *srptr; X X /* check each selected relation for updates */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) X if (srptr->sr_update) X if (!db_rupdate(srptr->sr_scan)) X return (FALSE); X X /* return successfully */ X return (TRUE); X} X X/* db_store - store tuples */ Xint db_store(slptr) X struct sel *slptr; X{ X struct srel *srptr; X X /* check each selected relation for stores */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) X if (srptr->sr_update) X if (!db_rstore(srptr->sr_scan)) X return (FALSE); X X /* return successfully */ X return (TRUE); X} X X/* db_bind - bind a user buffer to the value of an attribute */ Xint db_bind(slptr,rname,aname,avalue) X struct sel *slptr; char *rname,*aname,*avalue; X{ X struct binding *newbd; X struct srel *srptr; X X /* allocate and initialize a binding structure */ X if ((newbd = malloc(sizeof(struct binding))) == NULL) X return (db_ferror(INSMEM)); X newbd->bd_vuser = avalue; X X /* find the attribute */ X if (!find_attr(slptr,rname,aname,&newbd->bd_vtuple,&srptr,&newbd->bd_attr)) X return (FALSE); X X /* link the new binding into the binding list */ X newbd->bd_next = slptr->sl_bindings; X slptr->sl_bindings = newbd; X X /* return successfully */ X return (TRUE); X} X X/* db_get - get the value of an attribute */ Xint db_get(slptr,rname,aname,avalue) X struct sel *slptr; char *rname,*aname,*avalue; X{ X struct srel *srptr; X struct attribute *aptr; X char *vptr; X X /* find the attribute */ X if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr)) X return (FALSE); X X /* get the attribute value */ X db_aget(aptr,vptr,avalue); X X /* return successfully */ X return (TRUE); X} X X/* db_put - put the value of an attribute */ Xint db_put(slptr,rname,aname,avalue) X struct sel *slptr; char *rname,*aname,*avalue; X{ X struct srel *srptr; X struct attribute *aptr; X char *vptr; X X /* find the attribute */ X if (!find_attr(slptr,rname,aname,&vptr,&srptr,&aptr)) X return (FALSE); X X /* put the attribute value */ X db_aput(aptr,vptr,avalue); X X /* mark the tuple as updated */ X srptr->sr_update = TRUE; X X /* return successfully */ X return (TRUE); X} X X/* db_sattr - get selected attribute type, pointer, and length */ Xint db_sattr(slptr,rname,aname,ptype,pptr,plen) X struct sel *slptr; char *rname,*aname; X int *ptype; char **pptr; int *plen; X{ X struct srel *srptr; X struct attribute *aptr; X X if (!find_attr(slptr,rname,aname,pptr,&srptr,&aptr)) X return (FALSE); X *ptype = aptr->at_type; X *plen = aptr->at_size; X return (TRUE); X} X X/* get_sattrs(slptr) - get selected attributes */ Xstatic get_sattrs(slptr) X struct sel *slptr; X{ X struct sattr *newsattr,*lastsattr; X X /* check for "*" or blank field meaning all attributes are selected */ X if (db_token() == '*') { X db_ntoken(); X return (TRUE); X } X else if (db_token() != ID) X return (TRUE); X X /* parse a list of attribute names */ X lastsattr = NULL; X while (TRUE) { X X /* get attribute name */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X X /* allocate a selected attribute structure */ X if ((newsattr = malloc(sizeof(struct sattr))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the selected attribute structure */ X newsattr->sa_next = NULL; X X /* save the attribute name */ X if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) { X free(newsattr); X return (db_ferror(INSMEM)); X } X strcpy(newsattr->sa_aname,dbv_tstring); X X /* check for "." meaning "." */ X if (db_token() == '.') { X db_ntoken(); X X /* the previous ID was really the relation name */ X newsattr->sa_rname = newsattr->sa_aname; X X /* check for attribute name */ X if (db_ntoken() != ID) { X free(newsattr->sa_aname); free(newsattr); X return (db_ferror(SYNTAX)); X } X X /* save the attribute name */ X if ((newsattr->sa_aname = malloc(strlen(dbv_tstring)+1)) == NULL) { X free(newsattr->sa_aname); free(newsattr); X return (db_ferror(INSMEM)); X } X strcpy(newsattr->sa_aname,dbv_tstring); X } X else X newsattr->sa_rname = NULL; X X /* check for alternate attribute name */ X if (db_token() == ID) { X db_ntoken(); X X /* allocate space for the alternate name */ X if ((newsattr->sa_name = malloc(strlen(dbv_tstring)+1)) == NULL) { X if (newsattr->sa_rname != NULL) X free(newsattr->sa_rname); X free(newsattr->sa_aname); X free(newsattr); X return (db_ferror(INSMEM)); X } X strcpy(newsattr->sa_name,dbv_tstring); X } X else X newsattr->sa_name = NULL; X X /* link the selected attribute structure into the list */ X if (lastsattr == NULL) X slptr->sl_attrs = newsattr; X else X lastsattr->sa_next = newsattr; X lastsattr = newsattr; X X /* check for more attributes */ X if (db_token() != ',') X break; X db_ntoken(); X } X X /* return successfully */ X return (TRUE); X} X X/* get_srels(slptr) - get selected relations */ Xstatic get_srels(slptr) X struct sel *slptr; X{ X char rname[KEYWORDMAX+1],*aname; X X /* get the list of selected relations */ X while (TRUE) { X X /* check for relation name */ X if (db_ntoken() != ID) X return (db_ferror(SYNTAX)); X strcpy(rname,dbv_tstring); X X /* check for alternate relation name */ X if (db_token() == ID) { X db_ntoken(); X aname = dbv_tstring; X } X else X aname = NULL; X X /* add the relation name to the list */ X if (!srelation(slptr,rname,aname)) X return (FALSE); X X /* check for more selected relations */ X if (db_token() != ',') X break; X db_ntoken(); X } X X /* return successfully */ X return (TRUE); X} X X/* srelation - select a relation */ Xstatic srelation(slptr,rname,aname) X struct sel *slptr; char *rname,*aname; X{ X struct srel *srptr,*newsrel; X X /* allocate a new selected relation structure */ X if ((newsrel = malloc(sizeof(struct srel))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the new selected relation structure */ X newsrel->sr_ctuple = FALSE; X newsrel->sr_update = FALSE; X newsrel->sr_next = NULL; X X /* open the relation */ X if ((newsrel->sr_scan = db_ropen(rname)) == NULL) { X free(newsrel); X return (FALSE); X } X X /* check for alternate relation name */ X if (aname != NULL) { X X /* allocate space for the alternate name */ X if ((newsrel->sr_name = malloc(strlen(aname)+1)) == NULL) { X free(newsrel); X return (db_ferror(INSMEM)); X } X strcpy(newsrel->sr_name,aname); X } X else X newsrel->sr_name = NULL; X X /* find the end of the list of relation names */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) X if (srptr->sr_next == NULL) X break; X X /* link the new selected relation structure into the list */ X if (srptr == NULL) X slptr->sl_rels = newsrel; X else X srptr->sr_next = newsrel; X X /* return successfully */ X return (TRUE); X} X X/* check_attrs(slptr) - check the list of selected attributes */ Xstatic int check_attrs(slptr) X struct sel *slptr; X{ X struct sattr *saptr; X X /* check for all attributes selected */ X if (slptr->sl_attrs == NULL) X return (all_attrs(slptr)); X X /* check each selected attribute */ X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) X if (!find_attr(slptr,saptr->sa_rname,saptr->sa_aname, X &saptr->sa_aptr,&saptr->sa_srel,&saptr->sa_attr)) X return (FALSE); X X /* return successfully */ X return (TRUE); X} X X/* all_attrs(slptr) - create a list of all attributes */ Xstatic int all_attrs(slptr) X struct sel *slptr; X{ X struct sattr *newsattr,*lastsattr; X struct srel *srptr; X struct attribute *aptr; X int i,astart; X X /* loop through each selected relation */ X lastsattr = NULL; X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) { X X /* loop through each attribute within the relation */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i]; X X /* check for last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* allocate a new selected attribute structure */ X if ((newsattr = malloc(sizeof(struct sattr))) == NULL) X return (db_ferror(INSMEM)); X X /* initialize the new selected attribute structure */ X newsattr->sa_name = NULL; X newsattr->sa_srel = srptr; X newsattr->sa_aptr = srptr->sr_scan->sc_tuple + astart; X newsattr->sa_attr = aptr; X newsattr->sa_next = NULL; X X /* save the relation name */ X if ((newsattr->sa_rname = malloc(RNSIZE+1)) == NULL) { X free(newsattr); X return (db_ferror(INSMEM)); X } X strncpy(newsattr->sa_rname, X srptr->sr_scan->sc_relation->rl_name, X RNSIZE); X newsattr->sa_rname[RNSIZE] = 0; X X /* save the attribute name */ X if ((newsattr->sa_aname = malloc(ANSIZE+1)) == NULL) { X free(newsattr->sa_rname); X free(newsattr); X return (db_ferror(INSMEM)); X } X strncpy(newsattr->sa_aname, X srptr->sr_scan->sc_relation->rl_header.hd_attrs[i].at_name, X ANSIZE); X newsattr->sa_aname[ANSIZE] = 0; X X /* link the selected attribute into the list */ X if (lastsattr == NULL) X slptr->sl_attrs = newsattr; X else X lastsattr->sa_next = newsattr; X lastsattr = newsattr; X X /* update the attribute start */ X astart += aptr->at_size; X } X } X X /* return successfully */ X return (TRUE); X} X X/* find_attr - find a named attribute */ Xstatic int find_attr(slptr,rname,aname,paptr,psrel,pattr) X struct sel *slptr; char *rname,*aname; X char **paptr; struct attribute **pattr; X{ X /* check for unqualified or qualified attribute names */ X if (rname == NULL) X return (uattr(slptr,aname,paptr,psrel,pattr)); X else X return (qattr(slptr,rname,aname,paptr,psrel,pattr)); X} X X/* uattr - find an unqualified attribute name */ Xstatic int uattr(slptr,aname,paptr,psrel,pattr) X struct sel *slptr; char *aname; X char **paptr; struct srel **psrel; struct attribute **pattr; X{ X struct srel *srptr; X struct attribute *aptr; X int i,astart; X X /* loop through each selected relation */ X *pattr = NULL; X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) { X X /* loop through each attribute within the relation */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i]; X X /* check for last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* check for attribute name match */ X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) { X if (*pattr != NULL) X return (db_ferror(ATAMBG)); X *paptr = srptr->sr_scan->sc_tuple + astart; X *psrel = srptr; X *pattr = aptr; X } X X /* update the attribute start */ X astart += aptr->at_size; X } X } X X /* check whether attribute was found */ X if (*pattr == NULL) X return (db_ferror(ATUNDF)); X X /* return successfully */ X return (TRUE); X} X X/* qattr - find a qualified attribute name */ Xstatic int qattr(slptr,rname,aname,paptr,psrel,pattr) X struct sel *slptr; char *rname,*aname; X char **paptr; struct srel **psrel; struct attribute **pattr; X{ X struct srel *srptr; X struct attribute *aptr; X char *crname; X int i,astart; X X /* loop through each selected relation */ X for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next) { X X /* get relation name */ X if ((crname = srptr->sr_name) == NULL) X crname = srptr->sr_scan->sc_relation->rl_name; X X /* check for relation name match */ X if (db_sncmp(rname,crname,RNSIZE) == 0) { X X /* loop through each attribute within the relation */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &srptr->sr_scan->sc_relation->rl_header.hd_attrs[i]; X X /* check for last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* check for attribute name match */ X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) { X *paptr = srptr->sr_scan->sc_tuple + astart; X *psrel = srptr; X *pattr = aptr; X return (TRUE); X } X X /* update the attribute start */ X astart += aptr->at_size; X } X X /* attribute name not found */ X return (db_ferror(ATUNDF)); X } X } X X /* relation name not found */ X return (db_ferror(RLUNDF)); X} X X/* process(srptr) - process each tuple in a relation cross-product */ Xstatic int process(srptr) X struct srel *srptr; X{ X /* always get a new tuple if this is the last relation in the list */ X if (srptr->sr_next == NULL) { X X /* check for beginning of new scan */ X if (!srptr->sr_ctuple) X db_rbegin(srptr->sr_scan); X X /* return the next tuple in the relation */ X return (srptr->sr_ctuple = db_rfetch(srptr->sr_scan)); X } X X /* check for beginning of new scan */ X if (!srptr->sr_ctuple) { X db_rbegin(srptr->sr_scan); X X /* get the first tuple */ X if (!db_rfetch(srptr->sr_scan)) X return (FALSE); X } X X /* look for a match with the remaining relations in list */ X while (!process(srptr->sr_next)) X X /* get the next tuple in the scan */ X if (!db_rfetch(srptr->sr_scan)) X return (srptr->sr_ctuple = FALSE); X X /* found a match at this level */ X return (srptr->sr_ctuple = TRUE); X} X X/* db_aget - get the value of an attribute */ Xdb_aget(aptr,vptr,avalue) X struct attribute *aptr; char *vptr,*avalue; X{ X int i; X X /* get the attribute value */ X for (i = 0; i < aptr->at_size; i++) X *avalue++ = vptr[i]; X *avalue = EOS; X} X X/* db_aput - put the value of an attribute */ Xdb_aput(aptr,vptr,avalue) X struct attribute *aptr; char *vptr,*avalue; X{ X int i; X X /* initialize counter */ X i = 0; X X /* right justify numbers */ X if (aptr->at_type == TNUM) X for (; i < aptr->at_size - strlen(avalue); i++) X vptr[i] = ' '; X X /* put the attribute value */ X for (; i < aptr->at_size; i++) X if (*avalue == 0) X vptr[i] = 0; X else X vptr[i] = *avalue++; X} X SHAR_EOF if test 20482 -ne "`wc -c 'sel.c'`" then echo shar: error transmitting "'sel.c'" '(should have been 20482 characters)' fi echo shar: extracting "'srt.c'" '(8289 characters)' if test -f 'srt.c' then echo shar: over-writing existing file "'srt.c'" fi sed 's/^X//' << \SHAR_EOF > 'srt.c' X/* SDB - sort routines */ X X#include "stdio.h" X#include "sdbio.h" X Xextern int dbv_token; Xextern char dbv_tstring[]; Xextern int dbv_tvalue; X X/* get_skeys - get sort key list */ Xstatic struct skey *get_skeys(sptr) X struct scan *sptr; X{ X struct skey *skeys,*newskey,*lastskey; X X /* parse a list of attribute names */ X skeys = lastskey = NULL; X while (TRUE) { X X /* get attribute name */ X if (db_ntoken() != ID) X return (db_nerror(SYNTAX)); X X /* allocate a sort key structure */ X if ((newskey = malloc(sizeof(struct skey))) == NULL) X return (db_nerror(INSMEM)); X X /* initialize the sort key structure */ X newskey->sk_next = NULL; X X /* lookup the attribute name */ X if (!find_attr(sptr,newskey,dbv_tstring)) { X free(newskey); X return (NULL); X } X X /* check for ascending or descending */ X if (db_token() == ASCENDING || dbv_token == DESCENDING) { X newskey->sk_type = dbv_token; X db_ntoken(); X } X else X newskey->sk_type = ASCENDING; X X /* link the sort key structure into the list */ X if (lastskey == NULL) X skeys = newskey; X else X lastskey->sk_next = newskey; X lastskey = newskey; X X /* check for more attributes */ X if (db_token() != ',') X break; X db_ntoken(); X } X X /* return successfully */ X return (skeys); X} X X/* db_sort - sort tuples in a relation */ Xint *db_sort(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9) X char *fmt; X{ X struct scan *sptr1,*sptr2,*sptr3; /*dns*/ X struct skey *skeys; X int result; X X /* check for a command line */ X if (fmt != NULL) X db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9); X X /* checks for relation name */ X if (db_token() == ID) X db_ntoken(); X else X strcpy(dbv_tstring,"sdbcur"); X X /* open the relation */ X if ((sptr1 = db_ropen(dbv_tstring)) == NULL) X return (FALSE); X if ((sptr2 = db_ropen(dbv_tstring)) == NULL) { X db_rclose(sptr1); X return (FALSE); X } X if ((sptr3 = db_ropen(dbv_tstring)) == NULL) { /*dns*/ X db_rclose(sptr1); /*dns*/ X db_rclose(sptr2); /*dns*/ X return (FALSE); /*dns*/ X } X X /* checks for " by " */ X if (db_ntoken() != BY) X return (db_ferror(SYNTAX)); X if ((skeys = get_skeys(sptr1)) == NULL) { X db_rclose(sptr1); X db_rclose(sptr2); X db_rclose(sptr3); /*dns*/ X return (FALSE); X } X X /* do the sort */ X result = sort(skeys,sptr1,sptr2,sptr3); /*dns*/ X X /* close the relation */ X db_rclose(sptr1); X db_rclose(sptr2); X db_rclose(sptr3); /*dns*/ X X /* free the sort keys */ X free_skeys(skeys); X X return (result); X} X X/* free_skeys - free a list of sort keys */ Xstatic free_skeys(skeys) X struct skey *skeys; X{ X struct skey *thisskey; X X for (thisskey = skeys; skeys != NULL; thisskey = skeys) { X skeys = skeys->sk_next; X free(thisskey); X } X} X X/* find_attr - find an attribute */ Xstatic int find_attr(sptr,newskey,aname) X struct scan *sptr; struct skey *newskey; char *aname; X{ X struct attribute *aptr; X int i,astart; X X /* loop through each attribute within the relation */ X astart = 1; X for (i = 0; i < NATTRS; i++) { X X /* get a pointer to the current attribute */ X aptr = &sptr->sc_relation->rl_header.hd_attrs[i]; X X /* check for last attribute */ X if (aptr->at_name[0] == 0) X break; X X /* check for attribute name match */ X if (db_sncmp(aname,aptr->at_name,ANSIZE) == 0) { X newskey->sk_start = astart; X newskey->sk_aptr = aptr; X return (TRUE); X } X X /* update the attribute start */ X astart += aptr->at_size; X } X X /* attribute name not found */ X return (db_ferror(ATUNDF)); X} X X/* sort - sort the relation */ Xstatic int sort(skeys,sptr1,sptr2,sptr3) X struct skey *skeys; struct scan *sptr1,*sptr2,*sptr3; X{ X/* unsigned int j,k,l,r; dns */ X long int passes,swaps; /*dns*/ X int i, j, m, n; /*dns*/ X int rec1 = 0; /*dns*/ X int rec2 = 0; /*dns*/ X int rec3 = 0; /*dns*/ X int dns = 0; /*dns*/ X FILE *test; /*dns*/ X X passes = 0L; X swaps = 0L; X X /*dns ---> */ X test = fopen("sort.dat", "w"); X n = sptr1->sc_relation->rl_tcnt; X m = n; X X while( m>1 ) { X passes++; X if ((m/=3.14159) < 1) m = 1; X for ( j=1; j<=n-m; j++ ) { X if( rec1 != j+m ) { X if(dns) fprintf(test,"Read1: %d\n", j+m); X if (!db_rget(sptr1, rec1=j+m)) return (FALSE); X } X for ( i=j; i>=1; i-=m ) { X if( rec2 != i ) { X if(dns) fprintf(test,"Read2: %d\n", i); X if (!db_rget(sptr2, rec2=i)) return (FALSE); X } X if (compare(skeys,sptr1,sptr2) > 0) X break; X if(rec3 != i+m) { X if(dns) fprintf(test,"Read3: %d\n", i+m); X if (!db_rget(sptr3, rec3=i+m)) return (FALSE); X } X if(dns) fprintf(test,"Write 3,2: %d from %d\n", i+m, i); X assign( sptr3, sptr2 ); X swaps++; X } X if(rec1 != i+m) { X if(rec3 != i+m) { X if(dns) fprintf(test,"Read 3: %d\n", i+m); X if (!db_rget(sptr3, rec3=i+m)) return (FALSE); X } X if(dns) fprintf(test,"Write 3,1: %d from %d\n", i+m, j+m); X assign( sptr3, sptr1 ); X swaps++; X } X } X } X fclose(test); X X/* X l = 2; X r = sptr1->sc_relation->rl_tcnt; X k = r; X X do { X for (j = r; j >= l; j--) { X if (!db_rget(sptr1,j-1)) X return (FALSE); X if (!db_rget(sptr2,j)) X return (FALSE); X if (compare(skeys,sptr1,sptr2) > 0) { X swap(sptr1,sptr2); X k = j; X swaps++; X } X } X l = k + 1; X for (j = l; j <= r; j++) { X if (!db_rget(sptr1,j-1)) X return (FALSE); X if (!db_rget(sptr2,j)) X return (FALSE); X if (compare(skeys,sptr1,sptr2) > 0) { X swap(sptr1,sptr2); X k = j; X swaps++; X } X } X r = k - 1; X passes++; X } while (l <= r); X*/ X X printf("[ Passes: %ld Swaps: %ld ]\n",passes,swaps); X X return (TRUE); X} X X/* compare - compare two tuples */ Xstatic int compare(skeys,sptr1,sptr2) X struct skey *skeys; struct scan *sptr1,*sptr2; X{ X struct skey *cskey; X int result; X X for (cskey = skeys; cskey != NULL; cskey = cskey->sk_next) X if ((result = cattr(cskey,sptr1,sptr2)) != 0) X break; X X return (result); X} X X/* cattr - compare two attributes */ Xstatic int cattr(cskey,sptr1,sptr2) X struct skey *cskey; struct scan *sptr1,*sptr2; X{ X int astart,aend,i; X X astart = cskey->sk_start; X aend = astart + cskey->sk_aptr->at_size; X X for (i = astart; i < aend; i++) X if (sptr1->sc_tuple[i] != sptr2->sc_tuple[i]) X break; X X if (i == aend) X return (0); X X if (sptr1->sc_tuple[i] < sptr2->sc_tuple[i]) X if (cskey->sk_type == ASCENDING) X return (-1); X else X return (1); X else X if (cskey->sk_type == ASCENDING) X return (1); X else X return (-1); X} X X/* swap - swap two tuples */ X/* dns Xstatic int swap(sptr1,sptr2) X struct scan *sptr1,*sptr2; X{ X unsigned int tnum1,tnum2; X X tnum1 = sptr1->sc_atnum; X tnum2 = sptr2->sc_atnum; X X if (!db_rput(sptr1,tnum2)) X return (FALSE); X if (!db_rput(sptr2,tnum1)) X return (FALSE); X X return (TRUE); X} X dns */ X X X/* assign - assign one tupple to another */ Xstatic int assign(sptr1,sptr2) X struct scan *sptr1,*sptr2; X{ X unsigned int tnum1,tnum2; X X tnum1 = sptr1->sc_atnum; X X if (!db_rput(sptr2,tnum1)) X return (FALSE); X X return (TRUE); X} X SHAR_EOF if test 8289 -ne "`wc -c 'srt.c'`" then echo shar: error transmitting "'srt.c'" '(should have been 8289 characters)' fi echo shar: extracting "'tbl.c'" '(2554 characters)' if test -f 'tbl.c' then echo shar: over-writing existing file "'tbl.c'" fi sed 's/^X//' << \SHAR_EOF > 'tbl.c' X/* SDB - table output routines */ X X#include "stdio.h" X#include "sdbio.h" X Xstatic char buffer[TABLEMAX+1]; Xint bndx; X X/* db_thead - print a table header */ Xdb_thead(fp,slptr) X FILE *fp; struct sel *slptr; X{ X struct sattr *saptr; X int twidth,fwidth,i; X char *aname; X X /* compute the table width */ X twidth = 1; X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) X twidth += saptr->sa_attr->at_size + 3; X X /* print the top line of the table */ X bstart(); X for (i = 0; i < twidth; i++) X binsert('-'); X bprint(fp); X X /* print the label line of the table */ X bstart(); X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X fwidth = saptr->sa_attr->at_size; X binsert('|'); binsert(' '); X if ((aname = saptr->sa_name) == NULL) X aname = saptr->sa_aname; X for (i = 0; i < fwidth; i++) X if (*aname != 0) X binsert(*aname++); X else X binsert(' '); X binsert(' '); X } X binsert('|'); X bprint(fp); X X /* print the line under the labels */ X bstart(); X for (i = 0; i < twidth; i++) X binsert('-'); X bprint(fp); X} X X/* db_tfoot - print a table foot */ Xdb_tfoot(fp,slptr) X FILE *fp; struct sel *slptr; X{ X struct sattr *saptr; X int twidth,i; X X /* compute the table width */ X twidth = 1; X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) X twidth += saptr->sa_attr->at_size + 3; X X /* print the line at the foot of the table */ X bstart(); X for (i = 0; i < twidth; i++) X binsert('-'); X bprint(fp); X} X X/* db_tentry - print a table entry */ Xdb_tentry(fp,slptr) X FILE *fp; struct sel *slptr; X{ X struct sattr *saptr; X int fwidth,i; X X /* print a table entry */ X bstart(); X for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) { X fwidth = saptr->sa_attr->at_size; X binsert('|'); binsert(' '); X for (i = 0; i < fwidth; i++) X if (saptr->sa_aptr[i] != 0) X binsert(saptr->sa_aptr[i]); X else X binsert(' '); X binsert(' '); X } X binsert('|'); X bprint(fp); X} X X/* bstart - start building a line */ Xstatic bstart() X{ X bndx = 0; X} X X/* binsert - insert a character into the buffer */ Xstatic binsert(ch) X int ch; X{ X if (bndx < TABLEMAX) X buffer[bndx++] = ch; X} X X/* bprint - print the current line */ Xstatic bprint(fp) X FILE *fp; X{ X buffer[bndx] = EOS; X fprintf(fp,"%s\n",buffer); X} X SHAR_EOF if test 2554 -ne "`wc -c 'tbl.c'`" then echo shar: error transmitting "'tbl.c'" '(should have been 2554 characters)' fi echo shar: extracting "'sdbio.h'" '(7764 characters)' if test -f 'sdbio.h' then echo shar: over-writing existing file "'sdbio.h'" fi sed 's/^X//' << \SHAR_EOF > 'sdbio.h' X/* SDB - definition file */ X X#include "ctype.h" /*dns*/ X X/* compiler specific stuff (dns) */ X#define Lattice X X/* useful definitions */ X#define TRUE 1 X#define FALSE 0 X#ifndef NULL X#define NULL 0 X#endif X X/* Character definitions (dns) */ X#define BS 0x8 /*dns*/ X#define CR 0xD /*dns*/ X#define FF 0xC /*dns*/ X#define ESC 0x1B /*dns*/ X X/* program limits */ X#define LINEMAX 132 /* maximum input line length */ X#define TABLEMAX 132 /* maximum table output line */ X#define KEYWORDMAX 10 /* maximum keyword length */ X#define NUMBERMAX 20 /* maximum number length */ X#define STRINGMAX 132 /* maximum string length */ X#define CODEMAX 100 /* maximum length of code array */ X#define STACKMAX 20 /* maximum interpreter stack size */ X X/* token definitions */ X#define EOS 0 X#define LSS -1 X#define LEQ -2 X#define EQL -3 X#define NEQ -4 X#define GEQ -5 X#define GTR -6 X#define SELECT -7 X#define FROM -8 X#define WHERE -9 X#define CREATE -10 X#define DELETE -11 X#define INSERT -12 X#define EXIT -13 X#define CHAR -14 X#define NUM -15 X#define ID -16 X#define STRING -17 X#define NUMBER -18 X#define UPDATE -19 X#define PRINT -20 X#define IMPORT -21 X#define EXPORT -22 X#define INTO -23 X#define HELP -24 X#define COMPRESS -25 X#define EXTRACT -26 X#define DEFINE -27 X#define SHOW -28 X#define USING -29 X#define SORT -30 X#define BY -31 X#define ASCENDING -32 X#define DESCENDING -33 X#define SET -34 X X/* operand types */ X#define LITERAL 1 X#define ATTR 2 X#define TEMP 3 X X/* attribute data types */ X#define TCHAR 1 X#define TNUM 2 X X/* tuple status codes */ X#define UNUSED 0 X#define ACTIVE 1 X#define DELETED 2 X X/* relation header page format definitions */ X#define RNSIZE 10 /* size of a relation name */ X#define HSIZE 16 /* size of a relation entry */ X#define ASIZE 16 /* size of a attribute entry */ X#define ANSIZE 10 /* size of a attribute name */ X#define NATTRS 31 /* number of attributes in header block */ X X/* error code definitions */ X#define END 0 /* end of retrieval set */ X#define INSMEM 1 /* insufficient memory */ X#define RELFNF 2 /* relation file not found */ X#define BADHDR 3 /* bad relation file header */ X#define TUPINP 4 /* tuple input error */ X#define TUPOUT 5 /* tuple output error */ X#define RELFUL 6 /* relation file full */ X#define RELCRE 7 /* error creating relation file */ X#define DUPATT 8 /* duplicate attribute on relation create */ X#define MAXATT 9 /* too many attributes on relation create */ X#define INSBLK 10 /* insufficient disk blocks */ X#define SYNTAX 11 /* command syntax error */ X#define ATUNDF 12 /* attribute name undefined */ X#define ATAMBG 13 /* attribute name ambiguous */ X#define RLUNDF 14 /* relation name undefined */ X#define CDSIZE 15 /* boolean expression code too big */ X#define INPFNF 16 /* input file not found */ X#define OUTCRE 17 /* output file creation error */ X#define INDFNF 18 /* indirect command file not found */ X#define BADSET 19 /* bad set parameter */ X Xstruct attribute { X char at_name[ANSIZE]; /* attribute name */ X char at_type; /* attribute type */ X char at_size; /* attribute size in bytes */ X char at_scale; /* attribute scale factor (for numeric only) */ X char at_unused[ASIZE-ANSIZE-3]; /* unused space */ X}; X Xstruct header { /* sizeof(struct header) must be 512 bytes */ X char hd_tcnt[2]; /* # of tuples in relation */ X char hd_tmax[2]; /* maximum # of tuples */ X char hd_data[2]; /* offset to first data byte */ X char hd_size[2]; /* size of each tuple in bytes */ X char hd_unused[HSIZE-8]; /* unused space */ X struct attribute hd_attrs[NATTRS]; /* table of attributes */ X}; X Xstruct relation { X char rl_name[RNSIZE]; /* relation name */ X unsigned int rl_tcnt; /* # of tuples in relation (from hd_tcnt) */ X unsigned int rl_tmax; /* maximum # of tuples (from hd_tmax) */ X int rl_data; /* offset to first data byte (from hd_data) */ X int rl_size; /* size of eachtuple in bytes (from hd_size) */ X int rl_store; /* flag indicating a store happened */ X int rl_fd; /* file descriptor for relation file */ X int rl_scnref; /* number of scans referencing this relation */ X struct header rl_header; /* the relation file header block */ X struct relation *rl_next; /* pointer to next relation */ X}; X Xstruct scan { X struct relation *sc_relation; /* pointer to relation definition */ X unsigned int sc_dtnum; /* desired tuple number */ X unsigned int sc_atnum; /* actual tuple number */ X int sc_store; /* flag indicating a store happened */ X char *sc_tuple; /* tuple buffer */ X}; X Xstruct srel { X char *sr_name; /* alternate relation name */ X struct scan *sr_scan; /* relation scan structure ptr */ X int sr_ctuple; /* current tuple flag */ X int sr_update; /* updated tuple flag */ X struct srel *sr_next; /* next selected relation in list */ X}; X Xstruct sattr { X char *sa_rname; /* relation name */ X char *sa_aname; /* attribute name */ X char *sa_name; /* alternate attribute name */ X char *sa_aptr; /* pointer to attr in tuple buffer */ X struct srel *sa_srel; /* pointer to the selected relation */ X struct attribute *sa_attr; /* attribute structure ptr */ X struct sattr *sa_next; /* next selected attribute in list */ X}; X Xstruct operand { X int o_type; X union { X struct { X int ovc_type; X char *ovc_string; X int ovc_length; X } ov_char; X int ov_boolean; X } o_value; X}; X Xunion codecell { X int (*c_operator)(); X struct operand *c_operand; X}; X Xstruct binding { X struct attribute *bd_attr; /* bound attribute */ X char *bd_vtuple; /* pointer to value in tuple */ X char *bd_vuser; /* pointer to user buffer */ X struct binding *bd_next; /* next binding */ X}; X Xstruct sel { X struct srel *sl_rels; /* selected relations */ X struct sattr *sl_attrs; /* selected attributes */ X union codecell *sl_where; /* where clause */ X struct binding *sl_bindings; /* user variable bindings */ X}; X Xstruct mtext { X char *mt_text; X struct mtext *mt_next; X}; X Xstruct macro { X char *mc_name; X struct mtext *mc_mtext; X struct macro *mc_next; X}; X Xstruct ifile { X char *if_fp; X struct mtext *if_mtext; X char *if_cmdline; X int if_savech; X char *if_lptr; X struct ifile *if_next; X}; X Xstruct skey { X int sk_type; X struct attribute *sk_aptr; X int sk_start; X struct skey *sk_next; X}; X SHAR_EOF if test 7764 -ne "`wc -c 'sdbio.h'`" then echo shar: error transmitting "'sdbio.h'" '(should have been 7764 characters)' fi # End of shell archive exit 0 -- Usenet: [decvax|allegra|linus|ihnp4]!utzoo!yetti!oz Bitnet: oz@[yusol|yuyetti] You see things; and you say "WHY?" But I dream things that never were; and say "WHY NOT?" G. Bernard Shaw (Back to Methuselah)