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.
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
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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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! */
31 cpp_printer parse_out
;
33 int main
PARAMS ((int, char **));
35 /* Callback routines for the parser. Most of these are active only
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));
42 static void cb_ident
PARAMS ((cpp_reader
*, const cpp_token
*));
43 static void cb_enter_file
PARAMS ((cpp_reader
*));
44 static void cb_leave_file
PARAMS ((cpp_reader
*));
45 static void cb_def_pragma
PARAMS ((cpp_reader
*));
47 static void do_pragma_implementation
PARAMS ((cpp_reader
*));
48 static int dump_macros_helper
PARAMS ((cpp_reader
*, cpp_hashnode
*));
56 cpp_reader
*pfile
= &parse_in
;
58 int argi
= 1; /* Next argument to handle. */
60 p
= argv
[0] + strlen (argv
[0]);
61 while (p
!= argv
[0] && ! IS_DIR_SEPARATOR (p
[-1])) --p
;
64 xmalloc_set_program_name (progname
);
66 #ifdef HAVE_LC_MESSAGES
67 setlocale (LC_MESSAGES
, "");
69 (void) bindtextdomain (PACKAGE
, localedir
);
70 (void) textdomain (PACKAGE
);
72 cpp_reader_init (pfile
);
74 argi
+= cpp_handle_options (pfile
, argc
- argi
, argv
+ argi
);
75 if (argi
< argc
&& ! CPP_FATAL_ERRORS (pfile
))
76 cpp_fatal (pfile
, "Invalid option %s", argv
[argi
]);
77 if (CPP_FATAL_ERRORS (pfile
))
78 return (FATAL_EXIT_CODE
);
80 /* Open the output now. We must do so even if no_output is on,
81 because there may be other output than from the actual
82 preprocessing (e.g. from -dM). */
83 print
= cpp_printer_init (pfile
, &parse_out
);
85 return (FATAL_EXIT_CODE
);
88 if (! CPP_OPTION (pfile
, no_line_commands
)
89 && ! CPP_OPTION (pfile
, no_output
))
91 pfile
->cb
.enter_file
= cb_enter_file
;
92 pfile
->cb
.leave_file
= cb_leave_file
;
94 if (CPP_OPTION (pfile
, dump_includes
))
95 pfile
->cb
.include
= cb_include
;
96 if (CPP_OPTION (pfile
, debug_output
)
97 || CPP_OPTION (pfile
, dump_macros
) == dump_names
98 || CPP_OPTION (pfile
, dump_macros
) == dump_definitions
)
100 pfile
->cb
.define
= cb_define
;
101 pfile
->cb
.undef
= cb_undef
;
102 pfile
->cb
.poison
= cb_def_pragma
;
104 pfile
->cb
.ident
= cb_ident
;
105 pfile
->cb
.def_pragma
= cb_def_pragma
;
107 /* Register one #pragma which needs special handling. */
108 cpp_register_pragma(pfile
, 0, "implementation", do_pragma_implementation
);
109 cpp_register_pragma(pfile
, "GCC", "implementation", do_pragma_implementation
);
111 if (! cpp_start_read (pfile
, print
, CPP_OPTION (pfile
, in_fname
)))
112 return (FATAL_EXIT_CODE
);
114 if (CPP_OPTION (pfile
, no_output
))
115 while (CPP_BUFFER (pfile
) != NULL
)
116 cpp_scan_buffer_nooutput (pfile
);
118 while (CPP_BUFFER (pfile
) != NULL
)
119 cpp_scan_buffer (pfile
, print
);
121 if (CPP_OPTION (pfile
, dump_macros
) == dump_only
)
122 cpp_forall_identifiers (pfile
, dump_macros_helper
);
124 cpp_finish (pfile
, print
);
128 return (FATAL_EXIT_CODE
);
129 return (SUCCESS_EXIT_CODE
);
135 cb_ident (pfile
, token
)
137 const cpp_token
*token
;
139 cpp_printf (pfile
, &parse_out
, "#ident \"%.*s\"\n",
140 (int) token
->val
.str
.len
, token
->val
.str
.text
);
144 cb_define (pfile
, hash
)
148 if (pfile
->done_initializing
)
150 cpp_printf (pfile
, &parse_out
, "#define %s", hash
->name
);
151 if (CPP_OPTION (pfile
, debug_output
)
152 || CPP_OPTION (pfile
, dump_macros
) == dump_definitions
)
153 cpp_dump_definition (pfile
, parse_out
.outf
, hash
);
154 putc ('\n', parse_out
.outf
);
159 cb_undef (pfile
, hash
)
163 if (pfile
->done_initializing
)
164 cpp_printf (pfile
, &parse_out
, "#undef %s\n", hash
->name
);
168 cb_include (pfile
, dir
, str
, len
, ab
)
170 const unsigned char *dir
;
171 const unsigned char *str
;
181 cpp_printf (pfile
, &parse_out
, "#%s %c%.*s%c\n", dir
, l
, (int) len
, str
, r
);
185 cb_enter_file (pfile
)
188 cpp_buffer
*ip
= CPP_BUFFER (pfile
);
190 cpp_printf (pfile
, &parse_out
, "# 1 \"%s\"%s%s\n", ip
->nominal_fname
,
191 pfile
->done_initializing
? " 1" : "",
192 cpp_syshdr_flags (pfile
, ip
));
194 parse_out
.lineno
= 1;
195 parse_out
.last_fname
= ip
->nominal_fname
;
199 cb_leave_file (pfile
)
202 cpp_buffer
*ip
= CPP_BUFFER (pfile
);
204 cpp_printf (pfile
, &parse_out
, "# %u \"%s\" 2%s\n", ip
->lineno
,
205 ip
->nominal_fname
, cpp_syshdr_flags (pfile
, ip
));
207 parse_out
.lineno
= ip
->lineno
;
208 parse_out
.last_fname
= ip
->nominal_fname
;
212 cb_def_pragma (pfile
)
215 cpp_printf (pfile
, &parse_out
, "#pragma ");
216 cpp_output_list (pfile
, parse_out
.outf
, &pfile
->token_list
,
217 pfile
->first_directive_token
);
218 putc ('\n', parse_out
.outf
);
222 do_pragma_implementation (pfile
)
225 /* Be quiet about `#pragma implementation' for a file only if it hasn't
226 been included yet. */
227 const cpp_token
*tok
= cpp_get_token (pfile
);
230 if (tok
->type
!= CPP_EOF
)
232 if (tok
->type
!= CPP_STRING
|| cpp_get_token (pfile
)->type
!= CPP_EOF
)
234 cpp_error (pfile
, "malformed #pragma implementation");
238 /* Make a NUL-terminated copy of the string. */
239 copy
= alloca (tok
->val
.str
.len
+ 1);
240 memcpy (copy
, tok
->val
.str
.text
, tok
->val
.str
.len
);
241 copy
[tok
->val
.str
.len
] = '\0';
243 if (cpp_included (pfile
, copy
))
245 "#pragma implementation for %s appears after file is included",
249 /* forward to default-pragma handler. */
250 cb_def_pragma (pfile
);
253 /* Dump out the hash table. */
255 dump_macros_helper (pfile
, hp
)
259 if (hp
->type
== T_MACRO
)
261 cpp_printf (pfile
, &parse_out
, "#define %s", hp
->name
);
262 cpp_dump_definition (pfile
, parse_out
.outf
, hp
);
263 putc ('\n', parse_out
.outf
);