OSDN Git Service

2000-08-20 Zack Weinberg <zack@wolery.cumb.org>
[pf3gnuchains/gcc-fork.git] / gcc / cppmain.c
1 /* CPP main program, using CPP Library.
2    Copyright (C) 1995, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3    Written by Per Bothner, 1994-95.
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 "cpplib.h"
26 #include "intl.h"
27
28 const char *progname;
29
30 cpp_reader parse_in;
31 cpp_printer parse_out;
32
33 int main                PARAMS ((int, char **));
34
35 /* Callback routines for the parser.   Most of these are active only
36    in specific modes.  */
37 static void cb_define   PARAMS ((cpp_reader *, cpp_hashnode *));
38 static void cb_undef    PARAMS ((cpp_reader *, cpp_hashnode *));
39 static void cb_include  PARAMS ((cpp_reader *, const unsigned char *,
40                                  const unsigned char *, unsigned int, int));
41
42 static void cb_ident      PARAMS ((cpp_reader *, const unsigned char *,
43                                    unsigned int));
44 static void cb_enter_file PARAMS ((cpp_reader *));
45 static void cb_leave_file PARAMS ((cpp_reader *));
46 static void cb_rename_file PARAMS ((cpp_reader *));
47 static void cb_def_pragma PARAMS ((cpp_reader *));
48
49 static void do_pragma_implementation PARAMS ((cpp_reader *));
50 static int dump_macros_helper PARAMS ((cpp_reader *, cpp_hashnode *));
51
52 int
53 main (argc, argv)
54      int argc;
55      char **argv;
56 {
57   char *p;
58   cpp_reader *pfile = &parse_in;
59   cpp_printer *print;
60   int argi = 1;  /* Next argument to handle.  */
61
62   p = argv[0] + strlen (argv[0]);
63   while (p != argv[0] && ! IS_DIR_SEPARATOR (p[-1])) --p;
64   progname = p;
65
66   xmalloc_set_program_name (progname);
67
68 #ifdef HAVE_LC_MESSAGES
69   setlocale (LC_MESSAGES, "");
70 #endif
71   (void) bindtextdomain (PACKAGE, localedir);
72   (void) textdomain (PACKAGE);
73
74   cpp_init ();
75   cpp_reader_init (pfile);
76   
77   argi += cpp_handle_options (pfile, argc - argi , argv + argi);
78   if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
79     cpp_fatal (pfile, "Invalid option %s", argv[argi]);
80   if (CPP_FATAL_ERRORS (pfile))
81     return (FATAL_EXIT_CODE);
82
83   /* Open the output now.  We must do so even if no_output is on,
84      because there may be other output than from the actual
85      preprocessing (e.g. from -dM).  */
86   print = cpp_printer_init (pfile, &parse_out);
87   if (! print)
88     return (FATAL_EXIT_CODE);
89
90   /* Set callbacks.  */
91   if (! CPP_OPTION (pfile, no_line_commands)
92       && ! CPP_OPTION (pfile, no_output))
93     {
94       pfile->cb.enter_file = cb_enter_file;
95       pfile->cb.leave_file = cb_leave_file;
96       pfile->cb.rename_file = cb_rename_file;
97     }
98   if (CPP_OPTION (pfile, dump_includes))
99     pfile->cb.include  = cb_include;
100   if (CPP_OPTION (pfile, debug_output)
101       || CPP_OPTION (pfile, dump_macros) == dump_names
102       || CPP_OPTION (pfile, dump_macros) == dump_definitions)
103     {
104       pfile->cb.define = cb_define;
105       pfile->cb.undef  = cb_undef;
106       pfile->cb.poison = cb_def_pragma;
107     }
108   pfile->cb.ident      = cb_ident;
109   pfile->cb.def_pragma = cb_def_pragma;
110
111   /* Register one #pragma which needs special handling.  */
112   cpp_register_pragma(pfile, 0, "implementation", do_pragma_implementation);
113   cpp_register_pragma(pfile, "GCC", "implementation", do_pragma_implementation);
114
115   if (! cpp_start_read (pfile, print, CPP_OPTION (pfile, in_fname)))
116     return (FATAL_EXIT_CODE);
117
118   if (CPP_OPTION (pfile, no_output))
119     while (CPP_BUFFER (pfile) != NULL)
120       cpp_scan_buffer_nooutput (pfile);
121   else
122     while (CPP_BUFFER (pfile) != NULL)
123       cpp_scan_buffer (pfile, print);
124
125   if (CPP_OPTION (pfile, dump_macros) == dump_only)
126     cpp_forall_identifiers (pfile, dump_macros_helper);
127   
128   cpp_finish (pfile, print);
129   cpp_cleanup (pfile);
130
131   if (parse_in.errors)
132     return (FATAL_EXIT_CODE);
133   return (SUCCESS_EXIT_CODE);
134 }
135
136 /* Callbacks */
137
138 static void
139 cb_ident (pfile, str, len)
140      cpp_reader *pfile;
141      const unsigned char *str;
142      unsigned int len;
143 {
144   cpp_printf (pfile, &parse_out, "#ident \"%.*s\"\n", (int) len, str);
145   parse_out.lineno++;
146 }
147
148 static void
149 cb_define (pfile, hash)
150      cpp_reader *pfile;
151      cpp_hashnode *hash;
152 {
153   if (pfile->done_initializing)
154     {
155       cpp_printf (pfile, &parse_out, "#define %s", hash->name);
156       if (CPP_OPTION (pfile, debug_output)
157           || CPP_OPTION (pfile, dump_macros) == dump_definitions)
158         cpp_dump_definition (pfile, parse_out.outf, hash);
159       putc ('\n', parse_out.outf);
160       parse_out.lineno++;
161     }
162 }
163
164 static void
165 cb_undef (pfile, hash)
166      cpp_reader *pfile;
167      cpp_hashnode *hash;
168 {
169   if (pfile->done_initializing)
170     {
171       cpp_printf (pfile, &parse_out, "#undef %s\n", hash->name);
172       parse_out.lineno++;
173     }
174 }
175
176 static void
177 cb_include (pfile, dir, str, len, ab)
178      cpp_reader *pfile;
179      const unsigned char *dir;
180      const unsigned char *str;
181      unsigned int len;
182      int ab;
183 {
184   int l, r;
185   if (ab)
186     l = '<', r = '>';
187   else
188     l = '"', r = '"';
189
190   cpp_printf (pfile, &parse_out, "#%s %c%.*s%c\n", dir, l, (int) len, str, r);
191   parse_out.lineno++;
192 }
193
194 static void
195 cb_enter_file (pfile)
196      cpp_reader *pfile;
197 {
198   cpp_buffer *ip = CPP_BUFFER (pfile);
199
200   cpp_printf (pfile, &parse_out, "# 1 \"%s\"%s%s\n", ip->nominal_fname,
201               pfile->done_initializing ? " 1" : "",
202               cpp_syshdr_flags (pfile, ip));
203
204   parse_out.lineno = 1;
205   parse_out.last_fname = ip->nominal_fname;
206 }
207
208 static void
209 cb_leave_file (pfile)
210      cpp_reader *pfile;
211 {
212   cpp_buffer *ip = CPP_BUFFER (pfile);
213
214   cpp_printf (pfile, &parse_out, "# %u \"%s\" 2%s\n", ip->lineno,
215               ip->nominal_fname, cpp_syshdr_flags (pfile, ip));
216
217   parse_out.lineno = ip->lineno;
218   parse_out.last_fname = ip->nominal_fname;
219 }
220
221 static void
222 cb_rename_file (pfile)
223      cpp_reader *pfile;
224 {
225   cpp_buffer *ip = CPP_BUFFER (pfile);
226
227   cpp_printf (pfile, &parse_out, "# %u \"%s\"%s\n", ip->lineno,
228               ip->nominal_fname, cpp_syshdr_flags (pfile, ip));
229
230   parse_out.lineno = ip->lineno;
231   parse_out.last_fname = ip->nominal_fname;
232 }
233
234 static void
235 cb_def_pragma (pfile)
236      cpp_reader *pfile;
237 {
238   cpp_printf (pfile, &parse_out, "#pragma ");
239   cpp_output_list (pfile, parse_out.outf, &pfile->token_list,
240                    pfile->first_directive_token + 2);
241   putc ('\n', parse_out.outf);
242   parse_out.lineno++;
243 }
244
245 static void
246 do_pragma_implementation (pfile)
247      cpp_reader *pfile;
248 {
249   /* Be quiet about `#pragma implementation' for a file only if it hasn't
250      been included yet.  */
251   const cpp_token *tok = cpp_get_token (pfile);
252   char *copy;
253
254   if (tok->type != CPP_EOF)
255     {
256       if (tok->type != CPP_STRING || cpp_get_token (pfile)->type != CPP_EOF)
257         {
258           cpp_error (pfile, "malformed #pragma implementation");
259           return;
260         }
261
262       /* Make a NUL-terminated copy of the string.  */
263       copy = alloca (tok->val.str.len + 1);
264       memcpy (copy, tok->val.str.text, tok->val.str.len);
265       copy[tok->val.str.len] = '\0';
266   
267       if (cpp_included (pfile, copy))
268         cpp_warning (pfile,
269                 "#pragma implementation for %s appears after file is included",
270                      copy);
271     }
272
273   /* forward to default-pragma handler.  */
274   cb_def_pragma (pfile);
275 }
276
277 /* Dump out the hash table.  */
278 static int
279 dump_macros_helper (pfile, hp)
280      cpp_reader *pfile;
281      cpp_hashnode *hp;
282 {
283   if (hp->type == T_MACRO)
284     {
285       cpp_printf (pfile, &parse_out, "#define %s", hp->name);
286       cpp_dump_definition (pfile, parse_out.outf, hp);
287       putc ('\n', parse_out.outf);
288       parse_out.lineno++;
289     }
290
291   return 1;
292 }
293