Merge branch 'master' into verilog-ams
[sverilog.git] / driver / main.c
blob55fac84b314652c9583547e1a1f6627c8e2d79bd
1 /*
2 * Copyright (c) 2000-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)
8 * any later version.
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 # include "config.h"
21 # include "version.h"
23 const char NOTICE[] =
24 " This program is free software; you can redistribute it and/or modify\n"
25 " it under the terms of the GNU General Public License as published by\n"
26 " the Free Software Foundation; either version 2 of the License, or\n"
27 " (at your option) any later version.\n"
28 "\n"
29 " This program is distributed in the hope that it will be useful,\n"
30 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
31 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
32 " GNU General Public License for more details.\n"
33 "\n"
34 " You should have received a copy of the GNU General Public License\n"
35 " along with this program; if not, write to the Free Software\n"
36 " Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
39 const char HELP[] =
40 "Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile] [-g1|-g2|-g2x]\n"
41 " [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
42 " [-N file] [-o filename] [-p flag=value]\n"
43 " [-s topmodule] [-t target] [-T min|typ|max]\n"
44 " [-W class] [-y dir] [-Y suf] source_file(s)\n"
45 "\n"
46 "See the man page for details.";
48 #define MAXSIZE 4096
50 #include <stdio.h>
51 #include <unistd.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <assert.h>
56 #include <sys/types.h>
57 #ifdef HAVE_SYS_WAIT_H
58 #include <sys/wait.h>
59 #endif
61 #ifdef __MINGW32__
62 #include <windows.h>
63 #ifdef HAVE_LIBIBERTY_H
64 #include <libiberty.h>
65 #endif
66 #endif
68 #if HAVE_GETOPT_H
69 #include <getopt.h>
70 #endif
72 #if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
73 extern int getopt(int argc, char*argv[], const char*fmt);
74 extern int optind;
75 extern const char*optarg;
76 #endif
78 #if !defined(WIFEXITED)
79 # define WIFEXITED(rc) ((rc&0x7f) == 0)
80 #endif
82 #if !defined(WEXITSTATUS)
83 # define WEXITSTATUS(rc) (rc>>8)
84 #endif
86 #ifndef IVL_ROOT
87 # define IVL_ROOT "."
88 #endif
90 # include "globals.h"
91 #include "cfparse_misc.h" /* cfparse() */
93 #ifdef __MINGW32__
94 const char sep = '\\';
95 #else
96 const char sep = '/';
97 #endif
99 extern void cfreset(FILE*fd, const char*path);
101 const char*base = 0;
102 const char*pbase = 0;
103 const char*mtm = 0;
104 const char*opath = "a.out";
105 const char*npath = 0;
106 const char*targ = "vvp";
107 const char*depfile = 0;
109 const char*generation = "2x";
110 const char*gen_specify = "specify";
111 const char*gen_xtypes = "xtypes";
112 const char*gen_icarus = "icarus-misc";
113 const char*gen_io_range_error = "io-range-error";
114 const char*gen_verilog_ams = "no-verilog-ams";
116 /* Boolean: true means use a default include dir, false means don't */
117 int gen_std_include = 1;
119 char warning_flags[16] = "";
121 unsigned integer_width = 32;
123 char*mod_list = 0;
124 char*command_filename = 0;
126 /* These are used to collect the list of file names that will be
127 passed to ivlpp. Keep the list in a file because it can be a long
128 list. */
129 char*source_path = 0;
130 FILE*source_file = 0;
131 unsigned source_count = 0;
133 char*defines_path = 0;
134 FILE*defines_file = 0;
136 char*iconfig_path = 0;
137 FILE*iconfig_file = 0;
139 char*compiled_defines_path = 0;
141 static char iconfig_common_path_buf[4096] = "";
142 char*iconfig_common_path = iconfig_common_path_buf;
144 int synth_flag = 0;
145 int verbose_flag = 0;
147 FILE *fp;
149 char line[MAXSIZE];
150 char tmp[MAXSIZE];
152 static char ivl_root[MAXSIZE];
154 /* Structure to keep a FIFO list of the command files */
155 typedef struct t_command_file {
156 char *filename;
157 struct t_command_file *next;
158 } s_command_file, *p_command_file;
159 p_command_file cmd_file_head = NULL; /* The FIFO head */
160 p_command_file cmd_file_tail = NULL; /* The FIFO tail */
162 /* Function to add a command file name to the FIFO. */
163 void add_cmd_file(const char* filename)
165 p_command_file new;
167 new = (p_command_file) malloc(sizeof(s_command_file));
168 new->filename = strdup(filename);
169 new->next = NULL;
170 if (cmd_file_head == NULL) {
171 cmd_file_head = new;
172 cmd_file_tail = new;
173 } else {
174 cmd_file_tail->next = new;
175 cmd_file_tail = new;
179 /* Function to return the top command file name from the FIFO. */
180 char *get_cmd_file()
182 char *filename;
184 if (cmd_file_head == NULL) filename = NULL;
185 else {
186 p_command_file head;
188 filename = cmd_file_head->filename;
189 head = cmd_file_head;
190 cmd_file_head = cmd_file_head->next;
191 free(head);
193 return filename;
196 #ifdef __MINGW32__
197 # include <io.h>
198 # include <fcntl.h>
199 static FILE*fopen_safe(const char*path)
201 FILE*file = 0;
202 int fd;
204 fd = _open(path, _O_WRONLY|_O_CREAT|_O_EXCL, 0700);
205 if (fd != -1)
206 file = _fdopen(fd, "w");
208 return file;
210 #else
211 # include <fcntl.h>
212 static FILE*fopen_safe(const char*path)
214 FILE*file = 0;
215 int fd;
217 fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0700);
218 if (fd != -1)
219 file = fdopen(fd, "w");
221 return file;
223 #endif
225 static const char*my_tempfile(const char*str, FILE**fout)
227 FILE*file;
228 int retry;
230 static char pathbuf[8192];
232 const char*tmpdir = getenv("TMP");
233 if (tmpdir == 0)
234 tmpdir = getenv("TMPDIR");
235 if (tmpdir == 0)
236 tmpdir = getenv("TEMP");
237 #ifdef __MINGW32__
238 if (tmpdir == 0)
239 tmpdir = "C:\\TEMP";
240 #else
241 if (tmpdir == 0)
242 tmpdir = "/tmp";
243 #endif
245 assert(tmpdir);
246 assert((strlen(tmpdir) + strlen(str)) < sizeof pathbuf - 10);
248 srand(getpid());
249 retry = 100;
250 file = NULL;
251 while ((retry > 0) && (file == NULL)) {
252 unsigned code = rand();
253 sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
254 file = fopen_safe(pathbuf);
255 retry -= 1;
258 *fout = file;
259 return pathbuf;
263 * This is the default target type. It looks up the bits that are
264 * needed to run the command from the configuration file (which is
265 * already parsed for us) so we can handle must of the generic cases.
267 static int t_default(char*cmd, unsigned ncmd)
269 unsigned rc;
270 #ifdef __MINGW32__
271 unsigned ncmd_start = ncmd;
272 #endif
274 snprintf(tmp, sizeof tmp, " | %s/ivl", base);
275 rc = strlen(tmp);
276 cmd = realloc(cmd, ncmd+rc+1);
277 strcpy(cmd+ncmd, tmp);
278 ncmd += rc;
280 if (verbose_flag) {
281 const char*vv = " -v";
282 rc = strlen(vv);
283 cmd = realloc(cmd, ncmd+rc+1);
284 strcpy(cmd+ncmd, vv);
285 ncmd += rc;
288 if (npath != 0) {
289 snprintf(tmp, sizeof tmp, " -N%s", npath);
290 rc = strlen(tmp);
291 cmd = realloc(cmd, ncmd+rc+1);
292 strcpy(cmd+ncmd, tmp);
293 ncmd += rc;
296 snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
297 rc = strlen(tmp);
298 cmd = realloc(cmd, ncmd+rc+1);
299 strcpy(cmd+ncmd, tmp);
300 ncmd += rc;
302 snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
303 rc = strlen(tmp);
304 cmd = realloc(cmd, ncmd+rc+1);
305 strcpy(cmd+ncmd, tmp);
306 ncmd += rc;
308 #ifdef __MINGW32__
310 char *t;
311 for (t = cmd+ncmd_start; *t; t++)
313 if (*t == '/') *t = '\\';
316 #endif
319 if (verbose_flag)
320 printf("translate: %s\n", cmd);
323 rc = system(cmd);
324 if ( ! getenv("IVERILOG_ICONFIG")) {
325 remove(source_path);
326 remove(iconfig_path);
327 remove(defines_path);
328 remove(compiled_defines_path);
330 #ifdef __MINGW32__ /* MinGW just returns the exit status, so return it! */
331 return rc;
332 #else
334 if (rc != 0) {
335 if (rc == 127) {
336 fprintf(stderr, "Failed to execute: %s\n", cmd);
337 return 1;
340 if (WIFEXITED(rc))
341 return WEXITSTATUS(rc);
343 fprintf(stderr, "Command signaled: %s\n", cmd);
344 return -1;
347 return 0;
348 #endif
352 static void process_warning_switch(const char*name)
354 if (strcmp(name,"all") == 0) {
355 process_warning_switch("implicit");
356 process_warning_switch("portbind");
357 process_warning_switch("timescale");
358 } else if (strcmp(name,"implicit") == 0) {
359 if (! strchr(warning_flags, 'i'))
360 strcat(warning_flags, "i");
361 } else if (strcmp(name,"portbind") == 0) {
362 if (! strchr(warning_flags, 'p'))
363 strcat(warning_flags, "p");
364 } else if (strcmp(name,"timescale") == 0) {
365 if (! strchr(warning_flags, 't'))
366 strcat(warning_flags, "t");
367 /* Since the infinite loop check is not part of 'all' it
368 * does not have a no- version. */
369 } else if (strcmp(name,"infloop") == 0) {
370 if (! strchr(warning_flags, 'l'))
371 strcat(warning_flags, "l");
372 } else if (strcmp(name,"no-implicit") == 0) {
373 char*cp = strchr(warning_flags, 'i');
374 if (cp) while (*cp) {
375 cp[0] = cp[1];
376 cp += 1;
378 } else if (strcmp(name,"no-portbind") == 0) {
379 char*cp = strchr(warning_flags, 'p');
380 if (cp) while (*cp) {
381 cp[0] = cp[1];
382 cp += 1;
384 } else if (strcmp(name,"no-timescale") == 0) {
385 char*cp = strchr(warning_flags, 't');
386 if (cp) while (*cp) {
387 cp[0] = cp[1];
388 cp += 1;
393 void process_library_switch(const char *name)
395 fprintf(iconfig_file, "-y:%s\n", name);
398 void process_library_nocase_switch(const char *name)
400 fprintf(iconfig_file, "-yl:%s\n", name);
403 void process_library2_switch(const char *name)
405 fprintf(iconfig_file, "-Y:%s\n", name);
408 void process_include_dir(const char *name)
410 fprintf(defines_file, "I:%s\n", name);
413 void process_define(const char*name)
415 fprintf(defines_file,"D:%s\n", name);
419 * This function is called while processing a file name in a command
420 * file, or a file name on the command line. Look to see if there is a
421 * .sft suffix, and if so pass that as a sys_func file. Otherwise, it
422 * is a Verilog source file to be written into the file list.
424 void process_file_name(const char*name, int lib_flag)
426 if (strlen(name) > 4 && strcasecmp(".sft", name+strlen(name)-4) == 0) {
427 fprintf(iconfig_file,"sys_func:%s\n", name);
429 } else {
430 fprintf(source_file, "%s\n", name);
431 source_count += 1;
432 if (lib_flag)
433 fprintf(iconfig_file,"library_file:%s\n", name);
437 int process_generation(const char*name)
439 if (strcmp(name,"1995") == 0)
440 generation = "1995";
442 else if (strcmp(name,"2001") == 0)
443 generation = "2001";
445 else if (strcmp(name,"2005") == 0)
446 generation = "2005";
448 else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
449 generation = "1995";
450 gen_xtypes = "no-xtypes";
451 gen_icarus = "no-icarus-misc";
453 } else if (strcmp(name,"2") == 0) { /* Deprecated: use 2001 */
454 generation = "2001";
455 gen_xtypes = "no-xtypes";
456 gen_icarus = "no-icarus-misc";
458 } else if (strcmp(name,"2x") == 0) { /* Deprecated: use 2005/xtypes */
459 generation = "2005";
460 gen_xtypes = "xtypes";
461 gen_icarus = "icarus-misc";
463 } else if (strcmp(name,"xtypes") == 0)
464 gen_xtypes = "xtypes";
466 else if (strcmp(name,"no-xtypes") == 0)
467 gen_xtypes = "no-xtypes";
469 else if (strcmp(name,"icarus-misc") == 0)
470 gen_icarus = "icarus-misc";
472 else if (strcmp(name,"no-icarus-misc") == 0)
473 gen_icarus = "no-icarus-misc";
475 else if (strcmp(name,"specify") == 0)
476 gen_specify = "specify";
478 else if (strcmp(name,"no-specify") == 0)
479 gen_specify = "no-specify";
481 else if (strcmp(name,"std-include") == 0)
482 gen_std_include = 1;
484 else if (strcmp(name,"no-std-include") == 0)
485 gen_std_include = 0;
487 else if (strcmp(name,"io-range-error") == 0)
488 gen_io_range_error = "io-range-error";
490 else if (strcmp(name,"no-io-range-error") == 0)
491 gen_io_range_error = "no-io-range-error";
493 else if (strcmp(name,"verilog-ams") == 0)
494 gen_verilog_ams = "verilog-ams";
496 else if (strcmp(name,"no-verilog-ams") == 0)
497 gen_verilog_ams = "no-verilog-ams";
499 else {
500 fprintf(stderr, "Unknown/Unsupported Language generation "
501 "%s\n\n", name);
502 fprintf(stderr, "Supported generations are:\n");
503 fprintf(stderr, " 1995 -- IEEE1364-1995\n"
504 " 2001 -- IEEE1364-2001\n"
505 " 2005 -- IEEE1364-2005\n"
506 "Other generation flags:\n"
507 " specify | no-specify\n"
508 " verilog-ams | no-verinlog-ams\n"
509 " std-include | no-std-include\n"
510 " xtypes | no-xtypes\n"
511 " icarus-misc | no-icarus-misc\n"
512 " io-range-error | no-io-range-error\n");
513 return 1;
516 return 0;
520 * If it exists add the SFT file for the given module.
522 void add_sft_file(const char *module)
524 char *file;
526 file = (char *) malloc(strlen(base)+1+strlen(module)+4+1);
527 sprintf(file, "%s%c%s.sft", base, sep, module);
528 if (access(file, R_OK) == 0)
529 fprintf(iconfig_file, "sys_func:%s\n", file);
530 free(file);
533 int main(int argc, char **argv)
535 char*cmd;
536 unsigned ncmd;
537 int e_flag = 0;
538 int version_flag = 0;
539 int opt, idx, rc;
541 #ifdef __MINGW32__
542 { char * s;
543 char basepath[1024];
544 GetModuleFileName(NULL,basepath,1024);
546 /* Calculate the ivl_root from the path to the command. This
547 is necessary because of the installation process in
548 Windows. Mostly, it is those darn drive letters, but oh
549 well. We know the command path is formed like this:
551 D:\iverilog\bin\iverilog.exe
553 The IVL_ROOT in a Windows installation is the path:
555 D:\iverilog\lib\ivl
557 so we chop the file name and the last directory by
558 turning the last two \ characters to null. Then we append
559 the lib\ivl to finish. */
561 strncpy(ivl_root, basepath, MAXSIZE);
562 s = strrchr(ivl_root, sep);
563 if (s) *s = 0;
564 s = strrchr(ivl_root, sep);
565 if (s) *s = 0;
566 strcat(ivl_root, "\\lib\\ivl");
568 base = ivl_root;
571 #else
572 /* In a UNIX environment, the IVL_ROOT from the Makefile is
573 dependable. It points to the $prefix/lib/ivl directory,
574 where the sub-parts are installed. */
575 strcpy(ivl_root, IVL_ROOT);
576 base = ivl_root;
577 #endif
579 /* Create a temporary file for communicating input parameters
580 to the preprocessor. */
581 source_path = strdup(my_tempfile("ivrlg", &source_file));
582 if (NULL == source_file) {
583 fprintf(stderr, "%s: Error opening temporary file %s\n",
584 argv[0], source_path);
585 fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
586 return 1;
589 defines_path = strdup(my_tempfile("ivrlg2", &defines_file));
590 if (NULL == defines_file) {
591 fprintf(stderr, "%s: Error opening temporary file %s\n",
592 argv[0], defines_path);
593 fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
595 fclose(source_file);
596 remove(source_path);
597 return 1;
600 fprintf(defines_file, "D:__ICARUS__=1\n");
601 if (strcmp(gen_verilog_ams,"verilog-ams") == 0)
602 fprintf(defines_file, "D:__VAMS_ENABLE__=1\n");
604 /* Create another temporary file for passing configuration
605 information to ivl. */
607 if ( (iconfig_path = getenv("IVERILOG_ICONFIG")) ) {
608 fprintf(stderr, "%s: IVERILOG_ICONFIG=%s\n",
609 argv[0], iconfig_path);
611 iconfig_file = fopen(iconfig_path, "w");
613 } else {
615 iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
618 if (NULL == iconfig_file) {
619 fprintf(stderr, "%s: Error opening temporary file %s\n",
620 argv[0], iconfig_path);
621 fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
622 fclose(source_file);
623 remove(source_path);
625 fclose(defines_file);
626 remove(defines_path);
627 return 1;
630 /* Create a temporary file (I only really need the path) that
631 can carry preprocessor precompiled defines to the library. */
632 { FILE*tmp_file = 0;
633 compiled_defines_path = strdup(my_tempfile("ivrli", &tmp_file));
634 if (tmp_file) {
635 fclose(tmp_file);
639 while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
641 switch (opt) {
642 case 'B':
643 /* Undocumented feature: The preprocessor itself
644 may be located at a different location. If the
645 base starts with a 'P', set this special base
646 instead of the main base. */
647 if (optarg[0] == 'P') {
648 pbase = optarg+1;
649 } else {
650 base=optarg;
652 break;
653 case 'c':
654 case 'f':
655 add_cmd_file(optarg);
656 break;
657 case 'D':
658 process_define(optarg);
659 break;
660 case 'E':
661 e_flag = 1;
662 break;
663 case 'p':
664 fprintf(iconfig_file, "flag:%s\n", optarg);
665 break;
666 case 'd':
667 fprintf(iconfig_file, "debug:%s\n", optarg);
668 break;
670 case 'g':
671 rc = process_generation(optarg);
672 if (rc != 0)
673 return -1;
674 break;
675 case 'h':
676 fprintf(stderr, "%s\n", HELP);
677 return 1;
679 case 'I':
680 process_include_dir(optarg);
681 break;
683 case 'M':
684 depfile = optarg;
685 break;
687 case 'm':
688 fprintf(iconfig_file, "module:%s\n", optarg);
689 add_sft_file(optarg);
690 break;
692 case 'N':
693 npath = optarg;
694 break;
696 case 'o':
697 opath = optarg;
698 break;
700 case 'S':
701 synth_flag = 1;
702 break;
703 case 's':
704 fprintf(iconfig_file, "root:%s\n", optarg);
705 break;
706 case 'T':
707 if (strcmp(optarg,"min") == 0) {
708 mtm = "min";
709 } else if (strcmp(optarg,"typ") == 0) {
710 mtm = "typ";
711 } else if (strcmp(optarg,"max") == 0) {
712 mtm = "max";
713 } else {
714 fprintf(stderr, "%s: invalid -T%s argument\n",
715 argv[0], optarg);
716 return 1;
718 break;
719 case 't':
720 targ = optarg;
721 break;
722 case 'v':
723 verbose_flag = 1;
724 break;
725 case 'V':
726 version_flag = 1;
727 break;
728 case 'W':
729 process_warning_switch(optarg);
730 break;
731 case 'y':
732 process_library_switch(optarg);
733 break;
734 case 'Y':
735 process_library2_switch(optarg);
736 break;
737 case '?':
738 default:
739 return 1;
743 if (pbase == 0)
744 pbase = base;
746 if (version_flag || verbose_flag) {
747 printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
748 printf("Copyright 1998-2008 Stephen Williams\n");
749 puts(NOTICE);
751 if (version_flag)
752 return 0;
755 /* Make a common conf file path to reflect the target. */
756 sprintf(iconfig_common_path, "%s%c%s%s.conf",
757 base,sep, targ, synth_flag? "-s" : "");
759 /* Write values to the iconfig file. */
760 fprintf(iconfig_file, "basedir:%s\n", base);
762 /* Tell the core where to find the system.sft. This file
763 describes the system functions so that elaboration knows
764 how to handle them. */
765 fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
767 /* If verilog-ams is enabled, then include the va_math module
768 as well. */
769 if (strcmp(gen_verilog_ams,"verilog-ams") == 0) {
770 fprintf(iconfig_file, "sys_func:%s%cva_math.sft\n", base, sep);
771 fprintf(iconfig_file, "module:va_math\n");
774 if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
775 fprintf(iconfig_file, "generation:%s\n", generation);
776 fprintf(iconfig_file, "generation:%s\n", gen_specify);
777 fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
778 fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
779 fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
780 fprintf(iconfig_file, "generation:%s\n", gen_icarus);
781 fprintf(iconfig_file, "warnings:%s\n", warning_flags);
782 fprintf(iconfig_file, "out:%s\n", opath);
783 if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
785 while ( (command_filename = get_cmd_file()) ) {
786 int rc;
788 if (( fp = fopen(command_filename, "r")) == NULL ) {
789 fprintf(stderr, "%s: cannot open command file %s "
790 "for reading.\n", argv[0], command_filename);
791 return 1;
794 cfreset(fp, command_filename);
795 rc = cfparse();
796 if (rc != 0) {
797 fprintf(stderr, "%s: parsing failed in base command "
798 "file %s.\n", argv[0], command_filename);
799 return 1;
801 free(command_filename);
804 if (depfile) {
805 fprintf(defines_file, "M:%s\n", depfile);
808 /* Finally, process all the remaining words on the command
809 line as file names. */
810 for (idx = optind ; idx < argc ; idx += 1)
811 process_file_name(argv[idx], 0);
813 /* If the use of a default include directory is not
814 specifically disabled, then write that directory as the
815 very last include directory to use... always. */
816 if (gen_std_include) {
817 fprintf(defines_file, "I:%s%cinclude", base, sep);
820 fclose(source_file);
821 source_file = 0;
823 fclose(defines_file);
824 defines_file = 0;
826 if (source_count == 0) {
827 fprintf(stderr, "%s: no source files.\n\n%s\n", argv[0], HELP);
828 return 1;
832 /* Start building the preprocess command line. */
834 sprintf(tmp, "%s%civlpp %s%s -F%s -f%s -p%s ", pbase,sep,
835 verbose_flag?" -v":"",
836 e_flag?"":" -L", defines_path, source_path,
837 compiled_defines_path);
839 ncmd = strlen(tmp);
840 cmd = malloc(ncmd + 1);
841 strcpy(cmd, tmp);
843 /* If the -E flag was given on the command line, then all we
844 do is run the preprocessor and put the output where the
845 user wants it. */
846 if (e_flag) {
847 int rc;
848 if (strcmp(opath,"-") != 0) {
849 sprintf(tmp, " > %s", opath);
850 cmd = realloc(cmd, ncmd+strlen(tmp)+1);
851 strcpy(cmd+ncmd, tmp);
852 ncmd += strlen(tmp);
855 if (verbose_flag)
856 printf("preprocess: %s\n", cmd);
858 rc = system(cmd);
859 remove(source_path);
860 fclose(iconfig_file);
861 if ( ! getenv("IVERILOG_ICONFIG")) {
862 remove(iconfig_path);
863 remove(defines_path);
864 remove(compiled_defines_path);
867 if (rc != 0) {
868 if (WIFEXITED(rc)) {
869 fprintf(stderr, "errors preprocessing Verilog program.\n");
870 return WEXITSTATUS(rc);
873 fprintf(stderr, "Command signaled: %s\n", cmd);
874 return -1;
877 return 0;
880 fprintf(iconfig_file, "iwidth:%u\n", integer_width);
882 /* Write the preprocessor command needed to preprocess a
883 single file. This may be used to preprocess library
884 files. */
885 fprintf(iconfig_file, "ivlpp:%s%civlpp -L -F%s -P%s\n",
886 pbase, sep, defines_path, compiled_defines_path);
888 /* Done writing to the iconfig file. Close it now. */
889 fclose(iconfig_file);
891 return t_default(cmd, ncmd);
893 return 0;