]>
Commit | Line | Data |
---|---|---|
c6e83800 ZW |
1 | /* Dependency generator utility. |
2 | Copyright (C) 2004 Free Software Foundation, Inc. | |
3 | Contributed by Zack Weinberg, May 2004 | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify it | |
6 | under the terms of the GNU General Public License as published by the | |
7 | Free Software Foundation; either version 2, or (at your option) any | |
8 | later version. | |
9 | ||
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. | |
14 | ||
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 | |
200031d1 | 17 | Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
c6e83800 ZW |
18 | |
19 | In other words, you are welcome to use, share and improve this program. | |
20 | You are forbidden to forbid anyone else to use, share and improve | |
21 | what you give them. Help stamp out software-hoarding! */ | |
22 | ||
23 | #include "config.h" | |
24 | #include "system.h" | |
25 | #include "line-map.h" | |
26 | #include "cpplib.h" | |
27 | #include "getopt.h" | |
7731405b | 28 | #include "mkdeps.h" |
c6e83800 ZW |
29 | |
30 | const char *progname; | |
31 | const char *vpath; | |
32 | ||
33 | static const char *output_file; | |
34 | static bool had_errors; | |
35 | ||
36 | /* Option lists, to give to cpplib before each input file. */ | |
37 | struct cmd_line_macro | |
38 | { | |
39 | struct cmd_line_macro *next; | |
40 | bool is_undef; | |
41 | const char *macro; | |
42 | }; | |
43 | ||
44 | static struct cmd_line_macro *cmd_line_macros; | |
45 | static cpp_dir *cmd_line_searchpath; | |
46 | ||
47 | static void | |
48 | add_clm (const char *macro, bool is_undef) | |
49 | { | |
c3f829c1 | 50 | struct cmd_line_macro *clm = XNEW (struct cmd_line_macro); |
c6e83800 ZW |
51 | clm->next = cmd_line_macros; |
52 | clm->is_undef = is_undef; | |
53 | clm->macro = macro; | |
54 | cmd_line_macros = clm; | |
55 | } | |
56 | ||
57 | static void | |
58 | add_dir (char *name, bool sysp) | |
59 | { | |
c3f829c1 | 60 | cpp_dir *dir = XNEW (cpp_dir); |
c6e83800 ZW |
61 | dir->next = cmd_line_searchpath; |
62 | dir->name = name; | |
63 | dir->sysp = sysp; | |
64 | dir->construct = 0; | |
65 | dir->user_supplied_p = 1; | |
66 | cmd_line_searchpath = dir; | |
67 | } | |
68 | ||
69 | /* Command line processing. */ | |
70 | ||
71 | static void ATTRIBUTE_NORETURN | |
72 | usage (int errcode) | |
73 | { | |
74 | fprintf (stderr, | |
75 | "usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n", | |
76 | progname); | |
77 | exit (errcode); | |
78 | } | |
79 | ||
80 | static int | |
81 | parse_options (int argc, char **argv) | |
82 | { | |
83 | static const struct option longopts[] = { | |
84 | { "--help", no_argument, 0, 'h' }, | |
85 | { 0, 0, 0, 0 } | |
86 | }; | |
87 | ||
88 | for (;;) | |
89 | switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0)) | |
90 | { | |
91 | case 'h': usage (0); | |
92 | case 'D': add_clm (optarg, false); break; | |
93 | case 'U': add_clm (optarg, true); break; | |
94 | case 'I': add_dir (optarg, false); break; | |
95 | case 'J': add_dir (optarg, true); break; | |
96 | case 'o': | |
97 | if (output_file) | |
98 | { | |
99 | fprintf (stderr, "%s: too many output files\n", progname); | |
100 | usage (2); | |
101 | } | |
102 | output_file = optarg; | |
103 | break; | |
104 | case 'V': | |
105 | if (vpath) | |
106 | { | |
107 | fprintf (stderr, "%s: too many vpaths\n", progname); | |
108 | usage (2); | |
109 | } | |
110 | vpath = optarg; | |
111 | break; | |
112 | case '?': | |
113 | usage (2); /* getopt has issued the error message. */ | |
114 | ||
115 | case -1: /* end of options */ | |
116 | if (optind == argc) | |
117 | { | |
118 | fprintf (stderr, "%s: no input files\n", progname); | |
119 | usage (2); | |
120 | } | |
121 | return optind; | |
d90aed0d | 122 | |
c6e83800 ZW |
123 | default: |
124 | abort (); | |
125 | } | |
126 | } | |
127 | ||
128 | /* Set up cpplib from command line options. */ | |
129 | static cpp_reader * | |
130 | reader_init (struct line_maps *line_table) | |
131 | { | |
132 | cpp_reader *reader; | |
133 | cpp_options *options; | |
134 | ||
135 | linemap_init (line_table); | |
136 | reader = cpp_create_reader (CLK_GNUC89, 0, line_table); | |
137 | ||
138 | /* Ignore warnings and errors (we don't have access to system | |
139 | headers). Request dependency output. */ | |
140 | options = cpp_get_options (reader); | |
141 | options->inhibit_warnings = 1; | |
142 | options->inhibit_errors = 1; | |
143 | options->deps.style = DEPS_USER; | |
144 | ||
145 | /* Further initialization. */ | |
146 | cpp_post_options (reader); | |
147 | cpp_init_iconv (reader); | |
148 | cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath, | |
149 | false); | |
150 | if (vpath) | |
151 | { | |
152 | struct deps *deps = cpp_get_deps (reader); | |
153 | deps_add_vpath (deps, vpath); | |
154 | } | |
155 | ||
156 | return reader; | |
157 | } | |
158 | ||
159 | /* Process one input source file. */ | |
160 | static void | |
161 | process_file (const char *file) | |
162 | { | |
163 | struct line_maps line_table; | |
164 | cpp_reader *reader = reader_init (&line_table); | |
165 | ||
166 | if (!cpp_read_main_file (reader, file)) | |
167 | had_errors = true; | |
168 | else | |
169 | { | |
170 | struct cmd_line_macro *clm; | |
171 | ||
172 | cpp_init_builtins (reader, true); | |
173 | for (clm = cmd_line_macros; clm; clm = clm->next) | |
174 | (clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro); | |
175 | ||
176 | cpp_scan_nooutput (reader); | |
177 | if (cpp_finish (reader, stdout)) | |
178 | had_errors = true; | |
179 | } | |
180 | cpp_destroy (reader); | |
181 | linemap_free (&line_table); | |
182 | } | |
183 | ||
184 | /* Master control. */ | |
185 | ||
186 | int | |
187 | main(int argc, char **argv) | |
188 | { | |
189 | int first_input, i; | |
190 | ||
191 | progname = argv[0]; | |
192 | xmalloc_set_program_name (progname); | |
193 | ||
194 | first_input = parse_options (argc, argv); | |
195 | if (output_file) | |
196 | if (!freopen (output_file, "w", stdout)) | |
197 | { | |
198 | perror (output_file); | |
199 | return 1; | |
200 | } | |
201 | ||
202 | for (i = first_input; i < argc; i++) | |
203 | process_file (argv[i]); | |
204 | ||
205 | return had_errors; | |
206 | } |