794879efd5faa6fcccc288c7997321edcbfb15b4
[fw/sdcc] / support / cpp2 / sdcpp.c
1 /*-------------------------------------------------------------------------
2     sdcppmain.c - sdcpp: SDCC preprocessor main file, using cpplib.
3
4     Written by Borut Razem, 2006.
5
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
9     later version.
10
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.
15
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.
19
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 -------------------------------------------------------------------------*/
24
25 #include "config.h"
26 #include "system.h"
27 #include "cpplib.h"
28 #include "internal.h"
29 #include "version.h"
30 #include "mkdeps.h"
31 #include "opts.h"
32 #include "intl.h"
33 #include "c-pretty-print.h"
34 #include "diagnostic.h"
35
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)
39
40 const char *progname;           /* Needs to be global.  */
41
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, \
50   LANG_HOOKS_INIT, \
51   LANG_HOOKS_FINISH, \
52   LANG_HOOKS_PRINT_ERROR_FUNCTION, \
53 }
54
55 /* From c-lang.c */
56 #define LANG_HOOKS_INIT_OPTIONS sdcpp_common_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
64
65 static void sdcpp_initialize_diagnostics (diagnostic_context *context);
66 static void sdcpp_print_error_function (diagnostic_context *context, const char *file);
67
68 /* Each front end provides its own lang hook initializer.  */
69 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
70
71 /* Name of top-level original source file (what was input to cpp).
72    This comes from the #-command at the beginning of the actual input.
73    If there isn't any there, then this is the cc1 input file name.  */
74
75 const char *main_input_filename;
76
77 #ifndef USE_MAPPED_LOCATION
78 location_t unknown_location = { NULL, 0 };
79 #endif
80
81 /* Current position in real source file.  */
82
83 location_t input_location;
84
85 struct line_maps line_table;
86
87 /* Stack of currently pending input files.  */
88
89 struct file_stack *input_file_stack;
90
91 /* Incremented on each change to input_file_stack.  */
92 int input_file_stack_tick;
93
94 /* Temporarily suppress certain warnings.
95    This is set while reading code from a system header file.  */
96
97 int in_system_header = 0;
98
99 /* Nonzero means change certain warnings into errors.
100    Usually these are warnings about failure to conform to some standard.  */
101
102 int flag_pedantic_errors = 0;
103
104 cpp_reader *parse_in;           /* Declared in c-pragma.h.  */
105
106 /* Nonzero means `char' should be signed.  */
107
108 int flag_signed_char;
109
110 /* Nonzero means don't output line number information.  */
111
112 char flag_no_line_commands;
113
114 /* Nonzero causes -E output not to be done, but directives such as
115    #define that have side effects are still obeyed.  */
116
117 char flag_no_output;
118
119 /* Nonzero means dump macros in some fashion.  */
120
121 char flag_dump_macros;
122
123 /* Nonzero means pass #include lines through to the output.  */
124
125 char flag_dump_includes;
126
127 /* 0 means we want the preprocessor to not emit line directives for
128    the current working directory.  1 means we want it to do it.  -1
129    means we should decide depending on whether debugging information
130    is being emitted or not.  */
131
132 int flag_working_directory = -1;
133
134 /* The current working directory of a translation.  It's generally the
135    directory from which compilation was initiated, but a preprocessed
136    file may specify the original directory in which it was
137    created.  */
138
139 static const char *src_pwd;
140
141 /* Initialize src_pwd with the given string, and return true.  If it
142    was already initialized, return false.  As a special case, it may
143    be called with a NULL argument to test whether src_pwd has NOT been
144    initialized yet.  */
145
146 /* From intl.c */
147 /* Opening quotation mark for diagnostics.  */
148 const char *open_quote = "'";
149
150 /* Closing quotation mark for diagnostics.  */
151 const char *close_quote = "'";
152 /* ----------- */
153
154 bool
155 set_src_pwd (const char *pwd)
156 {
157   if (src_pwd)
158     return false;
159
160   src_pwd = xstrdup (pwd);
161   return true;
162 }
163
164 /* Return the directory from which the translation unit was initiated,
165    in case set_src_pwd() was not called before to assign it a
166    different value.  */
167
168 const char *
169 get_src_pwd (void)
170 {
171   if (! src_pwd)
172     src_pwd = getpwd ();
173
174    return src_pwd;
175 }
176
177 static void
178 sdcpp_initialize_diagnostics (diagnostic_context *context)
179 {
180   pretty_printer *base = context->printer;
181   c_pretty_printer *pp = xmalloc (sizeof (c_pretty_printer));
182   memcpy (pp_base (pp), base, sizeof (pretty_printer));
183   pp_c_pretty_printer_init (pp);
184   context->printer = (pretty_printer *) pp;
185
186   /* It is safe to free this object because it was previously malloc()'d.  */
187   free (base);
188 }
189
190 /* The default function to print out name of current function that caused
191    an error.  */
192 static void
193 sdcpp_print_error_function (diagnostic_context *context, const char *file)
194 {
195 }
196
197 /* Initialize the PRETTY-PRINTER for handling C codes.  */
198
199 void
200 pp_c_pretty_printer_init (c_pretty_printer *pp)
201 {
202 }
203
204 void
205 print_version (FILE *file, const char *indent)
206 {
207   fprintf (file, _("GNU CPP version %s (cpplib)"), version_string);
208 #ifdef TARGET_VERSION
209   TARGET_VERSION;
210 #endif
211   fputc ('\n', file);
212 }
213
214 /* Initialization of the front end environment, before command line
215    options are parsed.  Signal handlers, internationalization etc.
216    ARGV0 is main's argv[0].  */
217 static void
218 general_init (const char *argv0)
219 {
220   const char *p;
221
222   p = argv0 + strlen (argv0);
223   while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
224     --p;
225   progname = p;
226
227   xmalloc_set_program_name (progname);
228
229   hex_init ();
230
231   gcc_init_libintl ();
232
233   /* Initialize the diagnostics reporting machinery, so option parsing
234      can give warnings and errors.  */
235   diagnostic_initialize (global_dc);
236 }
237
238 /* Process the options that have been parsed.  */
239 static void
240 process_options (void)
241 {
242   /* Allow the front end to perform consistency checks and do further
243      initialization based on the command line options.  This hook also
244      sets the original filename if appropriate (e.g. foo.i -> foo.c)
245      so we can correctly initialize debug output.  */
246   /*no_backend =*/ (*lang_hooks.post_options) (&main_input_filename);
247   input_filename = main_input_filename;
248 }
249
250 #if 0
251 /* A warning.  Use this for code which is correct according to the
252    relevant language specification but is likely to be buggy anyway.  */
253 void
254 warning (const char *msgid, ...)
255 {
256   va_list ap;
257
258   va_start (ap, msgid);
259   fprintf (stderr, "%s: error: ", progname);
260   vfprintf (stderr, msgid, ap);
261   va_end (ap);
262 }
263
264 /* A hard error: the code is definitely ill-formed, and an object file
265    will not be produced.  */
266 void
267 error (const char *msgid, ...)
268 {
269   va_list ap;
270
271   va_start (ap, msgid);
272   fprintf (stderr, "%s: warning: ", progname);
273   vfprintf (stderr, msgid, ap);
274   va_end (ap);
275 }
276
277 /* Print a fatal I/O error message.  Argument are like printf.
278    Also include a system error message based on `errno'.  */
279 void
280 fatal_io_error (const char *msgid, ...)
281 {
282   va_list ap;
283
284   va_start (ap, msgid);
285   fprintf (stderr, "%s: %s: ", progname, xstrerror (errno));
286   vfprintf(stderr, msgid, ap);
287   va_end (ap);
288   exit (FATAL_EXIT_CODE);
289 }
290 #endif
291
292 /* Parse a -d... command line switch.  */
293
294 void
295 decode_d_option (const char *arg)
296 {
297   int c;
298
299   while (*arg)
300     switch (c = *arg++)
301       {
302       case 'D': /* These are handled by the preprocessor.  */
303       case 'I':
304       case 'M':
305       case 'N':
306         break;
307
308       default:
309         warning (0, "unrecognized gcc debugging option: %c", c);
310         break;
311       }
312 }
313
314 /* Language-dependent initialization.  Returns nonzero on success.  */
315 static int
316 lang_dependent_init (const char *name)
317 {
318   /* Other front-end initialization.  */
319   if ((*lang_hooks.init) () == 0)
320     return 0;
321
322   return 1;
323 }
324
325 /* Clean up: close opened files, etc.  */
326
327 static void
328 finalize (void)
329 {
330   /* Language-specific end of compilation actions.  */
331   (*lang_hooks.finish) ();
332 }
333
334 /* Initialize the compiler, and compile the input file.  */
335 static void
336 do_compile (void)
337 {
338   process_options ();
339
340   /* Don't do any more if an error has already occurred.  */
341   if (!errorcount)
342     {
343       /* Language-dependent initialization.  Returns true on success.  */
344       lang_dependent_init (main_input_filename);
345
346       finalize ();
347     }
348 }
349
350 /* Entry point of cc1, cc1plus, jc1, f771, etc.
351    Exit code is FATAL_EXIT_CODE if can't open files or if there were
352    any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
353
354    It is not safe to call this function more than once.  */
355
356 int
357 main (unsigned int argc, const char **argv)
358 {
359   /* Initialization of GCC's environment, and diagnostics.  */
360   general_init (argv[0]);
361
362   /* Parse the options and do minimal processing; basically just
363      enough to default flags appropriately.  */
364   decode_options (argc, argv);
365
366   /* Exit early if we can (e.g. -help).  */
367   if (!exit_after_options)
368     do_compile ();
369
370   if (errorcount || sorrycount)
371     return (FATAL_EXIT_CODE);
372
373   return (SUCCESS_EXIT_CODE);
374 }