]> granicus.if.org Git - yasm/commitdiff
Merge in FreeBSD patches to lemon.
authorPeter Johnson <peter@tortall.net>
Sun, 7 Apr 2002 21:57:43 +0000 (21:57 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 7 Apr 2002 21:57:43 +0000 (21:57 -0000)
svn path=/trunk/yasm/; revision=570

tools/lemon/lemon.c

index 9bc2f6784ca277ee9f80a4df71d6465deec2992b..539a4be0db60b3f52afe50651251c41acfda68ff 100644 (file)
@@ -26,7 +26,7 @@
 **   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>
@@ -1153,6 +1153,9 @@ void ErrorMsg(const char *filename, int lineno, const char *format, ...)
 ** 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
 */
@@ -1161,6 +1164,26 @@ void memory_error(void){
   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)
@@ -1176,15 +1199,22 @@ 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"
@@ -2270,6 +2300,7 @@ void Plink_delete(struct plink *plp)
     plp = nextpl;
   }
 }
+
 /*********************** From the file "report.c" **************************/
 /*
 ** Procedures for generating reports and tables in the LEMON parser generator.
@@ -2279,7 +2310,7 @@ PRIVATE char *file_makename(struct lemon *, const char *);
 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 *);
@@ -2295,15 +2326,16 @@ void print_stack_union(FILE *, struct lemon *, int *, int);
 */
 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);
@@ -2489,46 +2521,15 @@ void ReportOutput(struct lemon *lemp)
   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
@@ -2585,10 +2586,9 @@ PRIVATE void tplt_xfer(char *name, FILE *in, FILE *out, int *lineno)
 ** 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,'.');
@@ -2600,17 +2600,16 @@ PRIVATE FILE *tplt_open(struct lemon *lemp)
   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;
   }