1 /* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
2 Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
29 /* Include getopt.h for the sake of getopt_long. */
32 extern char *version_string
;
34 static void usage
PARAMS ((void)) ATTRIBUTE_NORETURN
;
35 static void aux_info_corrupted
PARAMS ((void)) ATTRIBUTE_NORETURN
;
36 static void declare_source_confusing
PARAMS ((const char *)) ATTRIBUTE_NORETURN
;
37 static const char *shortpath
PARAMS ((const char *, const char *));
38 extern void fancy_abort
PARAMS ((void)) ATTRIBUTE_NORETURN
;
39 static void notice
PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1
;
40 static char *savestring
PARAMS ((const char *, unsigned int));
41 static char *dupnstr
PARAMS ((const char *, size_t));
42 static const char *substr
PARAMS ((const char *, const char * const));
43 static int safe_read
PARAMS ((int, PTR
, int));
44 static void safe_write
PARAMS ((int, PTR
, int, const char *));
45 static void save_pointers
PARAMS ((void));
46 static void restore_pointers
PARAMS ((void));
47 static int is_id_char
PARAMS ((int));
48 static int in_system_include_dir
PARAMS ((const char *));
49 static int directory_specified_p
PARAMS ((const char *));
50 static int file_excluded_p
PARAMS ((const char *));
51 static char *unexpand_if_needed
PARAMS ((const char *));
52 static char *abspath
PARAMS ((const char *, const char *));
53 static void check_aux_info
PARAMS ((int));
54 static const char *find_corresponding_lparen
PARAMS ((const char *));
55 static int referenced_file_is_newer
PARAMS ((const char *, time_t));
56 static void save_def_or_dec
PARAMS ((const char *, int));
57 static void munge_compile_params
PARAMS ((const char *));
58 static int gen_aux_info_file
PARAMS ((const char *));
59 static void process_aux_info_file
PARAMS ((const char *, int, int));
60 static int identify_lineno
PARAMS ((const char *));
61 static void check_source
PARAMS ((int, const char *));
62 static const char *seek_to_line
PARAMS ((int));
63 static const char *forward_to_next_token_char
PARAMS ((const char *));
64 static void output_bytes
PARAMS ((const char *, size_t));
65 static void output_string
PARAMS ((const char *));
66 static void output_up_to
PARAMS ((const char *));
67 static int other_variable_style_function
PARAMS ((const char *));
68 static const char *find_rightmost_formals_list
PARAMS ((const char *));
69 static void do_cleaning
PARAMS ((char *, const char *));
70 static const char *careful_find_l_paren
PARAMS ((const char *));
71 static void do_processing
PARAMS ((void));
73 /* Look for these where the `const' qualifier is intentionally cast aside. */
76 /* Define a default place to find the SYSCALLS.X file. */
80 #ifndef STANDARD_EXEC_PREFIX
81 #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
82 #endif /* !defined STANDARD_EXEC_PREFIX */
84 static const char * const standard_exec_prefix
= STANDARD_EXEC_PREFIX
;
85 static const char * const target_machine
= DEFAULT_TARGET_MACHINE
;
86 static const char * const target_version
= DEFAULT_TARGET_VERSION
;
88 #ifndef GET_ENV_PATH_LIST
89 #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0)
92 #endif /* !defined (UNPROTOIZE) */
94 /* Suffix of aux_info files. */
96 static const char * const aux_info_suffix
= ".X";
98 /* String to attach to filenames for saved versions of original files. */
100 static const char * const save_suffix
= ".save";
104 /* File name of the file which contains descriptions of standard system
105 routines. Note that we never actually do anything with this file per se,
106 but we do read in its corresponding aux_info file. */
108 static const char syscalls_filename
[] = "SYSCALLS.c";
110 /* Default place to find the above file. */
112 static const char * default_syscalls_dir
;
114 /* Variable to hold the complete absolutized filename of the SYSCALLS.c.X
117 static char * syscalls_absolute_filename
;
119 #endif /* !defined (UNPROTOIZE) */
121 /* Type of the structure that holds information about macro unexpansions. */
123 struct unexpansion_struct
{
124 const char *expanded
;
125 const char *contracted
;
127 typedef struct unexpansion_struct unexpansion
;
129 /* A table of conversions that may need to be made for some (stupid) older
130 operating systems where these types are preprocessor macros rather than
131 typedefs (as they really ought to be).
133 WARNING: The contracted forms must be as small (or smaller) as the
134 expanded forms, or else havoc will ensue. */
136 static const unexpansion unexpansions
[] = {
137 { "struct _iobuf", "FILE" },
141 /* The number of "primary" slots in the hash tables for filenames and for
142 function names. This can be as big or as small as you like, except that
143 it must be a power of two. */
145 #define HASH_TABLE_SIZE (1 << 9)
147 /* Bit mask to use when computing hash values. */
149 static const int hash_mask
= (HASH_TABLE_SIZE
- 1);
151 /* Make a table of default system include directories
152 just as it is done in cccp.c. */
154 #ifndef STANDARD_INCLUDE_DIR
155 #define STANDARD_INCLUDE_DIR "/usr/include"
158 #ifndef LOCAL_INCLUDE_DIR
159 #define LOCAL_INCLUDE_DIR "/usr/local/include"
162 struct default_include
{ const char *fname
;
163 const char *component
;
164 int x1
, x2
; } include_defaults
[]
165 #ifdef INCLUDE_DEFAULTS
169 /* Pick up GNU C++ specific include files. */
170 { GPLUSPLUS_INCLUDE_DIR
, "G++", 1, 1 },
172 /* This is the dir for fixincludes. Put it just before
173 the files that we fix. */
174 { GCC_INCLUDE_DIR
, "GCC", 0, 0 },
175 /* For cross-compilation, this dir name is generated
176 automatically in Makefile.in. */
177 { CROSS_INCLUDE_DIR
, 0, 0, 0 },
178 /* This is another place that the target system's headers might be. */
179 { TOOL_INCLUDE_DIR
, "BINUTILS", 0, 0 },
180 #else /* not CROSS_COMPILE */
181 /* This should be /use/local/include and should come before
182 the fixincludes-fixed header files. */
183 { LOCAL_INCLUDE_DIR
, 0, 0, 1 },
184 /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
185 Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
186 { TOOL_INCLUDE_DIR
, "BINUTILS", 0, 0 },
187 /* This is the dir for fixincludes. Put it just before
188 the files that we fix. */
189 { GCC_INCLUDE_DIR
, "GCC", 0, 0 },
190 /* Some systems have an extra dir of include files. */
191 #ifdef SYSTEM_INCLUDE_DIR
192 { SYSTEM_INCLUDE_DIR
, 0, 0, 0 },
194 { STANDARD_INCLUDE_DIR
, 0, 0, 0},
195 #endif /* not CROSS_COMPILE */
198 #endif /* no INCLUDE_DEFAULTS */
200 /* Datatype for lists of directories or filenames. */
204 struct string_list
*next
;
207 static struct string_list
*string_list_cons
PARAMS ((const char *,
208 struct string_list
*));
210 /* List of directories in which files should be converted. */
212 struct string_list
*directory_list
;
214 /* List of file names which should not be converted.
215 A file is excluded if the end of its name, following a /,
216 matches one of the names in this list. */
218 struct string_list
*exclude_list
;
220 /* The name of the other style of variable-number-of-parameters functions
221 (i.e. the style that we want to leave unconverted because we don't yet
222 know how to convert them to this style. This string is used in warning
225 /* Also define here the string that we can search for in the parameter lists
226 taken from the .X files which will unambiguously indicate that we have
227 found a varargs style function. */
230 static const char * const other_var_style
= "stdarg";
231 #else /* !defined (UNPROTOIZE) */
232 static const char * const other_var_style
= "varargs";
233 /* Note that this is a string containing the expansion of va_alist.
234 But in `main' we discard all but the first token. */
235 static const char *varargs_style_indicator
= STRINGIFY (va_alist
);
236 #endif /* !defined (UNPROTOIZE) */
238 /* The following two types are used to create hash tables. In this program,
239 there are two hash tables which are used to store and quickly lookup two
240 different classes of strings. The first type of strings stored in the
241 first hash table are absolute filenames of files which protoize needs to
242 know about. The second type of strings (stored in the second hash table)
243 are function names. It is this second class of strings which really
244 inspired the use of the hash tables, because there may be a lot of them. */
246 typedef struct hash_table_entry_struct hash_table_entry
;
248 /* Do some typedefs so that we don't have to write "struct" so often. */
250 typedef struct def_dec_info_struct def_dec_info
;
251 typedef struct file_info_struct file_info
;
252 typedef struct f_list_chain_item_struct f_list_chain_item
;
255 static int is_syscalls_file
PARAMS ((const file_info
*));
256 static void rename_c_file
PARAMS ((const hash_table_entry
*));
257 static const def_dec_info
*find_extern_def
PARAMS ((const def_dec_info
*,
258 const def_dec_info
*));
259 static const def_dec_info
*find_static_definition
PARAMS ((const def_dec_info
*));
260 static void connect_defs_and_decs
PARAMS ((const hash_table_entry
*));
261 static void add_local_decl
PARAMS ((const def_dec_info
*, const char *));
262 static void add_global_decls
PARAMS ((const file_info
*, const char *));
263 #endif /* ! UNPROTOIZE */
264 static int needs_to_be_converted
PARAMS ((const file_info
*));
265 static void visit_each_hash_node
PARAMS ((const hash_table_entry
*,
266 void (*)(const hash_table_entry
*)));
267 static hash_table_entry
*add_symbol
PARAMS ((hash_table_entry
*, const char *));
268 static hash_table_entry
*lookup
PARAMS ((hash_table_entry
*, const char *));
269 static void free_def_dec
PARAMS ((def_dec_info
*));
270 static file_info
*find_file
PARAMS ((const char *, int));
271 static void reverse_def_dec_list
PARAMS ((const hash_table_entry
*));
272 static void edit_fn_declaration
PARAMS ((const def_dec_info
*, const char *));
273 static int edit_formals_lists
PARAMS ((const char *, unsigned int,
274 const def_dec_info
*));
275 static void edit_fn_definition
PARAMS ((const def_dec_info
*, const char *));
276 static void scan_for_missed_items
PARAMS ((const file_info
*));
277 static void edit_file
PARAMS ((const hash_table_entry
*));
279 /* In the struct below, note that the "_info" field has two different uses
280 depending on the type of hash table we are in (i.e. either the filenames
281 hash table or the function names hash table). In the filenames hash table
282 the info fields of the entries point to the file_info struct which is
283 associated with each filename (1 per filename). In the function names
284 hash table, the info field points to the head of a singly linked list of
285 def_dec_info entries which are all defs or decs of the function whose
286 name is pointed to by the "symbol" field. Keeping all of the defs/decs
287 for a given function name on a special list specifically for that function
288 name makes it quick and easy to find out all of the important information
289 about a given (named) function. */
291 struct hash_table_entry_struct
{
292 hash_table_entry
* hash_next
; /* -> to secondary entries */
293 const char * symbol
; /* -> to the hashed string */
295 const def_dec_info
* _ddip
;
299 #define ddip _info._ddip
300 #define fip _info._fip
302 /* Define a type specifically for our two hash tables. */
304 typedef hash_table_entry hash_table
[HASH_TABLE_SIZE
];
306 /* The following struct holds all of the important information about any
307 single filename (e.g. file) which we need to know about. */
309 struct file_info_struct
{
310 const hash_table_entry
* hash_entry
; /* -> to associated hash entry */
311 const def_dec_info
* defs_decs
; /* -> to chain of defs/decs */
312 time_t mtime
; /* Time of last modification. */
315 /* Due to the possibility that functions may return pointers to functions,
316 (which may themselves have their own parameter lists) and due to the
317 fact that returned pointers-to-functions may be of type "pointer-to-
318 function-returning-pointer-to-function" (ad nauseum) we have to keep
319 an entire chain of ANSI style formal parameter lists for each function.
321 Normally, for any given function, there will only be one formals list
322 on the chain, but you never know.
324 Note that the head of each chain of formals lists is pointed to by the
325 `f_list_chain' field of the corresponding def_dec_info record.
327 For any given chain, the item at the head of the chain is the *leftmost*
328 parameter list seen in the actual C language function declaration. If
329 there are other members of the chain, then these are linked in left-to-right
330 order from the head of the chain. */
332 struct f_list_chain_item_struct
{
333 const f_list_chain_item
* chain_next
; /* -> to next item on chain */
334 const char * formals_list
; /* -> to formals list string */
337 /* The following struct holds all of the important information about any
338 single function definition or declaration which we need to know about.
339 Note that for unprotoize we don't need to know very much because we
340 never even create records for stuff that we don't intend to convert
341 (like for instance defs and decs which are already in old K&R format
342 and "implicit" function declarations). */
344 struct def_dec_info_struct
{
345 const def_dec_info
* next_in_file
; /* -> to rest of chain for file */
346 file_info
* file
; /* -> file_info for containing file */
347 int line
; /* source line number of def/dec */
348 const char * ansi_decl
; /* -> left end of ansi decl */
349 hash_table_entry
* hash_entry
; /* -> hash entry for function name */
350 unsigned int is_func_def
; /* = 0 means this is a declaration */
351 const def_dec_info
* next_for_func
; /* -> to rest of chain for func name */
352 unsigned int f_list_count
; /* count of formals lists we expect */
353 char prototyped
; /* = 0 means already prototyped */
355 const f_list_chain_item
* f_list_chain
; /* -> chain of formals lists */
356 const def_dec_info
* definition
; /* -> def/dec containing related def */
357 char is_static
; /* = 0 means visibility is "extern" */
358 char is_implicit
; /* != 0 for implicit func decl's */
359 char written
; /* != 0 means written for implicit */
360 #else /* !defined (UNPROTOIZE) */
361 const char * formal_names
; /* -> to list of names of formals */
362 const char * formal_decls
; /* -> to string of formal declarations */
363 #endif /* !defined (UNPROTOIZE) */
366 /* Pointer to the tail component of the filename by which this program was
367 invoked. Used everywhere in error and warning messages. */
369 static const char *pname
;
371 /* Error counter. Will be non-zero if we should give up at the next convenient
374 static int errors
= 0;
377 /* ??? These comments should say what the flag mean as well as the options
380 /* File name to use for running gcc. Allows GCC 2 to be named
381 something other than gcc. */
382 static const char *compiler_file_name
= "gcc";
384 static int version_flag
= 0; /* Print our version number. */
385 static int quiet_flag
= 0; /* Don't print messages normally. */
386 static int nochange_flag
= 0; /* Don't convert, just say what files
387 we would have converted. */
388 static int nosave_flag
= 0; /* Don't save the old version. */
389 static int keep_flag
= 0; /* Don't delete the .X files. */
390 static const char ** compile_params
= 0; /* Option string for gcc. */
392 static const char *indent_string
= " "; /* Indentation for newly
393 inserted parm decls. */
394 #else /* !defined (UNPROTOIZE) */
395 static int local_flag
= 0; /* Insert new local decls (when?). */
396 static int global_flag
= 0; /* set by -g option */
397 static int cplusplus_flag
= 0; /* Rename converted files to *.C. */
398 static const char *nondefault_syscalls_dir
= 0; /* Dir to look for
400 #endif /* !defined (UNPROTOIZE) */
402 /* An index into the compile_params array where we should insert the source
403 file name when we are ready to exec the C compiler. A zero value indicates
404 that we have not yet called munge_compile_params. */
406 static int input_file_name_index
= 0;
408 /* An index into the compile_params array where we should insert the filename
409 for the aux info file, when we run the C compiler. */
410 static int aux_info_file_name_index
= 0;
412 /* Count of command line arguments which were "filename" arguments. */
414 static int n_base_source_files
= 0;
416 /* Points to a malloc'ed list of pointers to all of the filenames of base
417 source files which were specified on the command line. */
419 static const char **base_source_filenames
;
421 /* Line number of the line within the current aux_info file that we
422 are currently processing. Used for error messages in case the prototypes
423 info file is corrupted somehow. */
425 static int current_aux_info_lineno
;
427 /* Pointer to the name of the source file currently being converted. */
429 static const char *convert_filename
;
431 /* Pointer to relative root string (taken from aux_info file) which indicates
432 where directory the user was in when he did the compilation step that
433 produced the containing aux_info file. */
435 static const char *invocation_filename
;
437 /* Pointer to the base of the input buffer that holds the original text for the
438 source file currently being converted. */
440 static const char *orig_text_base
;
442 /* Pointer to the byte just beyond the end of the input buffer that holds the
443 original text for the source file currently being converted. */
445 static const char *orig_text_limit
;
447 /* Pointer to the base of the input buffer that holds the cleaned text for the
448 source file currently being converted. */
450 static const char *clean_text_base
;
452 /* Pointer to the byte just beyond the end of the input buffer that holds the
453 cleaned text for the source file currently being converted. */
455 static const char *clean_text_limit
;
457 /* Pointer to the last byte in the cleaned text buffer that we have already
458 (virtually) copied to the output buffer (or decided to ignore). */
460 static const char * clean_read_ptr
;
462 /* Pointer to the base of the output buffer that holds the replacement text
463 for the source file currently being converted. */
465 static char *repl_text_base
;
467 /* Pointer to the byte just beyond the end of the output buffer that holds the
468 replacement text for the source file currently being converted. */
470 static char *repl_text_limit
;
472 /* Pointer to the last byte which has been stored into the output buffer.
473 The next byte to be stored should be stored just past where this points
476 static char * repl_write_ptr
;
478 /* Pointer into the cleaned text buffer for the source file we are currently
479 converting. This points to the first character of the line that we last
480 did a "seek_to_line" to (see below). */
482 static const char *last_known_line_start
;
484 /* Number of the line (in the cleaned text buffer) that we last did a
485 "seek_to_line" to. Will be one if we just read a new source file
486 into the cleaned text buffer. */
488 static int last_known_line_number
;
490 /* The filenames hash table. */
492 static hash_table filename_primary
;
494 /* The function names hash table. */
496 static hash_table function_name_primary
;
498 /* The place to keep the recovery address which is used only in cases where
499 we get hopelessly confused by something in the cleaned original text. */
501 static jmp_buf source_confusion_recovery
;
503 /* A pointer to the current directory filename (used by abspath). */
505 static char *cwd_buffer
;
507 /* A place to save the read pointer until we are sure that an individual
508 attempt at editing will succeed. */
510 static const char * saved_clean_read_ptr
;
512 /* A place to save the write pointer until we are sure that an individual
513 attempt at editing will succeed. */
515 static char * saved_repl_write_ptr
;
517 /* Translate and output an error message. */
519 notice
VPARAMS ((const char *msgid
, ...))
521 #ifndef ANSI_PROTOTYPES
526 VA_START (ap
, msgid
);
528 #ifndef ANSI_PROTOTYPES
529 msgid
= va_arg (ap
, const char *);
532 vfprintf (stderr
, _(msgid
), ap
);
537 /* Make a copy of a string INPUT with size SIZE. */
540 savestring (input
, size
)
544 char *output
= (char *) xmalloc (size
+ 1);
545 strcpy (output
, input
);
549 /* More 'friendly' abort that prints the line and file.
550 config.h can #define abort fancy_abort if you like that sort of thing. */
555 notice ("%s: internal abort\n", pname
);
556 exit (FATAL_EXIT_CODE
);
559 /* Make a duplicate of the first N bytes of a given string in a newly
567 char *ret_val
= (char *) xmalloc (n
+ 1);
569 strncpy (ret_val
, s
, n
);
574 /* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
575 does not occur within s1. Assume neither s1 nor s2 are null pointers. */
580 const char *const s2
;
588 for (p1
= s1
, p2
= s2
; (c
= *p2
); p1
++, p2
++)
598 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
599 retrying if necessary. Return the actual number of bytes read. */
602 safe_read (desc
, ptr
, len
)
609 int nchars
= read (desc
, ptr
, left
);
620 /* Arithmetic on void pointers is a gcc extention. */
621 ptr
= (char *) ptr
+ nchars
;
627 /* Write LEN bytes at PTR to descriptor DESC,
628 retrying if necessary, and treating any real error as fatal. */
631 safe_write (desc
, ptr
, len
, out_fname
)
635 const char *out_fname
;
638 int written
= write (desc
, ptr
, len
);
641 int errno_val
= errno
;
643 if (errno_val
== EINTR
)
646 notice ("%s: error writing file `%s': %s\n",
647 pname
, shortpath (NULL
, out_fname
), xstrerror (errno_val
));
650 /* Arithmetic on void pointers is a gcc extention. */
651 ptr
= (char *) ptr
+ written
;
656 /* Get setup to recover in case the edit we are about to do goes awry. */
661 saved_clean_read_ptr
= clean_read_ptr
;
662 saved_repl_write_ptr
= repl_write_ptr
;
665 /* Call this routine to recover our previous state whenever something looks
666 too confusing in the source code we are trying to edit. */
671 clean_read_ptr
= saved_clean_read_ptr
;
672 repl_write_ptr
= saved_repl_write_ptr
;
675 /* Return true if the given character is a valid identifier character. */
681 return (ISALNUM (ch
) || (ch
== '_') || (ch
== '$'));
684 /* Give a message indicating the proper way to invoke this program and then
685 exit with non-zero status. */
691 notice ("%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
693 #else /* !defined (UNPROTOIZE) */
694 notice ("%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
696 #endif /* !defined (UNPROTOIZE) */
697 exit (FATAL_EXIT_CODE
);
700 /* Return true if the given filename (assumed to be an absolute filename)
701 designates a file residing anywhere beneath any one of the "system"
702 include directories. */
705 in_system_include_dir (path
)
708 struct default_include
*p
;
711 abort (); /* Must be an absolutized filename. */
713 for (p
= include_defaults
; p
->fname
; p
++)
714 if (!strncmp (path
, p
->fname
, strlen (p
->fname
))
715 && path
[strlen (p
->fname
)] == '/')
721 /* Return true if the given filename designates a file that the user has
722 read access to and for which the user has write access to the containing
726 file_could_be_converted (const char *path
)
728 char *const dir_name
= (char *) alloca (strlen (path
) + 1);
730 if (access (path
, R_OK
))
734 char *dir_last_slash
;
736 strcpy (dir_name
, path
);
737 dir_last_slash
= strrchr (dir_name
, '/');
739 *dir_last_slash
= '\0';
741 abort (); /* Should have been an absolutized filename. */
744 if (access (path
, W_OK
))
750 /* Return true if the given filename designates a file that we are allowed
751 to modify. Files which we should not attempt to modify are (a) "system"
752 include files, and (b) files which the user doesn't have write access to,
753 and (c) files which reside in directories which the user doesn't have
754 write access to. Unless requested to be quiet, give warnings about
755 files that we will not try to convert for one reason or another. An
756 exception is made for "system" include files, which we never try to
757 convert and for which we don't issue the usual warnings. */
760 file_normally_convertible (const char *path
)
762 char *const dir_name
= alloca (strlen (path
) + 1);
764 if (in_system_include_dir (path
))
768 char *dir_last_slash
;
770 strcpy (dir_name
, path
);
771 dir_last_slash
= strrchr (dir_name
, '/');
773 *dir_last_slash
= '\0';
775 abort (); /* Should have been an absolutized filename. */
778 if (access (path
, R_OK
))
781 notice ("%s: warning: no read access for file `%s'\n",
782 pname
, shortpath (NULL
, path
));
786 if (access (path
, W_OK
))
789 notice ("%s: warning: no write access for file `%s'\n",
790 pname
, shortpath (NULL
, path
));
794 if (access (dir_name
, W_OK
))
797 notice ("%s: warning: no write access for dir containing `%s'\n",
798 pname
, shortpath (NULL
, path
));
808 /* Return true if the given file_info struct refers to the special SYSCALLS.c.X
809 file. Return false otherwise. */
812 is_syscalls_file (fi_p
)
813 const file_info
*fi_p
;
815 char const *f
= fi_p
->hash_entry
->symbol
;
816 size_t fl
= strlen (f
), sysl
= sizeof (syscalls_filename
) - 1;
817 return sysl
<= fl
&& strcmp (f
+ fl
- sysl
, syscalls_filename
) == 0;
820 #endif /* !defined (UNPROTOIZE) */
822 /* Check to see if this file will need to have anything done to it on this
823 run. If there is nothing in the given file which both needs conversion
824 and for which we have the necessary stuff to do the conversion, return
825 false. Otherwise, return true.
827 Note that (for protoize) it is only valid to call this function *after*
828 the connections between declarations and definitions have all been made
829 by connect_defs_and_decs. */
832 needs_to_be_converted (file_p
)
833 const file_info
*file_p
;
835 const def_dec_info
*ddp
;
839 if (is_syscalls_file (file_p
))
842 #endif /* !defined (UNPROTOIZE) */
844 for (ddp
= file_p
->defs_decs
; ddp
; ddp
= ddp
->next_in_file
)
850 /* ... and if we a protoizing and this function is in old style ... */
852 /* ... and if this a definition or is a decl with an associated def ... */
853 && (ddp
->is_func_def
|| (!ddp
->is_func_def
&& ddp
->definition
))
855 #else /* defined (UNPROTOIZE) */
857 /* ... and if we are unprotoizing and this function is in new style ... */
860 #endif /* defined (UNPROTOIZE) */
862 /* ... then the containing file needs converting. */
867 /* Return 1 if the file name NAME is in a directory
868 that should be converted. */
871 directory_specified_p (name
)
874 struct string_list
*p
;
876 for (p
= directory_list
; p
; p
= p
->next
)
877 if (!strncmp (name
, p
->name
, strlen (p
->name
))
878 && name
[strlen (p
->name
)] == '/')
880 const char *q
= name
+ strlen (p
->name
) + 1;
882 /* If there are more slashes, it's in a subdir, so
883 this match doesn't count. */
895 /* Return 1 if the file named NAME should be excluded from conversion. */
898 file_excluded_p (name
)
901 struct string_list
*p
;
902 int len
= strlen (name
);
904 for (p
= exclude_list
; p
; p
= p
->next
)
905 if (!strcmp (name
+ len
- strlen (p
->name
), p
->name
)
906 && name
[len
- strlen (p
->name
) - 1] == '/')
912 /* Construct a new element of a string_list.
913 STRING is the new element value, and REST holds the remaining elements. */
915 static struct string_list
*
916 string_list_cons (string
, rest
)
918 struct string_list
*rest
;
920 struct string_list
*temp
921 = (struct string_list
*) xmalloc (sizeof (struct string_list
));
928 /* ??? The GNU convention for mentioning function args in its comments
929 is to capitalize them. So change "hash_tab_p" to HASH_TAB_P below.
930 Likewise for all the other functions. */
932 /* Given a hash table, apply some function to each node in the table. The
933 table to traverse is given as the "hash_tab_p" argument, and the
934 function to be applied to each node in the table is given as "func"
938 visit_each_hash_node (hash_tab_p
, func
)
939 const hash_table_entry
*hash_tab_p
;
940 void (*func
) PARAMS ((const hash_table_entry
*));
942 const hash_table_entry
*primary
;
944 for (primary
= hash_tab_p
; primary
< &hash_tab_p
[HASH_TABLE_SIZE
]; primary
++)
947 hash_table_entry
*second
;
950 for (second
= primary
->hash_next
; second
; second
= second
->hash_next
)
955 /* Initialize all of the fields of a new hash table entry, pointed
956 to by the "p" parameter. Note that the space to hold the entry
957 is assumed to have already been allocated before this routine is
960 static hash_table_entry
*
966 p
->symbol
= xstrdup (s
);
972 /* Look for a particular function name or filename in the particular
973 hash table indicated by "hash_tab_p". If the name is not in the
974 given hash table, add it. Either way, return a pointer to the
975 hash table entry for the given name. */
977 static hash_table_entry
*
978 lookup (hash_tab_p
, search_symbol
)
979 hash_table_entry
*hash_tab_p
;
980 const char *search_symbol
;
983 const char *search_symbol_char_p
= search_symbol
;
986 while (*search_symbol_char_p
)
987 hash_value
+= *search_symbol_char_p
++;
988 hash_value
&= hash_mask
;
989 p
= &hash_tab_p
[hash_value
];
991 return add_symbol (p
, search_symbol
);
992 if (!strcmp (p
->symbol
, search_symbol
))
997 if (!strcmp (p
->symbol
, search_symbol
))
1000 p
->hash_next
= (hash_table_entry
*) xmalloc (sizeof (hash_table_entry
));
1002 return add_symbol (p
, search_symbol
);
1005 /* Throw a def/dec record on the junk heap.
1007 Also, since we are not using this record anymore, free up all of the
1008 stuff it pointed to. */
1014 free ((NONCONST PTR
) p
->ansi_decl
);
1018 const f_list_chain_item
* curr
;
1019 const f_list_chain_item
* next
;
1021 for (curr
= p
->f_list_chain
; curr
; curr
= next
)
1023 next
= curr
->chain_next
;
1024 free ((NONCONST PTR
) curr
);
1027 #endif /* !defined (UNPROTOIZE) */
1032 /* Unexpand as many macro symbol as we can find.
1034 If the given line must be unexpanded, make a copy of it in the heap and
1035 return a pointer to the unexpanded copy. Otherwise return NULL. */
1038 unexpand_if_needed (aux_info_line
)
1039 const char *aux_info_line
;
1041 static char *line_buf
= 0;
1042 static int line_buf_size
= 0;
1043 const unexpansion
*unexp_p
;
1044 int got_unexpanded
= 0;
1046 char *copy_p
= line_buf
;
1050 line_buf_size
= 1024;
1051 line_buf
= (char *) xmalloc (line_buf_size
);
1056 /* Make a copy of the input string in line_buf, expanding as necessary. */
1058 for (s
= aux_info_line
; *s
!= '\n'; )
1060 for (unexp_p
= unexpansions
; unexp_p
->expanded
; unexp_p
++)
1062 const char *in_p
= unexp_p
->expanded
;
1063 size_t len
= strlen (in_p
);
1065 if (*s
== *in_p
&& !strncmp (s
, in_p
, len
) && !is_id_char (s
[len
]))
1067 int size
= strlen (unexp_p
->contracted
);
1069 if (copy_p
+ size
- line_buf
>= line_buf_size
)
1071 int offset
= copy_p
- line_buf
;
1073 line_buf_size
+= size
;
1074 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1075 copy_p
= line_buf
+ offset
;
1077 strcpy (copy_p
, unexp_p
->contracted
);
1080 /* Assume the there will not be another replacement required
1081 within the text just replaced. */
1084 goto continue_outer
;
1087 if (copy_p
- line_buf
== line_buf_size
)
1089 int offset
= copy_p
- line_buf
;
1091 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1092 copy_p
= line_buf
+ offset
;
1097 if (copy_p
+ 2 - line_buf
>= line_buf_size
)
1099 int offset
= copy_p
- line_buf
;
1101 line_buf
= (char *) xrealloc (line_buf
, line_buf_size
);
1102 copy_p
= line_buf
+ offset
;
1107 return (got_unexpanded
? savestring (line_buf
, copy_p
- line_buf
) : 0);
1110 /* Return the absolutized filename for the given relative
1111 filename. Note that if that filename is already absolute, it may
1112 still be returned in a modified form because this routine also
1113 eliminates redundant slashes and single dots and eliminates double
1114 dots to get a shortest possible filename from the given input
1115 filename. The absolutization of relative filenames is made by
1116 assuming that the given filename is to be taken as relative to
1117 the first argument (cwd) or to the current directory if cwd is
1121 abspath (cwd
, rel_filename
)
1123 const char *rel_filename
;
1125 /* Setup the current working directory as needed. */
1126 const char *cwd2
= (cwd
) ? cwd
: cwd_buffer
;
1127 char *const abs_buffer
1128 = (char *) alloca (strlen (cwd2
) + strlen (rel_filename
) + 2);
1129 char *endp
= abs_buffer
;
1132 /* Copy the filename (possibly preceded by the current working
1133 directory name) into the absolutization buffer. */
1138 if (rel_filename
[0] != '/')
1141 while ((*endp
++ = *src_p
++))
1143 *(endp
-1) = '/'; /* overwrite null */
1145 src_p
= rel_filename
;
1146 while ((*endp
++ = *src_p
++))
1150 /* Now make a copy of abs_buffer into abs_buffer, shortening the
1151 filename (by taking out slashes and dots) as we go. */
1153 outp
= inp
= abs_buffer
;
1154 *outp
++ = *inp
++; /* copy first slash */
1155 #if defined (apollo) || defined (_WIN32) || defined (__INTERIX)
1157 *outp
++ = *inp
++; /* copy second slash */
1163 else if (inp
[0] == '/' && outp
[-1] == '/')
1168 else if (inp
[0] == '.' && outp
[-1] == '/')
1172 else if (inp
[1] == '/')
1177 else if ((inp
[1] == '.') && (inp
[2] == 0 || inp
[2] == '/'))
1179 inp
+= (inp
[2] == '/') ? 3 : 2;
1181 while (outp
>= abs_buffer
&& *outp
!= '/')
1183 if (outp
< abs_buffer
)
1185 /* Catch cases like /.. where we try to backup to a
1186 point above the absolute root of the logical file
1189 notice ("%s: invalid file name: %s\n",
1190 pname
, rel_filename
);
1191 exit (FATAL_EXIT_CODE
);
1200 /* On exit, make sure that there is a trailing null, and make sure that
1201 the last character of the returned string is *not* a slash. */
1204 if (outp
[-1] == '/')
1207 /* Make a copy (in the heap) of the stuff left in the absolutization
1208 buffer and return a pointer to the copy. */
1210 return savestring (abs_buffer
, outp
- abs_buffer
);
1213 /* Given a filename (and possibly a directory name from which the filename
1214 is relative) return a string which is the shortest possible
1215 equivalent for the corresponding full (absolutized) filename. The
1216 shortest possible equivalent may be constructed by converting the
1217 absolutized filename to be a relative filename (i.e. relative to
1218 the actual current working directory). However if a relative filename
1219 is longer, then the full absolute filename is returned.
1223 Note that "simple-minded" conversion of any given type of filename (either
1224 relative or absolute) may not result in a valid equivalent filename if any
1225 subpart of the original filename is actually a symbolic link. */
1228 shortpath (cwd
, filename
)
1230 const char *filename
;
1234 char *cwd_p
= cwd_buffer
;
1236 int unmatched_slash_count
= 0;
1237 size_t filename_len
= strlen (filename
);
1239 path_p
= abspath (cwd
, filename
);
1240 rel_buf_p
= rel_buffer
= (char *) xmalloc (filename_len
);
1242 while (*cwd_p
&& (*cwd_p
== *path_p
))
1247 if (!*cwd_p
&& (!*path_p
|| *path_p
== '/')) /* whole pwd matched */
1249 if (!*path_p
) /* input *is* the current path! */
1260 while (*cwd_p
!= '/') /* backup to last slash */
1267 unmatched_slash_count
++;
1270 /* Find out how many directory levels in cwd were *not* matched. */
1272 if (*cwd_p
++ == '/')
1273 unmatched_slash_count
++;
1275 /* Now we know how long the "short name" will be.
1276 Reject it if longer than the input. */
1277 if (unmatched_slash_count
* 3 + strlen (path_p
) >= filename_len
)
1280 /* For each of them, put a `../' at the beginning of the short name. */
1281 while (unmatched_slash_count
--)
1283 /* Give up if the result gets to be longer
1284 than the absolute path name. */
1285 if (rel_buffer
+ filename_len
<= rel_buf_p
+ 3)
1292 /* Then tack on the unmatched part of the desired file's name. */
1295 if (rel_buffer
+ filename_len
<= rel_buf_p
)
1298 while ((*rel_buf_p
++ = *path_p
++));
1301 if (*(rel_buf_p
-1) == '/')
1302 *--rel_buf_p
= '\0';
1307 /* Lookup the given filename in the hash table for filenames. If it is a
1308 new one, then the hash table info pointer will be null. In this case,
1309 we create a new file_info record to go with the filename, and we initialize
1310 that record with some reasonable values. */
1312 /* FILENAME was const, but that causes a warning on AIX when calling stat.
1313 That is probably a bug in AIX, but might as well avoid the warning. */
1316 find_file (filename
, do_not_stat
)
1317 const char *filename
;
1320 hash_table_entry
*hash_entry_p
;
1322 hash_entry_p
= lookup (filename_primary
, filename
);
1323 if (hash_entry_p
->fip
)
1324 return hash_entry_p
->fip
;
1327 struct stat stat_buf
;
1328 file_info
*file_p
= (file_info
*) xmalloc (sizeof (file_info
));
1330 /* If we cannot get status on any given source file, give a warning
1331 and then just set its time of last modification to infinity. */
1334 stat_buf
.st_mtime
= (time_t) 0;
1337 if (stat (filename
, &stat_buf
) == -1)
1339 int errno_val
= errno
;
1340 notice ("%s: %s: can't get status: %s\n",
1341 pname
, shortpath (NULL
, filename
),
1342 xstrerror (errno_val
));
1343 stat_buf
.st_mtime
= (time_t) -1;
1347 hash_entry_p
->fip
= file_p
;
1348 file_p
->hash_entry
= hash_entry_p
;
1349 file_p
->defs_decs
= NULL
;
1350 file_p
->mtime
= stat_buf
.st_mtime
;
1355 /* Generate a fatal error because some part of the aux_info file is
1359 aux_info_corrupted ()
1361 notice ("\n%s: fatal error: aux info file corrupted at line %d\n",
1362 pname
, current_aux_info_lineno
);
1363 exit (FATAL_EXIT_CODE
);
1366 /* ??? This comment is vague. Say what the condition is for. */
1367 /* Check to see that a condition is true. This is kind of like an assert. */
1370 check_aux_info (cond
)
1374 aux_info_corrupted ();
1377 /* Given a pointer to the closing right parenthesis for a particular formals
1378 list (in an aux_info file) find the corresponding left parenthesis and
1379 return a pointer to it. */
1382 find_corresponding_lparen (p
)
1388 for (paren_depth
= 1, q
= p
-1; paren_depth
; q
--)
1403 /* Given a line from an aux info file, and a time at which the aux info
1404 file it came from was created, check to see if the item described in
1405 the line comes from a file which has been modified since the aux info
1406 file was created. If so, return non-zero, else return zero. */
1409 referenced_file_is_newer (l
, aux_info_mtime
)
1411 time_t aux_info_mtime
;
1417 check_aux_info (l
[0] == '/');
1418 check_aux_info (l
[1] == '*');
1419 check_aux_info (l
[2] == ' ');
1422 const char *filename_start
= p
= l
+ 3;
1426 filename
= (char *) alloca ((size_t) (p
- filename_start
) + 1);
1427 strncpy (filename
, filename_start
, (size_t) (p
- filename_start
));
1428 filename
[p
-filename_start
] = '\0';
1431 /* Call find_file to find the file_info record associated with the file
1432 which contained this particular def or dec item. Note that this call
1433 may cause a new file_info record to be created if this is the first time
1434 that we have ever known about this particular file. */
1436 fi_p
= find_file (abspath (invocation_filename
, filename
), 0);
1438 return (fi_p
->mtime
> aux_info_mtime
);
1441 /* Given a line of info from the aux_info file, create a new
1442 def_dec_info record to remember all of the important information about
1443 a function definition or declaration.
1445 Link this record onto the list of such records for the particular file in
1446 which it occurred in proper (descending) line number order (for now).
1448 If there is an identical record already on the list for the file, throw
1449 this one away. Doing so takes care of the (useless and troublesome)
1450 duplicates which are bound to crop up due to multiple inclusions of any
1451 given individual header file.
1453 Finally, link the new def_dec record onto the list of such records
1454 pertaining to this particular function name. */
1457 save_def_or_dec (l
, is_syscalls
)
1462 const char *semicolon_p
;
1463 def_dec_info
*def_dec_p
= (def_dec_info
*) xmalloc (sizeof (def_dec_info
));
1466 def_dec_p
->written
= 0;
1467 #endif /* !defined (UNPROTOIZE) */
1469 /* Start processing the line by picking off 5 pieces of information from
1470 the left hand end of the line. These are filename, line number,
1471 new/old/implicit flag (new = ANSI prototype format), definition or
1472 declaration flag, and extern/static flag). */
1474 check_aux_info (l
[0] == '/');
1475 check_aux_info (l
[1] == '*');
1476 check_aux_info (l
[2] == ' ');
1479 const char *filename_start
= p
= l
+ 3;
1484 filename
= (char *) alloca ((size_t) (p
- filename_start
) + 1);
1485 strncpy (filename
, filename_start
, (size_t) (p
- filename_start
));
1486 filename
[p
-filename_start
] = '\0';
1488 /* Call find_file to find the file_info record associated with the file
1489 which contained this particular def or dec item. Note that this call
1490 may cause a new file_info record to be created if this is the first time
1491 that we have ever known about this particular file.
1493 Note that we started out by forcing all of the base source file names
1494 (i.e. the names of the aux_info files with the .X stripped off) into the
1495 filenames hash table, and we simultaneously setup file_info records for
1496 all of these base file names (even if they may be useless later).
1497 The file_info records for all of these "base" file names (properly)
1498 act as file_info records for the "original" (i.e. un-included) files
1499 which were submitted to gcc for compilation (when the -aux-info
1500 option was used). */
1502 def_dec_p
->file
= find_file (abspath (invocation_filename
, filename
), is_syscalls
);
1506 const char *line_number_start
= ++p
;
1507 char line_number
[10];
1511 strncpy (line_number
, line_number_start
, (size_t) (p
- line_number_start
));
1512 line_number
[p
-line_number_start
] = '\0';
1513 def_dec_p
->line
= atoi (line_number
);
1516 /* Check that this record describes a new-style, old-style, or implicit
1517 definition or declaration. */
1519 p
++; /* Skip over the `:'. */
1520 check_aux_info ((*p
== 'N') || (*p
== 'O') || (*p
== 'I'));
1522 /* Is this a new style (ANSI prototyped) definition or declaration? */
1524 def_dec_p
->prototyped
= (*p
== 'N');
1528 /* Is this an implicit declaration? */
1530 def_dec_p
->is_implicit
= (*p
== 'I');
1532 #endif /* !defined (UNPROTOIZE) */
1536 check_aux_info ((*p
== 'C') || (*p
== 'F'));
1538 /* Is this item a function definition (F) or a declaration (C). Note that
1539 we treat item taken from the syscalls file as though they were function
1540 definitions regardless of what the stuff in the file says. */
1542 def_dec_p
->is_func_def
= ((*p
++ == 'F') || is_syscalls
);
1545 def_dec_p
->definition
= 0; /* Fill this in later if protoizing. */
1546 #endif /* !defined (UNPROTOIZE) */
1548 check_aux_info (*p
++ == ' ');
1549 check_aux_info (*p
++ == '*');
1550 check_aux_info (*p
++ == '/');
1551 check_aux_info (*p
++ == ' ');
1554 check_aux_info ((!strncmp (p
, "static", 6)) || (!strncmp (p
, "extern", 6)));
1555 #else /* !defined (UNPROTOIZE) */
1556 if (!strncmp (p
, "static", 6))
1557 def_dec_p
->is_static
= -1;
1558 else if (!strncmp (p
, "extern", 6))
1559 def_dec_p
->is_static
= 0;
1561 check_aux_info (0); /* Didn't find either `extern' or `static'. */
1562 #endif /* !defined (UNPROTOIZE) */
1565 const char *ansi_start
= p
;
1567 p
+= 6; /* Pass over the "static" or "extern". */
1569 /* We are now past the initial stuff. Search forward from here to find
1570 the terminating semicolon that should immediately follow the entire
1571 ANSI format function declaration. */
1578 /* Make a copy of the ansi declaration part of the line from the aux_info
1581 def_dec_p
->ansi_decl
1582 = dupnstr (ansi_start
, (size_t) ((semicolon_p
+1) - ansi_start
));
1584 /* Backup and point at the final right paren of the final argument list. */
1589 def_dec_p
->f_list_chain
= NULL
;
1590 #endif /* !defined (UNPROTOIZE) */
1592 while (p
!= ansi_start
&& (p
[-1] == ' ' || p
[-1] == '\t')) p
--;
1595 free_def_dec (def_dec_p
);
1600 /* Now isolate a whole set of formal argument lists, one-by-one. Normally,
1601 there will only be one list to isolate, but there could be more. */
1603 def_dec_p
->f_list_count
= 0;
1607 const char *left_paren_p
= find_corresponding_lparen (p
);
1610 f_list_chain_item
*cip
1611 = (f_list_chain_item
*) xmalloc (sizeof (f_list_chain_item
));
1614 = dupnstr (left_paren_p
+ 1, (size_t) (p
- (left_paren_p
+1)));
1616 /* Add the new chain item at the head of the current list. */
1618 cip
->chain_next
= def_dec_p
->f_list_chain
;
1619 def_dec_p
->f_list_chain
= cip
;
1621 #endif /* !defined (UNPROTOIZE) */
1622 def_dec_p
->f_list_count
++;
1624 p
= left_paren_p
- 2;
1626 /* p must now point either to another right paren, or to the last
1627 character of the name of the function that was declared/defined.
1628 If p points to another right paren, then this indicates that we
1629 are dealing with multiple formals lists. In that case, there
1630 really should be another right paren preceding this right paren. */
1635 check_aux_info (*--p
== ')');
1640 const char *past_fn
= p
+ 1;
1642 check_aux_info (*past_fn
== ' ');
1644 /* Scan leftwards over the identifier that names the function. */
1646 while (is_id_char (*p
))
1650 /* p now points to the leftmost character of the function name. */
1653 char *fn_string
= (char *) alloca (past_fn
- p
+ 1);
1655 strncpy (fn_string
, p
, (size_t) (past_fn
- p
));
1656 fn_string
[past_fn
-p
] = '\0';
1657 def_dec_p
->hash_entry
= lookup (function_name_primary
, fn_string
);
1661 /* Look at all of the defs and decs for this function name that we have
1662 collected so far. If there is already one which is at the same
1663 line number in the same file, then we can discard this new def_dec_info
1666 As an extra assurance that any such pair of (nominally) identical
1667 function declarations are in fact identical, we also compare the
1668 ansi_decl parts of the lines from the aux_info files just to be on
1671 This comparison will fail if (for instance) the user was playing
1672 messy games with the preprocessor which ultimately causes one
1673 function declaration in one header file to look differently when
1674 that file is included by two (or more) other files. */
1677 const def_dec_info
*other
;
1679 for (other
= def_dec_p
->hash_entry
->ddip
; other
; other
= other
->next_for_func
)
1681 if (def_dec_p
->line
== other
->line
&& def_dec_p
->file
== other
->file
)
1683 if (strcmp (def_dec_p
->ansi_decl
, other
->ansi_decl
))
1685 notice ("%s:%d: declaration of function `%s' takes different forms\n",
1686 def_dec_p
->file
->hash_entry
->symbol
,
1688 def_dec_p
->hash_entry
->symbol
);
1689 exit (FATAL_EXIT_CODE
);
1691 free_def_dec (def_dec_p
);
1699 /* If we are doing unprotoizing, we must now setup the pointers that will
1700 point to the K&R name list and to the K&R argument declarations list.
1702 Note that if this is only a function declaration, then we should not
1703 expect to find any K&R style formals list following the ANSI-style
1704 formals list. This is because GCC knows that such information is
1705 useless in the case of function declarations (function definitions
1706 are a different story however).
1708 Since we are unprotoizing, we don't need any such lists anyway.
1709 All we plan to do is to delete all characters between ()'s in any
1712 def_dec_p
->formal_names
= NULL
;
1713 def_dec_p
->formal_decls
= NULL
;
1715 if (def_dec_p
->is_func_def
)
1718 check_aux_info (*++p
== ' ');
1719 check_aux_info (*++p
== '/');
1720 check_aux_info (*++p
== '*');
1721 check_aux_info (*++p
== ' ');
1722 check_aux_info (*++p
== '(');
1725 const char *kr_names_start
= ++p
; /* Point just inside '('. */
1729 p
--; /* point to closing right paren */
1731 /* Make a copy of the K&R parameter names list. */
1733 def_dec_p
->formal_names
1734 = dupnstr (kr_names_start
, (size_t) (p
- kr_names_start
));
1737 check_aux_info (*++p
== ' ');
1740 /* p now points to the first character of the K&R style declarations
1741 list (if there is one) or to the star-slash combination that ends
1742 the comment in which such lists get embedded. */
1744 /* Make a copy of the K&R formal decls list and set the def_dec record
1747 if (*p
== '*') /* Are there no K&R declarations? */
1749 check_aux_info (*++p
== '/');
1750 def_dec_p
->formal_decls
= "";
1754 const char *kr_decls_start
= p
;
1756 while (p
[0] != '*' || p
[1] != '/')
1760 check_aux_info (*p
== ' ');
1762 def_dec_p
->formal_decls
1763 = dupnstr (kr_decls_start
, (size_t) (p
- kr_decls_start
));
1766 /* Handle a special case. If we have a function definition marked as
1767 being in "old" style, and if its formal names list is empty, then
1768 it may actually have the string "void" in its real formals list
1769 in the original source code. Just to make sure, we will get setup
1770 to convert such things anyway.
1772 This kludge only needs to be here because of an insurmountable
1773 problem with generating .X files. */
1775 if (!def_dec_p
->prototyped
&& !*def_dec_p
->formal_names
)
1776 def_dec_p
->prototyped
= 1;
1779 /* Since we are unprotoizing, if this item is already in old (K&R) style,
1780 we can just ignore it. If that is true, throw away the itme now. */
1782 if (!def_dec_p
->prototyped
)
1784 free_def_dec (def_dec_p
);
1788 #endif /* defined (UNPROTOIZE) */
1790 /* Add this record to the head of the list of records pertaining to this
1791 particular function name. */
1793 def_dec_p
->next_for_func
= def_dec_p
->hash_entry
->ddip
;
1794 def_dec_p
->hash_entry
->ddip
= def_dec_p
;
1796 /* Add this new def_dec_info record to the sorted list of def_dec_info
1797 records for this file. Note that we don't have to worry about duplicates
1798 (caused by multiple inclusions of header files) here because we have
1799 already eliminated duplicates above. */
1801 if (!def_dec_p
->file
->defs_decs
)
1803 def_dec_p
->file
->defs_decs
= def_dec_p
;
1804 def_dec_p
->next_in_file
= NULL
;
1808 int line
= def_dec_p
->line
;
1809 const def_dec_info
*prev
= NULL
;
1810 const def_dec_info
*curr
= def_dec_p
->file
->defs_decs
;
1811 const def_dec_info
*next
= curr
->next_in_file
;
1813 while (next
&& (line
< curr
->line
))
1817 next
= next
->next_in_file
;
1819 if (line
>= curr
->line
)
1821 def_dec_p
->next_in_file
= curr
;
1823 ((NONCONST def_dec_info
*) prev
)->next_in_file
= def_dec_p
;
1825 def_dec_p
->file
->defs_decs
= def_dec_p
;
1827 else /* assert (next == NULL); */
1829 ((NONCONST def_dec_info
*) curr
)->next_in_file
= def_dec_p
;
1830 /* assert (next == NULL); */
1831 def_dec_p
->next_in_file
= next
;
1836 /* Set up the vector COMPILE_PARAMS which is the argument list for running GCC.
1837 Also set input_file_name_index and aux_info_file_name_index
1838 to the indices of the slots where the file names should go. */
1840 /* We initialize the vector by removing -g, -O, -S, -c, and -o options,
1841 and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
1844 munge_compile_params (params_list
)
1845 const char *params_list
;
1847 /* Build up the contents in a temporary vector
1848 that is so big that to has to be big enough. */
1849 const char **temp_params
1850 = (const char **) alloca ((strlen (params_list
) + 8) * sizeof (char *));
1851 int param_count
= 0;
1854 temp_params
[param_count
++] = compiler_file_name
;
1857 while (ISSPACE ((const unsigned char)*params_list
))
1861 param
= params_list
;
1862 while (*params_list
&& !ISSPACE ((const unsigned char)*params_list
))
1864 if (param
[0] != '-')
1865 temp_params
[param_count
++]
1866 = dupnstr (param
, (size_t) (params_list
- param
));
1875 break; /* Don't copy these. */
1877 while (ISSPACE ((const unsigned char)*params_list
))
1880 && !ISSPACE ((const unsigned char)*params_list
))
1884 temp_params
[param_count
++]
1885 = dupnstr (param
, (size_t) (params_list
- param
));
1891 temp_params
[param_count
++] = "-aux-info";
1893 /* Leave room for the aux-info file name argument. */
1894 aux_info_file_name_index
= param_count
;
1895 temp_params
[param_count
++] = NULL
;
1897 temp_params
[param_count
++] = "-S";
1898 temp_params
[param_count
++] = "-o";
1899 temp_params
[param_count
++] = "/dev/null";
1901 /* Leave room for the input file name argument. */
1902 input_file_name_index
= param_count
;
1903 temp_params
[param_count
++] = NULL
;
1904 /* Terminate the list. */
1905 temp_params
[param_count
++] = NULL
;
1907 /* Make a copy of the compile_params in heap space. */
1910 = (const char **) xmalloc (sizeof (char *) * (param_count
+1));
1911 memcpy (compile_params
, temp_params
, sizeof (char *) * param_count
);
1914 /* Do a recompilation for the express purpose of generating a new aux_info
1915 file to go with a specific base source file.
1917 The result is a boolean indicating success. */
1920 gen_aux_info_file (base_filename
)
1921 const char *base_filename
;
1923 if (!input_file_name_index
)
1924 munge_compile_params ("");
1926 /* Store the full source file name in the argument vector. */
1927 compile_params
[input_file_name_index
] = shortpath (NULL
, base_filename
);
1928 /* Add .X to source file name to get aux-info file name. */
1929 compile_params
[aux_info_file_name_index
] =
1930 concat (compile_params
[input_file_name_index
], ".X", NULL
);
1933 notice ("%s: compiling `%s'\n",
1934 pname
, compile_params
[input_file_name_index
]);
1937 char *errmsg_fmt
, *errmsg_arg
;
1938 int wait_status
, pid
;
1940 pid
= pexecute (compile_params
[0], (char * const *) compile_params
,
1941 pname
, NULL
, &errmsg_fmt
, &errmsg_arg
,
1942 PEXECUTE_FIRST
| PEXECUTE_LAST
| PEXECUTE_SEARCH
);
1946 int errno_val
= errno
;
1947 fprintf (stderr
, "%s: ", pname
);
1948 fprintf (stderr
, errmsg_fmt
, errmsg_arg
);
1949 fprintf (stderr
, ": %s\n", xstrerror (errno_val
));
1953 pid
= pwait (pid
, &wait_status
, 0);
1956 notice ("%s: wait: %s\n", pname
, xstrerror (errno
));
1959 if (WIFSIGNALED (wait_status
))
1961 notice ("%s: subprocess got fatal signal %d\n",
1962 pname
, WTERMSIG (wait_status
));
1965 if (WIFEXITED (wait_status
))
1967 if (WEXITSTATUS (wait_status
) != 0)
1969 notice ("%s: %s exited with status %d\n",
1970 pname
, compile_params
[0], WEXITSTATUS (wait_status
));
1979 /* Read in all of the information contained in a single aux_info file.
1980 Save all of the important stuff for later. */
1983 process_aux_info_file (base_source_filename
, keep_it
, is_syscalls
)
1984 const char *base_source_filename
;
1988 size_t base_len
= strlen (base_source_filename
);
1989 char * aux_info_filename
1990 = (char *) alloca (base_len
+ strlen (aux_info_suffix
) + 1);
1991 char *aux_info_base
;
1992 char *aux_info_limit
;
1993 char *aux_info_relocated_name
;
1994 const char *aux_info_second_line
;
1995 time_t aux_info_mtime
;
1996 size_t aux_info_size
;
1999 /* Construct the aux_info filename from the base source filename. */
2001 strcpy (aux_info_filename
, base_source_filename
);
2002 strcat (aux_info_filename
, aux_info_suffix
);
2004 /* Check that the aux_info file exists and is readable. If it does not
2005 exist, try to create it (once only). */
2007 /* If file doesn't exist, set must_create.
2008 Likewise if it exists and we can read it but it is obsolete.
2009 Otherwise, report an error. */
2012 /* Come here with must_create set to 1 if file is out of date. */
2015 if (access (aux_info_filename
, R_OK
) == -1)
2017 if (errno
== ENOENT
)
2021 notice ("%s: warning: missing SYSCALLS file `%s'\n",
2022 pname
, aux_info_filename
);
2029 int errno_val
= errno
;
2030 notice ("%s: can't read aux info file `%s': %s\n",
2031 pname
, shortpath (NULL
, aux_info_filename
),
2032 xstrerror (errno_val
));
2037 #if 0 /* There is code farther down to take care of this. */
2041 stat (aux_info_file_name
, &s1
);
2042 stat (base_source_file_name
, &s2
);
2043 if (s2
.st_mtime
> s1
.st_mtime
)
2048 /* If we need a .X file, create it, and verify we can read it. */
2051 if (!gen_aux_info_file (base_source_filename
))
2056 if (access (aux_info_filename
, R_OK
) == -1)
2058 int errno_val
= errno
;
2059 notice ("%s: can't read aux info file `%s': %s\n",
2060 pname
, shortpath (NULL
, aux_info_filename
),
2061 xstrerror (errno_val
));
2068 struct stat stat_buf
;
2070 /* Get some status information about this aux_info file. */
2072 if (stat (aux_info_filename
, &stat_buf
) == -1)
2074 int errno_val
= errno
;
2075 notice ("%s: can't get status of aux info file `%s': %s\n",
2076 pname
, shortpath (NULL
, aux_info_filename
),
2077 xstrerror (errno_val
));
2082 /* Check on whether or not this aux_info file is zero length. If it is,
2083 then just ignore it and return. */
2085 if ((aux_info_size
= stat_buf
.st_size
) == 0)
2088 /* Get the date/time of last modification for this aux_info file and
2089 remember it. We will have to check that any source files that it
2090 contains information about are at least this old or older. */
2092 aux_info_mtime
= stat_buf
.st_mtime
;
2096 /* Compare mod time with the .c file; update .X file if obsolete.
2097 The code later on can fail to check the .c file
2098 if it did not directly define any functions. */
2100 if (stat (base_source_filename
, &stat_buf
) == -1)
2102 int errno_val
= errno
;
2103 notice ("%s: can't get status of aux info file `%s': %s\n",
2104 pname
, shortpath (NULL
, base_source_filename
),
2105 xstrerror (errno_val
));
2109 if (stat_buf
.st_mtime
> aux_info_mtime
)
2120 /* Open the aux_info file. */
2122 if ((aux_info_file
= open (aux_info_filename
, O_RDONLY
, 0444 )) == -1)
2124 int errno_val
= errno
;
2125 notice ("%s: can't open aux info file `%s' for reading: %s\n",
2126 pname
, shortpath (NULL
, aux_info_filename
),
2127 xstrerror (errno_val
));
2131 /* Allocate space to hold the aux_info file in memory. */
2133 aux_info_base
= xmalloc (aux_info_size
+ 1);
2134 aux_info_limit
= aux_info_base
+ aux_info_size
;
2135 *aux_info_limit
= '\0';
2137 /* Read the aux_info file into memory. */
2139 if (safe_read (aux_info_file
, aux_info_base
, aux_info_size
) !=
2140 (int) aux_info_size
)
2142 int errno_val
= errno
;
2143 notice ("%s: error reading aux info file `%s': %s\n",
2144 pname
, shortpath (NULL
, aux_info_filename
),
2145 xstrerror (errno_val
));
2146 free (aux_info_base
);
2147 close (aux_info_file
);
2151 /* Close the aux info file. */
2153 if (close (aux_info_file
))
2155 int errno_val
= errno
;
2156 notice ("%s: error closing aux info file `%s': %s\n",
2157 pname
, shortpath (NULL
, aux_info_filename
),
2158 xstrerror (errno_val
));
2159 free (aux_info_base
);
2160 close (aux_info_file
);
2165 /* Delete the aux_info file (unless requested not to). If the deletion
2166 fails for some reason, don't even worry about it. */
2168 if (must_create
&& !keep_it
)
2169 if (unlink (aux_info_filename
) == -1)
2171 int errno_val
= errno
;
2172 notice ("%s: can't delete aux info file `%s': %s\n",
2173 pname
, shortpath (NULL
, aux_info_filename
),
2174 xstrerror (errno_val
));
2177 /* Save a pointer into the first line of the aux_info file which
2178 contains the filename of the directory from which the compiler
2179 was invoked when the associated source file was compiled.
2180 This information is used later to help create complete
2181 filenames out of the (potentially) relative filenames in
2182 the aux_info file. */
2185 char *p
= aux_info_base
;
2192 invocation_filename
= p
; /* Save a pointer to first byte of path. */
2197 while (*p
++ != '\n')
2199 aux_info_second_line
= p
;
2200 aux_info_relocated_name
= 0;
2201 if (invocation_filename
[0] != '/')
2203 /* INVOCATION_FILENAME is relative;
2204 append it to BASE_SOURCE_FILENAME's dir. */
2206 aux_info_relocated_name
= xmalloc (base_len
+ (p
-invocation_filename
));
2207 strcpy (aux_info_relocated_name
, base_source_filename
);
2208 dir_end
= strrchr (aux_info_relocated_name
, '/');
2212 dir_end
= aux_info_relocated_name
;
2213 strcpy (dir_end
, invocation_filename
);
2214 invocation_filename
= aux_info_relocated_name
;
2220 const char *aux_info_p
;
2222 /* Do a pre-pass on the lines in the aux_info file, making sure that all
2223 of the source files referenced in there are at least as old as this
2224 aux_info file itself. If not, go back and regenerate the aux_info
2225 file anew. Don't do any of this for the syscalls file. */
2229 current_aux_info_lineno
= 2;
2231 for (aux_info_p
= aux_info_second_line
; *aux_info_p
; )
2233 if (referenced_file_is_newer (aux_info_p
, aux_info_mtime
))
2235 free (aux_info_base
);
2236 free (aux_info_relocated_name
);
2237 if (keep_it
&& unlink (aux_info_filename
) == -1)
2239 int errno_val
= errno
;
2240 notice ("%s: can't delete file `%s': %s\n",
2241 pname
, shortpath (NULL
, aux_info_filename
),
2242 xstrerror (errno_val
));
2249 /* Skip over the rest of this line to start of next line. */
2251 while (*aux_info_p
!= '\n')
2254 current_aux_info_lineno
++;
2258 /* Now do the real pass on the aux_info lines. Save their information in
2259 the in-core data base. */
2261 current_aux_info_lineno
= 2;
2263 for (aux_info_p
= aux_info_second_line
; *aux_info_p
;)
2265 char *unexpanded_line
= unexpand_if_needed (aux_info_p
);
2267 if (unexpanded_line
)
2269 save_def_or_dec (unexpanded_line
, is_syscalls
);
2270 free (unexpanded_line
);
2273 save_def_or_dec (aux_info_p
, is_syscalls
);
2275 /* Skip over the rest of this line and get to start of next line. */
2277 while (*aux_info_p
!= '\n')
2280 current_aux_info_lineno
++;
2284 free (aux_info_base
);
2285 free (aux_info_relocated_name
);
2290 /* Check an individual filename for a .c suffix. If the filename has this
2291 suffix, rename the file such that its suffix is changed to .C. This
2292 function implements the -C option. */
2296 const hash_table_entry
*hp
;
2298 const char *filename
= hp
->symbol
;
2299 int last_char_index
= strlen (filename
) - 1;
2300 char *const new_filename
= (char *) alloca (strlen (filename
) + 1);
2302 /* Note that we don't care here if the given file was converted or not. It
2303 is possible that the given file was *not* converted, simply because there
2304 was nothing in it which actually required conversion. Even in this case,
2305 we want to do the renaming. Note that we only rename files with the .c
2308 if (filename
[last_char_index
] != 'c' || filename
[last_char_index
-1] != '.')
2311 strcpy (new_filename
, filename
);
2312 new_filename
[last_char_index
] = 'C';
2314 if (link (filename
, new_filename
) == -1)
2316 int errno_val
= errno
;
2317 notice ("%s: warning: can't link file `%s' to `%s': %s\n",
2318 pname
, shortpath (NULL
, filename
),
2319 shortpath (NULL
, new_filename
), xstrerror (errno_val
));
2324 if (unlink (filename
) == -1)
2326 int errno_val
= errno
;
2327 notice ("%s: warning: can't delete file `%s': %s\n",
2328 pname
, shortpath (NULL
, filename
), xstrerror (errno_val
));
2334 #endif /* !defined (UNPROTOIZE) */
2336 /* Take the list of definitions and declarations attached to a particular
2337 file_info node and reverse the order of the list. This should get the
2338 list into an order such that the item with the lowest associated line
2339 number is nearest the head of the list. When these lists are originally
2340 built, they are in the opposite order. We want to traverse them in
2341 normal line number order later (i.e. lowest to highest) so reverse the
2345 reverse_def_dec_list (hp
)
2346 const hash_table_entry
*hp
;
2348 file_info
*file_p
= hp
->fip
;
2349 def_dec_info
*prev
= NULL
;
2350 def_dec_info
*current
= (def_dec_info
*)file_p
->defs_decs
;
2353 return; /* no list to reverse */
2356 if (! (current
= (def_dec_info
*)current
->next_in_file
))
2357 return; /* can't reverse a single list element */
2359 prev
->next_in_file
= NULL
;
2363 def_dec_info
*next
= (def_dec_info
*)current
->next_in_file
;
2365 current
->next_in_file
= prev
;
2370 file_p
->defs_decs
= prev
;
2375 /* Find the (only?) extern definition for a particular function name, starting
2376 from the head of the linked list of entries for the given name. If we
2377 cannot find an extern definition for the given function name, issue a
2378 warning and scrounge around for the next best thing, i.e. an extern
2379 function declaration with a prototype attached to it. Note that we only
2380 allow such substitutions for extern declarations and never for static
2381 declarations. That's because the only reason we allow them at all is
2382 to let un-prototyped function declarations for system-supplied library
2383 functions get their prototypes from our own extra SYSCALLS.c.X file which
2384 contains all of the correct prototypes for system functions. */
2386 static const def_dec_info
*
2387 find_extern_def (head
, user
)
2388 const def_dec_info
*head
;
2389 const def_dec_info
*user
;
2391 const def_dec_info
*dd_p
;
2392 const def_dec_info
*extern_def_p
= NULL
;
2393 int conflict_noted
= 0;
2395 /* Don't act too stupid here. Somebody may try to convert an entire system
2396 in one swell fwoop (rather than one program at a time, as should be done)
2397 and in that case, we may find that there are multiple extern definitions
2398 of a given function name in the entire set of source files that we are
2399 converting. If however one of these definitions resides in exactly the
2400 same source file as the reference we are trying to satisfy then in that
2401 case it would be stupid for us to fail to realize that this one definition
2402 *must* be the precise one we are looking for.
2404 To make sure that we don't miss an opportunity to make this "same file"
2405 leap of faith, we do a prescan of the list of records relating to the
2406 given function name, and we look (on this first scan) *only* for a
2407 definition of the function which is in the same file as the reference
2408 we are currently trying to satisfy. */
2410 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2411 if (dd_p
->is_func_def
&& !dd_p
->is_static
&& dd_p
->file
== user
->file
)
2414 /* Now, since we have not found a definition in the same file as the
2415 reference, we scan the list again and consider all possibilities from
2416 all files. Here we may get conflicts with the things listed in the
2417 SYSCALLS.c.X file, but if that happens it only means that the source
2418 code being converted contains its own definition of a function which
2419 could have been supplied by libc.a. In such cases, we should avoid
2420 issuing the normal warning, and defer to the definition given in the
2423 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2424 if (dd_p
->is_func_def
&& !dd_p
->is_static
)
2426 if (!extern_def_p
) /* Previous definition? */
2427 extern_def_p
= dd_p
; /* Remember the first definition found. */
2430 /* Ignore definition just found if it came from SYSCALLS.c.X. */
2432 if (is_syscalls_file (dd_p
->file
))
2435 /* Quietly replace the definition previously found with the one
2436 just found if the previous one was from SYSCALLS.c.X. */
2438 if (is_syscalls_file (extern_def_p
->file
))
2440 extern_def_p
= dd_p
;
2444 /* If we get here, then there is a conflict between two function
2445 declarations for the same function, both of which came from the
2448 if (!conflict_noted
) /* first time we noticed? */
2451 notice ("%s: conflicting extern definitions of '%s'\n",
2452 pname
, head
->hash_entry
->symbol
);
2455 notice ("%s: declarations of '%s' will not be converted\n",
2456 pname
, head
->hash_entry
->symbol
);
2457 notice ("%s: conflict list for '%s' follows:\n",
2458 pname
, head
->hash_entry
->symbol
);
2459 fprintf (stderr
, "%s: %s(%d): %s\n",
2461 shortpath (NULL
, extern_def_p
->file
->hash_entry
->symbol
),
2462 extern_def_p
->line
, extern_def_p
->ansi_decl
);
2466 fprintf (stderr
, "%s: %s(%d): %s\n",
2468 shortpath (NULL
, dd_p
->file
->hash_entry
->symbol
),
2469 dd_p
->line
, dd_p
->ansi_decl
);
2473 /* We want to err on the side of caution, so if we found multiple conflicting
2474 definitions for the same function, treat this as being that same as if we
2475 had found no definitions (i.e. return NULL). */
2482 /* We have no definitions for this function so do the next best thing.
2483 Search for an extern declaration already in prototype form. */
2485 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2486 if (!dd_p
->is_func_def
&& !dd_p
->is_static
&& dd_p
->prototyped
)
2488 extern_def_p
= dd_p
; /* save a pointer to the definition */
2490 notice ("%s: warning: using formals list from %s(%d) for function `%s'\n",
2492 shortpath (NULL
, dd_p
->file
->hash_entry
->symbol
),
2493 dd_p
->line
, dd_p
->hash_entry
->symbol
);
2497 /* Gripe about unprototyped function declarations that we found no
2498 corresponding definition (or other source of prototype information)
2501 Gripe even if the unprototyped declaration we are worried about
2502 exists in a file in one of the "system" include directories. We
2503 can gripe about these because we should have at least found a
2504 corresponding (pseudo) definition in the SYSCALLS.c.X file. If we
2505 didn't, then that means that the SYSCALLS.c.X file is missing some
2506 needed prototypes for this particular system. That is worth telling
2511 const char *file
= user
->file
->hash_entry
->symbol
;
2514 if (in_system_include_dir (file
))
2516 /* Why copy this string into `needed' at all?
2517 Why not just use user->ansi_decl without copying? */
2518 char *needed
= (char *) alloca (strlen (user
->ansi_decl
) + 1);
2521 strcpy (needed
, user
->ansi_decl
);
2522 p
= (NONCONST
char *) substr (needed
, user
->hash_entry
->symbol
)
2523 + strlen (user
->hash_entry
->symbol
) + 2;
2524 /* Avoid having ??? in the string. */
2530 notice ("%s: %d: `%s' used but missing from SYSCALLS\n",
2531 shortpath (NULL
, file
), user
->line
,
2532 needed
+7); /* Don't print "extern " */
2536 notice ("%s: %d: warning: no extern definition for `%s'\n",
2537 shortpath (NULL
, file
), user
->line
,
2538 user
->hash_entry
->symbol
);
2542 return extern_def_p
;
2545 /* Find the (only?) static definition for a particular function name in a
2546 given file. Here we get the function-name and the file info indirectly
2547 from the def_dec_info record pointer which is passed in. */
2549 static const def_dec_info
*
2550 find_static_definition (user
)
2551 const def_dec_info
*user
;
2553 const def_dec_info
*head
= user
->hash_entry
->ddip
;
2554 const def_dec_info
*dd_p
;
2555 int num_static_defs
= 0;
2556 const def_dec_info
*static_def_p
= NULL
;
2558 for (dd_p
= head
; dd_p
; dd_p
= dd_p
->next_for_func
)
2559 if (dd_p
->is_func_def
&& dd_p
->is_static
&& (dd_p
->file
== user
->file
))
2561 static_def_p
= dd_p
; /* save a pointer to the definition */
2564 if (num_static_defs
== 0)
2567 notice ("%s: warning: no static definition for `%s' in file `%s'\n",
2568 pname
, head
->hash_entry
->symbol
,
2569 shortpath (NULL
, user
->file
->hash_entry
->symbol
));
2571 else if (num_static_defs
> 1)
2573 notice ("%s: multiple static defs of `%s' in file `%s'\n",
2574 pname
, head
->hash_entry
->symbol
,
2575 shortpath (NULL
, user
->file
->hash_entry
->symbol
));
2578 return static_def_p
;
2581 /* Find good prototype style formal argument lists for all of the function
2582 declarations which didn't have them before now.
2584 To do this we consider each function name one at a time. For each function
2585 name, we look at the items on the linked list of def_dec_info records for
2586 that particular name.
2588 Somewhere on this list we should find one (and only one) def_dec_info
2589 record which represents the actual function definition, and this record
2590 should have a nice formal argument list already associated with it.
2592 Thus, all we have to do is to connect up all of the other def_dec_info
2593 records for this particular function name to the special one which has
2594 the full-blown formals list.
2596 Of course it is a little more complicated than just that. See below for
2600 connect_defs_and_decs (hp
)
2601 const hash_table_entry
*hp
;
2603 const def_dec_info
*dd_p
;
2604 const def_dec_info
*extern_def_p
= NULL
;
2605 int first_extern_reference
= 1;
2607 /* Traverse the list of definitions and declarations for this particular
2608 function name. For each item on the list, if it is a function
2609 definition (either old style or new style) then GCC has already been
2610 kind enough to produce a prototype for us, and it is associated with
2611 the item already, so declare the item as its own associated "definition".
2613 Also, for each item which is only a function declaration, but which
2614 nonetheless has its own prototype already (obviously supplied by the user)
2615 declare the item as its own definition.
2617 Note that when/if there are multiple user-supplied prototypes already
2618 present for multiple declarations of any given function, these multiple
2619 prototypes *should* all match exactly with one another and with the
2620 prototype for the actual function definition. We don't check for this
2621 here however, since we assume that the compiler must have already done
2622 this consistency checking when it was creating the .X files. */
2624 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2625 if (dd_p
->prototyped
)
2626 ((NONCONST def_dec_info
*) dd_p
)->definition
= dd_p
;
2628 /* Traverse the list of definitions and declarations for this particular
2629 function name. For each item on the list, if it is an extern function
2630 declaration and if it has no associated definition yet, go try to find
2631 the matching extern definition for the declaration.
2633 When looking for the matching function definition, warn the user if we
2636 If we find more that one function definition also issue a warning.
2638 Do the search for the matching definition only once per unique function
2639 name (and only when absolutely needed) so that we can avoid putting out
2640 redundant warning messages, and so that we will only put out warning
2641 messages when there is actually a reference (i.e. a declaration) for
2642 which we need to find a matching definition. */
2644 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2645 if (!dd_p
->is_func_def
&& !dd_p
->is_static
&& !dd_p
->definition
)
2647 if (first_extern_reference
)
2649 extern_def_p
= find_extern_def (hp
->ddip
, dd_p
);
2650 first_extern_reference
= 0;
2652 ((NONCONST def_dec_info
*) dd_p
)->definition
= extern_def_p
;
2655 /* Traverse the list of definitions and declarations for this particular
2656 function name. For each item on the list, if it is a static function
2657 declaration and if it has no associated definition yet, go try to find
2658 the matching static definition for the declaration within the same file.
2660 When looking for the matching function definition, warn the user if we
2661 fail to find one in the same file with the declaration, and refuse to
2662 convert this kind of cross-file static function declaration. After all,
2663 this is stupid practice and should be discouraged.
2665 We don't have to worry about the possibility that there is more than one
2666 matching function definition in the given file because that would have
2667 been flagged as an error by the compiler.
2669 Do the search for the matching definition only once per unique
2670 function-name/source-file pair (and only when absolutely needed) so that
2671 we can avoid putting out redundant warning messages, and so that we will
2672 only put out warning messages when there is actually a reference (i.e. a
2673 declaration) for which we actually need to find a matching definition. */
2675 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2676 if (!dd_p
->is_func_def
&& dd_p
->is_static
&& !dd_p
->definition
)
2678 const def_dec_info
*dd_p2
;
2679 const def_dec_info
*static_def
;
2681 /* We have now found a single static declaration for which we need to
2682 find a matching definition. We want to minimize the work (and the
2683 number of warnings), so we will find an appropriate (matching)
2684 static definition for this declaration, and then distribute it
2685 (as the definition for) any and all other static declarations
2686 for this function name which occur within the same file, and which
2687 do not already have definitions.
2689 Note that a trick is used here to prevent subsequent attempts to
2690 call find_static_definition for a given function-name & file
2691 if the first such call returns NULL. Essentially, we convert
2692 these NULL return values to -1, and put the -1 into the definition
2693 field for each other static declaration from the same file which
2694 does not already have an associated definition.
2695 This makes these other static declarations look like they are
2696 actually defined already when the outer loop here revisits them
2697 later on. Thus, the outer loop will skip over them. Later, we
2698 turn the -1's back to NULL's. */
2700 ((NONCONST def_dec_info
*) dd_p
)->definition
=
2701 (static_def
= find_static_definition (dd_p
))
2703 : (const def_dec_info
*) -1;
2705 for (dd_p2
= dd_p
->next_for_func
; dd_p2
; dd_p2
= dd_p2
->next_for_func
)
2706 if (!dd_p2
->is_func_def
&& dd_p2
->is_static
2707 && !dd_p2
->definition
&& (dd_p2
->file
== dd_p
->file
))
2708 ((NONCONST def_dec_info
*)dd_p2
)->definition
= dd_p
->definition
;
2711 /* Convert any dummy (-1) definitions we created in the step above back to
2712 NULL's (as they should be). */
2714 for (dd_p
= hp
->ddip
; dd_p
; dd_p
= dd_p
->next_for_func
)
2715 if (dd_p
->definition
== (def_dec_info
*) -1)
2716 ((NONCONST def_dec_info
*) dd_p
)->definition
= NULL
;
2719 #endif /* !defined (UNPROTOIZE) */
2721 /* Give a pointer into the clean text buffer, return a number which is the
2722 original source line number that the given pointer points into. */
2725 identify_lineno (clean_p
)
2726 const char *clean_p
;
2731 for (scan_p
= clean_text_base
; scan_p
<= clean_p
; scan_p
++)
2732 if (*scan_p
== '\n')
2737 /* Issue an error message and give up on doing this particular edit. */
2740 declare_source_confusing (clean_p
)
2741 const char *clean_p
;
2746 notice ("%s: %d: warning: source too confusing\n",
2747 shortpath (NULL
, convert_filename
), last_known_line_number
);
2749 notice ("%s: %d: warning: source too confusing\n",
2750 shortpath (NULL
, convert_filename
),
2751 identify_lineno (clean_p
));
2753 longjmp (source_confusion_recovery
, 1);
2756 /* Check that a condition which is expected to be true in the original source
2757 code is in fact true. If not, issue an error message and give up on
2758 converting this particular source file. */
2761 check_source (cond
, clean_p
)
2763 const char *clean_p
;
2766 declare_source_confusing (clean_p
);
2769 /* If we think of the in-core cleaned text buffer as a memory mapped
2770 file (with the variable last_known_line_start acting as sort of a
2771 file pointer) then we can imagine doing "seeks" on the buffer. The
2772 following routine implements a kind of "seek" operation for the in-core
2773 (cleaned) copy of the source file. When finished, it returns a pointer to
2774 the start of a given (numbered) line in the cleaned text buffer.
2776 Note that protoize only has to "seek" in the forward direction on the
2777 in-core cleaned text file buffers, and it never needs to back up.
2779 This routine is made a little bit faster by remembering the line number
2780 (and pointer value) supplied (and returned) from the previous "seek".
2781 This prevents us from always having to start all over back at the top
2782 of the in-core cleaned buffer again. */
2788 if (n
< last_known_line_number
)
2791 while (n
> last_known_line_number
)
2793 while (*last_known_line_start
!= '\n')
2794 check_source (++last_known_line_start
< clean_text_limit
, 0);
2795 last_known_line_start
++;
2796 last_known_line_number
++;
2798 return last_known_line_start
;
2801 /* Given a pointer to a character in the cleaned text buffer, return a pointer
2802 to the next non-whitespace character which follows it. */
2805 forward_to_next_token_char (ptr
)
2808 for (++ptr
; ISSPACE ((const unsigned char)*ptr
);
2809 check_source (++ptr
< clean_text_limit
, 0))
2814 /* Copy a chunk of text of length `len' and starting at `str' to the current
2815 output buffer. Note that all attempts to add stuff to the current output
2816 buffer ultimately go through here. */
2819 output_bytes (str
, len
)
2823 if ((repl_write_ptr
+ 1) + len
>= repl_text_limit
)
2825 size_t new_size
= (repl_text_limit
- repl_text_base
) << 1;
2826 char *new_buf
= (char *) xrealloc (repl_text_base
, new_size
);
2828 repl_write_ptr
= new_buf
+ (repl_write_ptr
- repl_text_base
);
2829 repl_text_base
= new_buf
;
2830 repl_text_limit
= new_buf
+ new_size
;
2832 memcpy (repl_write_ptr
+ 1, str
, len
);
2833 repl_write_ptr
+= len
;
2836 /* Copy all bytes (except the trailing null) of a null terminated string to
2837 the current output buffer. */
2843 output_bytes (str
, strlen (str
));
2846 /* Copy some characters from the original text buffer to the current output
2849 This routine takes a pointer argument `p' which is assumed to be a pointer
2850 into the cleaned text buffer. The bytes which are copied are the `original'
2851 equivalents for the set of bytes between the last value of `clean_read_ptr'
2852 and the argument value `p'.
2854 The set of bytes copied however, comes *not* from the cleaned text buffer,
2855 but rather from the direct counterparts of these bytes within the original
2858 Thus, when this function is called, some bytes from the original text
2859 buffer (which may include original comments and preprocessing directives)
2860 will be copied into the output buffer.
2862 Note that the request implied when this routine is called includes the
2863 byte pointed to by the argument pointer `p'. */
2869 size_t copy_length
= (size_t) (p
- clean_read_ptr
);
2870 const char *copy_start
= orig_text_base
+(clean_read_ptr
-clean_text_base
)+1;
2872 if (copy_length
== 0)
2875 output_bytes (copy_start
, copy_length
);
2879 /* Given a pointer to a def_dec_info record which represents some form of
2880 definition of a function (perhaps a real definition, or in lieu of that
2881 perhaps just a declaration with a full prototype) return true if this
2882 function is one which we should avoid converting. Return false
2886 other_variable_style_function (ansi_header
)
2887 const char *ansi_header
;
2891 /* See if we have a stdarg function, or a function which has stdarg style
2892 parameters or a stdarg style return type. */
2894 return substr (ansi_header
, "...") != 0;
2896 #else /* !defined (UNPROTOIZE) */
2898 /* See if we have a varargs function, or a function which has varargs style
2899 parameters or a varargs style return type. */
2902 int len
= strlen (varargs_style_indicator
);
2904 for (p
= ansi_header
; p
; )
2906 const char *candidate
;
2908 if ((candidate
= substr (p
, varargs_style_indicator
)) == 0)
2911 if (!is_id_char (candidate
[-1]) && !is_id_char (candidate
[len
]))
2917 #endif /* !defined (UNPROTOIZE) */
2920 /* Do the editing operation specifically for a function "declaration". Note
2921 that editing for function "definitions" are handled in a separate routine
2925 edit_fn_declaration (def_dec_p
, clean_text_p
)
2926 const def_dec_info
*def_dec_p
;
2927 const char *volatile clean_text_p
;
2929 const char *start_formals
;
2930 const char *end_formals
;
2931 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
2932 size_t func_name_len
= strlen (function_to_edit
);
2933 const char *end_of_fn_name
;
2937 const f_list_chain_item
*this_f_list_chain_item
;
2938 const def_dec_info
*definition
= def_dec_p
->definition
;
2940 /* If we are protoizing, and if we found no corresponding definition for
2941 this particular function declaration, then just leave this declaration
2942 exactly as it is. */
2947 /* If we are protoizing, and if the corresponding definition that we found
2948 for this particular function declaration defined an old style varargs
2949 function, then we want to issue a warning and just leave this function
2950 declaration unconverted. */
2952 if (other_variable_style_function (definition
->ansi_decl
))
2955 notice ("%s: %d: warning: varargs function declaration not converted\n",
2956 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
2961 #endif /* !defined (UNPROTOIZE) */
2963 /* Setup here to recover from confusing source code detected during this
2964 particular "edit". */
2967 if (setjmp (source_confusion_recovery
))
2969 restore_pointers ();
2970 notice ("%s: declaration of function `%s' not converted\n",
2971 pname
, function_to_edit
);
2975 /* We are editing a function declaration. The line number we did a seek to
2976 contains the comma or semicolon which follows the declaration. Our job
2977 now is to scan backwards looking for the function name. This name *must*
2978 be followed by open paren (ignoring whitespace, of course). We need to
2979 replace everything between that open paren and the corresponding closing
2980 paren. If we are protoizing, we need to insert the prototype-style
2981 formals lists. If we are unprotoizing, we need to just delete everything
2982 between the pairs of opening and closing parens. */
2984 /* First move up to the end of the line. */
2986 while (*clean_text_p
!= '\n')
2987 check_source (++clean_text_p
< clean_text_limit
, 0);
2988 clean_text_p
--; /* Point to just before the newline character. */
2990 /* Now we can scan backwards for the function name. */
2996 /* Scan leftwards until we find some character which can be
2997 part of an identifier. */
2999 while (!is_id_char (*clean_text_p
))
3000 check_source (--clean_text_p
> clean_read_ptr
, 0);
3002 /* Scan backwards until we find a char that cannot be part of an
3005 while (is_id_char (*clean_text_p
))
3006 check_source (--clean_text_p
> clean_read_ptr
, 0);
3008 /* Having found an "id break", see if the following id is the one
3009 that we are looking for. If so, then exit from this loop. */
3011 if (!strncmp (clean_text_p
+1, function_to_edit
, func_name_len
))
3013 char ch
= *(clean_text_p
+ 1 + func_name_len
);
3015 /* Must also check to see that the name in the source text
3016 ends where it should (in order to prevent bogus matches
3017 on similar but longer identifiers. */
3019 if (! is_id_char (ch
))
3020 break; /* exit from loop */
3024 /* We have now found the first perfect match for the function name in
3025 our backward search. This may or may not be the actual function
3026 name at the start of the actual function declaration (i.e. we could
3027 have easily been mislead). We will try to avoid getting fooled too
3028 often by looking forward for the open paren which should follow the
3029 identifier we just found. We ignore whitespace while hunting. If
3030 the next non-whitespace byte we see is *not* an open left paren,
3031 then we must assume that we have been fooled and we start over
3032 again accordingly. Note that there is no guarantee, that even if
3033 we do see the open paren, that we are in the right place.
3034 Programmers do the strangest things sometimes! */
3036 end_of_fn_name
= clean_text_p
+ strlen (def_dec_p
->hash_entry
->symbol
);
3037 start_formals
= forward_to_next_token_char (end_of_fn_name
);
3039 while (*start_formals
!= '(');
3041 /* start_of_formals now points to the opening left paren which immediately
3042 follows the name of the function. */
3044 /* Note that there may be several formals lists which need to be modified
3045 due to the possibility that the return type of this function is a
3046 pointer-to-function type. If there are several formals lists, we
3047 convert them in left-to-right order here. */
3050 this_f_list_chain_item
= definition
->f_list_chain
;
3051 #endif /* !defined (UNPROTOIZE) */
3058 end_formals
= start_formals
+ 1;
3060 for (; depth
; check_source (++end_formals
< clean_text_limit
, 0))
3062 switch (*end_formals
)
3075 /* end_formals now points to the closing right paren of the formals
3076 list whose left paren is pointed to by start_formals. */
3078 /* Now, if we are protoizing, we insert the new ANSI-style formals list
3079 attached to the associated definition of this function. If however
3080 we are unprotoizing, then we simply delete any formals list which
3083 output_up_to (start_formals
);
3085 if (this_f_list_chain_item
)
3087 output_string (this_f_list_chain_item
->formals_list
);
3088 this_f_list_chain_item
= this_f_list_chain_item
->chain_next
;
3093 notice ("%s: warning: too many parameter lists in declaration of `%s'\n",
3094 pname
, def_dec_p
->hash_entry
->symbol
);
3095 check_source (0, end_formals
); /* leave the declaration intact */
3097 #endif /* !defined (UNPROTOIZE) */
3098 clean_read_ptr
= end_formals
- 1;
3100 /* Now see if it looks like there may be another formals list associated
3101 with the function declaration that we are converting (following the
3102 formals list that we just converted. */
3105 const char *another_r_paren
= forward_to_next_token_char (end_formals
);
3107 if ((*another_r_paren
!= ')')
3108 || (*(start_formals
= forward_to_next_token_char (another_r_paren
)) != '('))
3111 if (this_f_list_chain_item
)
3114 notice ("\n%s: warning: too few parameter lists in declaration of `%s'\n",
3115 pname
, def_dec_p
->hash_entry
->symbol
);
3116 check_source (0, start_formals
); /* leave the decl intact */
3118 #endif /* !defined (UNPROTOIZE) */
3124 /* There does appear to be yet another formals list, so loop around
3125 again, and convert it also. */
3129 /* Edit a whole group of formals lists, starting with the rightmost one
3130 from some set of formals lists. This routine is called once (from the
3131 outside) for each function declaration which is converted. It is
3132 recursive however, and it calls itself once for each remaining formal
3133 list that lies to the left of the one it was originally called to work
3134 on. Thus, a whole set gets done in right-to-left order.
3136 This routine returns non-zero if it thinks that it should not be trying
3137 to convert this particular function definition (because the name of the
3138 function doesn't match the one expected). */
3141 edit_formals_lists (end_formals
, f_list_count
, def_dec_p
)
3142 const char *end_formals
;
3143 unsigned int f_list_count
;
3144 const def_dec_info
*def_dec_p
;
3146 const char *start_formals
;
3149 start_formals
= end_formals
- 1;
3151 for (; depth
; check_source (--start_formals
> clean_read_ptr
, 0))
3153 switch (*start_formals
)
3165 /* start_formals now points to the opening left paren of the formals list. */
3171 const char *next_end
;
3173 /* There should be more formal lists to the left of here. */
3175 next_end
= start_formals
- 1;
3176 check_source (next_end
> clean_read_ptr
, 0);
3177 while (ISSPACE ((const unsigned char)*next_end
))
3178 check_source (--next_end
> clean_read_ptr
, 0);
3179 check_source (*next_end
== ')', next_end
);
3180 check_source (--next_end
> clean_read_ptr
, 0);
3181 check_source (*next_end
== ')', next_end
);
3182 if (edit_formals_lists (next_end
, f_list_count
, def_dec_p
))
3186 /* Check that the function name in the header we are working on is the same
3187 as the one we would expect to find. If not, issue a warning and return
3190 if (f_list_count
== 0)
3192 const char *expected
= def_dec_p
->hash_entry
->symbol
;
3193 const char *func_name_start
;
3194 const char *func_name_limit
;
3195 size_t func_name_len
;
3197 for (func_name_limit
= start_formals
-1;
3198 ISSPACE ((const unsigned char)*func_name_limit
); )
3199 check_source (--func_name_limit
> clean_read_ptr
, 0);
3201 for (func_name_start
= func_name_limit
++;
3202 is_id_char (*func_name_start
);
3204 check_source (func_name_start
> clean_read_ptr
, 0);
3206 func_name_len
= func_name_limit
- func_name_start
;
3207 if (func_name_len
== 0)
3208 check_source (0, func_name_start
);
3209 if (func_name_len
!= strlen (expected
)
3210 || strncmp (func_name_start
, expected
, func_name_len
))
3212 notice ("%s: %d: warning: found `%s' but expected `%s'\n",
3213 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
3214 identify_lineno (func_name_start
),
3215 dupnstr (func_name_start
, func_name_len
),
3221 output_up_to (start_formals
);
3224 if (f_list_count
== 0)
3225 output_string (def_dec_p
->formal_names
);
3226 #else /* !defined (UNPROTOIZE) */
3228 unsigned f_list_depth
;
3229 const f_list_chain_item
*flci_p
= def_dec_p
->f_list_chain
;
3231 /* At this point, the current value of f_list count says how many
3232 links we have to follow through the f_list_chain to get to the
3233 particular formals list that we need to output next. */
3235 for (f_list_depth
= 0; f_list_depth
< f_list_count
; f_list_depth
++)
3236 flci_p
= flci_p
->chain_next
;
3237 output_string (flci_p
->formals_list
);
3239 #endif /* !defined (UNPROTOIZE) */
3241 clean_read_ptr
= end_formals
- 1;
3245 /* Given a pointer to a byte in the clean text buffer which points to
3246 the beginning of a line that contains a "follower" token for a
3247 function definition header, do whatever is necessary to find the
3248 right closing paren for the rightmost formals list of the function
3249 definition header. */
3252 find_rightmost_formals_list (clean_text_p
)
3253 const char *clean_text_p
;
3255 const char *end_formals
;
3257 /* We are editing a function definition. The line number we did a seek
3258 to contains the first token which immediately follows the entire set of
3259 formals lists which are part of this particular function definition
3262 Our job now is to scan leftwards in the clean text looking for the
3263 right-paren which is at the end of the function header's rightmost
3266 If we ignore whitespace, this right paren should be the first one we
3267 see which is (ignoring whitespace) immediately followed either by the
3268 open curly-brace beginning the function body or by an alphabetic
3269 character (in the case where the function definition is in old (K&R)
3270 style and there are some declarations of formal parameters). */
3272 /* It is possible that the right paren we are looking for is on the
3273 current line (together with its following token). Just in case that
3274 might be true, we start out here by skipping down to the right end of
3275 the current line before starting our scan. */
3277 for (end_formals
= clean_text_p
; *end_formals
!= '\n'; end_formals
++)
3283 /* Now scan backwards while looking for the right end of the rightmost
3284 formals list associated with this function definition. */
3288 const char *l_brace_p
;
3290 /* Look leftward and try to find a right-paren. */
3292 while (*end_formals
!= ')')
3294 if (ISSPACE ((unsigned char)*end_formals
))
3295 while (ISSPACE ((unsigned char)*end_formals
))
3296 check_source (--end_formals
> clean_read_ptr
, 0);
3298 check_source (--end_formals
> clean_read_ptr
, 0);
3301 ch
= *(l_brace_p
= forward_to_next_token_char (end_formals
));
3302 /* Since we are unprotoizing an ANSI-style (prototyped) function
3303 definition, there had better not be anything (except whitespace)
3304 between the end of the ANSI formals list and the beginning of the
3305 function body (i.e. the '{'). */
3307 check_source (ch
== '{', l_brace_p
);
3310 #else /* !defined (UNPROTOIZE) */
3312 /* Now scan backwards while looking for the right end of the rightmost
3313 formals list associated with this function definition. */
3318 const char *l_brace_p
;
3320 /* Look leftward and try to find a right-paren. */
3322 while (*end_formals
!= ')')
3324 if (ISSPACE ((const unsigned char)*end_formals
))
3325 while (ISSPACE ((const unsigned char)*end_formals
))
3326 check_source (--end_formals
> clean_read_ptr
, 0);
3328 check_source (--end_formals
> clean_read_ptr
, 0);
3331 ch
= *(l_brace_p
= forward_to_next_token_char (end_formals
));
3333 /* Since it is possible that we found a right paren before the starting
3334 '{' of the body which IS NOT the one at the end of the real K&R
3335 formals list (say for instance, we found one embedded inside one of
3336 the old K&R formal parameter declarations) we have to check to be
3337 sure that this is in fact the right paren that we were looking for.
3339 The one we were looking for *must* be followed by either a '{' or
3340 by an alphabetic character, while others *cannot* validly be followed
3341 by such characters. */
3343 if ((ch
== '{') || ISALPHA ((unsigned char)ch
))
3346 /* At this point, we have found a right paren, but we know that it is
3347 not the one we were looking for, so backup one character and keep
3350 check_source (--end_formals
> clean_read_ptr
, 0);
3353 #endif /* !defined (UNPROTOIZE) */
3360 /* Insert into the output file a totally new declaration for a function
3361 which (up until now) was being called from within the current block
3362 without having been declared at any point such that the declaration
3363 was visible (i.e. in scope) at the point of the call.
3365 We need to add in explicit declarations for all such function calls
3366 in order to get the full benefit of prototype-based function call
3367 parameter type checking. */
3370 add_local_decl (def_dec_p
, clean_text_p
)
3371 const def_dec_info
*def_dec_p
;
3372 const char *clean_text_p
;
3374 const char *start_of_block
;
3375 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
3377 /* Don't insert new local explicit declarations unless explicitly requested
3383 /* Setup here to recover from confusing source code detected during this
3384 particular "edit". */
3387 if (setjmp (source_confusion_recovery
))
3389 restore_pointers ();
3390 notice ("%s: local declaration for function `%s' not inserted\n",
3391 pname
, function_to_edit
);
3395 /* We have already done a seek to the start of the line which should
3396 contain *the* open curly brace which begins the block in which we need
3397 to insert an explicit function declaration (to replace the implicit one).
3399 Now we scan that line, starting from the left, until we find the
3400 open curly brace we are looking for. Note that there may actually be
3401 multiple open curly braces on the given line, but we will be happy
3402 with the leftmost one no matter what. */
3404 start_of_block
= clean_text_p
;
3405 while (*start_of_block
!= '{' && *start_of_block
!= '\n')
3406 check_source (++start_of_block
< clean_text_limit
, 0);
3408 /* Note that the line from the original source could possibly
3409 contain *no* open curly braces! This happens if the line contains
3410 a macro call which expands into a chunk of text which includes a
3411 block (and that block's associated open and close curly braces).
3412 In cases like this, we give up, issue a warning, and do nothing. */
3414 if (*start_of_block
!= '{')
3417 notice ("\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
3418 def_dec_p
->file
->hash_entry
->symbol
, def_dec_p
->line
,
3419 def_dec_p
->hash_entry
->symbol
);
3423 /* Figure out what a nice (pretty) indentation would be for the new
3424 declaration we are adding. In order to do this, we must scan forward
3425 from the '{' until we find the first line which starts with some
3426 non-whitespace characters (i.e. real "token" material). */
3429 const char *ep
= forward_to_next_token_char (start_of_block
) - 1;
3432 /* Now we have ep pointing at the rightmost byte of some existing indent
3433 stuff. At least that is the hope.
3435 We can now just scan backwards and find the left end of the existing
3436 indentation string, and then copy it to the output buffer. */
3438 for (sp
= ep
; ISSPACE ((const unsigned char)*sp
) && *sp
!= '\n'; sp
--)
3441 /* Now write out the open { which began this block, and any following
3442 trash up to and including the last byte of the existing indent that
3447 /* Now we go ahead and insert the new declaration at this point.
3449 If the definition of the given function is in the same file that we
3450 are currently editing, and if its full ANSI declaration normally
3451 would start with the keyword `extern', suppress the `extern'. */
3454 const char *decl
= def_dec_p
->definition
->ansi_decl
;
3456 if ((*decl
== 'e') && (def_dec_p
->file
== def_dec_p
->definition
->file
))
3458 output_string (decl
);
3461 /* Finally, write out a new indent string, just like the preceding one
3462 that we found. This will typically include a newline as the first
3463 character of the indent string. */
3465 output_bytes (sp
, (size_t) (ep
- sp
) + 1);
3469 /* Given a pointer to a file_info record, and a pointer to the beginning
3470 of a line (in the clean text buffer) which is assumed to contain the
3471 first "follower" token for the first function definition header in the
3472 given file, find a good place to insert some new global function
3473 declarations (which will replace scattered and imprecise implicit ones)
3474 and then insert the new explicit declaration at that point in the file. */
3477 add_global_decls (file_p
, clean_text_p
)
3478 const file_info
*file_p
;
3479 const char *clean_text_p
;
3481 const def_dec_info
*dd_p
;
3484 /* Setup here to recover from confusing source code detected during this
3485 particular "edit". */
3488 if (setjmp (source_confusion_recovery
))
3490 restore_pointers ();
3491 notice ("%s: global declarations for file `%s' not inserted\n",
3492 pname
, shortpath (NULL
, file_p
->hash_entry
->symbol
));
3496 /* Start by finding a good location for adding the new explicit function
3497 declarations. To do this, we scan backwards, ignoring whitespace
3498 and comments and other junk until we find either a semicolon, or until
3499 we hit the beginning of the file. */
3501 scan_p
= find_rightmost_formals_list (clean_text_p
);
3504 if (scan_p
< clean_text_base
)
3506 check_source (scan_p
> clean_read_ptr
, 0);
3511 /* scan_p now points either to a semicolon, or to just before the start
3512 of the whole file. */
3514 /* Now scan forward for the first non-whitespace character. In theory,
3515 this should be the first character of the following function definition
3516 header. We will put in the added declarations just prior to that. */
3519 while (ISSPACE ((const unsigned char)*scan_p
))
3523 output_up_to (scan_p
);
3525 /* Now write out full prototypes for all of the things that had been
3526 implicitly declared in this file (but only those for which we were
3527 actually able to find unique matching definitions). Avoid duplicates
3528 by marking things that we write out as we go. */
3531 int some_decls_added
= 0;
3533 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
3534 if (dd_p
->is_implicit
&& dd_p
->definition
&& !dd_p
->definition
->written
)
3536 const char *decl
= dd_p
->definition
->ansi_decl
;
3538 /* If the function for which we are inserting a declaration is
3539 actually defined later in the same file, then suppress the
3540 leading `extern' keyword (if there is one). */
3542 if (*decl
== 'e' && (dd_p
->file
== dd_p
->definition
->file
))
3545 output_string ("\n");
3546 output_string (decl
);
3547 some_decls_added
= 1;
3548 ((NONCONST def_dec_info
*) dd_p
->definition
)->written
= 1;
3550 if (some_decls_added
)
3551 output_string ("\n\n");
3554 /* Unmark all of the definitions that we just marked. */
3556 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
3557 if (dd_p
->definition
)
3558 ((NONCONST def_dec_info
*) dd_p
->definition
)->written
= 0;
3561 #endif /* !defined (UNPROTOIZE) */
3563 /* Do the editing operation specifically for a function "definition". Note
3564 that editing operations for function "declarations" are handled by a
3565 separate routine above. */
3568 edit_fn_definition (def_dec_p
, clean_text_p
)
3569 const def_dec_info
*def_dec_p
;
3570 const char *clean_text_p
;
3572 const char *end_formals
;
3573 const char *function_to_edit
= def_dec_p
->hash_entry
->symbol
;
3575 /* Setup here to recover from confusing source code detected during this
3576 particular "edit". */
3579 if (setjmp (source_confusion_recovery
))
3581 restore_pointers ();
3582 notice ("%s: definition of function `%s' not converted\n",
3583 pname
, function_to_edit
);
3587 end_formals
= find_rightmost_formals_list (clean_text_p
);
3589 /* end_of_formals now points to the closing right paren of the rightmost
3590 formals list which is actually part of the `header' of the function
3591 definition that we are converting. */
3593 /* If the header of this function definition looks like it declares a
3594 function with a variable number of arguments, and if the way it does
3595 that is different from that way we would like it (i.e. varargs vs.
3596 stdarg) then issue a warning and leave the header unconverted. */
3598 if (other_variable_style_function (def_dec_p
->ansi_decl
))
3601 notice ("%s: %d: warning: definition of %s not converted\n",
3602 shortpath (NULL
, def_dec_p
->file
->hash_entry
->symbol
),
3603 identify_lineno (end_formals
),
3605 output_up_to (end_formals
);
3609 if (edit_formals_lists (end_formals
, def_dec_p
->f_list_count
, def_dec_p
))
3611 restore_pointers ();
3612 notice ("%s: definition of function `%s' not converted\n",
3613 pname
, function_to_edit
);
3617 /* Have to output the last right paren because this never gets flushed by
3618 edit_formals_list. */
3620 output_up_to (end_formals
);
3625 const char *semicolon_p
;
3626 const char *limit_p
;
3628 int had_newlines
= 0;
3630 /* Now write out the K&R style formal declarations, one per line. */
3632 decl_p
= def_dec_p
->formal_decls
;
3633 limit_p
= decl_p
+ strlen (decl_p
);
3634 for (;decl_p
< limit_p
; decl_p
= semicolon_p
+ 2)
3636 for (semicolon_p
= decl_p
; *semicolon_p
!= ';'; semicolon_p
++)
3638 output_string ("\n");
3639 output_string (indent_string
);
3640 output_bytes (decl_p
, (size_t) ((semicolon_p
+ 1) - decl_p
));
3643 /* If there are no newlines between the end of the formals list and the
3644 start of the body, we should insert one now. */
3646 for (scan_p
= end_formals
+1; *scan_p
!= '{'; )
3648 if (*scan_p
== '\n')
3653 check_source (++scan_p
< clean_text_limit
, 0);
3656 output_string ("\n");
3658 #else /* !defined (UNPROTOIZE) */
3659 /* If we are protoizing, there may be some flotsam & jetsam (like comments
3660 and preprocessing directives) after the old formals list but before
3661 the following { and we would like to preserve that stuff while effectively
3662 deleting the existing K&R formal parameter declarations. We do so here
3663 in a rather tricky way. Basically, we white out any stuff *except*
3664 the comments/pp-directives in the original text buffer, then, if there
3665 is anything in this area *other* than whitespace, we output it. */
3667 const char *end_formals_orig
;
3668 const char *start_body
;
3669 const char *start_body_orig
;
3671 const char *scan_orig
;
3672 int have_flotsam
= 0;
3673 int have_newlines
= 0;
3675 for (start_body
= end_formals
+ 1; *start_body
!= '{';)
3676 check_source (++start_body
< clean_text_limit
, 0);
3678 end_formals_orig
= orig_text_base
+ (end_formals
- clean_text_base
);
3679 start_body_orig
= orig_text_base
+ (start_body
- clean_text_base
);
3680 scan
= end_formals
+ 1;
3681 scan_orig
= end_formals_orig
+ 1;
3682 for (; scan
< start_body
; scan
++, scan_orig
++)
3684 if (*scan
== *scan_orig
)
3686 have_newlines
|= (*scan_orig
== '\n');
3687 /* Leave identical whitespace alone. */
3688 if (!ISSPACE ((const unsigned char)*scan_orig
))
3689 *((NONCONST
char *)scan_orig
) = ' '; /* identical - so whiteout */
3695 output_bytes (end_formals_orig
+ 1,
3696 (size_t) (start_body_orig
- end_formals_orig
) - 1);
3699 output_string ("\n");
3701 output_string (" ");
3702 clean_read_ptr
= start_body
- 1;
3704 #endif /* !defined (UNPROTOIZE) */
3707 /* Clean up the clean text buffer. Do this by converting comments and
3708 preprocessing directives into spaces. Also convert line continuations
3709 into whitespace. Also, whiteout string and character literals. */
3712 do_cleaning (new_clean_text_base
, new_clean_text_limit
)
3713 char *new_clean_text_base
;
3714 const char *new_clean_text_limit
;
3717 int non_whitespace_since_newline
= 0;
3719 for (scan_p
= new_clean_text_base
; scan_p
< new_clean_text_limit
; scan_p
++)
3723 case '/': /* Handle comments. */
3724 if (scan_p
[1] != '*')
3726 non_whitespace_since_newline
= 1;
3730 while (scan_p
[1] != '/' || scan_p
[0] != '*')
3732 if (!ISSPACE ((const unsigned char)*scan_p
))
3734 if (++scan_p
>= new_clean_text_limit
)
3741 case '#': /* Handle pp directives. */
3742 if (non_whitespace_since_newline
)
3745 while (scan_p
[1] != '\n' || scan_p
[0] == '\\')
3747 if (!ISSPACE ((const unsigned char)*scan_p
))
3749 if (++scan_p
>= new_clean_text_limit
)
3755 case '\'': /* Handle character literals. */
3756 non_whitespace_since_newline
= 1;
3757 while (scan_p
[1] != '\'' || scan_p
[0] == '\\')
3759 if (scan_p
[0] == '\\'
3760 && !ISSPACE ((const unsigned char)scan_p
[1]))
3762 if (!ISSPACE ((const unsigned char)*scan_p
))
3764 if (++scan_p
>= new_clean_text_limit
)
3770 case '"': /* Handle string literals. */
3771 non_whitespace_since_newline
= 1;
3772 while (scan_p
[1] != '"' || scan_p
[0] == '\\')
3774 if (scan_p
[0] == '\\'
3775 && !ISSPACE ((const unsigned char)scan_p
[1]))
3777 if (!ISSPACE ((const unsigned char)*scan_p
))
3779 if (++scan_p
>= new_clean_text_limit
)
3782 if (!ISSPACE ((const unsigned char)*scan_p
))
3787 case '\\': /* Handle line continuations. */
3788 if (scan_p
[1] != '\n')
3794 non_whitespace_since_newline
= 0; /* Reset. */
3803 break; /* Whitespace characters. */
3807 non_whitespace_since_newline
= 1;
3813 /* Given a pointer to the closing right parenthesis for a particular formals
3814 list (in the clean text buffer) find the corresponding left parenthesis
3815 and return a pointer to it. */
3818 careful_find_l_paren (p
)
3824 for (paren_depth
= 1, q
= p
-1; paren_depth
; check_source (--q
>= clean_text_base
, 0))
3839 /* Scan the clean text buffer for cases of function definitions that we
3840 don't really know about because they were preprocessed out when the
3841 aux info files were created.
3843 In this version of protoize/unprotoize we just give a warning for each
3844 one found. A later version may be able to at least unprotoize such
3847 Note that we may easily find all function definitions simply by
3848 looking for places where there is a left paren which is (ignoring
3849 whitespace) immediately followed by either a left-brace or by an
3850 upper or lower case letter. Whenever we find this combination, we
3851 have also found a function definition header.
3853 Finding function *declarations* using syntactic clues is much harder.
3854 I will probably try to do this in a later version though. */
3857 scan_for_missed_items (file_p
)
3858 const file_info
*file_p
;
3860 static const char *scan_p
;
3861 const char *limit
= clean_text_limit
- 3;
3862 static const char *backup_limit
;
3864 backup_limit
= clean_text_base
- 1;
3866 for (scan_p
= clean_text_base
; scan_p
< limit
; scan_p
++)
3870 static const char *last_r_paren
;
3871 const char *ahead_p
;
3873 last_r_paren
= scan_p
;
3875 for (ahead_p
= scan_p
+ 1; ISSPACE ((const unsigned char)*ahead_p
); )
3876 check_source (++ahead_p
< limit
, limit
);
3878 scan_p
= ahead_p
- 1;
3880 if (ISALPHA ((const unsigned char)*ahead_p
) || *ahead_p
== '{')
3882 const char *last_l_paren
;
3883 const int lineno
= identify_lineno (ahead_p
);
3885 if (setjmp (source_confusion_recovery
))
3888 /* We know we have a function definition header. Now skip
3889 leftwards over all of its associated formals lists. */
3893 last_l_paren
= careful_find_l_paren (last_r_paren
);
3894 for (last_r_paren
= last_l_paren
-1;
3895 ISSPACE ((const unsigned char)*last_r_paren
); )
3896 check_source (--last_r_paren
>= backup_limit
, backup_limit
);
3898 while (*last_r_paren
== ')');
3900 if (is_id_char (*last_r_paren
))
3902 const char *id_limit
= last_r_paren
+ 1;
3903 const char *id_start
;
3905 const def_dec_info
*dd_p
;
3907 for (id_start
= id_limit
-1; is_id_char (*id_start
); )
3908 check_source (--id_start
>= backup_limit
, backup_limit
);
3910 backup_limit
= id_start
;
3911 if ((id_length
= (size_t) (id_limit
- id_start
)) == 0)
3915 char *func_name
= (char *) alloca (id_length
+ 1);
3916 static const char * const stmt_keywords
[]
3917 = { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
3918 const char * const *stmt_keyword
;
3920 strncpy (func_name
, id_start
, id_length
);
3921 func_name
[id_length
] = '\0';
3923 /* We must check here to see if we are actually looking at
3924 a statement rather than an actual function call. */
3926 for (stmt_keyword
= stmt_keywords
; *stmt_keyword
; stmt_keyword
++)
3927 if (!strcmp (func_name
, *stmt_keyword
))
3931 notice ("%s: found definition of `%s' at %s(%d)\n",
3934 shortpath (NULL
, file_p
->hash_entry
->symbol
),
3935 identify_lineno (id_start
));
3937 /* We really should check for a match of the function name
3938 here also, but why bother. */
3940 for (dd_p
= file_p
->defs_decs
; dd_p
; dd_p
= dd_p
->next_in_file
)
3941 if (dd_p
->is_func_def
&& dd_p
->line
== lineno
)
3944 /* If we make it here, then we did not know about this
3945 function definition. */
3947 notice ("%s: %d: warning: `%s' excluded by preprocessing\n",
3948 shortpath (NULL
, file_p
->hash_entry
->symbol
),
3949 identify_lineno (id_start
), func_name
);
3950 notice ("%s: function definition not converted\n",
3960 /* Do all editing operations for a single source file (either a "base" file
3961 or an "include" file). To do this we read the file into memory, keep a
3962 virgin copy there, make another cleaned in-core copy of the original file
3963 (i.e. one in which all of the comments and preprocessing directives have
3964 been replaced with whitespace), then use these two in-core copies of the
3965 file to make a new edited in-core copy of the file. Finally, rename the
3966 original file (as a way of saving it), and then write the edited version
3967 of the file from core to a disk file of the same name as the original.
3969 Note that the trick of making a copy of the original sans comments &
3970 preprocessing directives make the editing a whole lot easier. */
3974 const hash_table_entry
*hp
;
3976 struct stat stat_buf
;
3977 const file_info
*file_p
= hp
->fip
;
3978 char *new_orig_text_base
;
3979 char *new_orig_text_limit
;
3980 char *new_clean_text_base
;
3981 char *new_clean_text_limit
;
3984 int first_definition_in_file
;
3986 /* If we are not supposed to be converting this file, or if there is
3987 nothing in there which needs converting, just skip this file. */
3989 if (!needs_to_be_converted (file_p
))
3992 convert_filename
= file_p
->hash_entry
->symbol
;
3994 /* Convert a file if it is in a directory where we want conversion
3995 and the file is not excluded. */
3997 if (!directory_specified_p (convert_filename
)
3998 || file_excluded_p (convert_filename
))
4002 /* Don't even mention "system" include files unless we are
4003 protoizing. If we are protoizing, we mention these as a
4004 gentle way of prodding the user to convert his "system"
4005 include files to prototype format. */
4006 && !in_system_include_dir (convert_filename
)
4007 #endif /* defined (UNPROTOIZE) */
4009 notice ("%s: `%s' not converted\n",
4010 pname
, shortpath (NULL
, convert_filename
));
4014 /* Let the user know what we are up to. */
4017 notice ("%s: would convert file `%s'\n",
4018 pname
, shortpath (NULL
, convert_filename
));
4020 notice ("%s: converting file `%s'\n",
4021 pname
, shortpath (NULL
, convert_filename
));
4024 /* Find out the size (in bytes) of the original file. */
4026 /* The cast avoids an erroneous warning on AIX. */
4027 if (stat (convert_filename
, &stat_buf
) == -1)
4029 int errno_val
= errno
;
4030 notice ("%s: can't get status for file `%s': %s\n",
4031 pname
, shortpath (NULL
, convert_filename
),
4032 xstrerror (errno_val
));
4035 orig_size
= stat_buf
.st_size
;
4037 /* Allocate a buffer to hold the original text. */
4039 orig_text_base
= new_orig_text_base
= (char *) xmalloc (orig_size
+ 2);
4040 orig_text_limit
= new_orig_text_limit
= new_orig_text_base
+ orig_size
;
4042 /* Allocate a buffer to hold the cleaned-up version of the original text. */
4044 clean_text_base
= new_clean_text_base
= (char *) xmalloc (orig_size
+ 2);
4045 clean_text_limit
= new_clean_text_limit
= new_clean_text_base
+ orig_size
;
4046 clean_read_ptr
= clean_text_base
- 1;
4048 /* Allocate a buffer that will hopefully be large enough to hold the entire
4049 converted output text. As an initial guess for the maximum size of the
4050 output buffer, use 125% of the size of the original + some extra. This
4051 buffer can be expanded later as needed. */
4053 repl_size
= orig_size
+ (orig_size
>> 2) + 4096;
4054 repl_text_base
= (char *) xmalloc (repl_size
+ 2);
4055 repl_text_limit
= repl_text_base
+ repl_size
- 1;
4056 repl_write_ptr
= repl_text_base
- 1;
4061 /* Open the file to be converted in READ ONLY mode. */
4063 if ((input_file
= open (convert_filename
, O_RDONLY
, 0444)) == -1)
4065 int errno_val
= errno
;
4066 notice ("%s: can't open file `%s' for reading: %s\n",
4067 pname
, shortpath (NULL
, convert_filename
),
4068 xstrerror (errno_val
));
4072 /* Read the entire original source text file into the original text buffer
4073 in one swell fwoop. Then figure out where the end of the text is and
4074 make sure that it ends with a newline followed by a null. */
4076 if (safe_read (input_file
, new_orig_text_base
, orig_size
) !=
4079 int errno_val
= errno
;
4081 notice ("\n%s: error reading input file `%s': %s\n",
4082 pname
, shortpath (NULL
, convert_filename
),
4083 xstrerror (errno_val
));
4090 if (orig_size
== 0 || orig_text_limit
[-1] != '\n')
4092 *new_orig_text_limit
++ = '\n';
4096 /* Create the cleaned up copy of the original text. */
4098 memcpy (new_clean_text_base
, orig_text_base
,
4099 (size_t) (orig_text_limit
- orig_text_base
));
4100 do_cleaning (new_clean_text_base
, new_clean_text_limit
);
4105 size_t clean_size
= orig_text_limit
- orig_text_base
;
4106 char *const clean_filename
= (char *) alloca (strlen (convert_filename
) + 6 + 1);
4108 /* Open (and create) the clean file. */
4110 strcpy (clean_filename
, convert_filename
);
4111 strcat (clean_filename
, ".clean");
4112 if ((clean_file
= creat (clean_filename
, 0666)) == -1)
4114 int errno_val
= errno
;
4115 notice ("%s: can't create/open clean file `%s': %s\n",
4116 pname
, shortpath (NULL
, clean_filename
),
4117 xstrerror (errno_val
));
4121 /* Write the clean file. */
4123 safe_write (clean_file
, new_clean_text_base
, clean_size
, clean_filename
);
4129 /* Do a simplified scan of the input looking for things that were not
4130 mentioned in the aux info files because of the fact that they were
4131 in a region of the source which was preprocessed-out (via #if or
4134 scan_for_missed_items (file_p
);
4136 /* Setup to do line-oriented forward seeking in the clean text buffer. */
4138 last_known_line_number
= 1;
4139 last_known_line_start
= clean_text_base
;
4141 /* Now get down to business and make all of the necessary edits. */
4144 const def_dec_info
*def_dec_p
;
4146 first_definition_in_file
= 1;
4147 def_dec_p
= file_p
->defs_decs
;
4148 for (; def_dec_p
; def_dec_p
= def_dec_p
->next_in_file
)
4150 const char *clean_text_p
= seek_to_line (def_dec_p
->line
);
4152 /* clean_text_p now points to the first character of the line which
4153 contains the `terminator' for the declaration or definition that
4154 we are about to process. */
4158 if (global_flag
&& def_dec_p
->is_func_def
&& first_definition_in_file
)
4160 add_global_decls (def_dec_p
->file
, clean_text_p
);
4161 first_definition_in_file
= 0;
4164 /* Don't edit this item if it is already in prototype format or if it
4165 is a function declaration and we have found no corresponding
4168 if (def_dec_p
->prototyped
4169 || (!def_dec_p
->is_func_def
&& !def_dec_p
->definition
))
4172 #endif /* !defined (UNPROTOIZE) */
4174 if (def_dec_p
->is_func_def
)
4175 edit_fn_definition (def_dec_p
, clean_text_p
);
4178 if (def_dec_p
->is_implicit
)
4179 add_local_decl (def_dec_p
, clean_text_p
);
4181 #endif /* !defined (UNPROTOIZE) */
4182 edit_fn_declaration (def_dec_p
, clean_text_p
);
4186 /* Finalize things. Output the last trailing part of the original text. */
4188 output_up_to (clean_text_limit
- 1);
4190 /* If this is just a test run, stop now and just deallocate the buffers. */
4194 free (new_orig_text_base
);
4195 free (new_clean_text_base
);
4196 free (repl_text_base
);
4200 /* Change the name of the original input file. This is just a quick way of
4201 saving the original file. */
4206 = (char *) xmalloc (strlen (convert_filename
) + strlen (save_suffix
) + 2);
4208 strcpy (new_filename
, convert_filename
);
4209 strcat (new_filename
, save_suffix
);
4210 if (link (convert_filename
, new_filename
) == -1)
4212 int errno_val
= errno
;
4213 if (errno_val
== EEXIST
)
4216 notice ("%s: warning: file `%s' already saved in `%s'\n",
4218 shortpath (NULL
, convert_filename
),
4219 shortpath (NULL
, new_filename
));
4223 notice ("%s: can't link file `%s' to `%s': %s\n",
4225 shortpath (NULL
, convert_filename
),
4226 shortpath (NULL
, new_filename
),
4227 xstrerror (errno_val
));
4233 if (unlink (convert_filename
) == -1)
4235 int errno_val
= errno
;
4236 notice ("%s: can't delete file `%s': %s\n",
4237 pname
, shortpath (NULL
, convert_filename
),
4238 xstrerror (errno_val
));
4245 /* Open (and create) the output file. */
4247 if ((output_file
= creat (convert_filename
, 0666)) == -1)
4249 int errno_val
= errno
;
4250 notice ("%s: can't create/open output file `%s': %s\n",
4251 pname
, shortpath (NULL
, convert_filename
),
4252 xstrerror (errno_val
));
4256 /* Write the output file. */
4259 unsigned int out_size
= (repl_write_ptr
+ 1) - repl_text_base
;
4261 safe_write (output_file
, repl_text_base
, out_size
, convert_filename
);
4264 close (output_file
);
4267 /* Deallocate the conversion buffers. */
4269 free (new_orig_text_base
);
4270 free (new_clean_text_base
);
4271 free (repl_text_base
);
4273 /* Change the mode of the output file to match the original file. */
4275 /* The cast avoids an erroneous warning on AIX. */
4276 if (chmod (convert_filename
, stat_buf
.st_mode
) == -1)
4278 int errno_val
= errno
;
4279 notice ("%s: can't change mode of file `%s': %s\n",
4280 pname
, shortpath (NULL
, convert_filename
),
4281 xstrerror (errno_val
));
4284 /* Note: We would try to change the owner and group of the output file
4285 to match those of the input file here, except that may not be a good
4286 thing to do because it might be misleading. Also, it might not even
4287 be possible to do that (on BSD systems with quotas for instance). */
4290 /* Do all of the individual steps needed to do the protoization (or
4291 unprotoization) of the files referenced in the aux_info files given
4292 in the command line. */
4297 const char * const *base_pp
;
4298 const char * const * const end_pps
4299 = &base_source_filenames
[n_base_source_files
];
4303 #endif /* !defined (UNPROTOIZE) */
4305 /* One-by-one, check (and create if necessary), open, and read all of the
4306 stuff in each aux_info file. After reading each aux_info file, the
4307 aux_info_file just read will be automatically deleted unless the
4308 keep_flag is set. */
4310 for (base_pp
= base_source_filenames
; base_pp
< end_pps
; base_pp
++)
4311 process_aux_info_file (*base_pp
, keep_flag
, 0);
4315 /* Also open and read the special SYSCALLS.c aux_info file which gives us
4316 the prototypes for all of the standard system-supplied functions. */
4318 if (nondefault_syscalls_dir
)
4320 syscalls_absolute_filename
4321 = (char *) xmalloc (strlen (nondefault_syscalls_dir
) + 1
4322 + sizeof (syscalls_filename
));
4323 strcpy (syscalls_absolute_filename
, nondefault_syscalls_dir
);
4327 GET_ENV_PATH_LIST (default_syscalls_dir
, "GCC_EXEC_PREFIX");
4328 if (!default_syscalls_dir
)
4330 default_syscalls_dir
= standard_exec_prefix
;
4332 syscalls_absolute_filename
4333 = (char *) xmalloc (strlen (default_syscalls_dir
) + 0
4334 + strlen (target_machine
) + 1
4335 + strlen (target_version
) + 1
4336 + sizeof (syscalls_filename
));
4337 strcpy (syscalls_absolute_filename
, default_syscalls_dir
);
4338 strcat (syscalls_absolute_filename
, target_machine
);
4339 strcat (syscalls_absolute_filename
, "/");
4340 strcat (syscalls_absolute_filename
, target_version
);
4341 strcat (syscalls_absolute_filename
, "/");
4344 syscalls_len
= strlen (syscalls_absolute_filename
);
4345 if (*(syscalls_absolute_filename
+ syscalls_len
- 1) != '/')
4347 *(syscalls_absolute_filename
+ syscalls_len
++) = '/';
4348 *(syscalls_absolute_filename
+ syscalls_len
) = '\0';
4350 strcat (syscalls_absolute_filename
, syscalls_filename
);
4352 /* Call process_aux_info_file in such a way that it does not try to
4353 delete the SYSCALLS aux_info file. */
4355 process_aux_info_file (syscalls_absolute_filename
, 1, 1);
4357 #endif /* !defined (UNPROTOIZE) */
4359 /* When we first read in all of the information from the aux_info files
4360 we saved in it descending line number order, because that was likely to
4361 be faster. Now however, we want the chains of def & dec records to
4362 appear in ascending line number order as we get further away from the
4363 file_info record that they hang from. The following line causes all of
4364 these lists to be rearranged into ascending line number order. */
4366 visit_each_hash_node (filename_primary
, reverse_def_dec_list
);
4370 /* Now do the "real" work. The following line causes each declaration record
4371 to be "visited". For each of these nodes, an attempt is made to match
4372 up the function declaration with a corresponding function definition,
4373 which should have a full prototype-format formals list with it. Once
4374 these match-ups are made, the conversion of the function declarations
4375 to prototype format can be made. */
4377 visit_each_hash_node (function_name_primary
, connect_defs_and_decs
);
4379 #endif /* !defined (UNPROTOIZE) */
4381 /* Now convert each file that can be converted (and needs to be). */
4383 visit_each_hash_node (filename_primary
, edit_file
);
4387 /* If we are working in cplusplus mode, try to rename all .c files to .C
4388 files. Don't panic if some of the renames don't work. */
4390 if (cplusplus_flag
&& !nochange_flag
)
4391 visit_each_hash_node (filename_primary
, rename_c_file
);
4393 #endif /* !defined (UNPROTOIZE) */
4396 static struct option longopts
[] =
4398 {"version", 0, 0, 'V'},
4399 {"file_name", 0, 0, 'p'},
4400 {"quiet", 0, 0, 'q'},
4401 {"silent", 0, 0, 'q'},
4402 {"force", 0, 0, 'f'},
4403 {"keep", 0, 0, 'k'},
4404 {"nosave", 0, 0, 'N'},
4405 {"nochange", 0, 0, 'n'},
4406 {"compiler-options", 1, 0, 'c'},
4407 {"exclude", 1, 0, 'x'},
4408 {"directory", 1, 0, 'd'},
4410 {"indent", 1, 0, 'i'},
4412 {"local", 0, 0, 'l'},
4413 {"global", 0, 0, 'g'},
4415 {"syscalls-dir", 1, 0, 'B'},
4420 extern int main
PARAMS ((int, char **const));
4429 const char *params
= "";
4431 pname
= strrchr (argv
[0], '/');
4432 pname
= pname
? pname
+1 : argv
[0];
4434 #ifdef HAVE_LC_MESSAGES
4435 setlocale (LC_MESSAGES
, "");
4437 (void) bindtextdomain (PACKAGE
, localedir
);
4438 (void) textdomain (PACKAGE
);
4440 cwd_buffer
= getpwd ();
4443 notice ("%s: cannot get working directory: %s\n",
4444 pname
, xstrerror(errno
));
4445 return (FATAL_EXIT_CODE
);
4448 /* By default, convert the files in the current directory. */
4449 directory_list
= string_list_cons (cwd_buffer
, NULL
);
4451 while ((c
= getopt_long (argc
, argv
,
4455 "B:c:Cd:gklnNp:qvVx:",
4457 longopts
, &longind
)) != EOF
)
4459 if (c
== 0) /* Long option. */
4460 c
= longopts
[longind
].val
;
4464 compiler_file_name
= optarg
;
4468 = string_list_cons (abspath (NULL
, optarg
), directory_list
);
4471 exclude_list
= string_list_cons (optarg
, exclude_list
);
4501 indent_string
= optarg
;
4503 #else /* !defined (UNPROTOIZE) */
4514 nondefault_syscalls_dir
= optarg
;
4516 #endif /* !defined (UNPROTOIZE) */
4522 /* Set up compile_params based on -p and -c options. */
4523 munge_compile_params (params
);
4525 n_base_source_files
= argc
- optind
;
4527 /* Now actually make a list of the base source filenames. */
4529 base_source_filenames
4530 = (const char **) xmalloc ((n_base_source_files
+ 1) * sizeof (char *));
4531 n_base_source_files
= 0;
4532 for (; optind
< argc
; optind
++)
4534 const char *path
= abspath (NULL
, argv
[optind
]);
4535 int len
= strlen (path
);
4537 if (path
[len
-1] == 'c' && path
[len
-2] == '.')
4538 base_source_filenames
[n_base_source_files
++] = path
;
4541 notice ("%s: input file names must have .c suffixes: %s\n",
4542 pname
, shortpath (NULL
, path
));
4548 /* We are only interested in the very first identifier token in the
4549 definition of `va_list', so if there is more junk after that first
4550 identifier token, delete it from the `varargs_style_indicator'. */
4554 for (cp
= varargs_style_indicator
;
4555 ISALNUM ((const unsigned char)*cp
) || *cp
== '_'; cp
++)
4558 varargs_style_indicator
= savestring (varargs_style_indicator
,
4559 cp
- varargs_style_indicator
);
4561 #endif /* !defined (UNPROTOIZE) */
4568 fprintf (stderr
, "%s: %s\n", pname
, version_string
);
4572 return (errors
? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);