OSDN Git Service

* ChangeLog: Merge text from include/ChangeLog.
[pf3gnuchains/gcc-fork.git] / libcpp / makedepend.c
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
29 const char *progname;
30 const char *vpath;
31
32 static const char *output_file;
33 static bool had_errors;
34
35 /* Option lists, to give to cpplib before each input file.  */
36 struct cmd_line_macro
37 {
38   struct cmd_line_macro *next;
39   bool is_undef;
40   const char *macro;
41 };
42
43 static struct cmd_line_macro *cmd_line_macros;
44 static cpp_dir *cmd_line_searchpath;
45
46 static void
47 add_clm (const char *macro, bool is_undef)
48 {
49   struct cmd_line_macro *clm = xmalloc (sizeof (struct cmd_line_macro));
50   clm->next = cmd_line_macros;
51   clm->is_undef = is_undef;
52   clm->macro = macro;
53   cmd_line_macros = clm;
54 }
55
56 static void
57 add_dir (char *name, bool sysp)
58 {
59   cpp_dir *dir = xmalloc (sizeof (cpp_dir));
60   dir->next = cmd_line_searchpath;
61   dir->name = name;
62   dir->sysp = sysp;
63   dir->construct = 0;
64   dir->user_supplied_p = 1;
65   cmd_line_searchpath = dir;
66 }
67
68 /* Command line processing.  */
69
70 static void ATTRIBUTE_NORETURN
71 usage (int errcode)
72 {
73   fprintf (stderr,
74 "usage: %s [-vh] [-V vpath] [-Dname[=def]...] [-Uname] [-Idir...] [-o file] sources...\n",
75            progname);
76   exit (errcode);
77 }
78
79 static int
80 parse_options (int argc, char **argv)
81 {
82   static const struct option longopts[] = {
83     { "--help", no_argument, 0, 'h' },
84     { 0, 0, 0, 0 }
85   };
86
87   for (;;)
88     switch (getopt_long (argc, argv, "hD:U:I:J:o:V:", longopts, 0))
89       {
90       case 'h': usage (0);
91       case 'D': add_clm (optarg, false); break;
92       case 'U': add_clm (optarg, true);  break;
93       case 'I': add_dir (optarg, false); break;
94       case 'J': add_dir (optarg, true);  break;
95       case 'o':
96         if (output_file)
97           {
98             fprintf (stderr, "%s: too many output files\n", progname);
99             usage (2);
100           }
101         output_file = optarg;
102         break;
103       case 'V':
104         if (vpath)
105           {
106             fprintf (stderr, "%s: too many vpaths\n", progname);
107             usage (2);
108           }
109         vpath = optarg;
110         break;
111       case '?':
112         usage (2);  /* getopt has issued the error message.  */
113
114       case -1: /* end of options */
115         if (optind == argc)
116           {
117             fprintf (stderr, "%s: no input files\n", progname);
118             usage (2);
119           }
120         return optind;
121         
122       default:
123         abort ();
124       }
125 }
126
127 /* Set up cpplib from command line options.  */
128 static cpp_reader *
129 reader_init (struct line_maps *line_table)
130 {
131   cpp_reader *reader;
132   cpp_options *options;
133
134   linemap_init (line_table);
135   reader = cpp_create_reader (CLK_GNUC89, 0, line_table);
136
137   /* Ignore warnings and errors (we don't have access to system
138      headers).  Request dependency output.  */
139   options = cpp_get_options (reader);
140   options->inhibit_warnings = 1;
141   options->inhibit_errors = 1;
142   options->deps.style = DEPS_USER;
143
144   /* Further initialization.  */
145   cpp_post_options (reader);
146   cpp_init_iconv (reader);
147   cpp_set_include_chains (reader, cmd_line_searchpath, cmd_line_searchpath,
148                           false);
149   if (vpath)
150     {
151       struct deps *deps = cpp_get_deps (reader);
152       deps_add_vpath (deps, vpath);
153     }
154
155   return reader;
156 }
157
158 /* Process one input source file.  */
159 static void
160 process_file (const char *file)
161 {
162   struct line_maps line_table;
163   cpp_reader *reader = reader_init (&line_table);
164
165   if (!cpp_read_main_file (reader, file))
166     had_errors = true;
167   else
168     {
169       struct cmd_line_macro *clm;
170
171       cpp_init_builtins (reader, true);
172       for (clm = cmd_line_macros; clm; clm = clm->next)
173         (clm->is_undef ? cpp_undef : cpp_define) (reader, clm->macro);
174
175       cpp_scan_nooutput (reader);
176       if (cpp_finish (reader, stdout))
177         had_errors = true;
178     }
179   cpp_destroy (reader);
180   linemap_free (&line_table);
181 }
182
183 /* Master control.  */
184
185 int
186 main(int argc, char **argv)
187 {
188   int first_input, i;
189
190   progname = argv[0];
191   xmalloc_set_program_name (progname);
192
193   first_input = parse_options (argc, argv);
194   if (output_file)
195     if (!freopen (output_file, "w", stdout))
196       {
197         perror (output_file);
198         return 1;
199       }
200
201   for (i = first_input; i < argc; i++)
202     process_file (argv[i]);
203
204   return had_errors;
205 }