Command files can nest, -f is an alias for -c and better error messages.
This patch adds the ability to call command files from other command files. There is currently a limit of 16 total levels deep (15 stored plus the current file). -f is now an alias for -c for both the command line and command files. The parser also reports errors when they occur along with the file name and line number to aid in debugging problems.
This commit is contained in:
parent
bbf3116945
commit
d5fe5689e1
|
|
@ -27,17 +27,21 @@
|
|||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
/*
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
YYLTYPE yylloc;
|
||||
|
||||
static int comment_enter;
|
||||
static char* trim_trailing_white(char*txt, int trim);
|
||||
static char* trim_trailing_white(char*txt, int trim);
|
||||
|
||||
/*
|
||||
* Mostly copied from the flex manual. Do not make this arbitrary
|
||||
* depth without checking for looping files.
|
||||
*/
|
||||
#define MAX_CMDFILE_DEPTH 15
|
||||
|
||||
typedef struct t_cmdfile {
|
||||
char *cmdfile;
|
||||
YY_BUFFER_STATE buffer;
|
||||
} s_cmdfile;
|
||||
s_cmdfile cmdfile_stack[MAX_CMDFILE_DEPTH];
|
||||
int cmdfile_stack_ptr = 0;
|
||||
|
||||
%}
|
||||
|
||||
|
|
@ -51,12 +55,12 @@ static int comment_enter;
|
|||
/* Accept C++ style comments. */
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
<LCOMMENT>\n { cflloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
/* Accept C style comments. */
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>\n { cflloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
/* Accept shell type comments. */
|
||||
|
|
@ -65,7 +69,7 @@ static int comment_enter;
|
|||
/* Skip white space. */
|
||||
[ \t\f\r] { ; }
|
||||
/* Skip line ends, but also count the line. */
|
||||
\n { yylloc.first_line += 1; }
|
||||
\n { cflloc.first_line += 1; }
|
||||
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
|
@ -100,12 +104,16 @@ static int comment_enter;
|
|||
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
|
||||
|
||||
<PLUS_ARGS>\n {
|
||||
yylloc.first_line += 1;
|
||||
cflloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice the -a flag. */
|
||||
"-a" { return TOK_Da; }
|
||||
|
||||
/* Notice the -c or -f flag. */
|
||||
"-c" { return TOK_Dc; }
|
||||
"-f" { return TOK_Dc; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
|
|
@ -142,6 +150,18 @@ static int comment_enter;
|
|||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
/* At the end of file switch back to the previous buffer. */
|
||||
<<EOF>> {
|
||||
if (--cmdfile_stack_ptr < 0) {
|
||||
free(current_file);
|
||||
yyterminate();
|
||||
} else {
|
||||
yy_delete_buffer(YY_CURRENT_BUFFER);
|
||||
yy_switch_to_buffer(cmdfile_stack[cmdfile_stack_ptr].buffer);
|
||||
free(current_file);
|
||||
current_file = cmdfile_stack[cmdfile_stack_ptr].cmdfile;
|
||||
} }
|
||||
|
||||
%%
|
||||
|
||||
static char* trim_trailing_white(char*text, int trim)
|
||||
|
|
@ -164,10 +184,52 @@ int yywrap()
|
|||
return 1;
|
||||
}
|
||||
|
||||
void switch_to_command_file(const char *file)
|
||||
{
|
||||
char path[4096];
|
||||
char *cp;
|
||||
|
||||
if (cmdfile_stack_ptr >= MAX_CMDFILE_DEPTH) {
|
||||
fprintf(stderr, "Error: command files nested too deeply (%d) "
|
||||
"at %s:%d.\n", MAX_CMDFILE_DEPTH, current_file,
|
||||
cflloc.first_line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cmdfile_stack[cmdfile_stack_ptr].buffer = YY_CURRENT_BUFFER;
|
||||
cmdfile_stack[cmdfile_stack_ptr].cmdfile = current_file;
|
||||
cmdfile_stack_ptr += 1;
|
||||
|
||||
/*
|
||||
* If this is a relative file then add the current path to the
|
||||
* file name.
|
||||
*/
|
||||
if (file[0] != '/') {
|
||||
strcpy(path, current_file);
|
||||
cp = strrchr(path, '/');
|
||||
if (cp == 0) strcpy(path, file); /* A base file. */
|
||||
else {
|
||||
*(cp+1) = '\0';
|
||||
strcat(path, file);
|
||||
}
|
||||
} else strcpy(path, file); /* An absolute path. */
|
||||
|
||||
yyin = fopen(path, "r");
|
||||
if (yyin == NULL) {
|
||||
fprintf(stderr, "Error: unable to read nested command file (%s) "
|
||||
"at %s:%d.\n", path, current_file, cflloc.first_line);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
current_file = strdup(path);
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
|
||||
cflloc.first_line = 1;
|
||||
}
|
||||
|
||||
void cfreset(FILE*fd, const char*path)
|
||||
{
|
||||
yyin = fd;
|
||||
yyrestart(fd);
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = (char*)path;
|
||||
current_file = strdup(path);
|
||||
cflloc.first_line = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ static void translate_file_name(char*text)
|
|||
char*text;
|
||||
};
|
||||
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
|
||||
%token TOK_INTEGER_WIDTH
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
|
@ -93,6 +93,16 @@ item
|
|||
|
||||
| TOK_Da { }
|
||||
|
||||
/* Match a -c <cmdfile> or -f <cmdfile> */
|
||||
|
||||
| TOK_Dc TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
translate_file_name(tmp);
|
||||
switch_to_command_file(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -v <libfile> flag is ignored, and the <libfile> is processed
|
||||
as an ordinary source file. */
|
||||
|
||||
|
|
@ -173,6 +183,12 @@ item
|
|||
}
|
||||
free($1);
|
||||
}
|
||||
|
||||
| error
|
||||
{ fprintf(stderr, "Error: unable to parse line %d in "
|
||||
"%s.\n", cflloc.first_line, current_file);
|
||||
return 1;
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
|
|
|
|||
|
|
@ -36,32 +36,11 @@ struct cfltype {
|
|||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
int cflex(void);
|
||||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
void switch_to_command_file(const char *);
|
||||
char *current_file;
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.6 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.5 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/02 02:39:34 steve
|
||||
* Use my own cfltype to defend against bison 1.30.
|
||||
*
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.1 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ iverilog - Icarus Verilog compiler
|
|||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESVv] [-Bpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-ESVv] [-Bpath] [-ccmdfile|-fcmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-g1|-g2|-g2x|-gspecify|-gxtypes|-gio-range-error]
|
||||
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
|
||||
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
|
@ -29,8 +29,8 @@ program. However, the \fB-B\fP switch allows the user to select a
|
|||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP
|
||||
This flag specifies an input file that contains a list of Verilog
|
||||
.B -c\fIfile\fP -f\fIfile\fP
|
||||
These flags specifies an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
|
|
@ -278,6 +278,12 @@ A simple file name or file path is taken to be the name of a Verilog
|
|||
source file. The path starts with the first non-white-space
|
||||
character. Variables are substituted in file names.
|
||||
|
||||
.TP 8
|
||||
.B -c\ \fIcmdfile\fP -f\ \fIcmdfile\fP
|
||||
A \fB-c\fP or \fB-f\fP token prefixes a command file, exactly like it
|
||||
does on the command line. The cmdfile may be on the same line or the
|
||||
next non-comment line.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB-y\fP token prefixes a library directory in the command file,
|
||||
|
|
|
|||
106
driver/main.c
106
driver/main.c
|
|
@ -39,12 +39,13 @@ const char NOTICE[] =
|
|||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile] [-g1|-g2|-g2x]\n"
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
|
||||
"See man page for details.";
|
||||
"\n"
|
||||
"See the man page for details.";
|
||||
|
||||
#define MAXSIZE 4096
|
||||
|
||||
|
|
@ -448,7 +449,7 @@ int process_generation(const char*name)
|
|||
|
||||
else {
|
||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||
"%s\n", name);
|
||||
"%s\n\n", name);
|
||||
fprintf(stderr, "Supported generations are:\n");
|
||||
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
|
||||
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
|
||||
|
|
@ -586,7 +587,8 @@ int main(int argc, char **argv)
|
|||
base=optarg;
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
case 'c':
|
||||
case 'f':
|
||||
add_cmd_file(optarg);
|
||||
break;
|
||||
case 'D':
|
||||
|
|
@ -595,8 +597,6 @@ int main(int argc, char **argv)
|
|||
case 'E':
|
||||
e_flag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fprintf(stderr, "warning: The -f flag is moved to -p\n");
|
||||
case 'p':
|
||||
fprintf(iconfig_file, "flag:%s\n", optarg);
|
||||
break;
|
||||
|
|
@ -678,7 +678,7 @@ int main(int argc, char **argv)
|
|||
pbase = base;
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
|
||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n\n");
|
||||
printf("Copyright 1998-2003 Stephen Williams\n");
|
||||
puts(NOTICE);
|
||||
|
||||
|
|
@ -711,16 +711,16 @@ int main(int argc, char **argv)
|
|||
int rc;
|
||||
|
||||
if (( fp = fopen(command_filename, "r")) == NULL ) {
|
||||
fprintf(stderr, "%s: Can't open %s\n",
|
||||
argv[0], command_filename);
|
||||
fprintf(stderr, "%s: cannot open command file %s "
|
||||
"for reading.\n", argv[0], command_filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cfreset(fp, command_filename);
|
||||
rc = cfparse();
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "%s: error reading command file\n",
|
||||
command_filename);
|
||||
fprintf(stderr, "%s: parsing failed in base command "
|
||||
"file %s.\n", argv[0], command_filename);
|
||||
return 1;
|
||||
}
|
||||
free(command_filename);
|
||||
|
|
@ -743,8 +743,7 @@ int main(int argc, char **argv)
|
|||
defines_file = 0;
|
||||
|
||||
if (source_count == 0) {
|
||||
fprintf(stderr, "%s: No input files.\n", argv[0]);
|
||||
fprintf(stderr, "%s\n", HELP);
|
||||
fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -809,84 +808,3 @@ int main(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.76 2007/06/05 01:56:12 steve
|
||||
* Bring in .SFT file automatically if -m used.
|
||||
*
|
||||
* Revision 1.75 2007/04/19 02:52:53 steve
|
||||
* Add support for -v flag in command file.
|
||||
*
|
||||
* Revision 1.74 2007/04/18 03:23:38 steve
|
||||
* Add support for multiple command files. (Cary R.)
|
||||
*
|
||||
* Revision 1.73 2007/03/07 04:24:59 steve
|
||||
* Make integer width controllable.
|
||||
*
|
||||
* Revision 1.72 2006/10/02 18:15:47 steve
|
||||
* Fix handling of dep path in new argument passing method.
|
||||
*
|
||||
* Revision 1.71 2006/09/28 04:35:18 steve
|
||||
* Support selective control of specify and xtypes features.
|
||||
*
|
||||
* Revision 1.70 2006/09/20 22:30:52 steve
|
||||
* Do not pass -D__ICARUS__ to ivlpp.
|
||||
*
|
||||
* Revision 1.69 2006/07/26 00:11:40 steve
|
||||
* Pass depfiles through temp defines file.
|
||||
*
|
||||
* Revision 1.68 2006/07/26 00:02:48 steve
|
||||
* Pass defines and includes through temp file.
|
||||
*
|
||||
* Revision 1.67 2005/07/14 23:38:44 steve
|
||||
* Display as version 0.9.devel
|
||||
*
|
||||
* Revision 1.66 2005/06/28 04:25:55 steve
|
||||
* Remove reference to SystemVerilog.
|
||||
*
|
||||
* Revision 1.65 2004/06/17 14:47:22 steve
|
||||
* Add a .sft file for the system functions.
|
||||
*
|
||||
* Revision 1.64 2004/03/10 04:51:25 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.63 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.62 2003/12/12 04:36:48 steve
|
||||
* Fix make check to support -tconf configuration method.
|
||||
*
|
||||
* Revision 1.61 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.60 2003/11/13 05:55:33 steve
|
||||
* Move the DLL= flag to target config files.
|
||||
*
|
||||
* Revision 1.59 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.58 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.57 2003/10/26 22:43:42 steve
|
||||
* Improve -V messages,
|
||||
*
|
||||
* Revision 1.56 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.55 2003/09/23 05:57:15 steve
|
||||
* Pass -m flag from driver via iconfig file.
|
||||
*
|
||||
* Revision 1.54 2003/09/22 01:12:09 steve
|
||||
* Pass more ivl arguments through the iconfig file.
|
||||
*
|
||||
* Revision 1.53 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.52 2003/02/22 04:55:36 steve
|
||||
* portbind adds p, not i, flag.
|
||||
*
|
||||
* Revision 1.51 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue