Add support for specifying the output directory (avoiding nasty cd tricks when
using it in build scripts).
This commit is contained in:
parent
bbae0ba02c
commit
99ec64a7a0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
27
util/LLgen/src/utils.c
Normal 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 : */
|
||||
|
Loading…
Reference in a new issue