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 {
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 {
@ -10,11 +17,28 @@ cprogram {
-- tokens.c. If LLgen.g or tokens.g gets updated, they need
-- 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" },
vars = {
["+cflags"] = {
"-DLIBDIR=\\\""..posix.getcwd().."/"..cwd().."/lib\\\"",
"-DLIBDIR=\\\""..cwd().."/lib\\\"",
"-DNON_CORRECTING"
},
}
@ -55,8 +79,11 @@ definerule("llgen",
"util/LLgen+llgen",
e.srcs,
},
vars = {
srcs = e.srcs
},
commands = {
"cd %{dir} && rm -f %{outs} && %{abspath(ins)}"
"rm -f %{outs} && %{ins[1]} -o%{dirname(outs[1])} %{srcs}"
}
}
end

View file

@ -76,6 +76,9 @@ If the flag is given more than once,
will be more "verbose".
If it is given three times, a complete description of the
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
the sets that are computed are extended with the nonterminal
symbols and these extended sets are also included in the

View file

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

View file

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

View file

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

View file

@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
# include "extern.h"
# include "types.h"
@ -39,18 +40,20 @@ string libpath(string s)
char* libdir = getenv("LLGEN_LIB_DIR");
if (!libdir)
libdir = LIBDIR;
length = strlen(libdir) + strlen(s) + 2;
p = (string) alloc(length);
strcpy(p,libdir);
strcat(p,"/");
strcat(p,s);
return p;
return aprintf("%s/%s", libdir, s);
}
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);
}
close(fd);
return filename;
}

View file

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