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 {
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
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