Thread View: mod.amiga.sources
1 messages
1 total messages
Started by doc
Fri, 22 Aug 1986 22:46
sdb Database (2 of 3)
Author: doc
Date: Fri, 22 Aug 1986 22:46
Date: Fri, 22 Aug 1986 22:46
2129 lines
52837 bytes
52837 bytes
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# int.c
# io.c
# scn.c
# cmd.c
# This archive created: Fri Aug 22 17:39:48 1986
# By: Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > int.c
/* SDB - boolean expression evaluator */
#include "sdbio.h"
static struct operand *stack[STACKMAX],**sptr;
static union codecell *cptr;
/* db_interpret - interpret a boolean expression */
int db_interpret(slptr)
struct sel *slptr;
{
struct operand *result;
int r;
/* check for empty where clause */
if ((cptr = slptr->sl_where) == NULL)
return (TRUE);
/* setup stack */
sptr = stack;
/* execute the code */
while ((*(*cptr++).c_operator)())
;
/* get the result from the top of stack */
result = *--sptr;
r = result->o_value.ov_boolean;
if (result->o_type == TEMP)
free(result);
/* make sure the stack is empty */
while (sptr != stack) {
if ((*sptr)->o_type == TEMP)
free(*sptr);
sptr -= 1;
}
/* return result */
return (r);
}
int db_xstop()
{
return (FALSE);
}
int db_xpush()
{
*sptr++ = (*cptr++).c_operand;
}
int db_xand()
{
return (boolean('&'));
}
int db_xor()
{
return (boolean('|'));
}
static int boolean(opr)
{
struct operand *lval,*rval,*result;
int lv,rv,r;
rval = *--sptr; lval = *--sptr;
lv = lval->o_value.ov_boolean;
rv = rval->o_value.ov_boolean;
if ((result = malloc(sizeof(struct operand))) == NULL)
return (db_ferror(INSMEM));
result->o_type = TEMP;
switch (opr) {
case '&': r = (lv && rv);
break;
case '|': r = (lv || rv);
break;
}
result->o_value.ov_boolean = r;
*sptr++ = result;
if (lval->o_type == TEMP)
free(lval);
if (rval->o_type == TEMP)
free(rval);
return (TRUE);
}
int db_xnot()
{
struct operand *val,*result;
val = *--sptr;
if ((result = malloc(sizeof(struct operand))) == NULL)
return (db_ferror(INSMEM));
result->o_type = TEMP;
result->o_value.ov_boolean = !val->o_value.ov_boolean;
*sptr++ = result;
if (val->o_type == TEMP)
free(val);
return (TRUE);
}
int db_xlss()
{
return (compare(LSS));
}
int db_xleq()
{
return (compare(LEQ));
}
int db_xeql()
{
return (compare(EQL));
}
int db_xgeq()
{
return (compare(GEQ));
}
int db_xgtr()
{
return (compare(GTR));
}
int db_xneq()
{
return (compare(NEQ));
}
static int compare(cmp)
{
struct operand *lval,*rval,*result;
int i;
rval = *--sptr; lval = *--sptr;
if ((result = malloc(sizeof(struct operand))) == NULL)
return (db_ferror(INSMEM));
result->o_type = TEMP;
if (lval->o_value.ov_char.ovc_type == TCHAR)
i = comp(lval,rval);
else
i = ncomp(lval,rval);
switch (cmp) {
case LSS: i = (i < 0);
break;
case LEQ: i = (i <= 0);
break;
case EQL: i = (i == 0);
break;
case GEQ: i = (i >= 0);
break;
case GTR: i = (i > 0);
break;
case NEQ: i = (i != 0);
break;
}
result->o_value.ov_boolean = i;
*sptr++ = result;
if (lval->o_type == TEMP)
free(lval);
if (rval->o_type == TEMP)
free(rval);
return (TRUE);
}
static int comp(lval,rval)
struct operand *lval,*rval;
{
char *lptr,*rptr; int lctr,rctr;
int len;
lptr = lval->o_value.ov_char.ovc_string;
lctr = lval->o_value.ov_char.ovc_length;
rptr = rval->o_value.ov_char.ovc_string;
rctr = rval->o_value.ov_char.ovc_length;
while (lctr > 0 && (lptr[lctr-1] == 0 || lptr[lctr-1] == ' '))
lctr--;
while (rctr > 0 && (rptr[rctr-1] == 0 || rptr[rctr-1] == ' '))
rctr--;
if (lctr < rctr)
len = lctr;
else
len = rctr;
while ((len--) > 0) {
if (*lptr++ != *rptr++)
if (*--lptr < *--rptr)
return (-1);
else
return (1);
}
if (lctr == rctr)
return (0);
else if (lctr < rctr)
return (-1);
else
return (1);
}
static int ncomp(lval,rval)
struct operand *lval,*rval;
{
char lstr[NUMBERMAX+1],rstr[NUMBERMAX+1];
int len;
strncpy(lstr,lval->o_value.ov_char.ovc_string,
(len = lval->o_value.ov_char.ovc_length)); lstr[len] = EOS;
strncpy(rstr,rval->o_value.ov_char.ovc_string,
(len = rval->o_value.ov_char.ovc_length)); rstr[len] = EOS;
return (db_cmp(lstr,rstr));
}
SHAR_EOF
cat << \SHAR_EOF > io.c
/* SDB - relation file I/O routines */
#include <stdio.h>
#include "sdbio.h"
/* global error code variable */
int dbv_errcode;
/* list of currently loaded relation definitions */
static struct relation *relations = NULL;
/* rfind - find the specified relation */
static struct relation *rfind(rname)
char *rname;
{
int fd;
char filename[RNSIZE+5];
struct relation *rptr;
/* look for relation in list currently loaded */
for (rptr = relations; rptr != NULL; rptr = rptr->rl_next)
if (db_sncmp(rname,rptr->rl_name,RNSIZE) == 0)
return (rptr);
/* create a file name */
make_fname(filename,rname);
/* lookup the relation file */
#ifdef Lattice
if ((fd = open(filename,0x8000)) == -1) /*dns*/
#else
if ((fd = open(filename,0)) == -1)
#endif
return (db_nerror(RELFNF));
/* allocate a new relation structure */
if ((rptr = malloc(sizeof(struct relation))) == NULL) {
close(fd);
return (db_nerror(INSMEM));
}
/* initialize the relation structure */
rptr->rl_scnref = 0;
/* read the header block */
if ( read(fd,&rptr->rl_header,512) != 512) {
free(rptr);
close(fd);
return (db_nerror(BADHDR));
}
/* close the relation file */
close(fd);
/* extract header information */
rptr->rl_tcnt = db_cvword(rptr->rl_header.hd_tcnt);
rptr->rl_tmax = db_cvword(rptr->rl_header.hd_tmax);
rptr->rl_data = db_cvword(rptr->rl_header.hd_data);
rptr->rl_size = db_cvword(rptr->rl_header.hd_size);
/* store the relation name */
strncpy(rptr->rl_name,rname,RNSIZE);
/* link new relation into relation list */
rptr->rl_next = relations;
relations = rptr;
/* return the new relation structure pointer */
return (rptr);
}
/* db_ropen - open a relation file */
struct scan *db_ropen(rname)
char *rname;
{
struct relation *rptr;
struct scan *sptr;
char filename[RNSIZE+5];
/* find the relation definition */
if ((rptr = rfind(rname)) == NULL)
return (NULL);
/* allocate a new scan structure */
if ((sptr = malloc(sizeof(struct scan))) == NULL)
return (db_nerror(INSMEM));
/* allocate a tuple buffer */
if ((sptr->sc_tuple = malloc(rptr->rl_size)) == NULL) {
free(sptr);
return (db_nerror(INSMEM));
}
/* initialize the scan structure */
sptr->sc_relation = rptr; /* store the relation struct addrs */
sptr->sc_dtnum = 0; /* desired tuple (non-existant) */
sptr->sc_atnum = 0; /* actual tuple (non-existant) */
sptr->sc_store = FALSE; /* no store done since open */
/* open relation file if necessary */
if (rptr->rl_scnref++ == 0) {
/* create the relation file name */
make_fname(filename,rname);
/* open the relation file */
#ifdef Lattice
if ((rptr->rl_fd = open(filename,0x8002)) == -1) { /*dns*/
#else
if ((rptr->rl_fd = open(filename,2)) == -1) {
#endif
rptr->rl_scnref--;
free(sptr->sc_tuple); free(sptr);
return (db_nerror(RELFNF));
}
}
/* return the new scan structure pointer */
return (sptr);
}
/* db_rclose - close the relation file */
int db_rclose(sptr)
struct scan *sptr;
{
struct relation *rptr,*lastrptr;
/* close relation file if this is the last reference */
if (--sptr->sc_relation->rl_scnref == 0) {
/* rewrite header if any stores took place */
if (sptr->sc_store) {
/* store the tuple count back in the header */
db_cvbytes(sptr->sc_relation->rl_tcnt,
sptr->sc_relation->rl_header.hd_tcnt);
/* write the header block */
lseek(sptr->sc_relation->rl_fd,0L,0);
if (write(sptr->sc_relation->rl_fd,
&sptr->sc_relation->rl_header,512) != 512) {
close(sptr->sc_relation->rl_fd);
free(sptr->sc_tuple); free(sptr);
return (db_ferror(BADHDR));
}
}
/* close the relation file */
close(sptr->sc_relation->rl_fd);
/* free the relation header */
lastrptr = NULL;
for (rptr = relations; rptr != NULL; rptr = rptr->rl_next) {
if (rptr == sptr->sc_relation) {
if (lastrptr == NULL)
relations = rptr->rl_next;
else
lastrptr->rl_next = rptr->rl_next;
}
lastrptr = rptr;
}
free(sptr->sc_relation);
}
/* free the scan structure */
free(sptr->sc_tuple); free(sptr);
/* return successfully */
return (TRUE);
}
/* db_rcompress - compress a relation file */
int db_rcompress(sptr)
struct scan *sptr;
{
unsigned int next,nextfree,tcnt;
/* get the last used tuple */
tcnt = sptr->sc_relation->rl_tcnt;
/* loop through all of the tuples */
for (next = nextfree = 1; next <= tcnt; next++) {
/* read the tuple */
seek(sptr,next);
if (read(sptr->sc_relation->rl_fd,
sptr->sc_tuple,sptr->sc_relation->rl_size)
!= sptr->sc_relation->rl_size)
return (db_ferror(TUPINP));
/* rewrite the tuple if it is active */
if (sptr->sc_tuple[0] == ACTIVE) {
/* rewrite it only if it must move */
if (next != nextfree) {
/* write the tuple */
seek(sptr,nextfree);
if (write(sptr->sc_relation->rl_fd,
sptr->sc_tuple,sptr->sc_relation->rl_size)
!= sptr->sc_relation->rl_size)
return (db_ferror(TUPOUT));
}
/* update the next free tuple number */
nextfree += 1;
}
}
/* update the tuple count */
sptr->sc_relation->rl_tcnt = nextfree - 1;
/* remember which tuple is in the buffer */
sptr->sc_atnum = sptr->sc_relation->rl_tcnt;
/* reset the desired tuple */
sptr->sc_dtnum = 0;
/* remember that the index needs rewriting */
sptr->sc_store = TRUE;
/* return successfully */
return (TRUE);
}
/* db_rbegin - begin scan at first tuple in relation */
db_rbegin(sptr)
struct scan *sptr;
{
/* begin with the first tuple in the file */
sptr->sc_dtnum = 0;
}
/* db_rfetch - fetch the next tuple from the relation file */
int db_rfetch(sptr)
struct scan *sptr;
{
/* look for an active tuple */
while (TRUE) {
/* check for this being the last tuple */
if (!db_rget(sptr,sptr->sc_dtnum + 1))
return (FALSE);
/* increment the tuple number */
sptr->sc_dtnum += 1;
/* return if the tuple found is active */
if (sptr->sc_tuple[0] == ACTIVE)
return (TRUE);
}
}
/* db_rupdate - update the current tuple */
int db_rupdate(sptr)
struct scan *sptr;
{
/* make sure the status byte indicates an active tuple */
sptr->sc_tuple[0] = ACTIVE;
/* write the tuple */
return (db_rput(sptr,sptr->sc_atnum));
}
/* db_rdelete - delete the current tuple */
int db_rdelete(sptr)
struct scan *sptr;
{
/* make sure the status byte indicates a deleted tuple */
sptr->sc_tuple[0] = DELETED;
/* write the tuple */
return (db_rput(sptr,sptr->sc_atnum));
}
/* db_rstore - store a new tuple */
int db_rstore(sptr)
struct scan *sptr;
{
/* make sure there's room for this tuple */
if (sptr->sc_relation->rl_tcnt == sptr->sc_relation->rl_tmax)
return (db_ferror(RELFUL));
/* make sure the status byte indicates an active tuple */
sptr->sc_tuple[0] = ACTIVE;
/* write the tuple */
if (!db_rput(sptr,sptr->sc_relation->rl_tcnt + 1))
return (FALSE);
/* update the tuple count */
sptr->sc_relation->rl_tcnt += 1;
/* remember that a tuple was stored */
sptr->sc_store = TRUE;
/* return successfully */
return (TRUE);
}
/* db_rget - get a tuple from the relation file */
int db_rget(sptr,tnum)
struct scan *sptr; unsigned int tnum;
{
/* check to see if the tuple is already in the buffer */
if (tnum == sptr->sc_atnum)
return (TRUE);
/* check for this being beyond the last tuple */
if (tnum > sptr->sc_relation->rl_tcnt)
return (db_ferror(TUPINP));
/* read the tuple */
seek(sptr,tnum);
if (read(sptr->sc_relation->rl_fd,
sptr->sc_tuple,sptr->sc_relation->rl_size)
!= sptr->sc_relation->rl_size)
return (db_ferror(TUPINP));
/* remember which tuple is in the buffer */
sptr->sc_atnum = tnum;
/* return successfully */
return (TRUE);
}
/* db_rput - put a tuple to a relation file */
int db_rput(sptr,tnum)
struct scan *sptr; unsigned int tnum;
{
/* check for this being beyond the maximum tuple */
if (tnum > sptr->sc_relation->rl_tmax)
return (db_ferror(TUPOUT));
/* write the tuple */
seek(sptr,tnum);
if (write(sptr->sc_relation->rl_fd,
sptr->sc_tuple,sptr->sc_relation->rl_size)
!= sptr->sc_relation->rl_size)
return (db_ferror(TUPOUT));
/* remember which tuple is in the buffer */
sptr->sc_atnum = tnum;
/* return successfully */
return (TRUE);
}
/* seek - seek a tuple in a relation file */
static seek(sptr,tnum)
struct scan *sptr; unsigned int tnum;
{
long offset;
offset = (long) sptr->sc_relation->rl_data +
((long) (tnum - 1) * (long) sptr->sc_relation->rl_size);
lseek(sptr->sc_relation->rl_fd,offset,0);
}
/* make_fname - make a relation name into a file name */
static make_fname(fname,rname)
char *fname,*rname;
{
strncpy(fname,rname,RNSIZE); fname[RNSIZE] = 0;
strcat(fname,".sdb");
}
/* db_nerror - store the error code and return NULL */
int db_nerror(errcode)
int errcode;
{
dbv_errcode = errcode;
return (NULL);
}
/* db_ferror - store the error code and return FALSE */
int db_ferror(errcode)
int errcode;
{
dbv_errcode = errcode;
return (FALSE);
}
/* db_cvword - convert 2 bytes to a word */
int db_cvword(bytes)
char bytes[2];
{
return (((bytes[1] & 0377) << 8) + (bytes[0] & 0377));
}
/* db_cvbytes - convert a word to 2 bytes */
db_cvbytes(word,bytes)
int word; char bytes[2];
{
bytes[0] = word;
bytes[1] = word >> 8;
}
SHAR_EOF
cat << \SHAR_EOF > scn.c
/* SDB - token scanning routines */
#include <stdio.h>
#include "sdbio.h"
int dbv_token; /* current token */
int dbv_tvalue; /* integer token value */
char dbv_tstring[STRINGMAX+1]; /* string token value */
struct ifile *dbv_ifp; /* indirect file context */
struct macro *dbv_macros; /* macro definitions */
int dbv_fold; /* case fold alpha comparisons */
static char *iprompt,*cprompt; /* input prompts */
static char cmdline[LINEMAX+2],*lptr; /* current line and pointer */
static int atbol; /* flag indicating at bol */
static int savech; /* lookahead character */
static int savetkn; /* lookahead token */
static char *keywords[] = { /* keyword table */
"ascending",
"by",
"char",
"compress",
"create",
"define",
"delete",
"descending",
"exit",
"export",
"extract",
"from",
"help",
"insert",
"import",
"into",
"num",
"print",
"quit",
"select",
"set",
"show",
"sort",
"update",
"using",
"where",
NULL
};
static int keytokens[] = { /* token values for each keyword */
ASCENDING,
BY,
CHAR,
COMPRESS,
CREATE,
DEFINE,
DELETE,
DESCENDING,
EXIT,
EXPORT,
EXTRACT,
FROM,
HELP,
INSERT,
IMPORT,
INTO,
NUM,
PRINT,
EXIT,
SELECT,
SET,
SHOW,
SORT,
UPDATE,
USING,
WHERE,
NULL
};
/* db_sinit - initialize the scanner */
db_sinit()
{
/* at beginning of line */
atbol = TRUE;
/* make the command line null */
lptr = NULL;
/* no lookahead yet */
savech = EOS;
savetkn = NULL;
/* no indirect command files */
dbv_ifp = NULL;
/* no macros defined */
dbv_macros = NULL;
/* fold alpha comparisons */
dbv_fold = TRUE;
}
/* db_prompt(ip,cp) - initialize prompt strings */
db_prompt(ip,cp)
char *ip,*cp;
{
/* save initial and continuation prompt strings */
iprompt = ip;
cprompt = cp;
}
/* db_scan(fmt,args) - initiate line scan command parsing */
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
{
/* convert the command line and arguments */
sprintf(cmdline,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
/* start at the beginning of the command line */
lptr = cmdline;
iprompt = NULL;
dbv_ifp = NULL;
/* no lookahead yet */
savech = EOS;
savetkn = NULL;
/* fold alpha comparisons */
dbv_fold = TRUE;
}
/* db_flush - flush the current input line */
int db_flush()
{
while (savech != '\n')
if (savech > ' ')
return (db_ferror(SYNTAX));
else
savech = getchx();
savech = EOS;
atbol = TRUE;
return (TRUE);
}
/* db_gline - get a line from the current input */
char *db_gline(buf)
char *buf;
{
int ch,i;
for (i = 0; (ch = getch()) != '\n' && ch != -1; )
if (i < LINEMAX)
buf[i++] = ch;
else {
printf("*** line too long ***\nRetype> ");
i = 0;
}
buf[i] = EOS;
return (buf);
}
/* db_ifile - setup an indirect command file */
int db_ifile(fname)
char *fname;
{
struct ifile *new_ifp;
if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
return (db_ferror(INSMEM));
else if ((new_ifp->if_fp = fopen(fname,"r")) == NULL) {
free(new_ifp);
return (db_ferror(INDFNF));
}
new_ifp->if_mtext = NULL;
new_ifp->if_savech = savech;
new_ifp->if_lptr = lptr;
new_ifp->if_next = dbv_ifp;
dbv_ifp = new_ifp;
/* return successfully */
return (TRUE);
}
/* db_kill - kill indirect command file input */
db_kill()
{
struct ifile *old_ifp;
while ((old_ifp = dbv_ifp) != NULL) {
dbv_ifp = old_ifp->if_next;
if (old_ifp->if_fp != NULL)
fclose(old_ifp->if_fp);
savech = old_ifp->if_savech;
lptr = old_ifp->if_lptr;
free(old_ifp);
}
while (savech != '\n')
savech = getchx();
savech = EOS;
savetkn = NULL;
atbol = TRUE;
}
/* db_token - return the current input token */
int db_token()
{
struct macro *mptr;
struct ifile *new_ifp;
/* find a token that's not a macro call */
while (db_xtoken() == ID) {
/* check for a macro call */
for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
if (db_scmp(dbv_tstring,mptr->mc_name) == 0) {
if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
printf("*** error expanding macro: %s ***\n",dbv_tstring);
else {
new_ifp->if_fp = NULL;
new_ifp->if_mtext = mptr->mc_mtext->mt_next;
new_ifp->if_lptr = lptr; lptr = mptr->mc_mtext->mt_text;
new_ifp->if_savech = savech; savech = EOS;
new_ifp->if_next = dbv_ifp;
dbv_ifp = new_ifp;
}
savetkn = NULL;
break;
}
if (mptr == NULL)
break;
}
return (dbv_token);
}
/* db_xtoken - return the current input token */
int db_xtoken()
{
int ch;
/* check for a saved token */
if ((dbv_token = savetkn) != NULL)
return (dbv_token);
/* get the next non-blank character */
ch = nextch();
/* check type of character */
if (isalpha(ch)) /* identifier or keyword */
get_id();
else if (isdigit(ch)) /* number */
get_number();
else if (ch == '"') /* string */
get_string();
else if (get_rel()) /* relational operator */
;
else /* single character token */
dbv_token = getch();
/* save the lookahead token */
savetkn = dbv_token;
/* return the token */
return (dbv_token);
}
/* db_ntoken - get next token (after skipping the current one) */
int db_ntoken()
{
/* get the current token */
db_token();
/* make sure another is read on next call */
savetkn = NULL;
/* return the current token */
return (dbv_token);
}
/* db_xntoken - get next token (after skipping the current one) */
int db_xntoken()
{
/* get the current token */
db_xtoken();
/* make sure another is read on next call */
savetkn = NULL;
/* return the current token */
return (dbv_token);
}
/* db_scmp - compare two strings */
int db_scmp(str1,str2)
char *str1,*str2;
{
if (dbv_fold)
return (scmp(str1,str2));
else
return (strcmp(str1,str2));
}
/* db_sncmp - compare two strings with a maximum length */
int db_sncmp(str1,str2,len)
char *str1,*str2; int len;
{
if (dbv_fold)
return (sncmp(str1,str2,len));
else
return (strncmp(str1,str2,len));
}
/* scmp - compare two strings with alpha case folding */
static int scmp(str1,str2)
char *str1,*str2;
{
int ch1,ch2;
/* compare each character */
while (*str1 && *str2) {
/* fold the character from the first string */
if (isupper(*str1))
ch1 = tolower(*str1++);
else
ch1 = *str1++;
/* fold the character from the second string */
if (isupper(*str2))
ch2 = tolower(*str2++);
else
ch2 = *str2++;
/* compare the characters */
if (ch1 != ch2)
if (ch1 < ch2)
return (-1);
else
return (1);
}
/* check for strings of different lengths */
if (*str1 == *str2)
return (0);
else if (*str1 == 0)
return (-1);
else
return (1);
}
/* sncmp - compare two strings with alpha case folding and a maximum length */
static int sncmp(str1,str2,len)
char *str1,*str2; int len;
{
int ch1,ch2;
/* compare each character */
while (*str1 && *str2 && len > 0) {
/* fold the character from the first string */
if (isupper(*str1))
ch1 = tolower(*str1++);
else
ch1 = *str1++;
/* fold the character from the second string */
if (isupper(*str2))
ch2 = tolower(*str2++);
else
ch2 = *str2++;
/* compare the characters */
if (ch1 != ch2)
if (ch1 < ch2)
return (-1);
else
return (1);
/* decrement the string length */
len--;
}
/* check for strings of different lengths */
if (len == 0 || *str1 == *str2)
return (0);
else if (*str1 == 0)
return (-1);
else
return (1);
}
/* get_id - get a keyword or a user identifier */
static get_id()
{
int ch,nchars,i;
/* input letters and digits */
ch = nextch();
nchars = 0;
while (isalpha(ch) || isdigit(ch)) {
if (nchars < KEYWORDMAX)
dbv_tstring[nchars++] = ch;
getch(); ch = thisch();
}
/* terminate the keyword */
dbv_tstring[nchars] = EOS;
/* assume its an identifier */
dbv_token = ID;
/* check for keywords */
for (i = 0; keywords[i] != NULL; i++)
if (db_scmp(dbv_tstring,keywords[i]) == 0)
dbv_token = keytokens[i];
}
/* get_number - get a number */
static get_number()
{
int ch,ndigits,nodot;
/* read digits and at most one decimal point */
ch = nextch();
ndigits = 0; nodot = TRUE;
while (isdigit(ch) || (nodot && ch == '.')) {
if (ch == '.')
nodot = FALSE;
if (ndigits < NUMBERMAX)
dbv_tstring[ndigits++] = ch;
getch(); ch = thisch();
}
/* terminate the number */
dbv_tstring[ndigits] = EOS;
/* get the value of the number */
sscanf(dbv_tstring,"%d",&dbv_tvalue);
/* token is a number */
dbv_token = NUMBER;
}
/* get_string - get a string */
static get_string()
{
int ch,nchars;
/* skip the opening quote */
getch();
/* read characters until a closing quote is found */
ch = thisch();
nchars = 0;
while (ch && ch != '"') {
if (nchars < STRINGMAX)
dbv_tstring[nchars++] = ch;
getch(); ch = thisch();
}
/* terminate the string */
dbv_tstring[nchars] = EOS;
/* skip the closing quote */
getch();
/* token is a string */
dbv_token = STRING;
}
/* get_rel - get a relational operator */
static int get_rel()
{
int ch;
switch (ch = nextch()) {
case '=':
getch();
dbv_token = EQL;
return (TRUE);;
case '<':
getch(); ch = nextch();
if (ch == '>') {
getch();
dbv_token = NEQ;
}
else if (ch == '=') {
getch();
dbv_token = LEQ;
}
else
dbv_token = LSS;
return (TRUE);;
case '>':
getch(); ch = nextch();
if (ch == '=') {
getch();
dbv_token = GEQ;
}
else
dbv_token = GTR;
return (TRUE);;
default:
return (FALSE);
}
}
/* getch - get the next character */
static int getch()
{
char fname[STRINGMAX+1];
int ch,i;
/* return the lookahead character if there is one */
if (savech != EOS) {
ch = savech;
savech = EOS;
return (ch);
}
/* get a character */
ch = getchx();
/* skip spaces at the beginning of a command */
if (atbol && iprompt != NULL)
while (ch <= ' ')
ch = getchx();
/* use continuation prompt next time */
iprompt = NULL;
/* check for indirect command file */
while (ch == '@') {
for (i = 0; (savech = getchx()) > ' '; )
if (i < STRINGMAX)
fname[i++] = savech;
fname[i] = 0;
if (db_ifile(fname) != TRUE)
printf("*** error opening command file: %s ***\n",fname);
ch = getchx();
}
/* return the character */
return (ch);
}
/* getchx - get the next character */
static int getchx()
{
struct ifile *old_ifp;
int ch;
/* check for input from buffer */
if (lptr != NULL) {
while (*lptr == EOS)
if (dbv_ifp != NULL)
if (dbv_ifp->if_mtext == NULL) {
old_ifp = dbv_ifp;
ch = dbv_ifp->if_savech; savech = EOS;
lptr = dbv_ifp->if_lptr;
dbv_ifp = dbv_ifp->if_next;
free(old_ifp);
if (ch != EOS)
return (ch);
if (lptr == NULL)
break;
}
else {
lptr = dbv_ifp->if_mtext->mt_text;
dbv_ifp->if_mtext = dbv_ifp->if_mtext->mt_next;
}
else
return (EOS);
if (lptr != NULL)
return (*lptr++);
}
/* print prompt if necessary */
if (atbol && dbv_ifp == NULL) { /*dns*/
if (iprompt != NULL)
printf("%s",iprompt);
else if (cprompt != NULL)
printf("%s",cprompt);
#ifdef Lattice
fflush(stdout); /*dns*/
#endif
} /*dns*/
if (dbv_ifp == NULL)
if ((ch = getcx(stdin)) == '\n')
atbol = TRUE;
else
atbol = FALSE;
else {
if ((ch = getcx(dbv_ifp->if_fp)) == -1) {
old_ifp = dbv_ifp;
ch = dbv_ifp->if_savech; savech = EOS;
lptr = dbv_ifp->if_lptr;
dbv_ifp = dbv_ifp->if_next;
fclose(old_ifp->if_fp);
free(old_ifp);
}
}
/* return the character */
return (ch);
}
/* thisch - get the current character */
static int thisch()
{
/* get a lookahead character */
if (savech == EOS)
savech = getch();
/* return lookahead character */
return (savech);
}
/* nextch - get the next non-blank character */
static int nextch()
{
int ch;
/* skip blank characters */
while ((ch = thisch()) <= ' ' && ch != EOS)
getch();
/* return the first non-blank */
return (ch);
}
SHAR_EOF
cat << \SHAR_EOF > cmd.c
/* SDB - command parser */
#include <stdio.h>
#include "sdbio.h"
extern int dbv_token;
extern char dbv_tstring[];
extern int dbv_tvalue;
extern struct ifile *dbv_ifp;
extern struct macro *dbv_macros;
extern int dbv_fold;
#ifdef Lattice
int _fmode = 0; /*dns*/
#endif
/* db_parse - parse a command */
int db_parse(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9)
char *fmt;
{
int sts;
/* check for a command line */
if (fmt != NULL)
db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9);
/* determine the statement type */
switch (db_ntoken()) {
case ';': sts = TRUE;
break;
case COMPRESS:
sts = db_squeeze(NULL);
break;
case CREATE:
sts = create();
break;
case DEFINE:
sts = mc_define();
break;
case DELETE:
sts = delete();
break;
case EXIT:
exit();
case EXPORT:
sts = db_export(NULL);
break;
case EXTRACT:
sts = db_extract(NULL);
break;
case HELP:
sts = help();
break;
case IMPORT:
sts = db_import(NULL);
break;
case INSERT:
sts = insert();
break;
case PRINT:
sts = print();
break;
case SELECT:
sts = select();
break;
case SET:
sts = set();
break;
case SHOW:
sts = mc_show();
break;
case SORT:
sts = db_sort(NULL);
break;
case UPDATE:
sts = update();
break;
default:
return (db_ferror(SYNTAX));
}
return (sts);
}
/* help - print a short help message */
static int help()
{
FILE *fp;
int ch;
if ((fp = fopen("sdb.hlp","r")) != NULL) {
/* while ((ch = agetc(fp)) != EOF) dns */
while ((ch = getc(fp)) != EOF)
putchar(ch);
fclose(fp);
}
else
printf("No online help available. Read the manual\n");
/* return successfully */
return (TRUE);
}
/* create - create a new relation */
static int create()
{
struct relation *rptr;
char aname[STRINGMAX+1];
int atype;
/* get relation name */
if (db_ntoken() != ID)
return (db_ferror(SYNTAX));
/* start relation creation */
if ((rptr = db_rcreate(dbv_tstring)) == NULL)
return (FALSE);
/* check for attribute list */
if (db_ntoken() != '(') {
free(rptr);
return (db_ferror(SYNTAX));
}
/* parse the attributes */
while (TRUE) {
/* get the attribute name */
if (db_ntoken() != ID) {
free(rptr);
return (db_ferror(SYNTAX));
}
strcpy(aname,dbv_tstring);
/* get the attribute type */
db_ntoken();
if (dbv_token == CHAR)
atype = TCHAR;
else if (dbv_token == NUM)
atype = TNUM;
else {
free(rptr);
return (db_ferror(SYNTAX));
}
/* get the attribute size */
if (db_ntoken() != NUMBER) {
free(rptr);
return (db_ferror(SYNTAX));
}
/* add the attribute */
if (!db_rcattr(rptr,aname,atype,dbv_tvalue)) {
free(rptr);
return (FALSE);
}
/* check for end of attributes */
if (db_token() != ID)
break;
}
/* check for attribute list end */
if (db_ntoken() != ')') {
free(rptr);
return (db_ferror(SYNTAX));
}
/* check for relation size */
if (db_ntoken() != NUMBER) {
free(rptr);
return (db_ferror(SYNTAX));
}
/* finish relation creation */
if (!db_rcheader(rptr))
return (FALSE);
if (!db_rctuples(rptr,dbv_tvalue))
return (FALSE);
if (!db_rcdone(rptr))
return (FALSE);
/* return successfully */
return (TRUE);
}
/* insert - insert a tuple into a relation */
static int insert()
{
struct scan *sptr;
struct attribute *aptr;
char aname[ANSIZE+1],avalue[STRINGMAX+1];
int tcnt,astart,i;
/* get relation name */
if (db_token() == ID)
db_ntoken();
else
strcpy(dbv_tstring,"sdbcur");
/* make sure that the rest of the line is blank */
if (!db_flush())
return (FALSE);
/* open the relation */
if ((sptr = db_ropen(dbv_tstring)) == NULL)
return (FALSE);
/* insert tuples */
for (tcnt = 0; ; tcnt++) {
/* print separator if not the first tuple */
if (tcnt != 0)
printf("----\n");
/* get attribute values */
astart = 1;
for (i = 0; i < NATTRS; i++) {
/* get a pointer to the current attribute */
aptr = &sptr->sc_relation->rl_header.hd_attrs[i];
/* check for the last attribute */
if (aptr->at_name[0] == 0)
break;
/* get the attribute name */
strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0;
/* setup null prompt strings */
db_prompt(NULL,NULL);
/* prompt and input attribute value */
while (TRUE) {
if (dbv_ifp == NULL)
if (strlen(aname) < 8)
printf("%s\t\t: ",aname);
else
printf("%s\t: ",aname);
if (db_gline(avalue) != NULL)
break;
}
/* check for last insert */
if (i == 0 && avalue[0] == EOS)
break;
/* store the attribute value */
db_aput(aptr,&sptr->sc_tuple[astart],avalue);
/* update the attribute start */
astart += aptr->at_size;
}
/* check for last insert */
if (avalue[0] == EOS)
break;
/* store the new tuple */
if (!db_rstore(sptr)) {
db_rclose(sptr);
return (FALSE);
}
}
/* close the relation */
db_rclose(sptr);
/* check number of tuples inserted */
if (tcnt != 0) {
/* print tuple count */
printf("[ %d inserted ]\n",tcnt);
}
else
printf("[ none inserted ]\n");
/* return successfully */
return (TRUE);
}
/* delete - delete tuples from a relation */
static int delete()
{
struct sel *slptr;
struct srel *srptr;
int tcnt;
/* parse the retrieval clause */
if ((slptr = db_retrieve(NULL)) == NULL)
return (FALSE);
/* loop through the retrieved tuples */
for (tcnt = 0; db_fetch(slptr); tcnt++)
/* delete the retrieved tuples */
for (srptr = slptr->sl_rels; srptr != NULL; srptr = srptr->sr_next)
if (!db_rdelete(srptr->sr_scan)) {
db_done(slptr);
return (FALSE);
}
/* finish the retrieval */
db_done(slptr);
/* check number of tuples deleted */
if (tcnt != 0) {
/* print tuple count */
printf("[ %d deleted ]\n",tcnt);
}
else
printf("[ none deleted ]\n");
/* return successfully */
return (TRUE);
}
/* update - update tuples from a relation */
static int update()
{
struct sel *slptr;
struct sattr *saptr;
struct attribute *aptr;
char aname[ANSIZE+1],avalue[STRINGMAX+1],*ap;
int tcnt;
/* parse the selection clause */
if ((slptr = db_select(NULL)) == NULL)
return (FALSE);
/* make sure that the rest of the line is blank */
if (!db_flush()) {
db_done(slptr);
return (FALSE);
}
/* loop through the selected tuples */
for (tcnt = 0; db_fetch(slptr); tcnt++) {
/* print separator if not the first tuple */
if (tcnt != 0)
printf("----\n");
/* loop through the selected attributes */
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
/* get the attribute pointer */
aptr = saptr->sa_attr;
/* get the attribute name */
strncpy(aname,aptr->at_name,ANSIZE); aname[ANSIZE] = 0;
/* get the attribute value */
db_aget(aptr,saptr->sa_aptr,avalue);
for (ap = avalue; isspace(*ap); ap++)
;
/* print it */
if (strlen(aname) < 8)
printf("%s\t\t: %s\n",aname,ap);
else
printf("%s\t: %s\n",aname,ap);
/* setup null prompt strings */
db_prompt(NULL,NULL);
/* prompt and input attribute value */
while (TRUE) {
if (strlen(aname) < 8)
printf("%s\t\t: ",aname);
else
printf("%s\t: ",aname);
if (db_gline(avalue) != NULL)
break;
}
/* store the attribute value */
if (avalue[0] != EOS) {
db_aput(aptr,saptr->sa_aptr,avalue);
saptr->sa_srel->sr_update = TRUE;
}
}
/* update the tuples */
db_update(slptr);
}
/* finish the selection */
db_done(slptr);
/* check number of tuples updated */
if (tcnt != 0) {
/* print tuple count */
printf("[ %d updated ]\n",tcnt);
}
else
printf("[ none updated ]\n");
/* return successfully */
return (TRUE);
}
/* print - print tuples from a set of relations */
static int print()
{
struct sel *slptr;
FILE *ffp,*ofp;
int tcnt;
/* parse the using clause */
if (!using(&ffp,".frm"))
return (FALSE);
/* parse the select clause */
if ((slptr = db_select(NULL)) == NULL)
return (FALSE);
/* parse the into clause */
if (!db_to(&ofp,".txt")) {
db_done(slptr);
return (FALSE);
}
/* check for normal or formated output */
if (ffp == NULL)
tcnt = table(ofp,slptr);
else
tcnt = form(ofp,slptr,ffp);
/* finish the selection */
db_done(slptr);
/* close the form definition file */
if (ffp != NULL)
fclose(ffp);
/* close the output file */
if (ofp != stdout)
fclose(ofp);
/* check number of tuples selected */
if (tcnt != 0)
printf("[ %d found ]\n",tcnt);
else
printf("[ none found ]\n");
/* return successfully */
return (TRUE);
}
/* select - select tuples from a set of relations */
static int select()
{
struct sel *slptr;
struct relation *rptr;
struct sattr *saptr;
char *aname,*tbuf;
int tcnt,abase,i;
/* parse the select clause */
if ((slptr = db_select(NULL)) == NULL)
return (FALSE);
/* create a new relation */
if ((rptr = db_rcreate("sdbcur")) == NULL) {
db_done(slptr);
return (FALSE);
}
/* create the selected attributes */
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
/* decide which attribute name to use */
if ((aname = saptr->sa_name) == NULL)
aname = saptr->sa_aname;
/* add the attribute */
if (!db_rcattr(rptr,aname,saptr->sa_attr->at_type,
saptr->sa_attr->at_size)) {
free(rptr);
db_done(slptr);
return (FALSE);
}
}
/* create the relation header */
if (!db_rcheader(rptr)) {
db_done(slptr);
return (FALSE);
}
/* allocate and initialize a tuple buffer */
if ((tbuf = calloc(1,rptr->rl_size)) == NULL) {
db_rcdone(rptr);
return (db_ferror(INSMEM));
}
tbuf[0] = ACTIVE;
/* loop through the selected tuples */
for (tcnt = 0; db_fetch(slptr); tcnt++) {
/* create the tuple from the selected attributes */
abase = 1;
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
for (i = 0; i < saptr->sa_attr->at_size; i++)
tbuf[abase + i] = saptr->sa_aptr[i];
abase += i;
}
/* write the tuple */
if (write(rptr->rl_fd,tbuf,rptr->rl_size) != rptr->rl_size) {
db_rcdone(rptr);
free(tbuf);
return (db_ferror(INSBLK));
}
rptr->rl_tcnt++;
rptr->rl_tmax++;
}
/* finish the selection */
db_done(slptr);
/* finish relation creation */
if (!db_rcdone(rptr))
return (FALSE);
/* check number of tuples selected */
if (tcnt != 0)
printf("[ %d found ]\n",tcnt);
else
printf("[ none found ]\n");
/* return successfully */
return (TRUE);
}
/* mc_define - define a macro */
static int mc_define()
{
struct macro *mptr,*mlast;
struct mtext *tptr,*tlast;
char textline[LINEMAX+1];
/* get macro name */
if (db_xntoken() != ID)
return (db_ferror(SYNTAX));
/* make sure that the rest of the line is blank */
if (!db_flush())
return (FALSE);
/* find the macro in the macro table and free it */
for (mptr = dbv_macros, mlast = NULL; mptr != NULL; mlast = mptr, mptr = mptr->mc_next)
if (db_scmp(mptr->mc_name,dbv_tstring) == 0) {
if (mlast == NULL)
dbv_macros = mptr->mc_next;
else
mlast->mc_next = mptr->mc_next;
mc_free(mptr);
}
/* allocate and initialize a macro structure */
if ((mptr = malloc(sizeof(struct macro))) == NULL)
return (db_ferror(INSMEM));
if ((mptr->mc_name = malloc(strlen(dbv_tstring)+1)) == NULL) {
free(mptr);
return (db_ferror(INSMEM));
}
strcpy(mptr->mc_name,dbv_tstring);
mptr->mc_mtext = NULL;
/* setup null prompt strings */
db_prompt(NULL,"SDB-DEF> ");
/* get definition text */
for (tlast = NULL; ; tlast = tptr) {
/* get a line */
db_gline(textline);
if (textline[0] == EOS || textline[0] == '\n')
break;
/* allocate a macro text structure */
if ((tptr = malloc(sizeof(struct mtext))) == NULL) {
mc_free(mptr);
return (db_ferror(INSMEM));
}
if ((tptr->mt_text = malloc(strlen(textline)+1)) == NULL) {
mc_free(mptr);
return (db_ferror(INSMEM));
}
strcpy(tptr->mt_text,textline);
tptr->mt_next = NULL;
/* link it into the macro list */
if (tlast == NULL)
mptr->mc_mtext = tptr;
else
tlast->mt_next = tptr;
}
/* link the new macro into the macro list */
if (tlast == NULL)
mc_free(mptr);
else {
mptr->mc_next = dbv_macros;
dbv_macros = mptr;
}
/* return successfully */
return (TRUE);
}
/* mc_show - show a macro */
static int mc_show()
{
struct macro *mptr;
struct mtext *tptr;
/* get macro name */
if (db_xntoken() != ID)
return (db_ferror(SYNTAX));
/* find the macro in the macro table */
for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
if (db_scmp(mptr->mc_name,dbv_tstring) == 0) {
for (tptr = mptr->mc_mtext; tptr != NULL; tptr = tptr->mt_next)
printf("\t%s\n",tptr->mt_text);
break;
}
/* check for successful search */
if (mptr == NULL)
printf("*** no macro named: %s ***\n",dbv_tstring);
/* return successfully */
return (TRUE);
}
/* mc_free - free a macro definition */
static mc_free(mptr)
struct macro *mptr;
{
struct mtext *tptr;
while ((tptr = mptr->mc_mtext) != NULL) {
mptr->mc_mtext = tptr->mt_next;
free(tptr->mt_text);
free(tptr);
}
free(mptr->mc_name);
free(mptr);
}
/* db_to - redirect output into a file */
int db_to(pfp,ext)
FILE **pfp; char *ext;
{
#ifdef vms
int fd;
#endif
/* assume no into clause */
*pfp = stdout;
/* check for "into <fname>" */
if (db_token() != INTO)
return (TRUE);
db_ntoken();
if (db_ntoken() == ID)
strcat(dbv_tstring,ext);
else if (dbv_token != STRING)
return (db_ferror(SYNTAX));
/* open the output file */
#ifdef vms
if ((fd = creat(dbv_tstring,0,"rfm=var","rat=cr")) == -1)
return (db_ferror(OUTCRE));
*pfp = fdopen(fd,"w");
#else
#ifdef Lattice
_fmode = 0x8000; /*dns*/
#endif
*pfp = fopen(dbv_tstring,"w"); /*dns*/
#ifdef Lattice
_fmode = 0; /*dns*/
#endif
if (*pfp == NULL) /*dns*/
return (db_ferror(OUTCRE)); /*dns*/
#endif
/* return successfully */
return (TRUE);
}
/* using - get form definition file spec */
static int using(pfp,ext)
FILE **pfp; char *ext;
{
/* assume no using clause */
*pfp = NULL;
/* check for "using <fname>" */
if (db_token() != USING)
return (TRUE);
db_ntoken();
if (db_ntoken() == ID)
strcat(dbv_tstring,ext);
else if (dbv_token != STRING)
return (db_ferror(SYNTAX));
/* open the input file */
if ((*pfp = fopen(dbv_tstring,"r")) == NULL)
return (db_ferror(INPFNF));
/* return successfully */
return (TRUE);
}
/* table - output a relation table */
static int table(fp,slptr)
FILE *fp; struct sel *slptr;
{
int tcnt;
/* loop through the selected tuples */
for (tcnt = 0; db_fetch(slptr); tcnt++) {
/* print table head on first tuple selected */
if (tcnt == 0)
db_thead(fp,slptr);
/* print the tuple */
db_tentry(fp,slptr);
}
/* print table foot */
if (tcnt != 0)
db_tfoot(fp,slptr);
/* return the tuple count */
return (tcnt);
}
/* form - process a form */
static int form(ofp,slptr,ffp)
FILE *ofp; struct sel *slptr; FILE *ffp;
{
char aname[ANSIZE+1];
int ch,tcnt,pad;
/* loop through the selected tuples */
for (tcnt = 0; db_fetch(slptr); tcnt++) {
/* reposition the form definition file */
fseek(ffp,0L,0);
/* process the form */
while ((ch = getc(ffp)) != -1)
if (ch == '<') {
get_aname(ffp,aname,&pad);
put_avalue(ofp,slptr,aname,pad);
}
else
putc(ch,ofp);
}
/* return the tuple count */
return (tcnt);
}
/* get_aname - get an attribute name (and padding flag [mpk]) */
static get_aname(fp,aname,pad)
FILE *fp; char *aname; int *pad;
{
int ch;
if ((ch = getc(fp)) != '$') { /* mpk */
ungetc(ch,fp); /* put it back! */
*pad = 1;
}
else
*pad = 0;
while ((ch = getc(fp)) != '>')
if (!isspace(ch))
*aname++ = ch;
*aname = 0;
}
/* put_avalue - output attribute value */
static put_avalue(fp,slptr,aname,pad)
FILE *fp; struct sel *slptr; char *aname; int pad;
{
struct sattr *saptr;
char *saname;
int i;
/* loop through the selected attributes */
for (saptr = slptr->sl_attrs; saptr != NULL; saptr = saptr->sa_next) {
/* check the selected attribute name */
if ((saname = saptr->sa_name) == NULL)
saname = saptr->sa_aname;
if (db_scmp(saname,aname) == 0)
break;
}
if (saptr == NULL) {
fprintf(fp,"<error>");
return;
}
/* get the attribute value */
for (i = 0; i < saptr->sa_attr->at_size; i++)
if (saptr->sa_aptr[i] != 0)
putc(saptr->sa_aptr[i],fp);
else if (pad) /* MPK 25-Mar-1986 */
putc(' ',fp);
}
/* set - set internal parameters */
static int set()
{
int value;
/* process each set request */
while (db_token() == ID) {
/* skip the identifier */
db_ntoken();
/* check for "no" */
if (db_scmp(dbv_tstring,"no") == 0) {
value = FALSE;
if (db_token() != ID)
return (db_ferror(BADSET));
db_ntoken();
}
else
value = TRUE;
/* check for parameter to set */
if (db_scmp(dbv_tstring,"fold") == 0)
dbv_fold = value;
else
return (db_ferror(BADSET));
}
/* return successfully */
return (TRUE);
}
SHAR_EOF
# End of shell archive
exit 0
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads