Add VHDLPP support to ivlpp program

The ivlpp program is a good place to detect that the source file
is VHDL, and pass the source file to the vhdlpp program. Do so
automatically.
This commit is contained in:
Stephen Williams 2010-12-19 13:33:04 +02:00
parent 04b239a5fb
commit 05122d3e2c
6 changed files with 131 additions and 7 deletions

View File

@ -33,6 +33,8 @@ extern void dump_precompiled_defines(FILE*out);
an include directive in encountered. */
extern char**include_dir;
extern unsigned include_cnt;
/* Program to use for VHDL processing. */
extern char*vhdlpp_path;
extern int relative_include;

View File

@ -42,6 +42,15 @@ valid options include:
This option does *not* override existing `define
directives in the source file.
-F <path>
Read ivlpp options from a FLAGS FILE. This is not the same
as a file list. This file contains flags, not source
files. There may be multiple flags files.
-f <path>
Read ivlpp input files from a file list. There can be no
more then one file list.
-I <dir>
Add a directory to the include path. Normally, only "." is
in the search path. The -I flag causes other directories
@ -59,8 +68,42 @@ valid options include:
output.
-v
Print version and copyright information
Print version and copyright information before processing
input files.
-V
Print version and copyright information, then exit WITHOUT
processing any input files.
FLAGS FILE
A flags file contains flags for use by ivlpp. This is a convenient way
for programs to pass complex sets of flags to the ivlpp program.
Blank lines and lines that start with "#" are ignored. The latter can
be used as comment lines. All other lines are flag lines. Leading and
trailing white space are removed before the lines are interpreted.
Other lines have the simple format:
<key>:<value>
The colon character separates a key from the value. The supported
keys, with their corresponding values, are:
D:name=<value>
This is exactly the same as the "-Dname=<value>" described above.
I:<dir>
This is exctly the same as "-I<dir>".
relative include:<flag>
The <flag> can be "true" or "false". This enables "relative
includes" nesting behavior.
vhdlpp:<path>
Give the path to the vhdlpp program. This program is used to
process VHDL input files.
LOCATING INCLUDED FILES

View File

@ -59,6 +59,7 @@ struct include_stack_t
/* If the current input is from a file, this member is set. */
FILE* file;
int (*file_close)(FILE*);
/* If we are reparsing a macro expansion, file is 0 and this
* member points to the string in progress
@ -1614,8 +1615,10 @@ static void do_include()
{
/* standby is defined by include_filename() */
if (standby->path[0] == '/') {
if ((standby->file = fopen(standby->path, "r")))
if ((standby->file = fopen(standby->path, "r"))) {
standby->file_close = fclose;
goto code_that_switches_buffers;
}
} else {
unsigned idx, start = 1;
char path[4096];
@ -1644,6 +1647,7 @@ static void do_include()
sprintf(path, "%s/%s", include_dir[idx], standby->path);
if ((standby->file = fopen(path, "r"))) {
standby->file_close = fclose;
/* Free the original path before we overwrite it. */
free(standby->path);
standby->path = strdup(path);
@ -1750,6 +1754,58 @@ static void lexor_done()
}
}
/*
* Use this function to open a source file that is to be
* processed. Do NOT use this function for opening include files,
* instead only use this file for opening base source files.
*/
static void open_input_file(struct include_stack_t*isp)
{
char*cp;
int is_vhdl = 0;
isp->file = 0;
/* look for a suffix for the input file. If the suffix
indicates that this is a VHDL source file, then invoke
vhdlpp to get a data stream. */
cp = strrchr(isp->path, '.');
if (cp && vhdlpp_path) {
if (strcmp(cp, ".vhd") == 0) {
is_vhdl = 1;
} else if (strcmp(cp, ".vhdl") == 0) {
is_vhdl = 1;
}
}
if (is_vhdl == 0) {
isp->file = fopen(isp->path, "r");
isp->file_close = fclose;
return;
}
size_t cmdlen = strlen(vhdlpp_path);
cmdlen += strlen(isp->path);
cmdlen += 32;
char*cmd = malloc(cmdlen);
snprintf(cmd, cmdlen, "%s %s", vhdlpp_path, isp->path);
isp->file = popen(cmd, "r");
isp->file_close = pclose;
free(cmd);
return;
}
/*
* The load_next_input() function is called by the lexical analyzer
* when the current file runs out. When the EOF of the current input
* file is matched, this function figures out if this is the end of an
* included file (in which case the including file is resumed) or the
* end of a base file, in which case the next base source file is
* opened.
*/
static int load_next_input()
{
int line_mask_flag = 0;
@ -1773,7 +1829,8 @@ static int load_next_input()
if (isp->file)
{
free(isp->path);
fclose(isp->file);
assert(isp->file_close);
isp->file_close(isp->file);
}
else
{
@ -1813,7 +1870,7 @@ static int load_next_input()
istack->next = 0;
istack->lineno = 0;
istack->file = fopen(istack->path, "r");
open_input_file(istack);
if (istack->file == 0)
{
@ -1966,7 +2023,7 @@ void reset_lexor(FILE* out, char* paths[])
isp = malloc(sizeof(struct include_stack_t));
isp->next = 0;
isp->path = strdup(paths[0]);
isp->file = fopen(paths[0], "r");
open_input_file(isp);
isp->str = 0;
isp->lineno = 0;
isp->stringify_flag = 0;

View File

@ -57,7 +57,8 @@ extern const char*optarg;
char *dep_path = NULL;
/* Dependency file output mode */
char dep_mode = 'a';
/* Path to vhdlpp */
char *vhdlpp_path = 0;
/*
* Keep in source_list an array of pointers to file names. The array
@ -166,6 +167,13 @@ static int flist_read_flags(const char*path)
relative_include = 0;
}
} else if (strcmp(cp,"vhdlpp") == 0) {
if (vhdlpp_path) {
fprintf(stderr, "Ignore multiple vhdlpp flags\n");
} else {
vhdlpp_path = strdup(arg);
}
} else {
fprintf(stderr, "%s: Invalid keyword %s\n", path, cp);
}

View File

@ -92,6 +92,16 @@ lexor_keyword.o: lexor_keyword.cc parse.h
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
gperf -o -i 7 --ignore-case -C -k 1-4,6,9,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
install: all installdirs $(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@
$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@: vhdlpp@EXEEXT@
$(INSTALL_PROGRAM) ./vhdlpp@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/vhdlpp@EXEEXT@"
installdirs: $(srcdir)/../mkinstalldirs
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)"
uninstall:
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivhdlpp@EXEEXT@"
stamp-vhdlpp_config-h: $(srcdir)/vhdlpp_config.h.in ../config.status
@rm -f $@

View File

@ -46,6 +46,8 @@ const char NOTICE[] =
# include <getopt.h>
#endif
bool verbose_flag = false;
static void process_debug_token(const char*word)
{
if (strcmp(word, "yydebug") == 0) {
@ -71,6 +73,7 @@ int main(int argc, char*argv[])
VERSION " (" VERSION_TAG ")\n\n");
fprintf(stderr, "%s\n\n", COPYRIGHT);
fputs(NOTICE, stderr);
verbose_flag = true;
break;
case 'V':
@ -92,7 +95,8 @@ int main(int argc, char*argv[])
reset_lexor(fd, argv[idx]);
rc = yyparse();
fprintf(stderr, "yyparse() returns %d, parse_errors=%d\n", rc, parse_errors);
if (verbose_flag)
fprintf(stderr, "yyparse() returns %d, parse_errors=%d\n", rc, parse_errors);
if (parse_errors > 0) {
fprintf(stderr, "%d errors parsing %s\n", parse_errors, argv[idx]);