Category : C Source Code
Archive   : SDB.ZIP
Filename : SDBSCN.C

 
Output of file : SDBSCN.C contained in archive : SDB.ZIP
/* SDB - token scanning routines */

#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",
"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,
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 = 0;

/* 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 = 0;

/* 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 = (struct ifile *)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 = 0;
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 = (struct ifile *)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 = 0;
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) != 0)
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 = 0;

/* 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 = 0;

/* 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)
if (iprompt != NULL)
printf("%s",iprompt);
else if (cprompt != NULL)
printf("%s",cprompt);

if (dbv_ifp == NULL)
if ((ch = getc(stdin)) == '\n')
atbol = TRUE;
else
atbol = FALSE;
else {
if ((ch = getc(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);
}



  3 Responses to “Category : C Source Code
Archive   : SDB.ZIP
Filename : SDBSCN.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/