Add support for specifying the output directory (avoiding nasty cd tricks when

using it in build scripts).
This commit is contained in:
David Given 2022-07-14 01:15:29 +02:00
parent bbae0ba02c
commit 99ec64a7a0
8 changed files with 131 additions and 58 deletions

View file

@ -1,6 +1,13 @@
clibrary { clibrary {
name = "headers", name = "headers",
hdrs = { "./src/*.h" } -- rm alloc.h hdrs = {
"./src/cclass.h",
"./src/extern.h",
"./src/io.h",
"./src/Lpars.h",
"./src/sets.h",
"./src/types.h",
}
} }
cprogram { cprogram {
@ -10,11 +17,28 @@ cprogram {
-- tokens.c. If LLgen.g or tokens.g gets updated, they need -- tokens.c. If LLgen.g or tokens.g gets updated, they need
-- rebuilding. Use the bootstrap target to do this. -- rebuilding. Use the bootstrap target to do this.
srcs = { "./src/*.c" }, srcs = {
"./src/LLgen.c",
"./src/Lpars.c",
"./src/alloc.c",
"./src/cclass.c",
"./src/check.c",
"./src/compute.c",
"./src/gencode.c",
"./src/global.c",
"./src/machdep.c",
"./src/main.c",
"./src/name.c",
"./src/reach.c",
"./src/savegram.c",
"./src/sets.c",
"./src/tokens.c",
"./src/utils.c",
},
deps = { "+headers" }, deps = { "+headers" },
vars = { vars = {
["+cflags"] = { ["+cflags"] = {
"-DLIBDIR=\\\""..posix.getcwd().."/"..cwd().."/lib\\\"", "-DLIBDIR=\\\""..cwd().."/lib\\\"",
"-DNON_CORRECTING" "-DNON_CORRECTING"
}, },
} }
@ -55,8 +79,11 @@ definerule("llgen",
"util/LLgen+llgen", "util/LLgen+llgen",
e.srcs, e.srcs,
}, },
vars = {
srcs = e.srcs
},
commands = { commands = {
"cd %{dir} && rm -f %{outs} && %{abspath(ins)}" "rm -f %{outs} && %{ins[1]} -o%{dirname(outs[1])} %{srcs}"
} }
} }
end end

View file

@ -76,6 +76,9 @@ If the flag is given more than once,
will be more "verbose". will be more "verbose".
If it is given three times, a complete description of the If it is given three times, a complete description of the
grammar will be supplied. grammar will be supplied.
.IP \fB\-o\fP
Specifies the location of the output files. If not set, they
are placed in the current directory.
.IP \fB\-x\fP .IP \fB\-x\fP
the sets that are computed are extended with the nonterminal the sets that are computed are extended with the nonterminal
symbols and these extended sets are also included in the symbols and these extended sets are also included in the

View file

@ -97,37 +97,40 @@ extern int strip_grammar;
extern int in_production; extern int in_production;
/* LLgen.g */ /* LLgen.g */
void LLparse(void); extern void LLparse(void);
/* check.c */ /* check.c */
void conflchecks(void); extern void conflchecks(void);
/* compute.c */ /* compute.c */
void do_compute(void); extern void do_compute(void);
int empty(p_gram); extern int empty(p_gram);
int t_safety(int, int, int, int); extern int t_safety(int, int, int, int);
int t_after(int, int, int); extern int t_after(int, int, int);
/* gencode.c */ /* gencode.c */
void gencode(int); extern void gencode(int);
/* machdep.c */ /* machdep.c */
void TMPNAM(string); extern string maketempfile(void);
string libpath(string); extern string libpath(string);
/* main.c */ /* main.c */
void error(int lineno,string s,string t); extern void error(int lineno,string s,string t);
void warning(int lineno,string s,string t); extern void warning(int lineno,string s,string t);
void fatal(int lineno,string s,string t); extern void fatal(int lineno,string s,string t);
void copyfile(string); extern void copyfile(string);
void install(string, string); extern void install(string, string);
/* name.c */ /* name.c */
void name_init(void); extern void name_init(void);
string store(string); extern string store(string);
p_gram search(int, string, int); extern p_gram search(int, string, int);
/* reach.c */ /* reach.c */
void co_reach(void); extern void co_reach(void);
/* utils.c */
extern string aprintf(const char* fmt, ...);
#endif /* EXTERN_H_ */ #endif /* EXTERN_H_ */

View file

@ -45,15 +45,16 @@ FILE *fout;
FILE *fpars; FILE *fpars;
FILE *finput; FILE *finput;
FILE *fact; FILE *fact;
char f_pars[L_tmpnam+sizeof(char)]; /* Add one more character for NULL, just in case of buggy implementations. */ string f_dir;
char f_temp[L_tmpnam+sizeof(char)]; string f_pars;
string f_temp;
#ifdef NON_CORRECTING #ifdef NON_CORRECTING
char f_nc[20]; string f_nc;
#endif #endif
char f_out[20]; string f_out;
string f_input; string f_input;
char f_include[20]; string f_include;
char f_rec[20]; string f_rec;
string e_noopen = "Cannot open %s"; string e_noopen = "Cannot open %s";
int verbose; int verbose;
int wflag; int wflag;

View file

