0
|
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
|
|
17 Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
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"
|
|
28 #include "mkdeps.h"
|
|
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 {
|
|
50 struct cmd_line_macro *clm = XNEW (struct cmd_line_macro);
|
|
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 {
|
|
60 cpp_dir *dir = XNEW (cpp_dir);
|
|
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;
|
|
122
|
|
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 }
|