4.3BSD/usr/ingres/source/equel/main.c
# include <stdio.h>
# include "constants.h"
# include "globals.h"
# include <setjmp.h>
# include <sccs.h>
SCCSID(@(#)main.c 8.1 12/31/84)
/*
** MAIN.C -- Start up routines
**
** Usage:
** equel {-d | -v | -c | -y | -f | -f<integer> | <name>.q}
**
** Files:
** standard output -- for diagnostics
** <name>.q -- read
** <name>.c -- created and written
** any file appearing in a "#include" with a name
** <name>.q.h -- read
** <name>.c.h -- created and written
**
** Flags:
** possible arguments are:
** -d -- enables run-time errors to have the file name
** and line number where they occurred reported
** Defaults to off.
** -f -- specify the number of characters to fill
** an output line on quel commands
** as being very high (to get C code on the
** right line invariably).
** -f<integer> -- fill output lines to integer chars
** (0 is like -f alone)
** Defaults to FILLCNT.
** -y -- have the parser print debugging info
** Defaults to off.
** -v -- (verbose) have the lexical analizer
** print the kind of token it sees.
** (only available if xDEBUG is defined)
** Defaults to off.
** -c -- have every character read or backed up
** echoed (only if xDEBUG is defined)
** Defaults to off.
** -r -- reset all previous flags to default
** <name>.q -- name of a file to be equel'ed
**
** Compilation Flags:
** xDEBUG -- enables debugging flags -v and -c
**
** Compilation Instructions:
** to setup equel do :
** setup equel; setup libq
*/
/*
** MAIN -- invokes the pre-compiler on all the argument files
**
** Parameters:
** argc
** argv
**
** Returns:
** none
*/
int Exit_val = 0; /* Value to exit with */
jmp_buf Jmpbuf; /* nonlocal goto label */
main(argc, argv)
int argc;
char **argv;
{
extern char **argproc();
argv [argc] = 0;
for (argv++; *argv; )
{
argv = argproc(argv);
if (!Arg_error)
equel(Input_file_name);
}
exit(Exit_val);
}
/*
** ARGPROC -- process arguments on the command line
** Arguments have effect on all the files following them
** until a "-r" or an argument cancelling the first
**
** Also performs global initializations.
**
** Parameters:
** argv -- a 0 terminated string vector with the
** command lines components.
**
** Returns:
** a new argv with all the leading arguments taken out
**
** Side Effects:
** sets certain variables for certain flags
** -d -- Rtdb
** -c -- Chardebug
** -v -- Lex_debug
** -y -- yydebug
** -f -- Fillcnt
** -r -- resets all variables to default values
** Sets Arg_error on an argument error that should abort
** the pre-processing of the file read.
*/
char **argproc(argv)
char **argv;
{
/* initializations for a new file */
C_code_flg = Pre_proc_flg = 0;
yyline = Newline = Lineout = 1;
Block_level = Indir_level = In_string = Fillmode = 0;
Charcnt = Lastc = In_quote = 0;
Arg_error = 0;
/* free C variable trees, and symbol space */
freecvar(&C_locals);
freecvar(&F_locals);
freecvar(&C_globals);
freecvar(&F_globals);
symspfree();
for ( ; *argv && **argv == '-'; argv++)
{
switch (*++*argv)
{
# ifdef xDEBUG
case 'v' :
Lex_debug = 'v';
break;
case 'c' :
Chardebug = 'c';
break;
# endif
case 'y' :
yydebug = 1;
break;
case 'd' :
Rtdb = 1;
break;
case 'f' : /* line fill */
Fillcnt = atoi(++*argv);
if (!Fillcnt)
/* make SURE that C_CODE is put
* on line that it was typed in on
*/
Fillcnt = 30000;
break;
case 'r' : /* reset all flags to
* their default values.
*/
yydebug = Rtdb = 0;
Fillcnt = FILLCNT;
# ifdef xDEBUG
Lex_debug = Chardebug = 0;
# endif
break;
default :
printf("equel: invalid option: '-%c'\n", **argv);
}
}
if (*argv)
Input_file_name = *argv++;
else
{
printf("equel: missing file name after arguments\n");
Arg_error++;
}
return (argv);
}
/*
** EQUEL -- invokes the precompiler for a non-included file
**
** Parameters:
** filename -- the name of the file to pre-compile
**
** Returns:
** none
**
** Side Effects:
** performs the preprocessing on <filename>
*/
equel(filename)
char *filename;
{
char o_file [100];
register l;
l = length(filename);
if (l > sizeof o_file - 1)
{
printf("equel: filename \"%s\" too long\n",
filename);
return;
}
if (!sequal(".q", &filename [l - 2]))
{
printf("equel: EQUEL source files must end with .q\n");
return;
}
bmove(filename, o_file, l - 2);
bmove(".c", &o_file[l - 2], 3);
Input_file_name = filename;
In_file = Out_file = NULL;
if ((In_file = fopen(filename, "r")) == NULL)
cant("read", filename);
else if ((Out_file = fopen(o_file, "w")) == NULL)
cant("write", o_file);
else if (!setjmp(Jmpbuf))
yyparse();
/* if a reset(III) is done while processing
* an included file, then this closes all
* files skipped.
*/
while (restoref())
;
if (Out_file != NULL)
fclose(Out_file);
if (In_file != NULL)
fclose(In_file);
In_file = Out_file = NULL;
if (Block_level != 0)
yysemerr("unclosed block", 0);
Input_file_name = 0;
}
/*
** CANT -- print error message on failure to open a file
**
** Parameters:
** operation -- "read" or "write", according to what was
** attempted
** filename -- the name of the file on which attempted
**
** Returns:
** none
**
** Side Effects:
** Prints error message on standard output
*/
cant(operation, filename)
char *operation;
char *filename;
{
extern char *sys_errlist[];
extern int sys_nerr;
extern int errno;
char ebuf[BUFSIZ];
if (errno > 0 && errno <= sys_nerr)
sprintf(ebuf, "Can't %s \"%s\": %s", operation, filename,
sys_errlist[errno]);
else
sprintf(ebuf, "Can't %s \"%s\": unknown error", operation,
filename);
yysemerr(ebuf, 0);
}