1 const char COPYRIGHT
[] =
2 "Copyright (c) 1999 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
20 #ident "$Id: main.c,v 1.23 2006/10/02 18:16:18 steve Exp $"
26 " This program is free software; you can redistribute it and/or modify\n"
27 " it under the terms of the GNU General Public License as published by\n"
28 " the Free Software Foundation; either version 2 of the License, or\n"
29 " (at your option) any later version.\n"
31 " This program is distributed in the hope that it will be useful,\n"
32 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
33 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
34 " GNU General Public License for more details.\n"
36 " You should have received a copy of the GNU General Public License\n"
37 " along with this program; if not, write to the Free Software\n"
38 " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
41 const char VERSION
[] = "$Name: $ $State: Exp $";
51 #if defined(HAVE_GETOPT_H)
56 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
57 extern int getopt(int argc
, char*argv
[], const char*fmt
);
59 extern const char*optarg
;
61 /* Path to the dependency file, if there is one. */
62 char *dep_path
= NULL
;
65 * Keep in source_list an array of pointers to file names. The array
66 * is terminated by a pointer to null.
68 static char**source_list
= 0;
69 static unsigned source_cnt
= 0;
71 void add_source_file(const char*name
)
73 if (source_list
== 0) {
74 source_list
= calloc(2, sizeof(char*));
75 source_list
[0] = strdup(name
);
79 source_list
= realloc(source_list
, sizeof(char*) * (source_cnt
+2));
80 source_list
[source_cnt
+0] = strdup(name
);
81 source_list
[source_cnt
+1] = 0;
86 char**include_dir
= 0;
87 unsigned include_cnt
= 0;
89 int line_direct_flag
= 0;
91 unsigned error_count
= 0;
92 FILE *depend_file
= NULL
;
94 static int flist_read_flags(const char*path
)
97 FILE*fd
= fopen(path
, "r");
99 fprintf(stderr
, "%s: unable to open for reading.\n", path
);
103 while (fgets(line_buf
, sizeof line_buf
, fd
) != 0) {
104 /* Skip leading white space. */
105 char*cp
= line_buf
+ strspn(line_buf
, " \t\r\b\f");
106 /* Remove trailing white space. */
107 char*tail
= cp
+ strlen(cp
);
109 if (! isspace(tail
[-1]))
115 /* Skip empty lines */
118 /* Skip comment lines */
122 /* The arg points to the argument to the keyword. */
123 char*arg
= strchr(cp
, ':');
126 if (strcmp(cp
,"D") == 0) {
127 char*val
= strchr(arg
, '=');
133 define_macro(arg
, val
, 0, 0);
135 } else if (strcmp(cp
,"I") == 0) {
136 include_dir
= realloc(include_dir
,
137 (include_cnt
+1)*sizeof(char*));
138 include_dir
[include_cnt
] = strdup(arg
);
141 } else if (strcmp(cp
,"keyword") == 0) {
142 char*buf
= malloc(strlen(arg
) + 2);
144 strcpy(buf
+1, optarg
);
145 define_macro(optarg
, buf
, 1, 0);
148 } else if (strcmp(cp
,"M") == 0) {
150 fprintf(stderr
, "duplicate -M flag.\n");
152 dep_path
= strdup(arg
);
156 fprintf(stderr
, "%s: Invalid keyword %s\n", path
, cp
);
165 * This function reads from a file a list of file names. Each name
166 * starts with the first non-space character, and ends with the last
167 * non-space character. Spaces in the middle are OK.
169 static int flist_read_names(const char*path
)
173 FILE*fd
= fopen(path
, "r");
175 fprintf(stderr
, "%s: unable to open for reading.\n", path
);
179 while (fgets(line_buf
, sizeof line_buf
, fd
) != 0) {
180 char*cp
= line_buf
+ strspn(line_buf
, " \t\r\b\f");
181 char*tail
= cp
+ strlen(cp
);
183 if (! isspace(tail
[-1]))
196 int main(int argc
, char*argv
[])
199 const char*flist_path
= 0;
200 unsigned flag_errors
= 0;
204 /* Define preprocessor keywords that I plan to just pass. */
205 define_macro("celldefine", "`celldefine", 1, 0);
206 define_macro("default_nettype", "`default_nettype", 1, 0);
207 define_macro("delay_mode_distributed", "`delay_mode_distributed", 1, 0);
208 define_macro("delay_mode_unit", "`delay_mode_unit", 1, 0);
209 define_macro("delay_mode_path", "`delay_mode_path", 1, 0);
210 define_macro("disable_portfaults", "`disable_portfaults", 1, 0);
211 define_macro("enable_portfaults", "`enable_portfaults", 1, 0);
212 define_macro("endcelldefine", "`endcelldefine", 1, 0);
213 define_macro("endprotect", "`endprotect", 1, 0);
214 define_macro("nosuppress_faults", "`nosuppress_faults", 1, 0);
215 define_macro("nounconnected_drive", "`nounconnected_drive", 1, 0);
216 define_macro("protect", "`protect", 1, 0);
217 define_macro("resetall", "`resetall", 1, 0);
218 define_macro("suppress_faults", "`suppress_faults", 1, 0);
219 define_macro("timescale", "`timescale", 1, 0);
220 define_macro("unconnected_drive", "`unconnected_drive", 1, 0);
221 define_macro("uselib", "`uselib", 1, 0);
224 include_dir
= malloc(include_cnt
*sizeof(char*));
225 include_dir
[0] = 0; /* 0 is reserved for the current files path. */
226 include_dir
[1] = strdup(".");
228 while ((opt
=getopt(argc
, argv
, "F:f:K:Lo:v")) != EOF
) switch (opt
) {
231 flist_read_flags(optarg
);
236 fprintf(stderr
, "%s: duplicate -f flag\n", argv
[0]);
243 char*buf
= malloc(strlen(optarg
) + 2);
245 strcpy(buf
+1, optarg
);
246 define_macro(optarg
, buf
, 1, 0);
252 line_direct_flag
= 1;
257 fprintf(stderr
, "duplicate -o flag.\n");
264 fprintf(stderr
, "Icarus Verilog Preprocessor version %s\n",
266 fprintf(stderr
, "%s\n", COPYRIGHT
);
267 fputs(NOTICE
, stderr
);
276 fprintf(stderr
, "\nUsage: %s [-v][-L][-F<fil>][-f<fil>] <file>...\n"
277 " -F<fil> - Get defines and includes from file\n"
278 " -f<fil> - Read the sources listed in the file\n"
279 " -K<def> - Define a keyword macro that I just pass\n"
280 " -L - Emit line number directives\n"
281 " -o<fil> - Send the output to <fil>\n"
282 " -v - Print version information\n",
287 /* Collect the file names on the command line in the source
288 file list, then if there is a file list, read more file
290 for (idx
= optind
; idx
< argc
; idx
+= 1)
291 add_source_file(argv
[idx
]);
295 int rc
= flist_read_names(flist_path
);
300 /* Figure out what to use for an output file. Write to stdout
301 if no path is specified. */
303 out
= fopen(out_path
, "w");
313 depend_file
= fopen(dep_path
, "w");
314 if (depend_file
== 0) {
320 if (source_cnt
== 0) {
321 fprintf(stderr
, "%s: No input files given.\n", argv
[0]);
325 /* Pass to the lexical analyzer the list of input file, and
327 reset_lexor(out
, source_list
);
328 if (yyparse()) return -1;