Category : C Source Code
Archive   : SQLVER1.ZIP
Filename : PARSE.C
#include "C:\LANGUAGE\C\TURBO.C\40.570\DEFS.H"
#endif
/**/
/****************************************************************************/
/*
int checkcondition( );
-This routine is used to return a number that will be used in parsing
conditional expressions. Those values will be used to help determining
what action to take.
Calls:
------
-None
Called By:
----------
-checktuple( );
-comparison( );
*/
int checkcondition(string)
char *string;
{
if (strcmp(string,"=") == 0) return(1);
if (strcmp(string,">") == 0) return(2);
if (strcmp(string,"<") == 0) return(3);
if (strcmp(string,">=") == 0) return(4);
if (strcmp(string,"<=") == 0) return(5);
if (strcmp(string,"~=") == 0) return(6);
return(0); /* unknown condition */
}
/**/
/****************************************************************************/
/*
int nfields( );
-This routine returns the number of attributes that are contained
in a table.
Calls:
------
-nfields ( );
Called By:
----------
-insert ( );
-nfields ( );
-select ( );
*/
int nfields(list)
struct LIST *list;
{
if (list) return(nfields(list->rlist) + 1);
return(0);
}
/**/
/****************************************************************************/
/*
int checkfields( );
-This routine checks to see if the user has provided a valid list of
fields .
Calls:
------
-None
Called By:
----------
-insert( );
-select( );
*/
int checkfields(filelist,datalist)
struct LIST *filelist,
*datalist;
{
while(datalist)
{
struct LIST *list = filelist;
while(list)
{
if(strcmp(datalist->data.attribute,list->data.attribute) == 0) break;
list = list->rlist;
}
if (!list) return(-20);
if (list->data.order == -1) return(-21); /* duplicate field */
list->data.order = -1;
datalist = datalist->rlist;
}
while(filelist)
{
filelist->data.order = -1;
filelist = filelist->rlist;
}
return(0);
}
/**/
/****************************************************************************/
/*
void printerror( );
-This routine print's out an error message when the user has done
something illegal.
Calls:
------
-None
Called By:
----------
-main( );
*/
void printerror(error)
int error;
{
while (getc(stdin) != ';');
printf("\n Error: ");
switch(error)
{
case -31: printf("VIEW does not have the same number of attributes.\n");
break;
case -30: printf("Duplicate TABLE name is in the list.");
break;
case -29: printf("Character string expected.");
break;
case -28: printf("Illegal datatype given.");
break;
case -27: printf("\'SELECT\' expected.");
break;
case -26: printf("\'AS\' expected.");
break;
case -25: printf("condition (\'=\',\'~=\',\'>\',\'<\',\'>=\', or \'<=\') expected.");
break;
case -24: printf("= expected.");
break;
case -23: printf("constant expected.");
break;
case -22: printf("\'WHERE\' expected.");
break;
case -21: printf("Duplicate attribute in list.");
break;
case -20: printf("COLUMN not in table.");
break;
case -19: printf("There are more input fields than table allows.");
break;
case -18: printf("COMMA expected.");
break;
case -17: printf("NUMBER expected.");
break;
case -16: printf("\'VALUES\' or field list expected.");
break;
case -15: printf("IDENTIFIER size to long.");
break;
case -14: printf("Positive Integer Length expected.");
break;
case -13: printf("Type expected.");
break;
case -12: printf("Attribute expected.");
break;
case -11: printf("Right Paren expected.");
break;
case -10: printf("Left Paren expected.");
break;
case -9: printf("\'SET\' expected.");
break;
case -8: printf("TABLE already exists.");
break;
case -7: printf("Unknown command.");
break;
case -6: printf("semicolon expected.");
break;
case -5: printf("TABLE name not found.");
break;
case -4: printf("TABLE or VIEW expected.");
break;
case -3: printf("\'INTO\' expected.");
break;
case -2: printf("\'FROM\' expected.");
break;
case -1: printf("TABLE expected.");
break;
}
printf("\n");
}
/**/
/****************************************************************************/
/*
int command( );
-This routine is used to help determine the appropriate action to take
when parsing a command.
Calls:
------
-file ( );
Called By:
----------
-delete ( );
-scanner( );
-select ( );
*/
int command(string)
char *string;
{
if (strlen(string) > 8 ) return (0);
if (strcmp(string,")") == 0 ) return(-4);
if (strcmp(string,"(") == 0 ) return(-3);
if (strcmp(string,",") == 0 ) return(-2);
if (strcmp(string,";") == 0 ) return(-1);
if (strcmp(string,AND) == 0 ) return( 1);
if (strcmp(string,CREATE) == 0 ) return( 2);
if (strcmp(string,DELETE) == 0 ) return( 3);
if (strcmp(string,DROP) == 0 ) return( 4);
if (strcmp(string,EXIT) == 0 ) return( 5);
if (strcmp(string,FROM) == 0 ) return( 6);
if (strcmp(string,INSERT) == 0 ) return( 7);
if (strcmp(string,OR) == 0 ) return( 8);
if (strcmp(string,SELECT) == 0 ) return( 9);
if (strcmp(string,TABLE) == 0 ) return(10);
if (strcmp(string,UPDATE) == 0 ) return(11);
if (strcmp(string,WHERE) == 0 ) return(12);
if (strcmp(string,INTO) == 0 ) return(13);
if (strcmp(string,VIEW) == 0 ) return(14);
if (strcmp(string,DISTINCT) == 0 ) return(15);
if (strcmp(string,AS) == 0 ) return(16);
if (strcmp(string,VALUES) == 0 ) return(17);
if (strcmp(string,SET) == 0 ) return(18);
if (strcmp(string,"*") == 0 ) return(19);
if (strcmp(string,INT) == 0 ) return(20);
if (strcmp(string,CHAR) == 0 ) return(21);
if (strcmp(string,CLS) == 0 ) return(22);
if (file(string) == 99) return(99);
if (string == NULL) return(98);
return(0);
}
/**/
/****************************************************************************/
/*
int readconstant( );
-This routine reads a constant off of the commandline of a specified
type. If a character is entered when a integer is desired error -17
is returned. If the number is larger than a specified length then
error 15 is returned.
Calls:
------
-notspace ( );
Called By:
----------
-insert ( );
-update ( );
*/
int readconstant(data,datatype,length)
struct LIST *data;
int datatype,
length;
{
char *ch;
long value = 0;
data->data.attribute[0] = '\0';
ch = data->data.attribute;
*ch = NULL;
notspace( );
if (datatype)
{
char dh = NULL,
scanmask[7] = "%",
number[17] = "";
/*
create a mask that will permit the capability to see if the
integer entered is larger than the length of it. This will
allow for the ability to check to see if the integer is
not larger than the domain for it.
*/
strcat(scanmask,itoa(length,number,10));
strcat(scanmask,"ld");
if (scanf(scanmask,&value) == 0) return(-17);
dh = getc(stdin);
ungetc(dh,stdin);
if (isdigit(dh)) return(-15);
data->data.length = length;
data->data.value = value;
data->data.type = 1;
}
else
if ((*ch = getc(stdin)) != 0x27 && (*ch != '"')) /* ' || " */
{
ungetc(*ch,stdin);
*ch = NULL;
return(-29); /* attribute expected */
}
else
{
int i = 0;
while((*ch = getc(stdin)) != 0x27 && (*ch != '"') &&
(*ch != 0x0D) && (*ch != 0x0A)) *ch++;
if (*ch == 0x0D || *ch == 0x0A) return(-15);
*ch=NULL;
if (strlen(data->data.attribute) > length) return(-15);
/* padd remainder of field with spaces */
for (i = strlen(data->data.attribute);i < length;i++) *ch++ = ' ';
*ch=NULL;
}
return(0);
}
/**/
/****************************************************************************/
/*
void notspace( );
-This routine ignores spaces, tabs, and carriage returns entered on the
commandline.
Calls:
------
-None
Called By:
----------
-getvalue ( );
-parse ( );
-readconstant ( );
-scanner ( );
-shellcommand ( );
*/
void notspace(void)
{
char ch;
while (isspace(ch = getc(stdin))) if (ch == 0x0D) putc(ch,stdout);
ungetc(ch,stdin);
}
/**/
/****************************************************************************/
/*
int comparison( );
-This routine is used to extract conditional expressions off of the
commandline.
Calls:
------
-checkcondition( );
Called By:
----------
-scanner ( );
*/
int comparison(string)
char *string;
{
char *ch;
ch = string;
*ch = NULL;
*ch = getc(stdin);
if (*ch == '<' || *ch == '>')
{
*ch++;
*ch = getc(stdin);
if (*ch == '=') /* greater/less than equal to ? */
{
*ch++;
*ch = NULL;
return(checkcondition(string));
}
ungetc(*ch,stdin);
*ch = NULL;
return(checkcondition(string)); /* just greater/less than */
}
/* must be '=' or '~' (not equal) */
if (*ch == '~') *++ch = getc(stdin);
*ch++;
*ch = NULL;
return(checkcondition(string));
}
/**/
/****************************************************************************/
/*
int shellcommand( )
-This routine extracts the commandline when the user wants to execute
an external program. The first character of the command line is a '!'
and the last character is a carriage return. It returns 23 so that
parse( ) will no that a system call must be made to satisfy the request.
Calls:
------
-notspace( );
Called By:
----------
-scanner ( );
*/
int shellcommand(commandline)
char *commandline;
{
char *ch = commandline;
*ch = getc(stdin); /* read the '!' */
notspace( );
while((*ch++ = getc(stdin)) != '\n');
*ch=NULL;
return(23);
}
/**/
/****************************************************************************/
/*
int scanner( );
-This is part of the parsing functions used to extract strings off of
the commandline.
Calls:
------
-command ( );
-comparison ( );
-notspace ( );
-shellcommand( );
Called By:
----------
-attributelist ( );
-create ( );
-createview ( );
-delete ( );
-getspredicate ( );
-insert ( );
-parse ( );
-readfield ( );
-readselect ( );
-select ( );
-update ( );
*/
int scanner(string)
char *string;
{
char *ch;
ch = string;
*ch = NULL;
notspace( );
*ch = getc(stdin);
ungetc(*ch,stdin);
/* Was a condition entered ? */
if (*ch == '=' ||
*ch == '<' ||
*ch == '>' ||
*ch == '~') return(comparison(string));
if (*ch == '!') return(shellcommand(string));
/* Was a delimiter entered ? */
if (*ch == ';' ||
*ch == ',' ||
*ch == '*' ||
*ch == '(' ||
*ch == ')')
{
*++ch = NULL;
return(command(string));
}
while ((*ch = getc(stdin)) != ';')
{
if (isalpha(*ch)) *ch = toupper(*ch);
if (!(isalnum(*ch)) && (*ch != '.')) break;
*ch++;
}
if (*ch == 0x0D) putc(*ch,stdout);
if (!(isalnum(*ch)) && (*ch != '.')) ungetc(*ch,stdin);
*ch = NULL;
return(command(string));
}
/**/
/****************************************************************************/
/*
int parse( );
-This is the highest level of the parser. It parses for commands and
calls the appropriate function to carry out that command, with the
exception of the command "DROP".
Calls:
------
-create ( );
-delete ( );
-insert ( );
-notspace ( );
-scanner ( );
-select ( );
-update ( );
Called By:
----------
-main( );
*/
int parse(string,cmdfile)
char *string;
int cmdfile;
{
char ch;
int error = 0;
if (!(cmdfile)) prompt( );
switch(scanner(string))
{
case -1: /* SEMICOLON */
break;
case 2: /* CREATE */
error = scanner(string);
if (error != 10 && error != 14) return(-4);/* not TABLE/VIEW */
if ((error = create(string))) return(error);
break;
case 3: /* DELETE */
if (scanner(string) != 6) return(-2); /* not FROM */
if ((error = delete(string))) return(error);
break;
case 4: /* DROP */
if (scanner(string) != 10) return(-1); /* not TABLE */
if (scanner(string) != 99) return(-5); /* not table-name */
notspace( );
ch = getc(stdin);
ungetc(ch,stdin);
if (ch != ';') return(-6);
strcat(string,TAB);
unlink(string);
puts("\n TABLE dropped.");
break;
case 5: /* EXIT */
if (scanner(string) != -1) return(-6); /* no semicolon */
return(5);
case 7: /* INSERT */
if (scanner(string) != 13) return(-3); /* not INTO */
if ((error = insert(string))) return(error);
break;
case 9: /* SELECT */
if ((error = select(string,0,NULL))) return(error);
if (scanner(string) != -1) return(-6); /* no semicolon */
break;
case 11: /* UPDATE */
if ((error = update(string))) return(error);
if (scanner(string) != -1) return(-6); /* no semicolon */
break;
case 22: /* CLS */
if (scanner(string) != -1) return(-6); /* no semicolon */
cls( );
break;
case 23: /* Execute an external command */
system(string);
ungetc(';',stdin);
break;
default: /* UNKNOWN COMMAND */
while((ch = getc(stdin)) != ';');
ungetc(';',stdin);
return(-7);
}
getc(stdin); /* and finally read the semicolon */
return(0);
}
/**/
/****************************************************************************/
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
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/