** http://www.hwaci.com/drh/
**
** $IdPath$
-** $Id: lemon.c,v 1.5 2002/04/07 20:57:52 peter Exp $
+** $Id: lemon.c,v 1.6 2002/04/07 21:57:43 peter Exp $
*/
#include <stdio.h>
#include <stdarg.h>
** Main program file for the LEMON parser generator.
*/
+void setlempar(const char *);
+void setoutput(const char *);
+
/* Report an out-of-memory condition and abort. This function
** is used mostly by the "MemoryCheck" macro in struct.h
*/
exit(1);
}
+static const char *lempar_locations[] = {
+ NULL, "lempar.c"
+};
+
+void setlempar(const char *lempar)
+{
+ if (access(lempar, 004)) {
+ perror(lempar);
+ exit(1);
+ }
+ lempar_locations[0] = lempar;
+}
+
+static char *output_file = NULL;
+
+void setoutput(const char *base)
+{
+ if ((output_file = malloc(strlen(base) + 1)))
+ sprintf(output_file, "%s.", base);
+}
/* The main program. Parse the command line and do it... */
int main(int argc, char **argv)
{OPT_FLAG, "b", {&basisflag}, "Print only the basis in report."},
{OPT_FLAG, "c", {&compress}, "Don't compress the action table."},
{OPT_FLAG, "g", {&rpflag}, "Print grammar without actions."},
- {OPT_FLAG, "m", {&mhflag}, "Output a makeheaders compatible file"},
+ {OPT_FLAG, "m", {&mhflag}, "Output a makeheaders compatible file."},
+ {OPT_FSTR, "o", {0}, "Set the dirname/basename for the output file(s)."},
{OPT_FLAG, "q", {&quiet}, "(Quiet) Don't print the report file."},
{OPT_FLAG, "s", {&statistics}, "Print parser stats to standard output."},
+ {OPT_FSTR, "t", {0}, "An alternative template -- instead of "
+ "\"./lempar.c\"."},
{OPT_FLAG, "x", {&version}, "Print the version number."},
{OPT_FLAG,0,{0},0}
};
int i;
struct lemon lem;
+ /* Initialize function union members of options array */
+ options[4].arg.fstr = setoutput;
+ options[7].arg.fstr = setlempar;
+
OptInit(argv,options,stderr);
if( version ){
printf("Lemon version 1.0\n"
plp = nextpl;
}
}
+
/*********************** From the file "report.c" **************************/
/*
** Procedures for generating reports and tables in the LEMON parser generator.
PRIVATE FILE *file_open(struct lemon *, const char *, const char *);
void ConfigPrint(FILE *, struct config *);
int PrintAction(struct action *, FILE *, int);
-PRIVATE char *pathsearch(char *, char *, int);
+PRIVATE const char *pathsearch(void);
PRIVATE int compute_action(struct lemon *, struct action *);
PRIVATE void tplt_xfer(char *, FILE *, FILE *, int *);
PRIVATE FILE *tplt_open(struct lemon *);
*/
PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
{
- char *name;
- char *cp;
+ char *name = NULL;
+ char *cp, *fname;
- name = malloc( strlen(lemp->filename) + strlen(suffix) + 5 );
+ fname = output_file ? output_file : lemp->filename;
+ name = malloc( strlen(fname) + strlen(suffix));
if( name==0 ){
fprintf(stderr,"Can't allocate space for a filename.\n");
exit(1);
}
- strcpy(name,lemp->filename);
+ strcpy(name, fname);
cp = strrchr(name,'.');
if( cp ) *cp = 0;
strcat(name,suffix);
return;
}
-/* Search for the file "name" which is in the same directory as
-** the exacutable */
-PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
+PRIVATE const char *pathsearch(void)
{
- char *pathlist;
- char stdpathlist[] = ".:/bin:/usr/bin";
- char emptypathlist[] = "";
- char *path,*cp;
- char c;
+ int i;
-#ifdef __WIN32__
- cp = strrchr(argv0,'\\');
-#else
- cp = strrchr(argv0,'/');
-#endif
- if( cp ){
- c = *cp;
- *cp = 0;
- path = (char *)malloc( strlen(argv0) + strlen(name) + 2 );
- if( path ) sprintf(path,"%s/%s",argv0,name);
- *cp = c;
- }else{
- pathlist = getenv("PATH");
- if( pathlist==0 ) pathlist = stdpathlist;
- path = (char *)malloc( strlen(pathlist)+strlen(name)+2 );
- if( path!=0 ){
- while( *pathlist ){
- cp = strchr(pathlist,':');
- if( cp==0 ) cp = &pathlist[strlen(pathlist)];
- c = *cp;
- *cp = 0;
- sprintf(path,"%s/%s",pathlist,name);
- *cp = c;
- if( c==0 ) pathlist = emptypathlist;
- else pathlist = &cp[1];
- if( access(path,modemask)==0 ) break;
- }
- }
- }
- return path;
+ for (i = 0; i < sizeof(lempar_locations)/sizeof(char *); i++)
+ if (lempar_locations[i] && access(lempar_locations[i], 004) == 0)
+ return lempar_locations[i];
+
+ return(NULL);
}
/* Given an action, compute the integer value for that action
** a pointer to the opened file. */
PRIVATE FILE *tplt_open(struct lemon *lemp)
{
- static char templatename[] = "lempar.c";
char buf[1000];
FILE *in;
- char *tpltname;
+ const char *tpltname;
char *cp;
cp = strrchr(lemp->filename,'.');
if( access(buf,004)==0 ){
tpltname = buf;
}else{
- tpltname = pathsearch(lemp->argv0,templatename,0);
+ tpltname = pathsearch();
}
if( tpltname==0 ){
- fprintf(stderr,"Can't find the parser driver template file \"%s\".\n",
- templatename);
+ fprintf(stderr,"Can't find the parser driver template file.\n");
lemp->errorcnt++;
return 0;
}
in = fopen(tpltname,"r");
if( in==0 ){
- fprintf(stderr,"Can't open the template file \"%s\".\n",templatename);
+ fprintf(stderr,"Can't open the template file \"%s\".\n", tpltname);
lemp->errorcnt++;
return 0;
}