a small dbms (reposting sources) 1 of 3

Ozan Yigit oz at yetti.UUCP
Tue Sep 3 06:39:12 AEST 1985


I apologize. The second part of the previous posting was way too
big for some sites. It got chopped off. Here is a reposting of
all C sources, in three little parts. Some have inquired for the
source for the formatted documentation. Unfortunately, it was missing
from the decus tape. Also, you will notice that there is no man page,
nor a makefile.

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
# This archive created: Mon Sep  2 16:30:16 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 <fname>" */
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 <fname>" */
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,"<error>");
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        <expr>          ::= <lor> <EOS>
X        <lor>           ::= <land> { '|' <land> }
X        <land>          ::= <relat> { '&' <relat> }
X        <relat>         ::= <primary> { <relop> <primary> }
X        <primary>       ::= <factor> | <unop> <unary>
X        <factor>        ::= <number> | <string> | '(' <query> ')'
X        <number>        ::= <digit> | <number> <digit>
X        <string>        ::= '"' <chars> '"'
X        <chars>         ::= nil | <chars> <character>
X        <relop>         ::= '=' | '<>' | '<' | '>' | '<=' | '>='
X        <unop>          ::= '+' | '-' | '~'
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 "<filename> into <relation-name>" */
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 "<relation-name> [ into <filename> ]" */
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 "<relation-name>" */
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 "<relation-name> [ into <filename> ]" */
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 = "<error>";
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
#	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)



More information about the Comp.sources.unix mailing list