1 /* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
2 Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
27 #include "cppdefault.h"
31 #if ! defined( SIGCHLD ) && defined( SIGCLD )
32 # define SIGCHLD SIGCLD
40 /* Include getopt.h for the sake of getopt_long. */
43 /* Macro to see if the path elements match. */
44 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
45 #define IS_SAME_PATH_CHAR(a,b) (TOUPPER (a) == TOUPPER (b))
47 #define IS_SAME_PATH_CHAR(a,b) ((a) == (b))
50 /* Macro to see if the paths match. */
51 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
52 #define IS_SAME_PATH(a,b) (strcasecmp (a, b) == 0)
54 #define IS_SAME_PATH(a,b) (strcmp (a, b) == 0)
57 /* Suffix for aux-info files. */
59 #define AUX_INFO_SUFFIX "X"
61 #define AUX_INFO_SUFFIX ".X"
64 /* Suffix for saved files. */
66 #define SAVE_SUFFIX "sav"
68 #define SAVE_SUFFIX ".save"
71 /* Suffix for renamed C++ files. */
72 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
73 #define CPLUS_FILE_SUFFIX "cc"
75 #define CPLUS_FILE_SUFFIX "C"
78 static void usage
PARAMS ((void)) ATTRIBUTE_NORETURN
;
79 static void aux_info_corrupted
PARAMS ((void)) ATTRIBUTE_NORETURN
;
80 static void declare_source_confusing
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
81 static const char *shortpath
PARAMS ((const char *, const char *));
82 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
83 static void notice
PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1
;
84 static char *savestring
PARAMS ((const char *, unsigned int));
85 static char *dupnstr
PARAMS ((const char *, size_t));
86 static const char *substr
PARAMS ((const char *, const char * const));
87 static int safe_read
PARAMS ((int, void *, int));
88 static void safe_write
PARAMS ((int, void *, int, const char *));
89 static void save_pointers
PARAMS ((void));
90 static void restore_pointers
PARAMS ((void));
91 static int is_id_char
PARAMS ((int));
92 static int in_system_include_dir
PARAMS ((const char *));
93 static int directory_specified_p
PARAMS ((const char *));
94 static int file_excluded_p
PARAMS ((const char *));
95 static char *unexpand_if_needed
PARAMS ((const char *));
96 static char *abspath
PARAMS ((const char *, const char *));
97 static int is_abspath
PARAMS ((const char *));
98 static void check_aux_info
PARAMS ((int));
99 static const char *find_corresponding_lparen
PARAMS ((const char *));
100 static int referenced_file_is_newer
PARAMS ((const char *, time_t));
101 static void save_def_or_dec
PARAMS ((const char *, int));
102 static void munge_compile_params
PARAMS ((const char *));
103 static int gen_aux_info_file
PARAMS ((const char *));
104 static void process_aux_info_file
PARAMS ((const char *, int, int));
105 static int identify_lineno
PARAMS ((const char *));
106 static void check_source
PARAMS ((int, const char *));
107 static const char *seek_to_line
PARAMS ((int));
108 static const char *forward_to_next_token_char
PARAMS ((const char *));
109 static void output_bytes
PARAMS ((const char *, size_t));
110 static void output_string
PARAMS ((const char *));
111 static void output_up_to
PARAMS ((const char *));
112 static int other_variable_style_function
PARAMS ((const char *));
113 static const char *find_rightmost_formals_list
PARAMS ((const char *));
114 static void do_cleaning
PARAMS ((char *, const char *));
115 static const char *careful_find_l_paren
PARAMS ((const char *));
116 static void do_processing
PARAMS ((void));
118 /* Look for these where the `const' qualifier is intentionally cast aside. */
121 /* Define a default place to find the SYSCALLS.X file. */
125 #ifndef STANDARD_EXEC_PREFIX
126 #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
127 #endif /* !defined STANDARD_EXEC_PREFIX */
129 static const char * const standard_exec_prefix
= STANDARD_EXEC_PREFIX
;
130 static const char * const target_machine
= DEFAULT_TARGET_MACHINE
;
131 static const char * const target_version
= DEFAULT_TARGET_VERSION
;
133 #endif /* !defined (UNPROTOIZE) */
135 /* Suffix of aux_info files. */
137 static const char * const aux_info_suffix
= AUX_INFO_SUFFIX
;
139 /* String to attach to filenames for saved versions of original files. */
141 static const char * const save_suffix
= SAVE_SUFFIX
;
145 /* String to attach to C filenames renamed to C++. */
147 static const char * const cplus_suffix
= CPLUS_FILE_SUFFIX
;
149 /* File name of the file which contains descriptions of standard system
150 routines. Note that we never actually do anything with this file per se,
151 but we do read in its corresponding aux_info file. */
153 static const char syscalls_filename
[] = "SYSCALLS.c";
155 /* Default place to find the above file. */
157 static const char * default_syscalls_dir
;
159 /* Variable to hold the complete absolutized filename of the SYSCALLS.c.X
162 static char * syscalls_absolute_filename
;
164 #endif /* !defined (UNPROTOIZE) */
166 /* Type of the structure that holds information about macro unexpansions. */
168 struct unexpansion_struct
{
169 const char *const expanded
;
170 const char *const contracted
;
172 typedef struct unexpansion_struct unexpansion
;
174 /* A table of conversions that may need to be made for some (stupid) older
175 operating systems where these types are preprocessor macros rather than
176 typedefs (as they really ought to be).
178 WARNING: The contracted forms must be as small (or smaller) as the
179 expanded forms, or else havoc will ensue. */
181 static const unexpansion unexpansions
[] = {
182 { "struct _iobuf", "FILE" },
186 /* The number of "primary" slots in the hash tables for filenames and for
187 function names. This can be as big or as small as you like, except that
188 it must be a power of two. */
190 #define HASH_TABLE_SIZE (1 << 9)
192 /* Bit mask to use when computing hash values. */
194 static const int hash_mask
= (HASH_TABLE_SIZE
- 1);
197 /* Datatype for lists of directories or filenames. */
201 struct string_list
*next
;
204 static struct string_list
*string_list_cons
PARAMS ((const char *,
205 struct string_list
*));
207 /* List of directories in which files should be converted. */
209 struct string_list
*directory_list
;
211 /* List of file names which should not be converted.
212 A file is excluded if the end of its name, following a /,
213 matches one of the names in this list. */
215 struct string_list
*exclude_list
;
217 /* The name of the other style of variable-number-of-parameters functions
218 (i.e. the style that we want to leave unconverted because we don't yet
219 know how to convert them to this style. This string is used in warning
222 /* Also define here the string that we can search for in the parameter lists
223 taken from the .X files which will unambiguously indicate that we have
224 found a varargs style function. */
227 static const char * const other_var_style
= "stdarg";
228 #else /* !defined (UNPROTOIZE) */
229 static const char * const other_var_style
= "varargs";
230 static const char *varargs_style_indicator
= "va_alist";
231 #endif /* !defined (UNPROTOIZE) */
233 /* The following two types are used to create hash tables. In this program,
234 there are two hash tables which are used to store and quickly lookup two
235 different classes of strings. The first type of strings stored in the
236 first hash table are absolute filenames of files which protoize needs to
237 know about. The second type of strings (stored in the second hash table)
238 are function names. It is this second class of strings which really
239 inspired the use of the hash tables, because there may be a lot of them. */
241 typedef struct hash_table_entry_struct hash_table_entry
;
243 /* Do some typedefs so that we don't have to write "struct" so often. */
245 typedef struct def_dec_info_struct def_dec_info
;
246 typedef struct file_info_struct file_info
;
247 typedef struct f_list_chain_item_struct f_list_chain_item
;
250 static int is_syscalls_file
PARAMS ((const file_info
*));
251 static void rename_c_file
PARAMS ((const hash_table_entry
*));
252 static const def_dec_info
*find_extern_def
PARAMS ((const def_dec_info
*,
253 const def_dec_info
*));
254 static const def_dec_info
*find_static_definition
PARAMS ((const def_dec_info
*));
255 static void connect_defs_and_decs
PARAMS ((const hash_table_entry
*));
256 static void add_local_decl
PARAMS ((const def_dec_info
*, const char *));
257 static void add_global_decls
PARAMS ((const file_info
*, const char *));
258 #endif /* ! UNPROTOIZE */
259 static int needs_to_be_converted
PARAMS ((const file_info
*));
260 static void visit_each_hash_node
PARAMS ((const hash_table_entry
*,
261 void (*)(const hash_table_entry
*)));
262 static hash_table_entry
*add_symbol
PARAMS ((hash_table_entry
*, const char *));
263 static hash_table_entry
*lookup
PARAMS ((hash_table_entry
*, const char *));
264 static void free_def_dec
PARAMS ((def_dec_info
*));
265 static file_info
*find_file
PARAMS ((const char *, int));
266 static void reverse_def_dec_list
PARAMS ((const hash_table_entry
*));
267 static void edit_fn_declaration
PARAMS ((const def_dec_info
*, const char *));
268 static int edit_formals_lists
PARAMS ((const char *, unsigned int,
269 const def_dec_info
*));
270 static void edit_fn_definition
PARAMS ((const def_dec_info
*, const char *));
271 static void scan_for_missed_items
PARAMS ((const file_info
*));
272 static void edit_file
PARAMS ((const hash_table_entry
*));
274 /* In the struct below, note that the "_info" field has two different uses
275 depending on the type of hash table we are in (i.e. either the filenames
276 hash table or the function names hash table). In the filenames hash table
277 the info fields of the entries point to the file_info struct which is
278 associated with each filename (1 per filename). In the function names
279 hash table, the info field points to the head of a singly linked list of
280 def_dec_info entries which are all defs or decs of the function whose
281 name is pointed to by the "symbol" field. Keeping all of the defs/decs
282 for a given function name on a special list specifically for that function
283 name makes it quick and easy to find out all of the important information
284 about a given (named) function. */
286 struct hash_table_entry_struct
{
287 hash_table_entry
* hash_next
; /* -> to secondary entries */
288 const char * symbol
; /* -> to the hashed string */
290 const def_dec_info
* _ddip
;
294 #define ddip _info._ddip
295 #define fip _info._fip
297 /* Define a type specifically for our two hash tables. */
299 typedef hash_table_entry hash_table
[HASH_TABLE_SIZE
];
301 /* The following struct holds all of the important information about any
302 single filename (e.g. file) which we need to know about. */
304 struct file_info_struct
{
305 const hash_table_entry
* hash_entry
; /* -> to associated hash entry */
306 const def_dec_info
* defs_decs
; /* -> to chain of defs/decs */
307 time_t mtime
; /* Time of last modification. */
310 /* Due to the possibility that functions may return pointers to functions,
311 (which may themselves have their own parameter lists) and due to the
312 fact that returned pointers-to-functions may be of type "pointer-to-
313 function-returning-pointer-to-function" (ad nauseum) we have to keep
314 an entire chain of ANSI style formal parameter lists for each function.
316 Normally, for any given function, there will only be one formals list
317 on the chain, but you never know.
319 Note that the head of each chain of formals lists is pointed to by the
320 `f_list_chain' field of the corresponding def_dec_info record.
322 For any given chain, the item at the head of the chain is the *leftmost*
323 parameter list seen in the actual C language function declaration. If
324 there are other members of the chain, then these are linked in left-to-right
325 order from the head of the chain. */
327 struct f_list_chain_item_struct
{
328 const f_list_chain_item
* chain_next
; /* -> to next item on chain */
329 const char * formals_list
; /* -> to formals list string */
332 /* The following struct holds all of the important information about any
333 single function definition or declaration which we need to know about.
334 Note that for unprotoize we don't need to know very much because we
335 never even create records for stuff that we don't intend to convert
336 (like for instance defs and decs which are already in old K&R format
337 and "implicit" function declarations). */
339 struct def_dec_info_struct
{
340 const def_dec_info
* next_in_file
; /* -> to rest of chain for file */
341 file_info
* file
; /* -> file_info for containing file */
342 int line
; /* source line number of def/dec */
343 const char * ansi_decl
; /* -> left end of ansi decl */
344 hash_table_entry
* hash_entry
; /* -> hash entry for function name */
345 unsigned int is_func_def
; /* = 0 means this is a declaration */
346 const def_dec_info
* next_for_func
; /* -> to rest of chain for func name */
347 unsigned int f_list_count
; /* count of formals lists we expect */
348 char prototyped
; /* = 0 means already prototyped */
350 const f_list_chain_item
* f_list_chain
; /* -> chain of formals lists */
351 const def_dec_info
* definition
; /* -> def/dec containing related def */
352 char is_static
; /* = 0 means visibility is "extern" */
353 char is_implicit
; /* != 0 for implicit func decl's */
354 char written
; /* != 0 means written for implicit */
355 #else /* !defined (UNPROTOIZE) */
356 const char * formal_names
; /* -> to list of names of formals */
357 const char * formal_decls
; /* -> to string of formal declarations */
358 #endif /* !defined (UNPROTOIZE) */
361 /* Pointer to the tail component of the filename by which this program was
362 invoked. Used everywhere in error and warning messages. */
364 static const char *pname
;
366 /* Error counter. Will be nonzero if we should give up at the next convenient
369 static int errors
= 0;
372 /* ??? These comments should say what the flag mean as well as the options
375 /* File name to use for running gcc. Allows GCC 2 to be named
376 something other than gcc. */
377 static const char *compiler_file_name
= "gcc";
379 static int version_flag
= 0; /* Print our version number. */
380 static int quiet_flag
= 0; /* Don't print messages normally. */
381 static int nochange_flag
= 0; /* Don't convert, just say what files
382 we would have converted. */
383 static int nosave_flag
= 0; /* Don't save the old version. */
384 static int keep_flag
= 0; /* Don't delete the .X files. */
385 static const char ** compile_params
= 0; /* Option string for gcc. */
387 static const char *indent_string
= " "; /* Indentation for newly
388 inserted parm decls. */
389 #else /* !defined (UNPROTOIZE) */
390 static int local_flag
= 0; /* Insert new local decls (when?). */
391 static int global_flag
= 0; /* set by -g option */
392 static int cplusplus_flag
= 0; /* Rename converted files to *.C. */
393 static const char *nondefault_syscalls_dir
= 0; /* Dir to look for
395 #endif /* !defined (UNPROTOIZE) */
397 /* An index into the compile_params array where we should insert the source
398 file name when we are ready to exec the C compiler. A zero value indicates
399 that we have not yet called munge_compile_params. */
401 static int input_file_name_index
= 0;
403 /* An index into the compile_params array where we should insert the filename
404 for the aux info file, when we run the C compiler. */
405 static int aux_info_file_name_index
= 0;
407 /* Count of command line arguments which were "filename" arguments. */
409 static int n_base_source_files
= 0;
411 /* Points to a malloc'ed list of pointers to all of the filenames of base
412 source files which were specified on the command line. */
414 static const char **base_source_filenames
;
416 /* Line number of the line within the current aux_info file that we
417 are currently processing. Used for error messages in case the prototypes
418 info file is corrupted somehow. */
420 static int current_aux_info_lineno
;
422 /* Pointer to the name of the source file currently being converted. */
424 static const char *convert_filename
;
426 /* Pointer to relative root string (taken from aux_info file) which indicates
427 where directory the user was in when he did the compilation step that
428 produced the containing aux_info file. */
430 static const char *invocation_filename
;
432 /* Pointer to the base of the input buffer that holds the original text for the
433 source file currently being converted. */
435 static const char *orig_text_base
;
437 /* Pointer to the byte just beyond the end of the input buffer that holds the
438 original text for the source file currently being converted. */
440 static const char *orig_text_limit
;
442 /* Pointer to the base of the input buffer that holds the cleaned text for the
443 source file currently being converted. */
445 static const char *clean_text_base
;
447 /* Pointer to the byte just beyond the end of the input buffer that holds the
448 cleaned text for the source file currently being converted. */
450 static const char *clean_text_limit
;
452 /* Pointer to the last byte in the cleaned text buffer that we have already
453 (virtually) copied to the output buffer (or decided to ignore). */
455 static const char * clean_read_ptr
;
457 /* Pointer to the base of the output buffer that holds the replacement text
458 for the source file currently being converted. */
460 static char *repl_text_base
;
462 /* Pointer to the byte just beyond the end of the output buffer that holds the
463 replacement text for the source file currently being converted. */
465 static char *repl_text_limit
;
467 /* Pointer to the last byte which has been stored into the output buffer.
468 The next byte to be stored should be stored just past where this points
471 static char * repl_write_ptr
;
473 /* Pointer into the cleaned text buffer for the source file we are currently
474 converting. This points to the first character of the line that we last
475 did a "seek_to_line" to (see below). */
477 static const char *last_known_line_start
;
479 /* Number of the line (in the cleaned text buffer) that we last did a
480 "seek_to_line" to. Will be one if we just read a new source file
481 into the cleaned text buffer. */
483 static int last_known_line_number
;
485 /* The filenames hash table. */
487 static hash_table filename_primary
;
489 /* The function names hash table. */
491 static hash_table function_name_primary
;
493 /* The place to keep the recovery address which is used only in cases where
494 we get hopelessly confused by something in the cleaned original text. */
496 static jmp_buf source_confusion_recovery
;
498 /* A pointer to the current directory filename (used by abspath). */
500 static char *cwd_buffer
;
502 /* A place to save the read pointer until we are sure that an individual
503 attempt at editing will succeed. */
505 static const char * saved_clean_read_ptr
;
507 /* A place to save the write pointer until we are sure that an individual
508 attempt at editing will succeed. */
510 static char * saved_repl_write_ptr
;
512 /* Translate and output an error message. */
514 notice (const char *msgid
, ...)
518 va_start (ap
, msgid
);
519 vfprintf (stderr
, _(msgid
), ap
);
524 /* Make a copy of a string INPUT with size SIZE. */
527 savestring (input
, size
)
531 char *output
= (char *) xmalloc (size
+ 1);
532 strcpy (output
, input
);
536 /* More 'friendly' abort that prints the line and file.
537 config.h can #define abort fancy_abort if you like that sort of thing. */
542 notice ("%s: internal abort\n", pname
);
543 exit (FATAL_EXIT_CODE
);
546 /* Make a duplicate of the first N bytes of a given string in a newly
554 char *ret_val
= (char *) xmalloc (n
+ 1);
556 strncpy (ret_val
, s
, n
);
561 /* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
562 does not occur within s1. Assume neither s1 nor s2 are null pointers. */
567 const char *const s2
;
575 for (p1
= s1
, p2
= s2
; (c
= *p2
); p1
++, p2
++)
585 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
586 retrying if necessary. Return the actual number of bytes read. */
589 safe_read (desc
, ptr
, len
)
596 int nchars
= read (desc
, ptr
, left
);
607 /* Arithmetic on void pointers is a gcc extension. */
608 ptr
= (char *) ptr
+ nchars
;
614 /* Write LEN bytes at PTR to descriptor DESC,
615 retrying if necessary, and treating any real error as fatal. */
618 safe_write (desc
, ptr
, len
, out_fname
)
622 const char *out_fname
;
625 int written
= write (desc
, ptr
, len
);
628 int errno_val
= errno
;
630 if (errno_val
== EINTR
)
633 notice ("%s: error writing file `%s': %s\n",
634 pname
, shortpath (NULL
, out_fname
), xstrerror (errno_val
));
637 /* Arithmetic on void pointers is a gcc extension. */
638 ptr
= (char *) ptr
+ written
;
643 /* Get setup to recover in case the edit we are about to do goes awry. */
648 saved_clean_read_ptr
= clean_read_ptr
;
649 saved_repl_write_ptr
= repl_write_ptr
;
652 /* Call this routine to recover our previous state whenever something looks
653 too confusing in the source code we are trying to edit. */
658 clean_read_ptr
= saved_clean_read_ptr
;
659 repl_write_ptr
= saved_repl_write_ptr
;
662 /* Return true if the given character is a valid identifier character. */
668 return (ISIDNUM (ch
) || (ch
== '$'));
671 /* Give a message indicating the proper way to invoke this program and then
672 exit with nonzero status. */
678 notice ("%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
680 #else /* !defined (UNPROTOIZE) */
681 notice ("%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
683 #endif /* !defined (UNPROTOIZE) */
684 exit (FATAL_EXIT_CODE
);
687 /* Return true if the given filename (assumed to be an absolute filename)
688 designates a file residing anywhere beneath any one of the "system"
689 include directories. */
692 in_system_include_dir (path
)
695 const struct default_include
*p
;
697 if (! is_abspath (path
))
698 abort (); /* Must be an absolutized filename. */
700 for (p
= cpp_include_defaults
; p
->fname
; p
++)
701 if (!strncmp (path
, p
->fname
, strlen (p
->fname
))
702 && IS_DIR_SEPARATOR (path
[strlen (p
->fname
)]))
708 /* Return true if the given filename designates a file that the user has
709 read access to and for which the user has write access to the containing
713 file_could_be_converted (const char *path
)
715 char *const dir_name
= (char *) alloca (strlen (path
) + 1);
717 if (access (path
, R_OK
))
721 char *dir_last_slash
;
723 strcpy (dir_name
, path
);
724 dir_last_slash
= strrchr (dir_name
, DIR_SEPARATOR
);
725 #ifdef DIR_SEPARATOR_2
729 slash
= strrchr (dir_last_slash
? dir_last_slash
: dir_name
,
732 dir_last_slash
= slash
;
736 *dir_last_slash
= '\0';
738 abort (); /* Should have been an absolutized filename. */
741 if (access (path
, W_OK
))
747 /* Return true if the given filename designates a file that we are allowed
748 to modify. Files which we should not attempt to modify are (a) "system"
749 include files, and (b) files which the user doesn't have write access to,
750 and (c) files which reside in directories which the user doesn't have
751 write access to. Unless requested to be quiet, give warnings about
752 files that we will not try to convert for one reason or another. An
753 exception is made for "system" include files, which we never try to
754 convert and for which we don't issue the usual warnings. */
757 file_normally_convertible (const char *path
)
759 char *const dir_name
= alloca (strlen (path
) + 1);
761 if (in_system_include_dir (path
))
765 char *dir_last_slash
;
767 strcpy (dir_name
, path
);
768 dir_last_slash
= strrchr (dir_name
, DIR_SEPARATOR
);
769 #ifdef DIR_SEPARATOR_2
773 slash
= strrchr (dir_last_slash
? dir_last_slash
: dir_name
,
776 dir_last_slash
= slash
;
780 *dir_last_slash
= '\0';
782 abort (); /* Should have been an absolutized filename. */
785 if (access (path
, R_OK
))
788 notice ("%s: warning: no read access for file `%s'\n",
789 pname
, shortpath (NULL
, path
));
793 if (access (path
, W_OK
))
796 notice ("%s: warning: no write access for file `%s'\n",
797 pname
, shortpath (NULL
, path
));
801 if (access (dir_name
, W_OK
))
804 notice ("%s: warning: no write access for dir containing `%s'\n",
805 pname
, shortpath (NULL
, path
));
815 /* Return true if the given file_info struct refers to the special SYSCALLS.c.X
816 file. Return false otherwise. */
819 is_syscalls_file (fi_p
)
820 const file_info
*fi_p
;
822 char const *f
= fi_p
->hash_entry
->symbol
;
823 size_t fl
= strlen (f
), sysl
= sizeof (syscalls_filename
) - 1;
824 return sysl
<= fl
&& strcmp (f
+ fl
- sysl
, syscalls_filename
) == 0;
827 #endif /* !defined (UNPROTOIZE) */
829 /* Check to see if this file will need to have anything done to it on this
830 run. If there is nothing in the given file which both needs conversion
831 and for which we have the necessary stuff to do the conversion, return
832 false. Otherwise, return true.
834 Note that (for protoize) it is only valid to call this function *after*
835 the connections between declarations and definitions have all been made
836 by connect_defs_and_decs. */
839 needs_to_be_converted (file_p
)
840 const file_info
*file_p
;
842 const def_dec_info
*ddp
;
846 if (is_syscalls_file (file_p
))
849 #endif /* !defined (UNPROTOIZE) */
851 for (ddp
= file_p
->defs_decs
; ddp
; ddp
= ddp
->next_in_file
)
857 /* ... and if we a protoizing and this function is in old style ... */
859 /* ... and if this a definition or is a decl with an associated def ... */
860 && (ddp
->is_func_def
|| (!ddp
->is_func_def
&& ddp
->definition
))
862 #else /* defined (UNPROTOIZE) */
864 /* ... and if we are unprotoizing and this function is in new style ... */
867 #endif /* defined (UNPROTOIZE) */
869 /* ... then the containing file needs converting. */
874 /* Return 1 if the file name NAME is in a directory
875 that should be converted. */
878 directory_specified_p (name
)
881 struct string_list
*p
;
883 for (p
= directory_list
; p
; p
= p
->next
)
884 if (!strncmp (name
, p
->name
, strlen (p
->name
))
885 && IS_DIR_SEPARATOR (name
[strlen (p
->name
)]))
887 const char *q
= name
+ strlen (p
->name
) + 1;
889 /* If there are more slashes, it's in a subdir, so
890 this match doesn't count. */
892 if (IS_DIR_SEPARATOR (*(q
-1)))
902 /* Return 1 if the file named NAME should be excluded from conversion. */
905 file_excluded_p (name
)
908 struct string_list
*p
;
909 int len
= strlen (name
);
911 for (p
= exclude_list
; p
; p
= p
->next
)
912 if (!strcmp (name
+ len
- strlen (p
->name
), p
->name
)
913 && IS_DIR_SEPARATOR (name
[len
- strlen (p
->name
) - 1]))
919 /* Construct a new element of a string_list.
920 STRING is the new element value, and REST holds the remaining elements. */
922 static struct string_list
*
923 string_list_cons (string
, rest
)
925 struct string_list
*rest
;
927 struct string_list
*temp
928 = (struct string_list
*) xmalloc (sizeof (struct string_list
));
935 /* ??? The GNU convention for mentioning function args in its comments
936 is to capitalize them. So change "hash_tab_p" to HASH_TAB_P below.
937 Likewise for all the other functions. */
939 /* Given a hash table, apply some function to each node in the table. The
940 table to traverse is given as the "hash_tab_p" argument, and the
941 function to be applied to each node in the table is given as "func"
945 visit_each_hash_node (hash_tab_p
, func
)
946 const hash_table_entry
*hash_tab_p
;
947 void (*func
) PARAMS ((const hash_table_entry
*));
949 const hash_table_entry
*primary
;
951 for (primary
= hash_tab_p
; primary
< &hash_tab_p
[HASH_TABLE_SIZE
]; primary
++)
954 hash_table_entry
*second
;
957 for (second
= primary
->hash_next
; second
; second
= second
->hash_next
)
962 /* Initialize all of the fields of a new hash table entry, pointed
963 to by the "p" parameter. Note that the space to hold the entry
964 is assumed to have already been allocated before this routine is
967 static hash_table_entry
*
973 p
->symbol
= xstrdup (s
);
979 /* Look for a particular function name or filename in the particular
980 hash table indicated by "hash_tab_p". If the name is not in the
981 given hash table, add it. Either way, return a pointer to the
982 hash table entry for the given name. */
984 static hash_table_entry
*
985 lookup (hash_tab_p
, search_symbol
)
986 hash_table_entry
*hash_tab_p
;
987 const char *search_symbol
;
990 const char *search_symbol_char_p
= search_symbol
;
993 while (*search_symbol_char_p
)
994 hash_value
+= *search_symbol_char_p
++;
995 hash_value
&= hash_mask
;
996 p
= &hash_tab_p
[hash_value
];
998 return add_symbol (p
, search_symbol
);
999 if (!strcmp (p
->symbol
, search_symbol
))
1001 while (p
->hash_next
)
1004 if (!strcmp (p
->symbol
, search_symbol
))
1007 p
->hash_next
= (hash_table_entry
*) xmalloc (sizeof (hash_table_entry
));
1009 return add_symbol (p
, search_symbol
);
1012 /* Throw a def/dec record on the junk heap.
1014 Also, since we are not using this record anymore, free up all of the
1015 stuff it pointed to. */
1021 free ((NONCONST
void *) p
->ansi_decl
);
1025 const f_list_chain_item
* curr
;
1026 const f_list_chain_item
* next
;
1028 for (curr
= p
->f_list_chain
; curr
; curr
= next
)
1030 next
= curr
->chain_next
;
1031 free ((NONCONST
void *) curr
);
1034 #endif /* !defined (UNPROTOIZE) */
1039 /* Unexpand as many macro symbol as we can find.
1041 If the given line must be unexpanded, make a copy of it in the heap and
1042 return a pointer to the unexpanded copy. Otherwise return NULL. */
1045 unexpand_if_needed (aux_info_line
)
1046 const char *aux_info_line
;
1048 static char *line_buf
= 0;
1049 static int line_buf_size
= 0;
1050 const unexpansion
*unexp_p
;
1051 int got_unexpanded
= 0;
1053 char *copy_p
= line_buf
;
1057 line_buf_size
= 1024;
1058 line_buf
= (char *) xmalloc (line_buf_size
);
1063 /* Make a copy of the input string in line_buf, expanding as necessary. */
1065 for (s
= aux_info_line
; *s
!= '\n'; )
1067 for (unexp_p
= unexpansions
; unexp_p
->expanded
; unexp_p
++)
1069 const char *in_p
= unexp_p
->expanded
;
1070 size_t len
= strlen (in_p
);
1072 if (*s
== *in_p
&& !strncmp (s
, in_p
, len
) && !is_id_char (s
[len
]))
1074 int size
= strlen (unexp_p
->contracted
);
1076 if (copy_p
+ size
- line_buf
>= line_buf_size
)
1078 int offset
= copy_p
- line_buf
;
1080 line_buf_size
+= size
;
1081 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1082 copy_p
= line_buf
+ offset
;
1084 strcpy (copy_p
, unexp_p
->contracted
);
1087 /* Assume that there will not be another replacement required
1088 within the text just replaced. */
1091 goto continue_outer
;
1094 if (copy_p
- line_buf
== line_buf_size
)
1096 int offset
= copy_p
- line_buf
;
1098 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1099 copy_p
= line_buf
+ offset
;
1104 if (copy_p
+ 2 - line_buf
>= line_buf_size
)
1106 int offset
= copy_p
- line_buf
;
1108 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1109 copy_p
= line_buf
+ offset
;
1114 return (got_unexpanded
? savestring (line_buf
, copy_p
- line_buf
) : 0);
1117 /* Return 1 if pathname is absolute. */
1123 return (IS_DIR_SEPARATOR (path
[0])
1124 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
1125 /* Check for disk name on MS-DOS-based systems. */
1126 || (path
[0] && path
[1] == ':' && IS_DIR_SEPARATOR (path
[2]))
1131 /* Return the absolutized filename for the given relative
1132 filename. Note that if that filename is already absolute, it may
1133 still be returned in a modified form because this routine also
1134 eliminates redundant slashes and single dots and eliminates double
1135 dots to get a shortest possible filename from the given input
1136 filename. The absolutization of relative filenames is made by
1137 assuming that the given filename is to be taken as relative to
1138 the first argument (cwd) or to the current directory if cwd is
1142 abspath (cwd
, rel_filename
)
1144 const char *rel_filename
;
1146 /* Setup the current working directory as needed. */
1147 const char *const cwd2
= (cwd
) ? cwd
: cwd_buffer
;
1148 char *const abs_buffer
1149 = (char *) alloca (strlen (cwd2
) + strlen (rel_filename
) + 2);
1150 char *endp
= abs_buffer
;
1153 /* Copy the filename (possibly preceded by the current working
1154 directory name) into the absolutization buffer. */
1159 if (! is_abspath (rel_filename
))
1162 while ((*endp
++ = *src_p
++))
1164 *(endp
-1) = DIR_SEPARATOR
; /* overwrite null */
1166 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
1167 else if (IS_DIR_SEPARATOR (rel_filename
[0]))
1169 /* A path starting with a directory separator is considered absolute
1170 for dos based filesystems, but it's really not -- it's just the
1171 convention used throughout GCC and it works. However, in this
1172 case, we still need to prepend the drive spec from cwd_buffer. */
1177 src_p
= rel_filename
;
1178 while ((*endp
++ = *src_p
++))
1182 /* Now make a copy of abs_buffer into abs_buffer, shortening the
1183 filename (by taking out slashes and dots) as we go. */
1185 outp
= inp
= abs_buffer
;
1186 *outp
++ = *inp
++; /* copy first slash */
1187 #if defined (apollo) || defined (_WIN32) || defined (__INTERIX)
1188 if (IS_DIR_SEPARATOR (inp
[0]))
1189 *outp
++ = *inp
++; /* copy second slash */
1195 else if (IS_DIR_SEPARATOR (inp
[0]) && IS_DIR_SEPARATOR (outp
[-1]))
1200 else if (inp
[0] == '.' && IS_DIR_SEPARATOR (outp
[-1]))
1204 else if (IS_DIR_SEPARATOR (inp
[1]))
1209 else if ((inp
[1] == '.') && (inp
[2] == 0
1210 || IS_DIR_SEPARATOR (inp
[2])))
1212 inp
+= (IS_DIR_SEPARATOR (inp
[2])) ? 3 : 2;
1214 while (outp
>= abs_buffer
&& ! IS_DIR_SEPARATOR (*outp
))
1216 if (outp
< abs_buffer
)
1218 /* Catch cases like /.. where we try to backup to a
1219 point above the absolute root of the logical file
1222 notice ("%s: invalid file name: %s\n",
1223 pname
, rel_filename
);
1224 exit (FATAL_EXIT_CODE
);
1233 /* On exit, make sure that there is a trailing null, and make sure that
1234 the last character of the returned string is *not* a slash. */
1237 if (IS_DIR_SEPARATOR (outp
[-1]))
1240 /* Make a copy (in the heap) of the stuff left in the absolutization
1241 buffer and return a pointer to the copy. */
1243 return savestring (abs_buffer
, outp
- abs_buffer
);
1246 /* Given a filename (and possibly a directory name from which the filename
1247 is relative) return a string which is the shortest possible
1248 equivalent for the corresponding full (absolutized) filename. The
1249 shortest possible equivalent may be constructed by converting the
1250 absolutized filename to be a relative filename (i.e. relative to
1251 the actual current working directory). However if a relative filename
1252 is longer, then the full absolute filename is returned.
1256 Note that "simple-minded" conversion of any given type of filename (either
1257 relative or absolute) may not result in a valid equivalent filename if any
1258 subpart of the original filename is actually a symbolic link. */
1261 shortpath (cwd
, filename
)
1263 const char *filename
;
1267 char *cwd_p
= cwd_buffer
;
1269 int unmatched_slash_count
= 0;
1270 size_t filename_len
= strlen (filename
);
1272 path_p
= abspath (cwd
, filename
);
1273 rel_buf_p
= rel_buffer
= (char *) xmalloc (filename_len
);
1275 while (*cwd_p
&& IS_SAME_PATH_CHAR (*cwd_p
, *path_p
))
1280 if (!*cwd_p
&& (!*path_p
|| IS_DIR_SEPARATOR (*path_p
)))
1282 /* whole pwd matched */
1283 if (!*path_p
) /* input *is* the current path! */
1294 while (! IS_DIR_SEPARATOR (*cwd_p
)) /* backup to last slash */
1301 unmatched_slash_count
++;
1304 /* Find out how many directory levels in cwd were *not* matched. */
1306 if (IS_DIR_SEPARATOR (*(cwd_p
-1)))
1307 unmatched_slash_count
++;
1309 /* Now we know how long the "short name" will be.
1310 Reject it if longer than the input. */
1311 if (unmatched_slash_count
* 3 + strlen (path_p
) >= filename_len
)
1314 /* For each of them, put a `../' at the beginning of the short name. */
1315 while (unmatched_slash_count
--)
1317 /* Give up if the result gets to be longer
1318 than the absolute path name. */
1319 if (rel_buffer
+ filename_len
<= rel_buf_p
+ 3)
1323 *rel_buf_p
++ = DIR_SEPARATOR
;
1326 /* Then tack on the unmatched part of the desired file's name. */
1329 if (rel_buffer
+ filename_len
<= rel_buf_p
)
1332 while ((*rel_buf_p
++ = *path_p
++));
1335 if (IS_DIR_SEPARATOR (*(rel_buf_p
-1)))
1336 *--rel_buf_p
= '\0';
1341 /* Lookup the given filename in the hash table for filenames. If it is a
1342 new one, then the hash table info pointer will be null. In this case,
1343 we create a new file_info record to go with the filename, and we initialize
1344 that record with some reasonable values. */
1346 /* FILENAME was const, but that causes a warning on AIX when calling stat.
1347 That is probably a bug in AIX, but might as well avoid the warning. */
1350 find_file (filename
, do_not_stat
)
1351 const char *filename
;
1354 hash_table_entry
*hash_entry_p
;
1356 hash_entry_p
= lookup (filename_primary
, filename
);
1357 if (hash_entry_p
->fip
)
1358 return hash_entry_p
->fip
;
1361 struct stat stat_buf
;
1362 file_info
*file_p
= (file_info
*) xmalloc (sizeof (file_info
));
1364 /* If we cannot get status on any given source file, give a warning
1365 and then just set its time of last modification to infinity. */
1368 stat_buf
.st_mtime
= (time_t) 0;
1371 if (stat (filename
, &stat_buf
) == -1)
1373 int errno_val
= errno
;
1374 notice ("%s: %s: can't get status: %s\n",
1375 pname
, shortpath (NULL
, filename
),
1376 xstrerror (errno_val
));
1377 stat_buf
.st_mtime
= (time_t) -1;
1381 hash_entry_p
->fip
= file_p
;
1382 file_p
->hash_entry
= hash_entry_p
;
1383 file_p
->defs_decs
= NULL
;
1384 file_p
->mtime
= stat_buf
.st_mtime
;
1389 /* Generate a fatal error because some part of the aux_info file is
1393 aux_info_corrupted ()
1395 notice ("\n%s: fatal error: aux info file corrupted at line %d\n",
1396 pname
, current_aux_info_lineno
);
1397 exit (FATAL_EXIT_CODE
);
1400 /* ??? This comment is vague. Say what the condition is for. */
1401 /* Check to see that a condition is true. This is kind of like an assert. */
1404 check_aux_info (cond
)
1408 aux_info_corrupted ();
1411 /* Given a pointer to the closing right parenthesis for a particular formals
1412 list (in an aux_info file) find the corresponding left parenthesis and
1413 return a pointer to it. */
1416 find_corresponding_lparen (p
)
1422 for (paren_depth
= 1, q
= p
-1; paren_depth
; q
--)
1437 /* Given a line from an aux info file, and a time at which the aux info
1438 file it came from was created, check to see if the item described in
1439 the line comes from a file which has been modified since the aux info
1440 file was created. If so, return nonzero, else return zero. */
1443 referenced_file_is_newer (l
, aux_info_mtime
)
1445 time_t aux_info_mtime
;
1451 check_aux_info (l
[0] == '/');
1452 check_aux_info (l
[1] == '*');
1453 check_aux_info (l
[2] == ' ');
1456 const char *filename_start
= p
= l
+ 3;
1459 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
1460 || (*p
== ':' && *p
&& *(p
+1) && IS_DIR_SEPARATOR (*(p
+1)))
1464 filename
= (char *) alloca ((size_t) (p
- filename_start
) + 1);
1465 strncpy (filename
, filename_start
, (size_t) (p
- filename_start
));
1466 filename
[p
-filename_start
] = '\0';
1469 /* Call find_file to find the file_info record associated with the file
1470 which contained this particular def or dec item. Note that this call
1471 may cause a new file_info record to be created if this is the first time
1472 that we have ever known about this particular file. */
1474 fi_p
= find_file (abspath (invocation_filename
, filename
), 0);
1476 return (fi_p
->mtime
> aux_info_mtime
);
1479 /* Given a line of info from the aux_info file, create a new
1480 def_dec_info record to remember all of the important information about
1481 a function definition or declaration.
1483 Link this record onto the list of such records for the particular file in
1484 which it occurred in proper (descending) line number order (for now).
1486 If there is an identical record already on the list for the file, throw
1487 this one away. Doing so takes care of the (useless and troublesome)
1488 duplicates which are bound to crop up due to multiple inclusions of any
1489 given individual header file.
1491 Finally, link the new def_dec record onto the list of such records
1492 pertaining to this particular function name. */
1495 save_def_or_dec (l
, is_syscalls
)
1500 const char *semicolon_p
;
1501 def_dec_info
*def_dec_p
= (def_dec_info
*) xmalloc (sizeof (def_dec_info
));
1504 def_dec_p
->written
= 0;
1505 #endif /* !defined (UNPROTOIZE) */
1507 /* Start processing the line by picking off 5 pieces of information from
1508 the left hand end of the line. These are filename, line number,
1509 new/old/implicit flag (new = ANSI prototype format), definition or
1510 declaration flag, and extern/static flag). */
1512 check_aux_info (l
[0] == '/');
1513 check_aux_info (l
[1] == '*');
1514 check_aux_info (l
[2] == ' ');
1517 const char *filename_start
= p
= l
+ 3;
1521 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
1522 || (*p
== ':' && *p
&& *(p
+1) && IS_DIR_SEPARATOR (*(p
+1)))
1526 filename
= (char *) alloca ((size_t) (p
- filename_start
) + 1);
1527 strncpy (filename
, filename_start
, (size_t) (p
- filename_start
));
1528 filename
[p
-filename_start
] = '\0';
1530 /* Call find_file to find the file_info record associated with the file
1531 which contained this particular def or dec item. Note that this call
1532 may cause a new file_info record to be created if this is the first time
1533 that we have ever known about this particular file.
1535 Note that we started out by forcing all of the base source file names
1536 (i.e. the names of the aux_info files with the .X stripped off) into the
1537 filenames hash table, and we simultaneously setup file_info records for
1538 all of these base file names (even if they may be useless later).
1539 The file_info records for all of these "base" file names (properly)
1540 act as file_info records for the "original" (i.e. un-included) files
1541 which were submitted to gcc for compilation (when the -aux-info
1542 option was used). */
1544 def_dec_p
->file
= find_file (abspath (invocation_filename
, filename
), is_syscalls
);
1548 const char *line_number_start
= ++p
;
1549 char line_number
[10];
1552 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
1553 || (*p
== ':' && *p
&& *(p
+1) && IS_DIR_SEPARATOR (*(p
+1)))
1557 strncpy (line_number
, line_number_start
, (size_t) (p
- line_number_start
));
1558 line_number
[p
-line_number_start
] = '\0';
1559 def_dec_p
->line
= atoi (line_number
);
1562 /* Check that this record describes a new-style, old-style, or implicit
1563 definition or declaration. */
1565 p
++; /* Skip over the `:'. */
1566 check_aux_info ((*p
== 'N') || (*p
== 'O') || (*p
== 'I'));
1568 /* Is this a new style (ANSI prototyped) definition or declaration? */
1570 def_dec_p
->prototyped
= (*p
== 'N');
1574 /* Is this an implicit declaration? */
1576 def_dec_p
->is_implicit
= (*p
== 'I');
1578 #endif /* !defined (UNPROTOIZE) */
1582 check_aux_info ((*p
== 'C') || (*p
== 'F'));
1584 /* Is this item a function definition (F) or a declaration (C). Note that
1585 we treat item taken from the syscalls file as though they were function
1586 definitions regardless of what the stuff in the file says. */
1588 def_dec_p
->is_func_def
= ((*p
++ == 'F') || is_syscalls
);
1591 def_dec_p
->definition
= 0; /* Fill this in later if protoizing. */
1592 #endif /* !defined (UNPROTOIZE) */
1594 check_aux_info (*p
++ == ' ');
1595 check_aux_info (*p
++ == '*');
1596 check_aux_info (*p
++ == '/');
1597 check_aux_info (*p
++ == ' ');
1600 check_aux_info ((!strncmp (p
, "static", 6)) || (!strncmp (p
, "extern", 6)));
1601 #else /* !defined (UNPROTOIZE) */
1602 if (!strncmp (p
, "static", 6))
1603 def_dec_p
->is_static
= -1;
1604 else if (!strncmp (p
, "extern", 6))
1605 def_dec_p
->is_static
= 0;
1607 check_aux_info (0); /* Didn't find either `extern' or `static'. */
1608 #endif /* !defined (UNPROTOIZE) */
1611 const char *ansi_start
= p
;
1613 p
+= 6; /* Pass over the "static" or "extern". */
1615 /* We are now past the initial stuff. Search forward from here to find
1616 the terminating semicolon that should immediately follow the entire
1617 ANSI format function declaration. */
1624 /* Make a copy of the ansi declaration part of the line from the aux_info
1627 def_dec_p
->ansi_decl
1628 = dupnstr (ansi_start
, (size_t) ((semicolon_p
+1) - ansi_start
));
1630 /* Backup and point at the final right paren of the final argument list. */
1635 def_dec_p
->f_list_chain
= NULL
;
1636 #endif /* !defined (UNPROTOIZE) */
1638 while (p
!= ansi_start
&& (p
[-1] == ' ' || p
[-1] == '\t')) p
--;
1641 free_def_dec (def_dec_p
);
1646 /* Now isolate a whole set of formal argument lists, one-by-one. Normally,
1647 there will only be one list to isolate, but there could be more. */
1649 def_dec_p
->f_list_count
= 0;
1653 const char *left_paren_p
= find_corresponding_lparen (p
);
1656 f_list_chain_item
*cip
1657 = (f_list_chain_item
*) xmalloc (sizeof (f_list_chain_item
));
1660 = dupnstr (left_paren_p
+ 1, (size_t) (p
- (left_paren_p
+1)));
1662 /* Add the new chain item at the head of the current list. */
1664 cip
->chain_next
= def_dec_p
->f_list_chain
;
1665 def_dec_p
->f_list_chain
= cip
;
1667 #endif /* !defined (UNPROTOIZE) */
1668 def_dec_p
->f_list_count
++;
1670 p
= left_paren_p
- 2;
1672 /* p must now point either to another right paren, or to the last
1673 character of the name of the function that was declared/defined.
1674 If p points to another right paren, then this indicates that we
1675 are dealing with multiple formals lists. In that case, there
1676 really should be another right paren preceding this right paren. */
1681 check_aux_info (*--p
== ')');
1686 const char *past_fn
= p
+ 1;
1688 check_aux_info (*past_fn
== ' ');
1690 /* Scan leftwards over the identifier that names the function. */
1692 while (is_id_char (*p
))
1696 /* p now points to the leftmost character of the function name. */
1699 char *fn_string
= (char *) alloca (past_fn
- p
+ 1);
1701 strncpy (fn_string
, p
, (size_t) (past_fn
- p
));
1702 fn_string
[past_fn
-p
] = '\0';
1703 def_dec_p
->hash_entry
= lookup (function_name_primary
, fn_string
);
1707 /* Look at all of the defs and decs for this function name that we have
1708 collected so far. If there is already one which is at the same
1709 line number in the same file, then we can discard this new def_dec_info
1712 As an extra assurance that any such pair of (nominally) identical
1713 function declarations are in fact identical, we also compare the
1714 ansi_decl parts of the lines from the aux_info files just to be on
1717 This comparison will fail if (for instance) the user was playing
1718 messy games with the preprocessor which ultimately causes one
1719 function declaration in one header file to look differently when
1720 that file is included by two (or more) other files. */
1723 const def_dec_info
*other
;
1725 for (other
= def_dec_p
->hash_entry
->ddip
; other
; other
= other
->next_for_func
)
1727 if (def_dec_p
->line
== other
->line
&& def_dec_p
->file
== other
->file
)
1729 if (strcmp (def_dec_p
->ansi_decl
, other
->ansi_decl
))
1731 notice ("%s:%d: declaration of function `%s' takes different forms\n",
1732 def_dec_p
->file
->hash_entry
->symbol
,
1734 def_dec_p
->hash_entry
->symbol
);
1735 exit (FATAL_EXIT_CODE
);
1737 free_def_dec (def_dec_p
);
1745 /* If we are doing unprotoizing, we must now setup the pointers that will
1746 point to the K&R name list and to the K&R argument declarations list.
1748 Note that if this is only a function declaration, then we should not
1749 expect to find any K&R style formals list following the ANSI-style
1750 formals list. This is because GCC knows that such information is
1751 useless in the case of function declarations (function definitions
1752 are a different story however).
1754 Since we are unprotoizing, we don't need any such lists anyway.
1755 All we plan to do is to delete all characters between ()'s in any
1758 def_dec_p
->formal_names
= NULL
;
1759 def_dec_p
->formal_decls
= NULL
;
1761 if (def_dec_p
->is_func_def
)
1764 check_aux_info (*++p
== ' ');
1765 check_aux_info (*++p
== '/');
1766 check_aux_info (*++p
== '*');
1767 check_aux_info (*++p
== ' ');
1768 check_aux_info (*++p
== '(');
1771 const char *kr_names_start
= ++p
; /* Point just inside '('. */
1775 p
--; /* point to closing right paren */
1777 /* Make a copy of the K&R parameter names list. */
1779 def_dec_p
->formal_names
1780 = dupnstr (kr_names_start
, (size_t) (p
- kr_names_start
));
1783 check_aux_info (*++p
== ' ');
1786 /* p now points to the first character of the K&R style declarations
1787 list (if there is one) or to the star-slash combination that ends
1788 the comment in which such lists get embedded. */
1790 /* Make a copy of the K&R formal decls list and set the def_dec record
1793 if (*p
== '*') /* Are there no K&R declarations? */
1795 check_aux_info (*++p
== '/');
1796 def_dec_p
->formal_decls
= "";
1800 const char *kr_decls_start
= p
;
1802 while (p
[0] != '*' || p
[1] != '/')
1806 check_aux_info (*p
== ' ');
1808 def_dec_p
->formal_decls
1809 = dupnstr (kr_decls_start
, (size_t) (p
- kr_decls_start
));
1812 /* Handle a special case. If we have a function definition marked as
1813 being in "old" style, and if its formal names list is empty, then
1814 it may actually have the string "void" in its real formals list
1815 in the original source code. Just to make sure, we will get setup
1816 to convert such things anyway.
1818 This kludge only needs to be here because of an insurmountable
1819 problem with generating .X files. */
1821 if (!def_dec_p
->prototyped
&& !*def_dec_p
->formal_names
)
1822 def_dec_p
->prototyped
= 1;
1825 /* Since we are unprotoizing, if this item is already in old (K&R) style,
1826 we can just ignore it. If that is true, throw away the itme now. */
1828 if (!def_dec_p
->prototyped
)
1830 free_def_dec (def_dec_p
);
1834 #endif /* defined (UNPROTOIZE) */
1836 /* Add this record to the head of the list of records pertaining to this
1837 particular function name. */
1839 def_dec_p
->next_for_func
= def_dec_p
->hash_entry
->ddip
;
1840 def_dec_p
->hash_entry
->ddip
= def_dec_p
;
1842 /* Add this new def_dec_info record to the sorted list of def_dec_info
1843 records for this file. Note that we don't have to worry about duplicates
1844 (caused by multiple inclusions of header files) here because we have
1845 already eliminated duplicates above. */
1847 if (!def_dec_p
->file
->defs_decs
)
1849 def_dec_p
->file
->defs_decs
= def_dec_p
;
1850 def_dec_p
->next_in_file
= NULL
;
1854 int line
= def_dec_p
->line
;
1855 const def_dec_info
*prev
= NULL
;
1856 const def_dec_info
*curr
= def_dec_p
->file
->defs_decs
;
1857 const def_dec_info
*next
= curr
->next_in_file
;
1859 while (next
&& (line
< curr
->line
))
1863 next
= next
->next_in_file
;
1865 if (line
>= curr
->line
)
1867 def_dec_p
->next_in_file
= curr
;
1869 ((NONCONST def_dec_info
*) prev
)->next_in_file
= def_dec_p
;
1871 def_dec_p
->file
->defs_decs
= def_dec_p
;
1873 else /* assert (next == NULL); */
1875 ((NONCONST def_dec_info
*) curr
)->next_in_file
= def_dec_p
;
1876 /* assert (next == NULL); */
1877 def_dec_p
->next_in_file
= next
;
1882 /* Set up the vector COMPILE_PARAMS which is the argument list for running GCC.
1883 Also set input_file_name_index and aux_info_file_name_index
1884 to the indices of the slots where the file names should go. */
1886 /* We initialize the vector by removing -g, -O, -S, -c, and -o options,
1887 and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
1890 munge_compile_params (params_list
)
1891 const char *params_list
;
1893 /* Build up the contents in a temporary vector
1894 that is so big that to has to be big enough. */
1895 const char **temp_params
1896 = (const char **) alloca ((strlen (params_list
) + 8) * sizeof (char *));
1897 int param_count
= 0;
1901 temp_params
[param_count
++] = compiler_file_name
;
1904 while (ISSPACE ((const unsigned char)*params_list
))
1908 param
= params_list
;
1909 while (*params_list
&& !ISSPACE ((const unsigned char)*params_list
))
1911 if (param
[0] != '-')
1912 temp_params
[param_count
++]
1913 = dupnstr (param
, (size_t) (params_list
- param
));
1922 break; /* Don't copy these. */
1924 while (ISSPACE ((const unsigned char)*params_list
))
1927 && !ISSPACE ((const unsigned char)*params_list
))
1931 temp_params
[param_count
++]
1932 = dupnstr (param
, (size_t) (params_list
- param
));
1938 temp_params
[param_count
++] = "-aux-info";
1940 /* Leave room for the aux-info file name argument. */
1941 aux_info_file_name_index
= param_count
;
1942 temp_params
[param_count
++] = NULL
;
1944 temp_params
[param_count
++] = "-S";
1945 temp_params
[param_count
++] = "-o";
1947 if ((stat (HOST_BIT_BUCKET
, &st
) == 0)
1948 && (!S_ISDIR (st
.st_mode
))
1949 && (access (HOST_BIT_BUCKET
, W_OK
) == 0))
1950 temp_params
[param_count
++] = HOST_BIT_BUCKET
;
1952 /* FIXME: This is hardly likely to be right, if HOST_BIT_BUCKET is not
1953 writable. But until this is rejigged to use make_temp_file(), this
1954 is the best we can do. */
1955 temp_params
[param_count
++] = "/dev/null";
1957 /* Leave room for the input file name argument. */
1958 input_file_name_index
= param_count
;
1959 temp_params
[param_count
++] = NULL
;
1960 /* Terminate the list. */
1961 temp_params
[param_count
++] = NULL
;
1963 /* Make a copy of the compile_params in heap space. */
1966 = (const char **) xmalloc (sizeof (char *) * (param_count
+1));
1967 memcpy (compile_params
, temp_params
, sizeof (char *) * param_count
);
1970 /* Do a recompilation for the express purpose of generating a new aux_info
1971 file to go with a specific base source file.
1973 The result is a boolean indicating success. */
1976 gen_aux_info_file (base_filename
)
1977 const char *base_filename
;
1979 if (!input_file_name_index
)
1980 munge_compile_params ("");
1982 /* Store the full source file name in the argument vector. */
1983 compile_params
[input_file_name_index
] = shortpath (NULL
, base_filename
);
1984 /* Add .X to source file name to get aux-info file name. */
1985 compile_params
[aux_info_file_name_index
] =
1986 concat (compile_params
[input_file_name_index
], aux_info_suffix
, NULL
);
1989 notice ("%s: compiling `%s'\n",
1990 pname
, compile_params
[input_file_name_index
]);
1993 char *errmsg_fmt
, *errmsg_arg
;
1994 int wait_status
, pid
;
1996 pid
= pexecute (compile_params
[0], (char * const *) compile_params
,
1997 pname
, NULL
, &errmsg_fmt
, &errmsg_arg
,
1998 PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
);
2002 int errno_val
= errno
;
2003 fprintf (stderr
, "%s: ", pname
);
2004 fprintf (stderr
, errmsg_fmt
, errmsg_arg
);
2005 fprintf (stderr
, ": %s\n", xstrerror (errno_val
));
2009 pid
= pwait (pid
, &wait_status
, 0);
2012 notice ("%s: wait: %s\n", pname
, xstrerror (errno
));
2015 if (WIFSIGNALED (wait_status
))
2017 notice ("%s: subprocess got fatal signal %d\n",
2018 pname
, WTERMSIG (wait_status
));
2021 if (WIFEXITED (wait_status
))
2023 if (WEXITSTATUS (wait_status
) != 0)
2025 notice ("%s: %s exited with status %d\n",
2026 pname
, compile_params
[0], WEXITSTATUS (wait_status
));
2035 /* Read in all of the information contained in a single aux_info file.
2036 Save all of the important stuff for later. */
2039 process_aux_info_file (base_source_filename
, keep_it
, is_syscalls
)
2040 const char *base_source_filename
;
2044 size_t base_len
= strlen (base_source_filename
);
2045 char * aux_info_filename
2046 = (char *) alloca (base_len
+ strlen (aux_info_suffix
) + 1);
2047 char *aux_info_base
;
2048 char *aux_info_limit
;
2049 char *aux_info_relocated_name
;
2050 const char *aux_info_second_line
;
2051 time_t aux_info_mtime
;
2052 size_t aux_info_size
;
2055 /* Construct the aux_info filename from the base source filename. */
2057 strcpy (aux_info_filename
, base_source_filename
);
2058 strcat (aux_info_filename
, aux_info_suffix
);
2060 /* Check that the aux_info file exists and is readable. If it does not
2061 exist, try to create it (once only). */
2063 /* If file doesn't exist, set must_create.
2064 Likewise if it exists and we can read it but it is obsolete.
2065 Otherwise, report an error. */
2068 /* Come here with must_create set to 1 if file is out of date. */
2071 if (access (aux_info_filename
, R_OK
) == -1)
2073 if (errno
== ENOENT
)
2077 notice ("%s: warning: missing SYSCALLS file `%s'\n",
2078 pname
, aux_info_filename
);
2085 int errno_val
= errno
;
2086 notice ("%s: can't read aux info file `%s': %s\n",
2087 pname
, shortpath (NULL
, aux_info_filename
),
2088 xstrerror (errno_val
));
2093 #if 0 /* There is code farther down to take care of this. */
2097 stat (aux_info_file_name
, &s1
);
2098 stat (base_source_file_name
, &s2
);
2099 if (s2
.st_mtime
> s1
.st_mtime
)
2104 /* If we need a .X file, create it, and verify we can read it. */
2107 if (!gen_aux_info_file (base_source_filename
))
2112 if (access (aux_info_filename
, R_OK
) == -1)
2114 int errno_val
= errno
;
2115 notice ("%s: can't read aux info file `%s': %s\n",
2116 pname
, shortpath (NULL
, aux_info_filename
),
2117 xstrerror (errno_val
));
2124 struct stat stat_buf
;
2126 /* Get some status information about this aux_info file. */
2128 if (stat (aux_info_filename
, &stat_buf
) == -1)
2130 int errno_val
= errno
;
2131 notice ("%s: can't get status of aux info file `%s': %s\n",
2132 pname
, shortpath (NULL
, aux_info_filename
),
2133 xstrerror (errno_val
));
2138 /* Check on whether or not this aux_info file is zero length. If it is,
2139 then just ignore it and return. */
2141 if ((aux_info_size
= stat_buf
.st_size
) == 0)
2144 /* Get the date/time of last modification for this aux_info file and
2145 remember it. We will have to check that any source files that it
2146 contains information about are at least this old or older. */
2148 aux_info_mtime
= stat_buf
.st_mtime
;
2152 /* Compare mod time with the .c file; update .X file if obsolete.
2153 The code later on can fail to check the .c file
2154 if it did not directly define any functions. */
2156 if (stat (base_source_filename
, &stat_buf
) == -1)
2158 int errno_val
= errno
;
2159 notice ("%s: can't get status of aux info file `%s': %s\n",
2160 pname
, shortpath (NULL
, base_source_filename
),
2161 xstrerror (errno_val
));
2165 if (stat_buf
.st_mtime
> aux_info_mtime
)
2177 /* Open the aux_info file. */
2179 fd_flags
= O_RDONLY
;
2181 /* Use binary mode to avoid having to deal with different EOL characters. */
2182 fd_flags
|= O_BINARY
;
2184 if ((aux_info_file
= open (aux_info_filename
, fd_flags
, 0444 )) == -1)
2186 int errno_val
= errno
;
2187 notice ("%s: can't open aux info file `%s' for reading: %s\n",
2188 pname
, shortpath (NULL
, aux_info_filename
),
2189 xstrerror (errno_val
));
2193 /* Allocate space to hold the aux_info file in memory. */
2195 aux_info_base
= xmalloc (aux_info_size
+ 1);
2196 aux_info_limit
= aux_info_base
+ aux_info_size
;
2197 *aux_info_limit
= '\0';
2199 /* Read the aux_info file into memory. */
2201 if (safe_read (aux_info_file
, aux_info_base
, aux_info_size
) !=
2202 (int) aux_info_size
)
2204 int errno_val
= errno
;
2205 notice ("%s: error reading aux info file `%s': %s\n",
2206 pname
, shortpath (NULL
, aux_info_filename
),
2207 xstrerror (errno_val
));
2208 free (aux_info_base
);
2209 close (aux_info_file
);
2213 /* Close the aux info file. */
2215 if (close (aux_info_file
))
2217 int errno_val
= errno
;
2218 notice ("%s: error closing aux info file `%s': %s\n",
2219 pname
, shortpath (NULL
, aux_info_filename
),
2220 xstrerror (errno_val
));
2221 free (aux_info_base
);
2222 close (aux_info_file
);
2227 /* Delete the aux_info file (unless requested not to). If the deletion
2228 fails for some reason, don't even worry about it. */
2230 if (must_create
&& !keep_it
)
2231 if (unlink (aux_info_filename
) == -1)
2233 int errno_val
= errno
;
2234 notice ("%s: can't delete aux info file `%s': %s\n",
2235 pname
, shortpath (NULL
, aux_info_filename
),
2236 xstrerror (errno_val
));
2239 /* Save a pointer into the first line of the aux_info file which
2240 contains the filename of the directory from which the compiler
2241 was invoked when the associated source file was compiled.
2242 This information is used later to help create complete
2243 filenames out of the (potentially) relative filenames in
2244 the aux_info file. */
2247 char *p
= aux_info_base
;
2250 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
2251 || (*p
== ':' && *p
&& *(p
+1) && IS_DIR_SEPARATOR (*(p
+1)))
2258 invocation_filename
= p
; /* Save a pointer to first byte of path. */
2261 *p
++ = DIR_SEPARATOR
;
2263 while (*p
++ != '\n')
2265 aux_info_second_line
= p
;
2266 aux_info_relocated_name
= 0;
2267 if (! is_abspath (invocation_filename
))
2269 /* INVOCATION_FILENAME is relative;
2270 append it to BASE_SOURCE_FILENAME's dir. */
2272 aux_info_relocated_name
= xmalloc (base_len
+ (p
-invocation_filename
));
2273 strcpy (aux_info_relocated_name
, base_source_filename
);
2274 dir_end
= strrchr (aux_info_relocated_name
, DIR_SEPARATOR
);
2275 #ifdef DIR_SEPARATOR_2
2279 slash
= strrchr (dir_end
? dir_end
: aux_info_relocated_name
,
2288 dir_end
= aux_info_relocated_name
;
2289 strcpy (dir_end
, invocation_filename
);
2290 invocation_filename
= aux_info_relocated_name
;
2296 const char *aux_info_p
;
2298 /* Do a pre-pass on the lines in the aux_info file, making sure that all
2299 of the source files referenced in there are at least as old as this
2300 aux_info file itself. If not, go back and regenerate the aux_info
2301 file anew. Don't do any of this for the syscalls file. */
2305 current_aux_info_lineno
= 2;
2307 for (aux_info_p
= aux_info_second_line
; *aux_info_p
; )
2309 if (referenced_file_is_newer (aux_info_p
, aux_info_mtime
))
2311 free (aux_info_base
);
2312 free (aux_info_relocated_name
);
2313 if (keep_it
&& unlink (aux_info_filename
) == -1)
2315 int errno_val
= errno
;
2316 notice ("%s: can't delete file `%s': %s\n",
2317 pname
, shortpath (NULL
, aux_info_filename
),
2318 xstrerror (errno_val
));
2325 /* Skip over the rest of this line to start of next line. */
2327 while (*aux_info_p
!= '\n')
2330 current_aux_info_lineno
++;
2334 /* Now do the real pass on the aux_info lines. Save their information in
2335 the in-core data base. */
2337 current_aux_info_lineno
= 2;
2339 for (aux_info_p
= aux_info_second_line
; *aux_info_p
;)
2341 char *unexpanded_line
= unexpand_if_needed (aux_info_p
);
2343 if (unexpanded_line
)
2345 save_def_or_dec (unexpanded_line
, is_syscalls
);
2346 free (unexpanded_line
);
2349 save_def_or_dec (aux_info_p
, is_syscalls
);
2351 /* Skip over the rest of this line and get to start of next line. */
2353 while (*aux_info_p
!= '\n')
2356 current_aux_info_lineno
++;
2360 free (aux_info_base
);
2361 free (aux_info_relocated_name
);
2366 /* Check an individual filename for a .c suffix. If the filename has this
2367 suffix, rename the file such that its suffix is changed to .C. This
2368 function implements the -C option. */
2372 const hash_table_entry
*hp
;
2374 const char *filename
= hp
->symbol
;
2375 int last_char_index
= strlen (filename
) - 1;
2376 char *const new_filename
= (char *) alloca (strlen (filename
)
2377 + strlen (cplus_suffix
) + 1);
2379 /* Note that we don't care here if the given file was converted or not. It
2380 is possible that the given file was *not* converted, simply because there
2381 was nothing in it which actually required conversion. Even in this case,
2382 we want to do the renaming. Note that we only rename files with the .c
2383 suffix (except for the syscalls file, which is left alone). */
2385 if (filename
[last_char_index
] != 'c' || filename
[last_char_index
-1] != '.'
2386 || IS_SAME_PATH (syscalls_absolute_filename
, filename
))
2389 strcpy (new_filename
, filename
);
2390 strcpy (&new_filename
[last_char_index
], cplus_suffix
);
2392 if (rename (filename
, new_filename
) == -1)
2394 int errno_val
= errno
;
2395 notice ("%s: warning: can't rename file `%s' to `%s': %s\n",
2396 pname
, shortpath (NULL
, filename
),
2397 shortpath (NULL
, new_filename
), xstrerror (errno_val
));
2403 #endif /* !defined (UNPROTOIZE) */
2405 /* Take the list of definitions and declarations attached to a particular
2406 file_info node and reverse the order of the list. This should get the
2407 list into an order such that the item with the lowest associated line
2408 number is nearest the head of the list. When these lists are originally
2409 built, they are in the opposite order. We want to traverse them in
2410 normal line number order later (i.e. lowest to highest) so reverse the
2414 reverse_def_dec_list (hp
)
2415 const hash_table_entry
*hp
;
2417 file_info
*file_p
= hp
->fip
;
2418 def_dec_info
*prev
= NULL
;
2419 def_dec_info
*current
= (def_dec_info
*) file_p
->defs_decs
;
2422 return; /* no list to reverse */
2425 if (! (current
= (def_dec_info
*) current
->next_in_file
))
2426 return; /* can't reverse a single list element */
2428 prev
->next_in_file
= NULL
;
2432 def_dec_info
*next
= (def_dec_info
*) current
->next_in_file
;
2434 current
->next_in_file
= prev
;
2439 file_p
->defs_decs
= prev
;
2444 /* Find the (only?) extern definition for a particular function name, starting
2445 from the head of the linked list of entries for the given name. If we
2446 cannot find an extern definition for the given function name, issue a
2447 warning and scrounge around for the next best thing, i.e. an extern
2448 function declaration with a prototype attached to it. Note that we only
2449 allow such substitutions for extern declarations and never for static
2450 declarations. That's because the only reason we allow them at all is
2451 to let un-prototyped function declarations for system-supplied library
2452 functions get their prototypes from our own extra SYSCALLS.c.X file which
2453 contains all of the correct prototypes for system functions. */
2455 static const def_dec_info
*
2456 find_extern_def (head
, user
)
2457 const def_dec_info
*head
;
2458 const def_dec_info
*user
;
2460 const def_dec_info
*dd_p
;
2461 const def_dec_info
*extern_def_p
= NULL
;
2462 int conflict_noted
= 0;
2464 /* Don't act too stupid here. Somebody may try to convert an entire system
2465 in one swell fwoop (rather than one program at a time, as should be done)
2466 and in that case, we may find that there are multiple extern definitions
2467 of a given function name in the entire set of source files that we are
2468 converting. If however one of these definitions resides in exactly the
2469 same source file as the reference we are trying to satisfy then in that
2470 case it would be stupid for us to fail to realize that this one definition
2471 *must* be the precise one we are looking for.
2473 To make sure that we don't miss an opportunity to make this "same file"
2474 leap of faith, we do a prescan of the list of records relating to the
2475 given function name, and we look (on this first scan) *only* for a
2476 definition of the function which is in the same file as the reference
2477 we are currently trying to satisfy. */
2479 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2480 if (dd_p
->is_func_def
&& !dd_p
->is_static
&& dd_p
->file
== user
->file
)
2483 /* Now, since we have not found a definition in the same file as the
2484 reference, we scan the list again and consider all possibilities from
2485 all files. Here we may get conflicts with the things listed in the
2486 SYSCALLS.c.X file, but if that happens it only means that the source
2487 code being converted contains its own definition of a function which
2488 could have been supplied by libc.a. In such cases, we should avoid
2489 issuing the normal warning, and defer to the definition given in the
2492 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2493 if (dd_p
->is_func_def
&& !dd_p
->is_static
)
2495 if (!extern_def_p
) /* Previous definition? */
2496 extern_def_p
= dd_p
; /* Remember the first definition found. */
2499 /* Ignore definition just found if it came from SYSCALLS.c.X. */
2501 if (is_syscalls_file (dd_p
->file
))
2504 /* Quietly replace the definition previously found with the one
2505 just found if the previous one was from SYSCALLS.c.X. */
2507 if (is_syscalls_file (extern_def_p
->file
))
2509 extern_def_p
= dd_p
;
2513 /* If we get here, then there is a conflict between two function
2514 declarations for the same function, both of which came from the
2517 if (!conflict_noted
) /* first time we noticed? */
2520 notice ("%s: conflicting extern definitions of '%s'\n",
2521 pname
, head
->hash_entry
->symbol
);
2524 notice ("%s: declarations of '%s' will not be converted\n",
2525 pname
, head
->hash_entry
->symbol
);
2526 notice ("%s: conflict list for '%s' follows:\n",
2527 pname
, head
->hash_entry
->symbol
);
2528 fprintf (stderr
, "%s: %s(%d): %s\n",
2530 shortpath (NULL
, extern_def_p
->file
->hash_entry
->symbol
),
2531 extern_def_p
->line
, extern_def_p
->ansi_decl
);
2535 fprintf (stderr
, "%s: %s(%d): %s\n",
2537 shortpath (NULL
, dd_p
->file
->hash_entry
->symbol
),
2538 dd_p
->line
, dd_p
->ansi_decl
);
2542 /* We want to err on the side of caution, so if we found multiple conflicting
2543 definitions for the same function, treat this as being that same as if we
2544 had found no definitions (i.e. return NULL). */
2551 /* We have no definitions for this function so do the next best thing.
2552 Search for an extern declaration already in prototype form. */
2554 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2555 if (!dd_p
->is_func_def
&& !dd_p
->is_static
&& dd_p
->prototyped
)
2557 extern_def_p
= dd_p
; /* save a pointer to the definition */
2559 notice ("%s: warning: using formals list from %s(%d) for function `%s'\n",
2561 shortpath (NULL
, dd_p
->file
->hash_entry
->symbol
),
2562 dd_p
->line
, dd_p
->hash_entry
->symbol
);
2566 /* Gripe about unprototyped function declarations that we found no
2567 corresponding definition (or other source of prototype information)
2570 Gripe even if the unprototyped declaration we are worried about
2571 exists in a file in one of the "system" include directories. We
2572 can gripe about these because we should have at least found a
2573 corresponding (pseudo) definition in the SYSCALLS.c.X file. If we
2574 didn't, then that means that the SYSCALLS.c.X file is missing some
2575 needed prototypes for this particular system. That is worth telling
2580 const char *file
= user
->file
->hash_entry
->symbol
;
2583 if (in_system_include_dir (file
))
2585 /* Why copy this string into `needed' at all?
2586 Why not just use user->ansi_decl without copying? */
2587 char *needed
= (char *) alloca (strlen (user
->ansi_decl
) + 1);
2590 strcpy (needed
, user
->ansi_decl
);
2591 p
= (NONCONST
char *) substr (needed
, user
->hash_entry
->symbol
)
2592 + strlen (user
->hash_entry
->symbol
) + 2;
2593 /* Avoid having ??? in the string. */
2599 notice ("%s: %d: `%s' used but missing from SYSCALLS\n",
2600 shortpath (NULL
, file
), user
->line
,
2601 needed
+7); /* Don't print "extern " */
2605 notice ("%s: %d: warning: no extern definition for `%s'\n",
2606 shortpath (NULL
, file
), user
->line
,
2607 user
->hash_entry
->symbol
);
2611 return extern_def_p
;
2614 /* Find the (only?) static definition for a particular function name in a
2615 given file. Here we get the function-name and the file info indirectly
2616 from the def_dec_info record pointer which is passed in. */
2618 static const def_dec_info
*
2619 find_static_definition (user
)
2620 const def_dec_info
*user
;
2622 const def_dec_info
*head
= user
->hash_entry
->ddip
;
2623 const def_dec_info
*dd_p
;
2624 int num_static_defs
= 0;
2625 const def_dec_info
*static_def_p
= NULL
;
2627 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2628 if (dd_p
->is_func_def
&& dd_p
->is_static
&& (dd_p
->file
== user
->file
))
2630 static_def_p
= dd_p
; /* save a pointer to the definition */
2633 if (num_static_defs
== 0)
2636 notice ("%s: warning: no static definition for `%s' in file `%s'\n",
2637 pname
, head
->hash_entry
->symbol
,
2638 shortpath (NULL
, user
->file
->hash_entry
->symbol
));
2640 else if (num_static_defs
> 1)
2642 notice ("%s: multiple static defs of `%s' in file `%s'\n",
2643 pname
, head
->hash_entry
->symbol
,
2644 shortpath (NULL
, user
->file
->hash_entry
->symbol
));
2647 return static_def_p
;
2650 /* Find good prototype style formal argument lists for all of the function
2651 declarations which didn't have them before now.
2653 To do this we consider each function name one at a time. For each function
2654 name, we look at the items on the linked list of def_dec_info records for
2655 that particular name.
2657 Somewhere on this list we should find one (and only one) def_dec_info
2658 record which represents the actual function definition, and this record
2659 should have a nice formal argument list already associated with it.
2661 Thus, all we have to do is to connect up all of the other def_dec_info
2662 records for this particular function name to the special one which has
2663 the full-blown formals list.
2665 Of course it is a little more complicated than just that. See below for
2669 connect_defs_and_decs (hp
)
2670 const hash_table_entry
*hp
;
2672 const def_dec_info
*dd_p
;
2673 const def_dec_info
*extern_def_p
= NULL
;
2674 int first_extern_reference
= 1;
2676 /* Traverse the list of definitions and declarations for this particular
2677 function name. For each item on the list, if it is a function
2678 definition (either old style or new style) then GCC has already been
2679 kind enough to produce a prototype for us, and it is associated with
2680 the item already, so declare the item as its own associated "definition".
2682 Also, for each item which is only a function declaration, but which
2683 nonetheless has its own prototype already (obviously supplied by the user)
2684 declare the item as its own definition.
2686 Note that when/if there are multiple user-supplied prototypes already
2687 present for multiple declarations of any given function, these multiple
2688 prototypes *should* all match exactly with one another and with the
2689 prototype for the actual function definition. We don't check for this
2690 here however, since we assume that the compiler must have already done
2691 this consistency checking when it was creating the .X files. */
2693 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2694 if (dd_p
->prototyped
)
2695 ((NONCONST def_dec_info
*) dd_p
)->definition
= dd_p
;
2697 /* Traverse the list of definitions and declarations for this particular
2698 function name. For each item on the list, if it is an extern function
2699 declaration and if it has no associated definition yet, go try to find
2700 the matching extern definition for the declaration.
2702 When looking for the matching function definition, warn the user if we
2705 If we find more that one function definition also issue a warning.
2707 Do the search for the matching definition only once per unique function
2708 name (and only when absolutely needed) so that we can avoid putting out
2709 redundant warning messages, and so that we will only put out warning
2710 messages when there is actually a reference (i.e. a declaration) for
2711 which we need to find a matching definition. */
2713 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2714 if (!dd_p
->is_func_def
&& !dd_p
->is_static
&& !dd_p
->definition
)
2716 if (first_extern_reference
)
2718 extern_def_p
= find_extern_def (hp
->ddip
, dd_p
);
2719 first_extern_reference
= 0;
2721 ((NONCONST def_dec_info
*) dd_p
)->definition
= extern_def_p
;
2724 /* Traverse the list of definitions and declarations for this particular
2725 function name. For each item on the list, if it is a static function
2726 declaration and if it has no associated definition yet, go try to find
2727 the matching static definition for the declaration within the same file.
2729 When looking for the matching function definition, warn the user if we
2730 fail to find one in the same file with the declaration, and refuse to
2731 convert this kind of cross-file static function declaration. After all,
2732 this is stupid practice and should be discouraged.
2734 We don't have to worry about the possibility that there is more than one
2735 matching function definition in the given file because that would have
2736 been flagged as an error by the compiler.
2738 Do the search for the matching definition only once per unique
2739 function-name/source-file pair (and only when absolutely needed) so that
2740 we can avoid putting out redundant warning messages, and so that we will
2741 only put out warning messages when there is actually a reference (i.e. a
2742 declaration) for which we actually need to find a matching definition. */
2744 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2745 if (!dd_p
->is_func_def
&& dd_p
->is_static
&& !dd_p
->definition
)
2747 const def_dec_info
*dd_p2
;
2748 const def_dec_info
*static_def
;
2750 /* We have now found a single static declaration for which we need to
2751 find a matching definition. We want to minimize the work (and the
2752 number of warnings), so we will find an appropriate (matching)
2753 static definition for this declaration, and then distribute it
2754 (as the definition for) any and all other static declarations
2755 for this function name which occur within the same file, and which
2756 do not already have definitions.
2758 Note that a trick is used here to prevent subsequent attempts to
2759 call find_static_definition for a given function-name & file
2760 if the first such call returns NULL. Essentially, we convert
2761 these NULL return values to -1, and put the -1 into the definition
2762 field for each other static declaration from the same file which
2763 does not already have an associated definition.
2764 This makes these other static declarations look like they are
2765 actually defined already when the outer loop here revisits them
2766 later on. Thus, the outer loop will skip over them. Later, we
2767 turn the -1's back to NULL's. */
2769 ((NONCONST def_dec_info
*) dd_p
)->definition
=
2770 (static_def
= find_static_definition (dd_p
))
2772 : (const def_dec_info
*) -1;
2774 for (dd_p2
= dd_p
->next_for_func
; dd_p2
; dd_p2
= dd_p2
->next_for_func
)
2775 if (!dd_p2
->is_func_def
&& dd_p2
->is_static
2776 && !dd_p2
->definition
&& (dd_p2
->file
== dd_p
->file
))
2777 ((NONCONST def_dec_info
*) dd_p2
)->definition
= dd_p
->definition
;
2780 /* Convert any dummy (-1) definitions we created in the step above back to
2781 NULL's (as they should be). */
2783 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2784 if (dd_p
->definition
== (def_dec_info
*) -1)
2785 ((NONCONST def_dec_info
*) dd_p
)->definition
= NULL
;
2788 #endif /* !defined (UNPROTOIZE) */
2790 /* Give a pointer into the clean text buffer, return a number which is the
2791 original source line number that the given pointer points into. */
2794 identify_lineno (clean_p
)
2795 const char *clean_p
;
2800 for (scan_p
= clean_text_base
; scan_p
<= clean_p
; scan_p
++)
2801 if (*scan_p
== '\n')
2806 /* Issue an error message and give up on doing this particular edit. */
2809 declare_source_confusing (clean_p
)
2810 const char *clean_p
;
2815 notice ("%s: %d: warning: source too confusing\n",
2816 shortpath (NULL
, convert_filename
), last_known_line_number
);
2818 notice ("%s: %d: warning: source too confusing\n",
2819 shortpath (NULL
, convert_filename
),
2820 identify_lineno (clean_p
));
2822 longjmp (source_confusion_recovery
, 1);
2825 /* Check that a condition which is expected to be true in the original source
2826 code is in fact true. If not, issue an error message and give up on
2827 converting this particular source file. */
2830 check_source (cond
, clean_p
)
2832 const char *clean_p
;
2835 declare_source_confusing (clean_p
);
2838 /* If we think of the in-core cleaned text buffer as a memory mapped
2839 file (with the variable last_known_line_start acting as sort of a
2840 file pointer) then we can imagine doing "seeks" on the buffer. The
2841 following routine implements a kind of "seek" operation for the in-core
2842 (cleaned) copy of the source file. When finished, it returns a pointer to
2843 the start of a given (numbered) line in the cleaned text buffer.
2845 Note that protoize only has to "seek" in the forward direction on the
2846 in-core cleaned text file buffers, and it never needs to back up.
2848 This routine is made a little bit faster by remembering the line number
2849 (and pointer value) supplied (and returned) from the previous "seek".
2850 This prevents us from always having to start all over back at the top
2851 of the in-core cleaned buffer again. */
2857 if (n
< last_known_line_number
)
2860 while (n
> last_known_line_number
)
2862 while (*last_known_line_start
!= '\n')
2863 check_source (++last_known_line_start
< clean_text_limit
, 0);
2864 last_known_line_start
++;
2865 last_known_line_number
++;
2867 return last_known_line_start
;
2870 /* Given a pointer to a character in the cleaned text buffer, return a pointer
2871 to the next non-whitespace character which follows it. */
2874 forward_to_next_token_char (ptr
)
2877 for (++ptr
; ISSPACE ((const unsigned char)*ptr
);
2878 check_source (++ptr
< clean_text_limit
, 0))
2883 /* Copy a chunk of text of length `len' and starting at `str' to the current
2884 output buffer. Note that all attempts to add stuff to the current output
2885 buffer ultimately go through here. */
2888 output_bytes (str
, len
)
2892 if ((repl_write_ptr
+ 1) + len
>= repl_text_limit
)
2894 size_t new_size
= (repl_text_limit
- repl_text_base
) << 1;
2895 char *new_buf
= (char *) xrealloc (repl_text_base
, new_size
);
2897 repl_write_ptr
= new_buf
+ (repl_write_ptr
- repl_text_base
);
2898 repl_text_base
= new_buf
;
2899 repl_text_limit
= new_buf
+ new_size
;
2901 memcpy (repl_write_ptr
+ 1, str
, len
);
2902 repl_write_ptr
+= len
;
2905 /* Copy all bytes (except the trailing null) of a null terminated string to
2906 the current output buffer. */
2912 output_bytes (str
, strlen (str
));
2915 /* Copy some characters from the original text buffer to the current output
2918 This routine takes a pointer argument `p' which is assumed to be a pointer
2919 into the cleaned text buffer. The bytes which are copied are the `original'
2920 equivalents for the set of bytes between the last value of `clean_read_ptr'
2921 and the argument value `p'.
2923 The set of bytes copied however, comes *not* from the cleaned text buffer,
2924 but rather from the direct counterparts of these bytes within the original
2927 Thus, when this function is called, some bytes from the original text
2928 buffer (which may include original comments and preprocessing directives)
2929 will be copied into the output buffer.
2931 Note that the request implied when this routine is called includes the
2932 byte pointed to by the argument pointer `p'. */
2938 size_t copy_length
= (size_t) (p
- clean_read_ptr
);
2939 const char *copy_start
= orig_text_base
+(clean_read_ptr
-clean_text_base
)+1;
2941 if (copy_length
== 0)
2944 output_bytes (copy_start
, copy_length
);
2948 /* Given a pointer to a def_dec_info record which represents some form of
2949 definition of a function (perhaps a real definition, or in lieu of that
2950 perhaps just a declaration with a full prototype) return true if this
2951 function is one which we should avoid converting. Return false
2955 other_variable_style_function (ansi_header
)
2956 const char *ansi_header
;
2960 /* See if we have a stdarg function, or a function which has stdarg style
2961 parameters or a stdarg style return type. */
2963 return substr (ansi_header
, "...") != 0;
2965 #else /* !defined (UNPROTOIZE) */
2967 /* See if we have a varargs function, or a function which has varargs style
2968 parameters or a varargs style return type. */
2971 int len
= strlen (varargs_style_indicator
);
2973 for (p
= ansi_header
; p
; )
2975 const char *candidate
;
2977 if ((candidate
= substr (p
, varargs_style_indicator
)) == 0)
2980 if (!is_id_char (candidate
[-1]) && !is_id_char (candidate
[len
]))
2986 #endif /* !defined (UNPROTOIZE) */
2989 /* Do the editing operation specifically for a function "declaration". Note
2990 that editing for function "definitions" are handled in a separate routine
2994 edit_fn_declaration (def_dec_p
, clean_text_p
)
2995 const def_dec_info
*def_dec_p
;
2996 const char *volatile clean_text_p
;
2998 const char *start_formals
;
2999 const char *end_formals
;
3000 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
3001 size_t func_name_len
= strlen (function_to_edit
);
3002 const char *end_of_fn_name
;
3006 const f_list_chain_item
*this_f_list_chain_item
;
3007 const def_dec_info
*definition
= def_dec_p
->definition
;
3009 /* If we are protoizing, and if we found no corresponding definition for
3010 this particular function declaration, then just leave this declaration
3011 exactly as it is. */
3016 /* If we are protoizing, and if the corresponding definition that we found
3017 for this particular function declaration defined an old style varargs
3018 function, then we want to issue a warning and just leave this function
3019 declaration unconverted. */
3021 if (other_variable_style_function (definition
->ansi_decl
))
3024 notice ("%s: %d: warning: varargs function declaration not converted\n",
3025 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
3030 #endif /* !defined (UNPROTOIZE) */
3032 /* Setup here to recover from confusing source code detected during this
3033 particular "edit". */
3036 if (setjmp (source_confusion_recovery
))
3038 restore_pointers ();
3039 notice ("%s: declaration of function `%s' not converted\n",
3040 pname
, function_to_edit
);
3044 /* We are editing a function declaration. The line number we did a seek to
3045 contains the comma or semicolon which follows the declaration. Our job
3046 now is to scan backwards looking for the function name. This name *must*
3047 be followed by open paren (ignoring whitespace, of course). We need to
3048 replace everything between that open paren and the corresponding closing
3049 paren. If we are protoizing, we need to insert the prototype-style
3050 formals lists. If we are unprotoizing, we need to just delete everything
3051 between the pairs of opening and closing parens. */
3053 /* First move up to the end of the line. */
3055 while (*clean_text_p
!= '\n')
3056 check_source (++clean_text_p
< clean_text_limit
, 0);
3057 clean_text_p
--; /* Point to just before the newline character. */
3059 /* Now we can scan backwards for the function name. */
3065 /* Scan leftwards until we find some character which can be
3066 part of an identifier. */
3068 while (!is_id_char (*clean_text_p
))
3069 check_source (--clean_text_p
> clean_read_ptr
, 0);
3071 /* Scan backwards until we find a char that cannot be part of an
3074 while (is_id_char (*clean_text_p
))
3075 check_source (--clean_text_p
> clean_read_ptr
, 0);
3077 /* Having found an "id break", see if the following id is the one
3078 that we are looking for. If so, then exit from this loop. */
3080 if (!strncmp (clean_text_p
+1, function_to_edit
, func_name_len
))
3082 char ch
= *(clean_text_p
+ 1 + func_name_len
);
3084 /* Must also check to see that the name in the source text
3085 ends where it should (in order to prevent bogus matches
3086 on similar but longer identifiers. */
3088 if (! is_id_char (ch
))
3089 break; /* exit from loop */
3093 /* We have now found the first perfect match for the function name in
3094 our backward search. This may or may not be the actual function
3095 name at the start of the actual function declaration (i.e. we could
3096 have easily been mislead). We will try to avoid getting fooled too
3097 often by looking forward for the open paren which should follow the
3098 identifier we just found. We ignore whitespace while hunting. If
3099 the next non-whitespace byte we see is *not* an open left paren,
3100 then we must assume that we have been fooled and we start over
3101 again accordingly. Note that there is no guarantee, that even if
3102 we do see the open paren, that we are in the right place.
3103 Programmers do the strangest things sometimes! */
3105 end_of_fn_name
= clean_text_p
+ strlen (def_dec_p
->hash_entry
->symbol
);
3106 start_formals
= forward_to_next_token_char (end_of_fn_name
);
3108 while (*start_formals
!= '(');
3110 /* start_of_formals now points to the opening left paren which immediately
3111 follows the name of the function. */
3113 /* Note that there may be several formals lists which need to be modified
3114 due to the possibility that the return type of this function is a
3115 pointer-to-function type. If there are several formals lists, we
3116 convert them in left-to-right order here. */
3119 this_f_list_chain_item
= definition
->f_list_chain
;
3120 #endif /* !defined (UNPROTOIZE) */
3127 end_formals
= start_formals
+ 1;
3129 for (; depth
; check_source (++end_formals
< clean_text_limit
, 0))
3131 switch (*end_formals
)
3144 /* end_formals now points to the closing right paren of the formals
3145 list whose left paren is pointed to by start_formals. */
3147 /* Now, if we are protoizing, we insert the new ANSI-style formals list
3148 attached to the associated definition of this function. If however
3149 we are unprotoizing, then we simply delete any formals list which
3152 output_up_to (start_formals
);
3154 if (this_f_list_chain_item
)
3156 output_string (this_f_list_chain_item
->formals_list
);
3157 this_f_list_chain_item
= this_f_list_chain_item
->chain_next
;
3162 notice ("%s: warning: too many parameter lists in declaration of `%s'\n",
3163 pname
, def_dec_p
->hash_entry
->symbol
);
3164 check_source (0, end_formals
); /* leave the declaration intact */
3166 #endif /* !defined (UNPROTOIZE) */
3167 clean_read_ptr
= end_formals
- 1;
3169 /* Now see if it looks like there may be another formals list associated
3170 with the function declaration that we are converting (following the
3171 formals list that we just converted. */
3174 const char *another_r_paren
= forward_to_next_token_char (end_formals
);
3176 if ((*another_r_paren
!= ')')
3177 || (*(start_formals
= forward_to_next_token_char (another_r_paren
)) != '('))
3180 if (this_f_list_chain_item
)
3183 notice ("\n%s: warning: too few parameter lists in declaration of `%s'\n",
3184 pname
, def_dec_p
->hash_entry
->symbol
);
3185 check_source (0, start_formals
); /* leave the decl intact */
3187 #endif /* !defined (UNPROTOIZE) */
3193 /* There does appear to be yet another formals list, so loop around
3194 again, and convert it also. */
3198 /* Edit a whole group of formals lists, starting with the rightmost one
3199 from some set of formals lists. This routine is called once (from the
3200 outside) for each function declaration which is converted. It is
3201 recursive however, and it calls itself once for each remaining formal
3202 list that lies to the left of the one it was originally called to work
3203 on. Thus, a whole set gets done in right-to-left order.
3205 This routine returns nonzero if it thinks that it should not be trying
3206 to convert this particular function definition (because the name of the
3207 function doesn't match the one expected). */
3210 edit_formals_lists (end_formals
, f_list_count
, def_dec_p
)
3211 const char *end_formals
;
3212 unsigned int f_list_count
;
3213 const def_dec_info
*def_dec_p
;
3215 const char *start_formals
;
3218 start_formals
= end_formals
- 1;
3220 for (; depth
; check_source (--start_formals
> clean_read_ptr
, 0))
3222 switch (*start_formals
)
3234 /* start_formals now points to the opening left paren of the formals list. */
3240 const char *next_end
;
3242 /* There should be more formal lists to the left of here. */
3244 next_end
= start_formals
- 1;
3245 check_source (next_end
> clean_read_ptr
, 0);
3246 while (ISSPACE ((const unsigned char)*next_end
))
3247 check_source (--next_end
> clean_read_ptr
, 0);
3248 check_source (*next_end
== ')', next_end
);
3249 check_source (--next_end
> clean_read_ptr
, 0);
3250 check_source (*next_end
== ')', next_end
);
3251 if (edit_formals_lists (next_end
, f_list_count
, def_dec_p
))
3255 /* Check that the function name in the header we are working on is the same
3256 as the one we would expect to find. If not, issue a warning and return
3259 if (f_list_count
== 0)
3261 const char *expected
= def_dec_p
->hash_entry
->symbol
;
3262 const char *func_name_start
;
3263 const char *func_name_limit
;
3264 size_t func_name_len
;
3266 for (func_name_limit
= start_formals
-1;
3267 ISSPACE ((const unsigned char)*func_name_limit
); )
3268 check_source (--func_name_limit
> clean_read_ptr
, 0);
3270 for (func_name_start
= func_name_limit
++;
3271 is_id_char (*func_name_start
);
3273 check_source (func_name_start
> clean_read_ptr
, 0);
3275 func_name_len
= func_name_limit
- func_name_start
;
3276 if (func_name_len
== 0)
3277 check_source (0, func_name_start
);
3278 if (func_name_len
!= strlen (expected
)
3279 || strncmp (func_name_start
, expected
, func_name_len
))
3281 notice ("%s: %d: warning: found `%s' but expected `%s'\n",
3282 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
3283 identify_lineno (func_name_start
),
3284 dupnstr (func_name_start
, func_name_len
),
3290 output_up_to (start_formals
);
3293 if (f_list_count
== 0)
3294 output_string (def_dec_p
->formal_names
);
3295 #else /* !defined (UNPROTOIZE) */
3297 unsigned f_list_depth
;
3298 const f_list_chain_item
*flci_p
= def_dec_p
->f_list_chain
;
3300 /* At this point, the current value of f_list count says how many
3301 links we have to follow through the f_list_chain to get to the
3302 particular formals list that we need to output next. */
3304 for (f_list_depth
= 0; f_list_depth
< f_list_count
; f_list_depth
++)
3305 flci_p
= flci_p
->chain_next
;
3306 output_string (flci_p
->formals_list
);
3308 #endif /* !defined (UNPROTOIZE) */
3310 clean_read_ptr
= end_formals
- 1;
3314 /* Given a pointer to a byte in the clean text buffer which points to
3315 the beginning of a line that contains a "follower" token for a
3316 function definition header, do whatever is necessary to find the
3317 right closing paren for the rightmost formals list of the function
3318 definition header. */
3321 find_rightmost_formals_list (clean_text_p
)
3322 const char *clean_text_p
;
3324 const char *end_formals
;
3326 /* We are editing a function definition. The line number we did a seek
3327 to contains the first token which immediately follows the entire set of
3328 formals lists which are part of this particular function definition
3331 Our job now is to scan leftwards in the clean text looking for the
3332 right-paren which is at the end of the function header's rightmost
3335 If we ignore whitespace, this right paren should be the first one we
3336 see which is (ignoring whitespace) immediately followed either by the
3337 open curly-brace beginning the function body or by an alphabetic
3338 character (in the case where the function definition is in old (K&R)
3339 style and there are some declarations of formal parameters). */
3341 /* It is possible that the right paren we are looking for is on the
3342 current line (together with its following token). Just in case that
3343 might be true, we start out here by skipping down to the right end of
3344 the current line before starting our scan. */
3346 for (end_formals
= clean_text_p
; *end_formals
!= '\n'; end_formals
++)
3352 /* Now scan backwards while looking for the right end of the rightmost
3353 formals list associated with this function definition. */
3357 const char *l_brace_p
;
3359 /* Look leftward and try to find a right-paren. */
3361 while (*end_formals
!= ')')
3363 if (ISSPACE ((unsigned char)*end_formals
))
3364 while (ISSPACE ((unsigned char)*end_formals
))
3365 check_source (--end_formals
> clean_read_ptr
, 0);
3367 check_source (--end_formals
> clean_read_ptr
, 0);
3370 ch
= *(l_brace_p
= forward_to_next_token_char (end_formals
));
3371 /* Since we are unprotoizing an ANSI-style (prototyped) function
3372 definition, there had better not be anything (except whitespace)
3373 between the end of the ANSI formals list and the beginning of the
3374 function body (i.e. the '{'). */
3376 check_source (ch
== '{', l_brace_p
);
3379 #else /* !defined (UNPROTOIZE) */
3381 /* Now scan backwards while looking for the right end of the rightmost
3382 formals list associated with this function definition. */
3387 const char *l_brace_p
;
3389 /* Look leftward and try to find a right-paren. */
3391 while (*end_formals
!= ')')
3393 if (ISSPACE ((const unsigned char)*end_formals
))
3394 while (ISSPACE ((const unsigned char)*end_formals
))
3395 check_source (--end_formals
> clean_read_ptr
, 0);
3397 check_source (--end_formals
> clean_read_ptr
, 0);
3400 ch
= *(l_brace_p
= forward_to_next_token_char (end_formals
));
3402 /* Since it is possible that we found a right paren before the starting
3403 '{' of the body which IS NOT the one at the end of the real K&R
3404 formals list (say for instance, we found one embedded inside one of
3405 the old K&R formal parameter declarations) we have to check to be
3406 sure that this is in fact the right paren that we were looking for.
3408 The one we were looking for *must* be followed by either a '{' or
3409 by an alphabetic character, while others *cannot* validly be followed
3410 by such characters. */
3412 if ((ch
== '{') || ISALPHA ((unsigned char) ch
))
3415 /* At this point, we have found a right paren, but we know that it is
3416 not the one we were looking for, so backup one character and keep
3419 check_source (--end_formals
> clean_read_ptr
, 0);
3422 #endif /* !defined (UNPROTOIZE) */
3429 /* Insert into the output file a totally new declaration for a function
3430 which (up until now) was being called from within the current block
3431 without having been declared at any point such that the declaration
3432 was visible (i.e. in scope) at the point of the call.
3434 We need to add in explicit declarations for all such function calls
3435 in order to get the full benefit of prototype-based function call
3436 parameter type checking. */
3439 add_local_decl (def_dec_p
, clean_text_p
)
3440 const def_dec_info
*def_dec_p
;
3441 const char *clean_text_p
;
3443 const char *start_of_block
;
3444 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
3446 /* Don't insert new local explicit declarations unless explicitly requested
3452 /* Setup here to recover from confusing source code detected during this
3453 particular "edit". */
3456 if (setjmp (source_confusion_recovery
))
3458 restore_pointers ();
3459 notice ("%s: local declaration for function `%s' not inserted\n",
3460 pname
, function_to_edit
);
3464 /* We have already done a seek to the start of the line which should
3465 contain *the* open curly brace which begins the block in which we need
3466 to insert an explicit function declaration (to replace the implicit one).
3468 Now we scan that line, starting from the left, until we find the
3469 open curly brace we are looking for. Note that there may actually be
3470 multiple open curly braces on the given line, but we will be happy
3471 with the leftmost one no matter what. */
3473 start_of_block
= clean_text_p
;
3474 while (*start_of_block
!= '{' && *start_of_block
!= '\n')
3475 check_source (++start_of_block
< clean_text_limit
, 0);
3477 /* Note that the line from the original source could possibly
3478 contain *no* open curly braces! This happens if the line contains
3479 a macro call which expands into a chunk of text which includes a
3480 block (and that block's associated open and close curly braces).
3481 In cases like this, we give up, issue a warning, and do nothing. */
3483 if (*start_of_block
!= '{')
3486 notice ("\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
3487 def_dec_p
->file
->hash_entry
->symbol
, def_dec_p
->line
,
3488 def_dec_p
->hash_entry
->symbol
);
3492 /* Figure out what a nice (pretty) indentation would be for the new
3493 declaration we are adding. In order to do this, we must scan forward
3494 from the '{' until we find the first line which starts with some
3495 non-whitespace characters (i.e. real "token" material). */
3498 const char *ep
= forward_to_next_token_char (start_of_block
) - 1;
3501 /* Now we have ep pointing at the rightmost byte of some existing indent
3502 stuff. At least that is the hope.
3504 We can now just scan backwards and find the left end of the existing
3505 indentation string, and then copy it to the output buffer. */
3507 for (sp
= ep
; ISSPACE ((const unsigned char)*sp
) && *sp
!= '\n'; sp
--)
3510 /* Now write out the open { which began this block, and any following
3511 trash up to and including the last byte of the existing indent that
3516 /* Now we go ahead and insert the new declaration at this point.
3518 If the definition of the given function is in the same file that we
3519 are currently editing, and if its full ANSI declaration normally
3520 would start with the keyword `extern', suppress the `extern'. */
3523 const char *decl
= def_dec_p
->definition
->ansi_decl
;
3525 if ((*decl
== 'e') && (def_dec_p
->file
== def_dec_p
->definition
->file
))
3527 output_string (decl
);
3530 /* Finally, write out a new indent string, just like the preceding one
3531 that we found. This will typically include a newline as the first
3532 character of the indent string. */
3534 output_bytes (sp
, (size_t) (ep
- sp
) + 1);
3538 /* Given a pointer to a file_info record, and a pointer to the beginning
3539 of a line (in the clean text buffer) which is assumed to contain the
3540 first "follower" token for the first function definition header in the
3541 given file, find a good place to insert some new global function
3542 declarations (which will replace scattered and imprecise implicit ones)
3543 and then insert the new explicit declaration at that point in the file. */
3546 add_global_decls (file_p
, clean_text_p
)
3547 const file_info
*file_p
;
3548 const char *clean_text_p
;
3550 const def_dec_info
*dd_p
;
3553 /* Setup here to recover from confusing source code detected during this
3554 particular "edit". */
3557 if (setjmp (source_confusion_recovery
))
3559 restore_pointers ();
3560 notice ("%s: global declarations for file `%s' not inserted\n",
3561 pname
, shortpath (NULL
, file_p
->hash_entry
->symbol
));
3565 /* Start by finding a good location for adding the new explicit function
3566 declarations. To do this, we scan backwards, ignoring whitespace
3567 and comments and other junk until we find either a semicolon, or until
3568 we hit the beginning of the file. */
3570 scan_p
= find_rightmost_formals_list (clean_text_p
);
3573 if (scan_p
< clean_text_base
)
3575 check_source (scan_p
> clean_read_ptr
, 0);
3580 /* scan_p now points either to a semicolon, or to just before the start
3581 of the whole file. */
3583 /* Now scan forward for the first non-whitespace character. In theory,
3584 this should be the first character of the following function definition
3585 header. We will put in the added declarations just prior to that. */
3588 while (ISSPACE ((const unsigned char)*scan_p
))
3592 output_up_to (scan_p
);
3594 /* Now write out full prototypes for all of the things that had been
3595 implicitly declared in this file (but only those for which we were
3596 actually able to find unique matching definitions). Avoid duplicates
3597 by marking things that we write out as we go. */
3600 int some_decls_added
= 0;
3602 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
3603 if (dd_p
->is_implicit
&& dd_p
->definition
&& !dd_p
->definition
->written
)
3605 const char *decl
= dd_p
->definition
->ansi_decl
;
3607 /* If the function for which we are inserting a declaration is
3608 actually defined later in the same file, then suppress the
3609 leading `extern' keyword (if there is one). */
3611 if (*decl
== 'e' && (dd_p
->file
== dd_p
->definition
->file
))
3614 output_string ("\n");
3615 output_string (decl
);
3616 some_decls_added
= 1;
3617 ((NONCONST def_dec_info
*) dd_p
->definition
)->written
= 1;
3619 if (some_decls_added
)
3620 output_string ("\n\n");
3623 /* Unmark all of the definitions that we just marked. */
3625 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
3626 if (dd_p
->definition
)
3627 ((NONCONST def_dec_info
*) dd_p
->definition
)->written
= 0;
3630 #endif /* !defined (UNPROTOIZE) */
3632 /* Do the editing operation specifically for a function "definition". Note
3633 that editing operations for function "declarations" are handled by a
3634 separate routine above. */
3637 edit_fn_definition (def_dec_p
, clean_text_p
)
3638 const def_dec_info
*def_dec_p
;
3639 const char *clean_text_p
;
3641 const char *end_formals
;
3642 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
3644 /* Setup here to recover from confusing source code detected during this
3645 particular "edit". */
3648 if (setjmp (source_confusion_recovery
))
3650 restore_pointers ();
3651 notice ("%s: definition of function `%s' not converted\n",
3652 pname
, function_to_edit
);
3656 end_formals
= find_rightmost_formals_list (clean_text_p
);
3658 /* end_of_formals now points to the closing right paren of the rightmost
3659 formals list which is actually part of the `header' of the function
3660 definition that we are converting. */
3662 /* If the header of this function definition looks like it declares a
3663 function with a variable number of arguments, and if the way it does
3664 that is different from that way we would like it (i.e. varargs vs.
3665 stdarg) then issue a warning and leave the header unconverted. */
3667 if (other_variable_style_function (def_dec_p
->ansi_decl
))
3670 notice ("%s: %d: warning: definition of %s not converted\n",
3671 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
3672 identify_lineno (end_formals
),
3674 output_up_to (end_formals
);
3678 if (edit_formals_lists (end_formals
, def_dec_p
->f_list_count
, def_dec_p
))
3680 restore_pointers ();
3681 notice ("%s: definition of function `%s' not converted\n",
3682 pname
, function_to_edit
);
3686 /* Have to output the last right paren because this never gets flushed by
3687 edit_formals_list. */
3689 output_up_to (end_formals
);
3694 const char *semicolon_p
;
3695 const char *limit_p
;
3697 int had_newlines
= 0;
3699 /* Now write out the K&R style formal declarations, one per line. */
3701 decl_p
= def_dec_p
->formal_decls
;
3702 limit_p
= decl_p
+ strlen (decl_p
);
3703 for (;decl_p
< limit_p
; decl_p
= semicolon_p
+ 2)
3705 for (semicolon_p
= decl_p
; *semicolon_p
!= ';'; semicolon_p
++)
3707 output_string ("\n");
3708 output_string (indent_string
);
3709 output_bytes (decl_p
, (size_t) ((semicolon_p
+ 1) - decl_p
));
3712 /* If there are no newlines between the end of the formals list and the
3713 start of the body, we should insert one now. */
3715 for (scan_p
= end_formals
+1; *scan_p
!= '{'; )
3717 if (*scan_p
== '\n')
3722 check_source (++scan_p
< clean_text_limit
, 0);
3725 output_string ("\n");
3727 #else /* !defined (UNPROTOIZE) */
3728 /* If we are protoizing, there may be some flotsam & jetsam (like comments
3729 and preprocessing directives) after the old formals list but before
3730 the following { and we would like to preserve that stuff while effectively
3731 deleting the existing K&R formal parameter declarations. We do so here
3732 in a rather tricky way. Basically, we white out any stuff *except*
3733 the comments/pp-directives in the original text buffer, then, if there
3734 is anything in this area *other* than whitespace, we output it. */
3736 const char *end_formals_orig
;
3737 const char *start_body
;
3738 const char *start_body_orig
;
3740 const char *scan_orig
;
3741 int have_flotsam
= 0;
3742 int have_newlines
= 0;
3744 for (start_body
= end_formals
+ 1; *start_body
!= '{';)
3745 check_source (++start_body
< clean_text_limit
, 0);
3747 end_formals_orig
= orig_text_base
+ (end_formals
- clean_text_base
);
3748 start_body_orig
= orig_text_base
+ (start_body
- clean_text_base
);
3749 scan
= end_formals
+ 1;
3750 scan_orig
= end_formals_orig
+ 1;
3751 for (; scan
< start_body
; scan
++, scan_orig
++)
3753 if (*scan
== *scan_orig
)
3755 have_newlines
|= (*scan_orig
== '\n');
3756 /* Leave identical whitespace alone. */
3757 if (!ISSPACE ((const unsigned char)*scan_orig
))
3758 *((NONCONST
char *) scan_orig
) = ' '; /* identical - so whiteout */
3764 output_bytes (end_formals_orig
+ 1,
3765 (size_t) (start_body_orig
- end_formals_orig
) - 1);
3768 output_string ("\n");
3770 output_string (" ");
3771 clean_read_ptr
= start_body
- 1;
3773 #endif /* !defined (UNPROTOIZE) */
3776 /* Clean up the clean text buffer. Do this by converting comments and
3777 preprocessing directives into spaces. Also convert line continuations
3778 into whitespace. Also, whiteout string and character literals. */
3781 do_cleaning (new_clean_text_base
, new_clean_text_limit
)
3782 char *new_clean_text_base
;
3783 const char *new_clean_text_limit
;
3786 int non_whitespace_since_newline
= 0;
3788 for (scan_p
= new_clean_text_base
; scan_p
< new_clean_text_limit
; scan_p
++)
3792 case '/': /* Handle comments. */
3793 if (scan_p
[1] != '*')
3795 non_whitespace_since_newline
= 1;
3799 while (scan_p
[1] != '/' || scan_p
[0] != '*')
3801 if (!ISSPACE ((const unsigned char)*scan_p
))
3803 if (++scan_p
>= new_clean_text_limit
)
3810 case '#': /* Handle pp directives. */
3811 if (non_whitespace_since_newline
)
3814 while (scan_p
[1] != '\n' || scan_p
[0] == '\\')
3816 if (!ISSPACE ((const unsigned char)*scan_p
))
3818 if (++scan_p
>= new_clean_text_limit
)
3824 case '\'': /* Handle character literals. */
3825 non_whitespace_since_newline
= 1;
3826 while (scan_p
[1] != '\'' || scan_p
[0] == '\\')
3828 if (scan_p
[0] == '\\'
3829 && !ISSPACE ((const unsigned char) scan_p
[1]))
3831 if (!ISSPACE ((const unsigned char)*scan_p
))
3833 if (++scan_p
>= new_clean_text_limit
)
3839 case '"': /* Handle string literals. */
3840 non_whitespace_since_newline
= 1;
3841 while (scan_p
[1] != '"' || scan_p
[0] == '\\')
3843 if (scan_p
[0] == '\\'
3844 && !ISSPACE ((const unsigned char) scan_p
[1]))
3846 if (!ISSPACE ((const unsigned char)*scan_p
))
3848 if (++scan_p
>= new_clean_text_limit
)
3851 if (!ISSPACE ((const unsigned char)*scan_p
))
3856 case '\\': /* Handle line continuations. */
3857 if (scan_p
[1] != '\n')
3863 non_whitespace_since_newline
= 0; /* Reset. */
3872 break; /* Whitespace characters. */
3876 non_whitespace_since_newline
= 1;
3882 /* Given a pointer to the closing right parenthesis for a particular formals
3883 list (in the clean text buffer) find the corresponding left parenthesis
3884 and return a pointer to it. */
3887 careful_find_l_paren (p
)
3893 for (paren_depth
= 1, q
= p
-1; paren_depth
; check_source (--q
>= clean_text_base
, 0))
3908 /* Scan the clean text buffer for cases of function definitions that we
3909 don't really know about because they were preprocessed out when the
3910 aux info files were created.
3912 In this version of protoize/unprotoize we just give a warning for each
3913 one found. A later version may be able to at least unprotoize such
3916 Note that we may easily find all function definitions simply by
3917 looking for places where there is a left paren which is (ignoring
3918 whitespace) immediately followed by either a left-brace or by an
3919 upper or lower case letter. Whenever we find this combination, we
3920 have also found a function definition header.
3922 Finding function *declarations* using syntactic clues is much harder.
3923 I will probably try to do this in a later version though. */
3926 scan_for_missed_items (file_p
)
3927 const file_info
*file_p
;
3929 static const char *scan_p
;
3930 const char *limit
= clean_text_limit
- 3;
3931 static const char *backup_limit
;
3933 backup_limit
= clean_text_base
- 1;
3935 for (scan_p
= clean_text_base
; scan_p
< limit
; scan_p
++)
3939 static const char *last_r_paren
;
3940 const char *ahead_p
;
3942 last_r_paren
= scan_p
;
3944 for (ahead_p
= scan_p
+ 1; ISSPACE ((const unsigned char)*ahead_p
); )
3945 check_source (++ahead_p
< limit
, limit
);
3947 scan_p
= ahead_p
- 1;
3949 if (ISALPHA ((const unsigned char)*ahead_p
) || *ahead_p
== '{')
3951 const char *last_l_paren
;
3952 const int lineno
= identify_lineno (ahead_p
);
3954 if (setjmp (source_confusion_recovery
))
3957 /* We know we have a function definition header. Now skip
3958 leftwards over all of its associated formals lists. */
3962 last_l_paren
= careful_find_l_paren (last_r_paren
);
3963 for (last_r_paren
= last_l_paren
-1;
3964 ISSPACE ((const unsigned char)*last_r_paren
); )
3965 check_source (--last_r_paren
>= backup_limit
, backup_limit
);
3967 while (*last_r_paren
== ')');
3969 if (is_id_char (*last_r_paren
))
3971 const char *id_limit
= last_r_paren
+ 1;
3972 const char *id_start
;
3974 const def_dec_info
*dd_p
;
3976 for (id_start
= id_limit
-1; is_id_char (*id_start
); )
3977 check_source (--id_start
>= backup_limit
, backup_limit
);
3979 backup_limit
= id_start
;
3980 if ((id_length
= (size_t) (id_limit
- id_start
)) == 0)
3984 char *func_name
= (char *) alloca (id_length
+ 1);
3985 static const char * const stmt_keywords
[]
3986 = { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
3987 const char * const *stmt_keyword
;
3989 strncpy (func_name
, id_start
, id_length
);
3990 func_name
[id_length
] = '\0';
3992 /* We must check here to see if we are actually looking at
3993 a statement rather than an actual function call. */
3995 for (stmt_keyword
= stmt_keywords
; *stmt_keyword
; stmt_keyword
++)
3996 if (!strcmp (func_name
, *stmt_keyword
))
4000 notice ("%s: found definition of `%s' at %s(%d)\n",
4003 shortpath (NULL
, file_p
->hash_entry
->symbol
),
4004 identify_lineno (id_start
));
4006 /* We really should check for a match of the function name
4007 here also, but why bother. */
4009 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
4010 if (dd_p
->is_func_def
&& dd_p
->line
== lineno
)
4013 /* If we make it here, then we did not know about this
4014 function definition. */
4016 notice ("%s: %d: warning: `%s' excluded by preprocessing\n",
4017 shortpath (NULL
, file_p
->hash_entry
->symbol
),
4018 identify_lineno (id_start
), func_name
);
4019 notice ("%s: function definition not converted\n",
4029 /* Do all editing operations for a single source file (either a "base" file
4030 or an "include" file). To do this we read the file into memory, keep a
4031 virgin copy there, make another cleaned in-core copy of the original file
4032 (i.e. one in which all of the comments and preprocessing directives have
4033 been replaced with whitespace), then use these two in-core copies of the
4034 file to make a new edited in-core copy of the file. Finally, rename the
4035 original file (as a way of saving it), and then write the edited version
4036 of the file from core to a disk file of the same name as the original.
4038 Note that the trick of making a copy of the original sans comments &
4039 preprocessing directives make the editing a whole lot easier. */
4043 const hash_table_entry
*hp
;
4045 struct stat stat_buf
;
4046 const file_info
*file_p
= hp
->fip
;
4047 char *new_orig_text_base
;
4048 char *new_orig_text_limit
;
4049 char *new_clean_text_base
;
4050 char *new_clean_text_limit
;
4053 int first_definition_in_file
;
4055 /* If we are not supposed to be converting this file, or if there is
4056 nothing in there which needs converting, just skip this file. */
4058 if (!needs_to_be_converted (file_p
))
4061 convert_filename
= file_p
->hash_entry
->symbol
;
4063 /* Convert a file if it is in a directory where we want conversion
4064 and the file is not excluded. */
4066 if (!directory_specified_p (convert_filename
)
4067 || file_excluded_p (convert_filename
))
4071 /* Don't even mention "system" include files unless we are
4072 protoizing. If we are protoizing, we mention these as a
4073 gentle way of prodding the user to convert his "system"
4074 include files to prototype format. */
4075 && !in_system_include_dir (convert_filename
)
4076 #endif /* defined (UNPROTOIZE) */
4078 notice ("%s: `%s' not converted\n",
4079 pname
, shortpath (NULL
, convert_filename
));
4083 /* Let the user know what we are up to. */
4086 notice ("%s: would convert file `%s'\n",
4087 pname
, shortpath (NULL
, convert_filename
));
4089 notice ("%s: converting file `%s'\n",
4090 pname
, shortpath (NULL
, convert_filename
));
4093 /* Find out the size (in bytes) of the original file. */
4095 /* The cast avoids an erroneous warning on AIX. */
4096 if (stat (convert_filename
, &stat_buf
) == -1)
4098 int errno_val
= errno
;
4099 notice ("%s: can't get status for file `%s': %s\n",
4100 pname
, shortpath (NULL
, convert_filename
),
4101 xstrerror (errno_val
));
4104 orig_size
= stat_buf
.st_size
;
4106 /* Allocate a buffer to hold the original text. */
4108 orig_text_base
= new_orig_text_base
= (char *) xmalloc (orig_size
+ 2);
4109 orig_text_limit
= new_orig_text_limit
= new_orig_text_base
+ orig_size
;
4111 /* Allocate a buffer to hold the cleaned-up version of the original text. */
4113 clean_text_base
= new_clean_text_base
= (char *) xmalloc (orig_size
+ 2);
4114 clean_text_limit
= new_clean_text_limit
= new_clean_text_base
+ orig_size
;
4115 clean_read_ptr
= clean_text_base
- 1;
4117 /* Allocate a buffer that will hopefully be large enough to hold the entire
4118 converted output text. As an initial guess for the maximum size of the
4119 output buffer, use 125% of the size of the original + some extra. This
4120 buffer can be expanded later as needed. */
4122 repl_size
= orig_size
+ (orig_size
>> 2) + 4096;
4123 repl_text_base
= (char *) xmalloc (repl_size
+ 2);
4124 repl_text_limit
= repl_text_base
+ repl_size
- 1;
4125 repl_write_ptr
= repl_text_base
- 1;
4131 /* Open the file to be converted in READ ONLY mode. */
4133 fd_flags
= O_RDONLY
;
4135 /* Use binary mode to avoid having to deal with different EOL characters. */
4136 fd_flags
|= O_BINARY
;
4138 if ((input_file
= open (convert_filename
, fd_flags
, 0444)) == -1)
4140 int errno_val
= errno
;
4141 notice ("%s: can't open file `%s' for reading: %s\n",
4142 pname
, shortpath (NULL
, convert_filename
),
4143 xstrerror (errno_val
));
4147 /* Read the entire original source text file into the original text buffer
4148 in one swell fwoop. Then figure out where the end of the text is and
4149 make sure that it ends with a newline followed by a null. */
4151 if (safe_read (input_file
, new_orig_text_base
, orig_size
) !=
4154 int errno_val
= errno
;
4156 notice ("\n%s: error reading input file `%s': %s\n",
4157 pname
, shortpath (NULL
, convert_filename
),
4158 xstrerror (errno_val
));
4165 if (orig_size
== 0 || orig_text_limit
[-1] != '\n')
4167 *new_orig_text_limit
++ = '\n';
4171 /* Create the cleaned up copy of the original text. */
4173 memcpy (new_clean_text_base
, orig_text_base
,
4174 (size_t) (orig_text_limit
- orig_text_base
));
4175 do_cleaning (new_clean_text_base
, new_clean_text_limit
);
4180 size_t clean_size
= orig_text_limit
- orig_text_base
;
4181 char *const clean_filename
= (char *) alloca (strlen (convert_filename
) + 6 + 1);
4183 /* Open (and create) the clean file. */
4185 strcpy (clean_filename
, convert_filename
);
4186 strcat (clean_filename
, ".clean");
4187 if ((clean_file
= creat (clean_filename
, 0666)) == -1)
4189 int errno_val
= errno
;
4190 notice ("%s: can't create/open clean file `%s': %s\n",
4191 pname
, shortpath (NULL
, clean_filename
),
4192 xstrerror (errno_val
));
4196 /* Write the clean file. */
4198 safe_write (clean_file
, new_clean_text_base
, clean_size
, clean_filename
);
4204 /* Do a simplified scan of the input looking for things that were not
4205 mentioned in the aux info files because of the fact that they were
4206 in a region of the source which was preprocessed-out (via #if or
4209 scan_for_missed_items (file_p
);
4211 /* Setup to do line-oriented forward seeking in the clean text buffer. */
4213 last_known_line_number
= 1;
4214 last_known_line_start
= clean_text_base
;
4216 /* Now get down to business and make all of the necessary edits. */
4219 const def_dec_info
*def_dec_p
;
4221 first_definition_in_file
= 1;
4222 def_dec_p
= file_p
->defs_decs
;
4223 for (; def_dec_p
; def_dec_p
= def_dec_p
->next_in_file
)
4225 const char *clean_text_p
= seek_to_line (def_dec_p
->line
);
4227 /* clean_text_p now points to the first character of the line which
4228 contains the `terminator' for the declaration or definition that
4229 we are about to process. */
4233 if (global_flag
&& def_dec_p
->is_func_def
&& first_definition_in_file
)
4235 add_global_decls (def_dec_p
->file
, clean_text_p
);
4236 first_definition_in_file
= 0;
4239 /* Don't edit this item if it is already in prototype format or if it
4240 is a function declaration and we have found no corresponding
4243 if (def_dec_p
->prototyped
4244 || (!def_dec_p
->is_func_def
&& !def_dec_p
->definition
))
4247 #endif /* !defined (UNPROTOIZE) */
4249 if (def_dec_p
->is_func_def
)
4250 edit_fn_definition (def_dec_p
, clean_text_p
);
4253 if (def_dec_p
->is_implicit
)
4254 add_local_decl (def_dec_p
, clean_text_p
);
4256 #endif /* !defined (UNPROTOIZE) */
4257 edit_fn_declaration (def_dec_p
, clean_text_p
);
4261 /* Finalize things. Output the last trailing part of the original text. */
4263 output_up_to (clean_text_limit
- 1);
4265 /* If this is just a test run, stop now and just deallocate the buffers. */
4269 free (new_orig_text_base
);
4270 free (new_clean_text_base
);
4271 free (repl_text_base
);
4275 /* Change the name of the original input file. This is just a quick way of
4276 saving the original file. */
4281 = (char *) xmalloc (strlen (convert_filename
) + strlen (save_suffix
) + 2);
4283 strcpy (new_filename
, convert_filename
);
4285 /* MSDOS filenames are restricted to 8.3 format, so we save `foo.c'
4286 as `foo.<save_suffix>'. */
4287 new_filename
[(strlen (convert_filename
) - 1] = '\0';
4289 strcat (new_filename
, save_suffix
);
4291 /* Don't overwrite existing file. */
4292 if (access (new_filename
, F_OK
) == 0)
4295 notice ("%s: warning: file `%s' already saved in `%s'\n",
4297 shortpath (NULL
, convert_filename
),
4298 shortpath (NULL
, new_filename
));
4300 else if (rename (convert_filename
, new_filename
) == -1)
4302 int errno_val
= errno
;
4303 notice ("%s: can't link file `%s' to `%s': %s\n",
4305 shortpath (NULL
, convert_filename
),
4306 shortpath (NULL
, new_filename
),
4307 xstrerror (errno_val
));
4312 if (unlink (convert_filename
) == -1)
4314 int errno_val
= errno
;
4315 /* The file may have already been renamed. */
4316 if (errno_val
!= ENOENT
)
4318 notice ("%s: can't delete file `%s': %s\n",
4319 pname
, shortpath (NULL
, convert_filename
),
4320 xstrerror (errno_val
));
4328 /* Open (and create) the output file. */
4330 if ((output_file
= creat (convert_filename
, 0666)) == -1)
4332 int errno_val
= errno
;
4333 notice ("%s: can't create/open output file `%s': %s\n",
4334 pname
, shortpath (NULL
, convert_filename
),
4335 xstrerror (errno_val
));
4339 /* Use binary mode to avoid changing the existing EOL character. */
4340 setmode (output_file
, O_BINARY
);
4343 /* Write the output file. */
4346 unsigned int out_size
= (repl_write_ptr
+ 1) - repl_text_base
;
4348 safe_write (output_file
, repl_text_base
, out_size
, convert_filename
);
4351 close (output_file
);
4354 /* Deallocate the conversion buffers. */
4356 free (new_orig_text_base
);
4357 free (new_clean_text_base
);
4358 free (repl_text_base
);
4360 /* Change the mode of the output file to match the original file. */
4362 /* The cast avoids an erroneous warning on AIX. */
4363 if (chmod (convert_filename
, stat_buf
.st_mode
) == -1)
4365 int errno_val
= errno
;
4366 notice ("%s: can't change mode of file `%s': %s\n",
4367 pname
, shortpath (NULL
, convert_filename
),
4368 xstrerror (errno_val
));
4371 /* Note: We would try to change the owner and group of the output file
4372 to match those of the input file here, except that may not be a good
4373 thing to do because it might be misleading. Also, it might not even
4374 be possible to do that (on BSD systems with quotas for instance). */
4377 /* Do all of the individual steps needed to do the protoization (or
4378 unprotoization) of the files referenced in the aux_info files given
4379 in the command line. */
4384 const char * const *base_pp
;
4385 const char * const * const end_pps
4386 = &base_source_filenames
[n_base_source_files
];
4390 #endif /* !defined (UNPROTOIZE) */
4392 /* One-by-one, check (and create if necessary), open, and read all of the
4393 stuff in each aux_info file. After reading each aux_info file, the
4394 aux_info_file just read will be automatically deleted unless the
4395 keep_flag is set. */
4397 for (base_pp
= base_source_filenames
; base_pp
< end_pps
; base_pp
++)
4398 process_aux_info_file (*base_pp
, keep_flag
, 0);
4402 /* Also open and read the special SYSCALLS.c aux_info file which gives us
4403 the prototypes for all of the standard system-supplied functions. */
4405 if (nondefault_syscalls_dir
)
4407 syscalls_absolute_filename
4408 = (char *) xmalloc (strlen (nondefault_syscalls_dir
) + 1
4409 + sizeof (syscalls_filename
));
4410 strcpy (syscalls_absolute_filename
, nondefault_syscalls_dir
);
4414 GET_ENVIRONMENT (default_syscalls_dir
, "GCC_EXEC_PREFIX");
4415 if (!default_syscalls_dir
)
4417 default_syscalls_dir
= standard_exec_prefix
;
4419 syscalls_absolute_filename
4420 = (char *) xmalloc (strlen (default_syscalls_dir
) + 0
4421 + strlen (target_machine
) + 1
4422 + strlen (target_version
) + 1
4423 + sizeof (syscalls_filename
));
4424 strcpy (syscalls_absolute_filename
, default_syscalls_dir
);
4425 strcat (syscalls_absolute_filename
, target_machine
);
4426 strcat (syscalls_absolute_filename
, "/");
4427 strcat (syscalls_absolute_filename
, target_version
);
4428 strcat (syscalls_absolute_filename
, "/");
4431 syscalls_len
= strlen (syscalls_absolute_filename
);
4432 if (! IS_DIR_SEPARATOR (*(syscalls_absolute_filename
+ syscalls_len
- 1)))
4434 *(syscalls_absolute_filename
+ syscalls_len
++) = DIR_SEPARATOR
;
4435 *(syscalls_absolute_filename
+ syscalls_len
) = '\0';
4437 strcat (syscalls_absolute_filename
, syscalls_filename
);
4439 /* Call process_aux_info_file in such a way that it does not try to
4440 delete the SYSCALLS aux_info file. */
4442 process_aux_info_file (syscalls_absolute_filename
, 1, 1);
4444 #endif /* !defined (UNPROTOIZE) */
4446 /* When we first read in all of the information from the aux_info files
4447 we saved in it descending line number order, because that was likely to
4448 be faster. Now however, we want the chains of def & dec records to
4449 appear in ascending line number order as we get further away from the
4450 file_info record that they hang from. The following line causes all of
4451 these lists to be rearranged into ascending line number order. */
4453 visit_each_hash_node (filename_primary
, reverse_def_dec_list
);
4457 /* Now do the "real" work. The following line causes each declaration record
4458 to be "visited". For each of these nodes, an attempt is made to match
4459 up the function declaration with a corresponding function definition,
4460 which should have a full prototype-format formals list with it. Once
4461 these match-ups are made, the conversion of the function declarations
4462 to prototype format can be made. */
4464 visit_each_hash_node (function_name_primary
, connect_defs_and_decs
);
4466 #endif /* !defined (UNPROTOIZE) */
4468 /* Now convert each file that can be converted (and needs to be). */
4470 visit_each_hash_node (filename_primary
, edit_file
);
4474 /* If we are working in cplusplus mode, try to rename all .c files to .C
4475 files. Don't panic if some of the renames don't work. */
4477 if (cplusplus_flag
&& !nochange_flag
)
4478 visit_each_hash_node (filename_primary
, rename_c_file
);
4480 #endif /* !defined (UNPROTOIZE) */
4483 static const struct option longopts
[] =
4485 {"version", 0, 0, 'V'},
4486 {"file_name", 0, 0, 'p'},
4487 {"quiet", 0, 0, 'q'},
4488 {"silent", 0, 0, 'q'},
4489 {"force", 0, 0, 'f'},
4490 {"keep", 0, 0, 'k'},
4491 {"nosave", 0, 0, 'N'},
4492 {"nochange", 0, 0, 'n'},
4493 {"compiler-options", 1, 0, 'c'},
4494 {"exclude", 1, 0, 'x'},
4495 {"directory", 1, 0, 'd'},
4497 {"indent", 1, 0, 'i'},
4499 {"local", 0, 0, 'l'},
4500 {"global", 0, 0, 'g'},
4502 {"syscalls-dir", 1, 0, 'B'},
4507 extern int main
PARAMS ((int, char **const));
4516 const char *params
= "";
4518 pname
= strrchr (argv
[0], DIR_SEPARATOR
);
4519 #ifdef DIR_SEPARATOR_2
4523 slash
= strrchr (pname
? pname
: argv
[0], DIR_SEPARATOR_2
);
4528 pname
= pname
? pname
+1 : argv
[0];
4531 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
4532 receive the signal. A different setting is inheritable */
4533 signal (SIGCHLD
, SIG_DFL
);
4536 gcc_init_libintl ();
4538 cwd_buffer
= getpwd ();
4541 notice ("%s: cannot get working directory: %s\n",
4542 pname
, xstrerror(errno
));
4543 return (FATAL_EXIT_CODE
);
4546 /* By default, convert the files in the current directory. */
4547 directory_list
= string_list_cons (cwd_buffer
, NULL
);
4549 while ((c
= getopt_long (argc
, argv
,
4553 "B:c:Cd:gklnNp:qvVx:",
4555 longopts
, &longind
)) != EOF
)
4557 if (c
== 0) /* Long option. */
4558 c
= longopts
[longind
].val
;
4562 compiler_file_name
= optarg
;
4566 = string_list_cons (abspath (NULL
, optarg
), directory_list
);
4569 exclude_list
= string_list_cons (optarg
, exclude_list
);
4599 indent_string
= optarg
;
4601 #else /* !defined (UNPROTOIZE) */
4612 nondefault_syscalls_dir
= optarg
;
4614 #endif /* !defined (UNPROTOIZE) */
4620 /* Set up compile_params based on -p and -c options. */
4621 munge_compile_params (params
);
4623 n_base_source_files
= argc
- optind
;
4625 /* Now actually make a list of the base source filenames. */
4627 base_source_filenames
4628 = (const char **) xmalloc ((n_base_source_files
+ 1) * sizeof (char *));
4629 n_base_source_files
= 0;
4630 for (; optind
< argc
; optind
++)
4632 const char *path
= abspath (NULL
, argv
[optind
]);
4633 int len
= strlen (path
);
4635 if (path
[len
-1] == 'c' && path
[len
-2] == '.')
4636 base_source_filenames
[n_base_source_files
++] = path
;
4639 notice ("%s: input file names must have .c suffixes: %s\n",
4640 pname
, shortpath (NULL
, path
));
4646 /* We are only interested in the very first identifier token in the
4647 definition of `va_list', so if there is more junk after that first
4648 identifier token, delete it from the `varargs_style_indicator'. */
4652 for (cp
= varargs_style_indicator
; ISIDNUM (*cp
); cp
++)
4655 varargs_style_indicator
= savestring (varargs_style_indicator
,
4656 cp
- varargs_style_indicator
);
4658 #endif /* !defined (UNPROTOIZE) */
4665 fprintf (stderr
, "%s: %s\n", pname
, version_string
);
4669 return (errors
? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);