@ -20,22 +20,23 @@
/* FILES */ /* FILES */
# define OUTFILE "%s.output" /* -v option */ # define OUTFILE "%s/%s.output" /* -v option */
# define HFILE "%spars.h" /* file for "#define's " */ # define HFILE "%s/%spars.h" /* file for "#define's " */
# define RFILE "%spars.c" /* Error recovery */ # define RFILE "%s/%spars.c" /* Error recovery */
#ifdef NON_CORRECTING #ifdef NON_CORRECTING
# define NCFILE "%sncor.c" /* Non-corrcting error recovery */ # define NCFILE "%s/%sncor.c" /* Non-corrcting error recovery */
#endif #endif
extern FILE *finput; extern FILE *finput;
extern FILE *fpars; extern FILE *fpars;
extern FILE *fact; extern FILE *fact;
extern FILE *fout; extern FILE *fout;
extern char f_pars[]; extern string f_dir;
extern char f_temp[]; extern string f_pars;
extern char f_out[]; extern string f_temp;
extern string f_input; extern string f_out;
extern char f_include[]; extern string f_input;
extern char f_rec[]; extern string f_include;
extern string f_rec;
#ifdef NON_CORRECTING #ifdef NON_CORRECTING
extern char f_nc[]; extern string f_nc;
#endif #endif

View file

@ -18,6 +18,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
# include "extern.h" # include "extern.h"
# include "types.h" # include "types.h"
@ -39,18 +40,20 @@ string libpath(string s)
char* libdir = getenv("LLGEN_LIB_DIR"); char* libdir = getenv("LLGEN_LIB_DIR");
if (!libdir) if (!libdir)
libdir = LIBDIR; libdir = LIBDIR;
length = strlen(libdir) + strlen(s) + 2; return aprintf("%s/%s", libdir, s);
p = (string) alloc(length);
strcpy(p,libdir);
strcat(p,"/");
strcat(p,s);
return p;
} }
void TMPNAM(string result) string maketempfile()
{ {
if (tmpnam(result)==NULL) string tmp = getenv("TMP");
{ if (!tmp)
tmp = "/tmp";
string filename = aprintf("%s/llgen-XXXXXX", tmp);
int fd = mkstemp(filename);
if (fd == -1)
fatal(1, "Cannot create temporary file.", NULL); fatal(1, "Cannot create temporary file.", NULL);
}
close(fd);
return filename;
} }

View file

@ -37,8 +37,9 @@ int main(int argc, register string argv[])
{ {
register string arg; register string arg;
TMPNAM(f_temp); f_dir = ".";
TMPNAM(f_pars); f_temp = maketempfile();
f_pars = maketempfile();
/* Initialize */ /* Initialize */
@ -116,6 +117,12 @@ int main(int argc, register string argv[])
case 'G': case 'G':
strip_grammar = 1; strip_grammar = 1;
continue; continue;
case 'o':
case 'O':
f_dir = ++arg;
break;
default: default:
fprintf(stderr, "illegal option : %c\n", *arg); fprintf(stderr, "illegal option : %c\n", *arg);
exit(1); exit(1);
@ -170,16 +177,16 @@ int main(int argc, register string argv[])
} }
name_init(); name_init();
readgrammar(argc, argv); readgrammar(argc, argv);
sprintf(f_out, OUTFILE, prefix ? prefix : "LL"); f_out = aprintf(OUTFILE, f_dir, prefix ? prefix : "LL");
/* for the following two filenames only one L is used; historical /* for the following two filenames only one L is used; historical
reasons ... reasons ...
*/ */
sprintf(f_include, HFILE, prefix ? prefix : "L"); f_include = aprintf(HFILE, f_dir, prefix ? prefix : "L");
sprintf(f_rec, RFILE, prefix ? prefix : "L"); f_rec = aprintf(RFILE, f_dir, prefix ? prefix : "L");
#ifdef NON_CORRECTING #ifdef NON_CORRECTING
if (non_corr) if (non_corr)
sprintf(f_nc, NCFILE, prefix ? prefix : "L"); f_nc = aprintf(NCFILE, f_dir, prefix ? prefix : "L");
#endif #endif
setinit(ntneeded); setinit(ntneeded);
maxnt = &nonterms[nnonterms]; maxnt = &nonterms[nnonterms];
@ -377,6 +384,7 @@ void install(string target, string source)
register int c1, c2; register int c1, c2;
register FILE *f1, *f2; register FILE *f1, *f2;
int cnt; int cnt;
string realtarget = (target[0] != '/') ? aprintf("%s/%s", f_dir, target) : target;
/* /*
* First open temporary, generated for source * First open temporary, generated for source
@ -388,10 +396,10 @@ void install(string target, string source)
/* /*
* Now open target for reading * Now open target for reading
*/ */
if ((f2 = fopen(target, "r")) == NULL) if ((f2 = fopen(realtarget, "r")) == NULL)
{ {
fclose(f1); fclose(f1);
copyto(target, f_pars); copyto(realtarget, f_pars);
return; return;
} }
/* /*
@ -420,6 +428,6 @@ void install(string target, string source)
{ {
fatal(0, "%s : not a file generated by LLgen", target); fatal(0, "%s : not a file generated by LLgen", target);
} }
copyto(target, f_pars); copyto(realtarget, f_pars);
} }
} }

27
util/LLgen/src/utils.c Normal file
View file

@ -0,0 +1,27 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
const char* aprintf(const char* fmt, ...)
{
int n;
char* p;
va_list ap;
va_start(ap, fmt);
n = vsnprintf(NULL, 0, fmt, ap) + 1;
va_end(ap);
p = malloc(n);
if (!p)
return NULL;
va_start(ap, fmt);
vsnprintf(p, n, fmt, ap);
va_end(ap);
return p;
}
/* vim: set sw=4 ts=4 expandtab : */