1 const char COPYRIGHT
[] =
2 "Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)";
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
23 " This program is free software; you can redistribute it and/or modify\n"
24 " it under the terms of the GNU General Public License as published by\n"
25 " the Free Software Foundation; either version 2 of the License, or\n"
26 " (at your option) any later version.\n"
28 " This program is distributed in the hope that it will be useful,\n"
29 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
30 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
31 " GNU General Public License for more details.\n"
33 " You should have received a copy of the GNU General Public License\n"
34 " along with this program; if not, write to the Free Software\n"
35 " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
38 const char VERSION
[] = "$Name: $ $State: Exp $";
48 #if defined(HAVE_GETOPT_H)
53 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
54 extern int getopt(int argc
, char*argv
[], const char*fmt
);
56 extern const char*optarg
;
58 /* Path to the dependency file, if there is one. */
59 char *dep_path
= NULL
;
63 * Keep in source_list an array of pointers to file names. The array
64 * is terminated by a pointer to null.
66 static char**source_list
= 0;
67 static unsigned source_cnt
= 0;
69 void add_source_file(const char*name
)
71 if (source_list
== 0) {
72 source_list
= calloc(2, sizeof(char*));
73 source_list
[0] = strdup(name
);
77 source_list
= realloc(source_list
, sizeof(char*) * (source_cnt
+2));
78 source_list
[source_cnt
+0] = strdup(name
);
79 source_list
[source_cnt
+1] = 0;
84 char**include_dir
= 0;
85 unsigned include_cnt
= 0;
87 int line_direct_flag
= 0;
89 unsigned error_count
= 0;
90 FILE *depend_file
= NULL
;
92 static int flist_read_flags(const char*path
)
95 FILE*fd
= fopen(path
, "r");
97 fprintf(stderr
, "%s: unable to open for reading.\n", path
);
101 while (fgets(line_buf
, sizeof line_buf
, fd
) != 0) {
102 /* Skip leading white space. */
103 char*cp
= line_buf
+ strspn(line_buf
, " \t\r\b\f");
104 /* Remove trailing white space. */
105 char*tail
= cp
+ strlen(cp
);
107 if (! isspace(tail
[-1]))
113 /* Skip empty lines */
116 /* Skip comment lines */
120 /* The arg points to the argument to the keyword. */
121 char*arg
= strchr(cp
, ':');
124 if (strcmp(cp
,"D") == 0) {
125 char*val
= strchr(arg
, '=');
131 define_macro(arg
, val
, 0, 0);
133 } else if (strcmp(cp
,"I") == 0) {
134 include_dir
= realloc(include_dir
,
135 (include_cnt
+1)*sizeof(char*));
136 include_dir
[include_cnt
] = strdup(arg
);
139 } else if (strcmp(cp
,"keyword") == 0) {
140 char*buf
= malloc(strlen(arg
) + 2);
142 strcpy(buf
+1, optarg
);
143 define_macro(optarg
, buf
, 1, 0);
146 } else if (strcmp(cp
,"M") == 0) {
148 fprintf(stderr
, "duplicate -M flag.\n");
150 dep_path
= strdup(arg
);
154 fprintf(stderr
, "%s: Invalid keyword %s\n", path
, cp
);
163 * This function reads from a file a list of file names. Each name
164 * starts with the first non-space character, and ends with the last
165 * non-space character. Spaces in the middle are OK.
167 static int flist_read_names(const char*path
)
171 FILE*fd
= fopen(path
, "r");
173 fprintf(stderr
, "%s: unable to open for reading.\n", path
);
177 while (fgets(line_buf
, sizeof line_buf
, fd
) != 0) {
178 char*cp
= line_buf
+ strspn(line_buf
, " \t\r\b\f");
179 char*tail
= cp
+ strlen(cp
);
181 if (! isspace(tail
[-1]))
194 int main(int argc
, char*argv
[])
197 const char*flist_path
= 0;
198 unsigned flag_errors
= 0;
201 char*precomp_out_path
= 0;
202 FILE*precomp_out
= NULL
;
204 /* Define preprocessor keywords that I plan to just pass. */
205 define_macro("celldefine", "`celldefine", 1, 0);
206 define_macro("default_decay_time", "`default_decay_time", 1, 0);
207 define_macro("default_nettype", "`default_nettype", 1, 0);
208 define_macro("default_trireg_strength", "`default_trireg_strength", 1, 0);
209 define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
210 define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
211 define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
212 define_macro("delay_mode_zero", "`delay_mode_zero", 1, 0);
213 define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
214 define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
215 define_macro("endcelldefine", "`endcelldefine", 1, 0);
216 define_macro("endprotect", "`endprotect", 1, 0);
217 define_macro("line", "`line", 1, 0);
218 define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
219 define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0);
220 define_macro("protect", "`protect", 1, 0);
221 define_macro("resetall", "`resetall", 1, 0);
222 define_macro("suppress_faults", "`suppress_faults", 1, 0);
223 define_macro("timescale", "`timescale", 1, 0);
224 define_macro("unconnected_drive", "`unconnected_drive", 1, 0);
225 define_macro("uselib", "`uselib", 1, 0);
228 include_dir
= malloc(include_cnt
*sizeof(char*));
229 include_dir
[0] = 0; /* 0 is reserved for the current files path. */
230 include_dir
[1] = strdup(".");
232 while ((opt
=getopt(argc
, argv
, "F:f:K:Lo:p:P:v")) != EOF
) switch (opt
) {
235 flist_read_flags(optarg
);
240 fprintf(stderr
, "%s: duplicate -f flag\n", argv
[0]);
247 char*buf
= malloc(strlen(optarg
) + 2);
249 strcpy(buf
+1, optarg
);
250 define_macro(optarg
, buf
, 1, 0);
256 line_direct_flag
= 1;
261 fprintf(stderr
, "duplicate -o flag.\n");
268 if (precomp_out_path
) {
269 fprintf(stderr
, "duplicate -p flag.\n");
271 precomp_out_path
= optarg
;
276 FILE*src
= fopen(optarg
, "rb");
281 load_precompiled_defines(src
);
287 fprintf(stderr
, "Icarus Verilog Preprocessor version %s\n",
289 fprintf(stderr
, "%s\n", COPYRIGHT
);
290 fputs(NOTICE
, stderr
);
299 fprintf(stderr
, "\nUsage: %s [-v][-L][-F<fil>][-f<fil>] <file>...\n"
300 " -F<fil> - Get defines and includes from file\n"
301 " -f<fil> - Read the sources listed in the file\n"
302 " -K<def> - Define a keyword macro that I just pass\n"
303 " -L - Emit line number directives\n"
304 " -o<fil> - Send the output to <fil>\n"
305 " -p<fil> - Write precompiled defines to <fil>\n"
306 " -P<fil> - Read precompiled defines from <fil>\n"
307 " -v - Print version information\n",
312 /* Collect the file names on the command line in the source
313 file list, then if there is a file list, read more file
315 for (idx
= optind
; idx
< argc
; idx
+= 1)
316 add_source_file(argv
[idx
]);
320 int rc
= flist_read_names(flist_path
);
325 /* Figure out what to use for an output file. Write to stdout
326 if no path is specified. */
328 out
= fopen(out_path
, "w");
337 if (precomp_out_path
) {
338 precomp_out
= fopen(precomp_out_path
, "wb");
339 if (precomp_out
== 0) {
340 perror(precomp_out_path
);
346 depend_file
= fopen(dep_path
, "w");
347 if (depend_file
== 0) {
353 if (source_cnt
== 0) {
354 fprintf(stderr
, "%s: No input files given.\n", argv
[0]);
358 /* Pass to the lexical analyzer the list of input file, and
360 reset_lexor(out
, source_list
);
361 if (yylex()) return -1;
368 dump_precompiled_defines(precomp_out
);