1 /*-------------------------------------------------------------------------
2 sdcppmain.c - sdcpp: SDCC preprocessor main file, using cpplib.
4 Written by Borut Razem, 2006.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
33 #include "c-pretty-print.h"
34 #include "diagnostic.h"
36 #define CPP_FATAL_LIMIT 1000
37 /* True if we have seen a "fatal" error. */
38 #define CPP_FATAL_ERRORS(PFILE) (cpp_errors (PFILE) >= CPP_FATAL_LIMIT)
40 const char *progname; /* Needs to be global. */
42 /* From laghooks-def.h */
43 /* The whole thing. The structure is defined in langhooks.h. */
44 #define LANG_HOOKS_INITIALIZER { \
45 LANG_HOOKS_INIT_OPTIONS, \
46 LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
47 LANG_HOOKS_HANDLE_OPTION, \
48 LANG_HOOKS_MISSING_ARGUMENT, \
49 LANG_HOOKS_POST_OPTIONS, \
52 LANG_HOOKS_PRINT_ERROR_FUNCTION, \
56 #define LANG_HOOKS_INIT_OPTIONS sdcpp_init_options
57 #define LANG_HOOKS_INITIALIZE_DIAGNOSTICS sdcpp_initialize_diagnostics
58 #define LANG_HOOKS_HANDLE_OPTION sdcpp_common_handle_option
59 #define LANG_HOOKS_MISSING_ARGUMENT sdcpp_common_missing_argument
60 #define LANG_HOOKS_POST_OPTIONS sdcpp_common_post_options
61 #define LANG_HOOKS_INIT sdcpp_common_init
62 #define LANG_HOOKS_FINISH sdcpp_common_finish
63 #define LANG_HOOKS_PRINT_ERROR_FUNCTION sdcpp_print_error_function
65 static unsigned int sdcpp_init_options (unsigned int argc, const char **argv);
66 static void sdcpp_initialize_diagnostics (diagnostic_context *context);
67 static void sdcpp_print_error_function (diagnostic_context *context, const char *file);
69 /* Each front end provides its own lang hook initializer. */
70 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
72 /* Name of top-level original source file (what was input to cpp).
73 This comes from the #-command at the beginning of the actual input.
74 If there isn't any there, then this is the cc1 input file name. */
76 const char *main_input_filename;
78 #ifndef USE_MAPPED_LOCATION
79 location_t unknown_location = { NULL, 0 };
82 /* Current position in real source file. */
84 location_t input_location;
86 struct line_maps line_table;
88 /* Stack of currently pending input files. */
90 struct file_stack *input_file_stack;
92 /* Incremented on each change to input_file_stack. */
93 int input_file_stack_tick;
95 /* Temporarily suppress certain warnings.
96 This is set while reading code from a system header file. */
98 int in_system_header = 0;
100 /* Nonzero means change certain warnings into errors.
101 Usually these are warnings about failure to conform to some standard. */
103 int flag_pedantic_errors = 0;
105 cpp_reader *parse_in; /* Declared in c-pragma.h. */
107 /* Nonzero means `char' should be signed. */
109 int flag_signed_char;
111 /* Nonzero means don't output line number information. */
113 char flag_no_line_commands;
115 /* Nonzero causes -E output not to be done, but directives such as
116 #define that have side effects are still obeyed. */
120 /* Nonzero means dump macros in some fashion. */
122 char flag_dump_macros;
124 /* Nonzero means pass #include lines through to the output. */
126 char flag_dump_includes;
128 /* 0 means we want the preprocessor to not emit line directives for
129 the current working directory. 1 means we want it to do it. -1
130 means we should decide depending on whether debugging information
131 is being emitted or not. */
133 int flag_working_directory = -1;
135 /* The current working directory of a translation. It's generally the
136 directory from which compilation was initiated, but a preprocessed
137 file may specify the original directory in which it was
140 static const char *src_pwd;
142 /* Initialize src_pwd with the given string, and return true. If it
143 was already initialized, return false. As a special case, it may
144 be called with a NULL argument to test whether src_pwd has NOT been
148 /* Opening quotation mark for diagnostics. */
149 const char *open_quote = "'";
151 /* Closing quotation mark for diagnostics. */
152 const char *close_quote = "'";
156 set_src_pwd (const char *pwd)
161 src_pwd = xstrdup (pwd);
165 /* Return the directory from which the translation unit was initiated,
166 in case set_src_pwd() was not called before to assign it a
178 /* SDCPP specific pragmas */
182 do_pragma_sdcc_hash (cpp_reader *pfile)
184 const cpp_token *tok = _cpp_lex_token (pfile);
186 if (tok->type == CPP_PLUS)
188 CPP_OPTION(pfile, allow_naked_hash)++;
190 else if (tok->type == CPP_MINUS)
192 CPP_OPTION(pfile, allow_naked_hash)--;
196 cpp_error (pfile, CPP_DL_ERROR,
197 "invalid #pragma sdcc_hash directive, need '+' or '-'");
202 pedantic_parse_number pragma */
204 do_pragma_pedantic_parse_number (cpp_reader *pfile)
206 const cpp_token *tok = _cpp_lex_token (pfile);
208 if (tok->type == CPP_PLUS)
210 CPP_OPTION(pfile, pedantic_parse_number)++;
212 else if (tok->type == CPP_MINUS)
214 CPP_OPTION(pfile, pedantic_parse_number)--;
218 cpp_error (pfile, CPP_DL_ERROR,
219 "invalid #pragma pedantic_parse_number directive, need '+' or '-'");
223 /* SDCC _asm specific
224 switch _asm block preprocessing on / off */
226 do_pragma_preproc_asm (cpp_reader *pfile)
228 const cpp_token *tok = _cpp_lex_token (pfile);
230 if (tok->type == CPP_PLUS)
232 CPP_OPTION(pfile, preproc_asm)++;
234 else if (tok->type == CPP_MINUS)
236 CPP_OPTION(pfile, preproc_asm)--;
240 cpp_error (pfile, CPP_DL_ERROR,
241 "invalid #pragma preproc_asm directive, need '+' or '-'");
245 /* SDCPP specific option initialization */
247 sdcpp_init_options (unsigned int argc, const char **argv)
249 unsigned int ret = sdcpp_common_init_options(argc, argv);
251 CPP_OPTION (parse_in, allow_naked_hash) = 0;
252 CPP_OPTION (parse_in, preproc_asm) = 1;
253 CPP_OPTION (parse_in, pedantic_parse_number) = 0;
254 CPP_OPTION (parse_in, obj_ext) = NULL;
256 /* Kevin abuse for SDCC. */
257 cpp_register_pragma(parse_in, 0, "sdcc_hash", do_pragma_sdcc_hash, false);
258 /* SDCC _asm specific */
259 cpp_register_pragma(parse_in, 0, "preproc_asm", do_pragma_preproc_asm, false);
261 cpp_register_pragma(parse_in, 0, "pedantic_parse_number", do_pragma_pedantic_parse_number, false);
263 /* SDCC _asm specific */
264 parse_in->spec_nodes.n__asm = cpp_lookup (parse_in, DSC("_asm"));
270 sdcpp_initialize_diagnostics (diagnostic_context *context)
272 pretty_printer *base = context->printer;
273 c_pretty_printer *pp = xmalloc (sizeof (c_pretty_printer));
274 memcpy (pp_base (pp), base, sizeof (pretty_printer));
275 pp_c_pretty_printer_init (pp);
276 context->printer = (pretty_printer *) pp;
278 /* It is safe to free this object because it was previously malloc()'d. */
282 /* The default function to print out name of current function that caused
285 sdcpp_print_error_function (diagnostic_context *context, const char *file)
289 /* Initialize the PRETTY-PRINTER for handling C codes. */
292 pp_c_pretty_printer_init (c_pretty_printer *pp)
297 print_version (FILE *file, const char *indent)
299 fprintf (file, _("GNU CPP version %s (cpplib)"), version_string);
300 #ifdef TARGET_VERSION
306 /* Initialization of the front end environment, before command line
307 options are parsed. Signal handlers, internationalization etc.
308 ARGV0 is main's argv[0]. */
310 general_init (const char *argv0)
314 p = argv0 + strlen (argv0);
315 while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
319 xmalloc_set_program_name (progname);
325 /* Initialize the diagnostics reporting machinery, so option parsing
326 can give warnings and errors. */
327 diagnostic_initialize (global_dc);
330 /* Process the options that have been parsed. */
332 process_options (void)
334 /* Allow the front end to perform consistency checks and do further
335 initialization based on the command line options. This hook also
336 sets the original filename if appropriate (e.g. foo.i -> foo.c)
337 so we can correctly initialize debug output. */
338 /*no_backend =*/ (*lang_hooks.post_options) (&main_input_filename);
339 input_filename = main_input_filename;
343 /* A warning. Use this for code which is correct according to the
344 relevant language specification but is likely to be buggy anyway. */
346 warning (const char *msgid, ...)
350 va_start (ap, msgid);
351 fprintf (stderr, "%s: error: ", progname);
352 vfprintf (stderr, msgid, ap);
356 /* A hard error: the code is definitely ill-formed, and an object file
357 will not be produced. */
359 error (const char *msgid, ...)
363 va_start (ap, msgid);
364 fprintf (stderr, "%s: warning: ", progname);
365 vfprintf (stderr, msgid, ap);
369 /* Print a fatal I/O error message. Argument are like printf.
370 Also include a system error message based on `errno'. */
372 fatal_io_error (const char *msgid, ...)
376 va_start (ap, msgid);
377 fprintf (stderr, "%s: %s: ", progname, xstrerror (errno));
378 vfprintf(stderr, msgid, ap);
380 exit (FATAL_EXIT_CODE);
384 /* Parse a -d... command line switch. */
387 decode_d_option (const char *arg)
394 case 'D': /* These are handled by the preprocessor. */
401 warning (0, "unrecognized gcc debugging option: %c", c);
406 /* Language-dependent initialization. Returns nonzero on success. */
408 lang_dependent_init (const char *name)
410 /* Other front-end initialization. */
411 if ((*lang_hooks.init) () == 0)
417 /* Clean up: close opened files, etc. */
422 /* Language-specific end of compilation actions. */
423 (*lang_hooks.finish) ();
426 /* Initialize the compiler, and compile the input file. */
432 /* Don't do any more if an error has already occurred. */
435 /* Language-dependent initialization. Returns true on success. */
436 lang_dependent_init (main_input_filename);
442 /* Entry point of cc1, cc1plus, jc1, f771, etc.
443 Exit code is FATAL_EXIT_CODE if can't open files or if there were
444 any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
446 It is not safe to call this function more than once. */
449 main (unsigned int argc, const char **argv)
451 /* Initialization of GCC's environment, and diagnostics. */
452 general_init (argv[0]);
454 /* Parse the options and do minimal processing; basically just
455 enough to default flags appropriately. */
456 decode_options (argc, argv);
458 /* Exit early if we can (e.g. -help). */
459 if (!exit_after_options)
462 if (errorcount || sorrycount)
463 return (FATAL_EXIT_CODE);
465 return (SUCCESS_EXIT_CODE);