1 /* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
2 Copyright (C) 1989, 92-97, 1998 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. */
21 /* Any reasonable C++ compiler should have all of the same features
22 as __STDC__ plus more, so make sure that __STDC__ is defined if
23 __cplusplus is defined. */
25 #if defined(__cplusplus) && !defined(__STDC__)
27 #endif /* defined(__cplusplus) && !defined(__STDC__) */
29 #if defined(__GNUC__) || defined (__GNUG__)
30 #define VOLATILE volatile
43 /* Users are not supposed to use _POSIX_SOURCE to say the
44 system is a POSIX system. That is not what _POSIX_SOURCE means! -- rms */
45 /* If the user asked for POSIX via _POSIX_SOURCE, turn on POSIX code. */
46 #if defined(_POSIX_SOURCE) && !defined(POSIX)
51 #ifdef POSIX /* We should be able to define _POSIX_SOURCE unconditionally,
52 but some systems respond in buggy ways to it,
53 including SunOS 4.1.1. Which we don't classify as POSIX. */
54 /* In case this is a POSIX system with an ANSI C compiler,
55 ask for definition of all POSIX facilities. */
62 #if ! defined (_WIN32) || defined (__CYGWIN32__)
63 #if defined(POSIX) || defined(CONCURRENT)
70 #include "gansidecl.h"
72 /* Some systems like Linux don't declare rindex if _POSIX_SOURCE is declared,
73 but it normally does declare it. This means that configure thinks we don't
74 need to declare it. Favor using strrchr if it is available. */
79 #define strrchr rindex
84 /* Include getopt.h for the sake of getopt_long.
85 We don't need the declaration of getopt, and it could conflict
86 with something from a system header file, so effectively nullify that. */
87 #define getopt getopt_loser
91 extern char *version_string;
93 /* Systems which are compatible only with POSIX 1003.1-1988 (but *not*
94 with POSIX 1003.1-1990), e.g. Ultrix 4.2, might not have
95 const qualifiers in the prototypes in the system include files.
96 Unfortunately, this can lead to GCC issuing lots of warnings for
97 calls to the following functions. To eliminate these warnings we
98 provide the following #defines. */
100 #define my_access(file,flag) access((char *)file, flag)
101 #define my_stat(file,pkt) stat((char *)file, pkt)
103 #define my_link(file1, file2) -1
105 #define my_link(file1, file2) link((char *)file1, (char *)file2)
107 #define my_unlink(file) unlink((char *)file)
108 #define my_open(file, mode, flag) open((char *)file, mode, flag)
109 #define my_chmod(file, mode) chmod((char *)file, mode)
111 extern char *getpwd ();
113 extern char *choose_temp_base PROTO ((void));
114 extern char * my_strerror PROTO ((int));
116 extern int pexecute PROTO ((const char *, char * const *, const char *,
117 const char *, char **, char **, int));
118 extern int pwait PROTO ((int, int *, int));
119 /* Flag arguments to pexecute. */
120 #define PEXECUTE_FIRST 1
121 #define PEXECUTE_LAST 2
122 #define PEXECUTE_SEARCH 4
124 static void usage PROTO ((void)) ATTRIBUTE_NORETURN;
125 static void aux_info_corrupted PROTO ((void)) ATTRIBUTE_NORETURN;
126 static void declare_source_confusing PROTO ((const char *)) ATTRIBUTE_NORETURN;
128 /* Aliases for pointers to void.
129 These were made to facilitate compilation with old brain-dead DEC C
130 compilers which didn't properly grok `void*' types. */
133 typedef void * pointer_type;
134 typedef const void * const_pointer_type;
136 typedef char * pointer_type;
137 typedef char * const_pointer_type;
143 #include <sys/wait.h>
145 #else /* !defined(POSIX) */
148 #define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
151 #define WTERMSIG(S) ((S) & 0x7f)
154 #define WIFEXITED(S) (((S) & 0xff) == 0)
157 #define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
160 /* Declaring stat or __flsbuf with a prototype
161 causes conflicts with system headers on some systems. */
163 #if 0 /* These conflict with stdio.h on some systems. */
165 extern int fprintf (FILE *, const char *, ...);
166 extern int printf (const char *, ...);
167 extern int open (const char *, int, ...);
172 extern int fflush ();
177 extern int unlink ();
178 extern int access ();
180 #if 0 /* size_t from sys/types.h may fail to match GCC.
181 If so, we would get a warning from this. */
182 extern size_t strlen ()
185 #endif /* !defined (POSIX) */
187 /* Look for these where the `const' qualifier is intentionally cast aside. */
191 /* Define a default place to find the SYSCALLS.X file. */
193 #ifndef STD_PROTO_DIR
194 #define STD_PROTO_DIR "/usr/local/lib"
195 #endif /* !defined (STD_PROTO_DIR) */
197 /* Suffix of aux_info files. */
199 static const char * const aux_info_suffix = ".X";
201 /* String to attach to filenames for saved versions of original files. */
203 static const char * const save_suffix = ".save";
207 /* File name of the file which contains descriptions of standard system
208 routines. Note that we never actually do anything with this file per se,
209 but we do read in its corresponding aux_info file. */
211 static const char syscalls_filename[] = "SYSCALLS.c";
213 /* Default place to find the above file. */
215 static const char * const default_syscalls_dir = STD_PROTO_DIR;
217 /* Variable to hold the complete absolutized filename of the SYSCALLS.c.X
220 static char * syscalls_absolute_filename;
222 #endif /* !defined (UNPROTOIZE) */
224 /* Type of the structure that holds information about macro unexpansions. */
226 struct unexpansion_struct {
227 const char *expanded;
228 const char *contracted;
230 typedef struct unexpansion_struct unexpansion;
232 /* A table of conversions that may need to be made for some (stupid) older
233 operating systems where these types are preprocessor macros rather than
234 typedefs (as they really ought to be).
236 WARNING: The contracted forms must be as small (or smaller) as the
237 expanded forms, or else havoc will ensue. */
239 static const unexpansion unexpansions[] = {
240 { "struct _iobuf", "FILE" },
244 /* The number of "primary" slots in the hash tables for filenames and for
245 function names. This can be as big or as small as you like, except that
246 it must be a power of two. */
248 #define HASH_TABLE_SIZE (1 << 9)
250 /* Bit mask to use when computing hash values. */
252 static const int hash_mask = (HASH_TABLE_SIZE - 1);
254 /* Make a table of default system include directories
255 just as it is done in cccp.c. */
257 #ifndef STANDARD_INCLUDE_DIR
258 #define STANDARD_INCLUDE_DIR "/usr/include"
261 #ifndef LOCAL_INCLUDE_DIR
262 #define LOCAL_INCLUDE_DIR "/usr/local/include"
265 struct default_include { const char *fname;
266 const char *component;
267 int x1, x2; } include_defaults[]
268 #ifdef INCLUDE_DEFAULTS
272 /* Pick up GNU C++ specific include files. */
273 { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
275 /* This is the dir for fixincludes. Put it just before
276 the files that we fix. */
277 { GCC_INCLUDE_DIR, "GCC", 0, 0 },
278 /* For cross-compilation, this dir name is generated
279 automatically in Makefile.in. */
280 { CROSS_INCLUDE_DIR, 0, 0, 0 },
281 /* This is another place that the target system's headers might be. */
282 { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
283 #else /* not CROSS_COMPILE */
284 /* This should be /use/local/include and should come before
285 the fixincludes-fixed header files. */
286 { LOCAL_INCLUDE_DIR, 0, 0, 1 },
287 /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
288 Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
289 { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 },
290 /* This is the dir for fixincludes. Put it just before
291 the files that we fix. */
292 { GCC_INCLUDE_DIR, "GCC", 0, 0 },
293 /* Some systems have an extra dir of include files. */
294 #ifdef SYSTEM_INCLUDE_DIR
295 { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
297 { STANDARD_INCLUDE_DIR, 0, 0, 0},
298 #endif /* not CROSS_COMPILE */
301 #endif /* no INCLUDE_DEFAULTS */
303 /* Datatype for lists of directories or filenames. */
307 struct string_list *next;
310 /* List of directories in which files should be converted. */
312 struct string_list *directory_list;
314 /* List of file names which should not be converted.
315 A file is excluded if the end of its name, following a /,
316 matches one of the names in this list. */
318 struct string_list *exclude_list;
320 /* The name of the other style of variable-number-of-parameters functions
321 (i.e. the style that we want to leave unconverted because we don't yet
322 know how to convert them to this style. This string is used in warning
325 /* Also define here the string that we can search for in the parameter lists
326 taken from the .X files which will unambiguously indicate that we have
327 found a varargs style function. */
330 static const char * const other_var_style = "stdarg";
331 #else /* !defined (UNPROTOIZE) */
332 static const char * const other_var_style = "varargs";
333 /* Note that this is a string containing the expansion of va_alist.
334 But in `main' we discard all but the first token. */
335 static const char *varargs_style_indicator = STRINGIFY (va_alist);
336 #endif /* !defined (UNPROTOIZE) */
338 /* The following two types are used to create hash tables. In this program,
339 there are two hash tables which are used to store and quickly lookup two
340 different classes of strings. The first type of strings stored in the
341 first hash table are absolute filenames of files which protoize needs to
342 know about. The second type of strings (stored in the second hash table)
343 are function names. It is this second class of strings which really
344 inspired the use of the hash tables, because there may be a lot of them. */
346 typedef struct hash_table_entry_struct hash_table_entry;
348 /* Do some typedefs so that we don't have to write "struct" so often. */
350 typedef struct def_dec_info_struct def_dec_info;
351 typedef struct file_info_struct file_info;
352 typedef struct f_list_chain_item_struct f_list_chain_item;
354 /* In the struct below, note that the "_info" field has two different uses
355 depending on the type of hash table we are in (i.e. either the filenames
356 hash table or the function names hash table). In the filenames hash table
357 the info fields of the entries point to the file_info struct which is
358 associated with each filename (1 per filename). In the function names
359 hash table, the info field points to the head of a singly linked list of
360 def_dec_info entries which are all defs or decs of the function whose
361 name is pointed to by the "symbol" field. Keeping all of the defs/decs
362 for a given function name on a special list specifically for that function
363 name makes it quick and easy to find out all of the important information
364 about a given (named) function. */
366 struct hash_table_entry_struct {
367 hash_table_entry * hash_next; /* -> to secondary entries */
368 const char * symbol; /* -> to the hashed string */
370 const def_dec_info * _ddip;
374 #define ddip _info._ddip
375 #define fip _info._fip
377 /* Define a type specifically for our two hash tables. */
379 typedef hash_table_entry hash_table[HASH_TABLE_SIZE];
381 /* The following struct holds all of the important information about any
382 single filename (e.g. file) which we need to know about. */
384 struct file_info_struct {
385 const hash_table_entry * hash_entry; /* -> to associated hash entry */
386 const def_dec_info * defs_decs; /* -> to chain of defs/decs */
387 time_t mtime; /* Time of last modification. */
390 /* Due to the possibility that functions may return pointers to functions,
391 (which may themselves have their own parameter lists) and due to the
392 fact that returned pointers-to-functions may be of type "pointer-to-
393 function-returning-pointer-to-function" (ad nauseum) we have to keep
394 an entire chain of ANSI style formal parameter lists for each function.
396 Normally, for any given function, there will only be one formals list
397 on the chain, but you never know.
399 Note that the head of each chain of formals lists is pointed to by the
400 `f_list_chain' field of the corresponding def_dec_info record.
402 For any given chain, the item at the head of the chain is the *leftmost*
403 parameter list seen in the actual C language function declaration. If
404 there are other members of the chain, then these are linked in left-to-right
405 order from the head of the chain. */
407 struct f_list_chain_item_struct {
408 const f_list_chain_item * chain_next; /* -> to next item on chain */
409 const char * formals_list; /* -> to formals list string */
412 /* The following struct holds all of the important information about any
413 single function definition or declaration which we need to know about.
414 Note that for unprotoize we don't need to know very much because we
415 never even create records for stuff that we don't intend to convert
416 (like for instance defs and decs which are already in old K&R format
417 and "implicit" function declarations). */
419 struct def_dec_info_struct {
420 const def_dec_info * next_in_file; /* -> to rest of chain for file */
421 file_info * file; /* -> file_info for containing file */
422 int line; /* source line number of def/dec */
423 const char * ansi_decl; /* -> left end of ansi decl */
424 hash_table_entry * hash_entry; /* -> hash entry for function name */
425 unsigned int is_func_def; /* = 0 means this is a declaration */
426 const def_dec_info * next_for_func; /* -> to rest of chain for func name */
427 unsigned int f_list_count; /* count of formals lists we expect */
428 char prototyped; /* = 0 means already prototyped */
430 const f_list_chain_item * f_list_chain; /* -> chain of formals lists */
431 const def_dec_info * definition; /* -> def/dec containing related def */
432 char is_static; /* = 0 means visibility is "extern" */
433 char is_implicit; /* != 0 for implicit func decl's */
434 char written; /* != 0 means written for implicit */
435 #else /* !defined (UNPROTOIZE) */
436 const char * formal_names; /* -> to list of names of formals */
437 const char * formal_decls; /* -> to string of formal declarations */
438 #endif /* !defined (UNPROTOIZE) */
441 /* Pointer to the tail component of the filename by which this program was
442 invoked. Used everywhere in error and warning messages. */
444 static const char *pname;
446 /* Error counter. Will be non-zero if we should give up at the next convenient
449 static int errors = 0;
452 /* ??? These comments should say what the flag mean as well as the options
455 /* File name to use for running gcc. Allows GCC 2 to be named
456 something other than gcc. */
457 static const char *compiler_file_name = "gcc";
459 static int version_flag = 0; /* Print our version number. */
460 static int quiet_flag = 0; /* Don't print messages normally. */
461 static int nochange_flag = 0; /* Don't convert, just say what files
462 we would have converted. */
463 static int nosave_flag = 0; /* Don't save the old version. */
464 static int keep_flag = 0; /* Don't delete the .X files. */
465 static const char ** compile_params = 0; /* Option string for gcc. */
467 static const char *indent_string = " "; /* Indentation for newly
468 inserted parm decls. */
469 #else /* !defined (UNPROTOIZE) */
470 static int local_flag = 0; /* Insert new local decls (when?). */
471 static int global_flag = 0; /* set by -g option */
472 static int cplusplus_flag = 0; /* Rename converted files to *.C. */
473 static const char *nondefault_syscalls_dir = 0; /* Dir to look for
475 #endif /* !defined (UNPROTOIZE) */
477 /* An index into the compile_params array where we should insert the source
478 file name when we are ready to exec the C compiler. A zero value indicates
479 that we have not yet called munge_compile_params. */
481 static int input_file_name_index = 0;
483 /* An index into the compile_params array where we should insert the filename
484 for the aux info file, when we run the C compiler. */
485 static int aux_info_file_name_index = 0;
487 /* Count of command line arguments which were "filename" arguments. */
489 static int n_base_source_files = 0;
491 /* Points to a malloc'ed list of pointers to all of the filenames of base
492 source files which were specified on the command line. */
494 static const char **base_source_filenames;
496 /* Line number of the line within the current aux_info file that we
497 are currently processing. Used for error messages in case the prototypes
498 info file is corrupted somehow. */
500 static int current_aux_info_lineno;
502 /* Pointer to the name of the source file currently being converted. */
504 static const char *convert_filename;
506 /* Pointer to relative root string (taken from aux_info file) which indicates
507 where directory the user was in when he did the compilation step that
508 produced the containing aux_info file. */
510 static const char *invocation_filename;
512 /* Pointer to the base of the input buffer that holds the original text for the
513 source file currently being converted. */
515 static const char *orig_text_base;
517 /* Pointer to the byte just beyond the end of the input buffer that holds the
518 original text for the source file currently being converted. */
520 static const char *orig_text_limit;
522 /* Pointer to the base of the input buffer that holds the cleaned text for the
523 source file currently being converted. */
525 static const char *clean_text_base;
527 /* Pointer to the byte just beyond the end of the input buffer that holds the
528 cleaned text for the source file currently being converted. */
530 static const char *clean_text_limit;
532 /* Pointer to the last byte in the cleaned text buffer that we have already
533 (virtually) copied to the output buffer (or decided to ignore). */
535 static const char * clean_read_ptr;
537 /* Pointer to the base of the output buffer that holds the replacement text
538 for the source file currently being converted. */
540 static char *repl_text_base;
542 /* Pointer to the byte just beyond the end of the output buffer that holds the
543 replacement text for the source file currently being converted. */
545 static char *repl_text_limit;
547 /* Pointer to the last byte which has been stored into the output buffer.
548 The next byte to be stored should be stored just past where this points
551 static char * repl_write_ptr;
553 /* Pointer into the cleaned text buffer for the source file we are currently
554 converting. This points to the first character of the line that we last
555 did a "seek_to_line" to (see below). */
557 static const char *last_known_line_start;
559 /* Number of the line (in the cleaned text buffer) that we last did a
560 "seek_to_line" to. Will be one if we just read a new source file
561 into the cleaned text buffer. */
563 static int last_known_line_number;
565 /* The filenames hash table. */
567 static hash_table filename_primary;
569 /* The function names hash table. */
571 static hash_table function_name_primary;
573 /* The place to keep the recovery address which is used only in cases where
574 we get hopelessly confused by something in the cleaned original text. */
576 static jmp_buf source_confusion_recovery;
578 /* A pointer to the current directory filename (used by abspath). */
580 static char *cwd_buffer;
582 /* A place to save the read pointer until we are sure that an individual
583 attempt at editing will succeed. */
585 static const char * saved_clean_read_ptr;
587 /* A place to save the write pointer until we are sure that an individual
588 attempt at editing will succeed. */
590 static char * saved_repl_write_ptr;
592 /* Forward declaration. */
594 static const char *shortpath ();
606 static char buffer[30];
610 if (e > 0 && e < sys_nerr)
611 return sys_errlist[e];
613 sprintf (buffer, "Unknown error %d", e);
618 /* Allocate some space, but check that the allocation was successful. */
619 /* alloca.c uses this, so don't make it static. */
627 rv = (pointer_type) malloc (byte_count);
630 fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
631 exit (FATAL_EXIT_CODE);
632 return 0; /* avoid warnings */
638 /* Reallocate some space, but check that the reallocation was successful. */
641 xrealloc (old_space, byte_count)
642 pointer_type old_space;
647 rv = (pointer_type) realloc (old_space, byte_count);
650 fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
651 exit (FATAL_EXIT_CODE);
652 return 0; /* avoid warnings */
658 /* Deallocate the area pointed to by an arbitrary pointer, but first, strip
659 the `const' qualifier from it and also make sure that the pointer value
664 const_pointer_type p;
667 free ((NONCONST pointer_type) p);
670 /* Make a copy of a string INPUT with size SIZE. */
673 savestring (input, size)
677 char *output = (char *) xmalloc (size + 1);
678 strcpy (output, input);
682 /* Make a copy of the concatenation of INPUT1 and INPUT2. */
685 savestring2 (input1, size1, input2, size2)
691 char *output = (char *) xmalloc (size1 + size2 + 1);
692 strcpy (output, input1);
693 strcpy (&output[size1], input2);
697 /* More 'friendly' abort that prints the line and file.
698 config.h can #define abort fancy_abort if you like that sort of thing. */
703 fprintf (stderr, "%s: internal abort\n", pname);
704 exit (FATAL_EXIT_CODE);
707 /* Make a duplicate of the first N bytes of a given string in a newly
715 char *ret_val = (char *) xmalloc (n + 1);
717 strncpy (ret_val, s, n);
722 /* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
723 does not occur within s1. Assume neither s1 nor s2 are null pointers. */
728 const char *const s2;
736 for (p1 = s1, p2 = s2; (c = *p2); p1++, p2++)
746 /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
747 retrying if necessary. Return the actual number of bytes read. */
750 safe_read (desc, ptr, len)
757 int nchars = read (desc, ptr, left);
774 /* Write LEN bytes at PTR to descriptor DESC,
775 retrying if necessary, and treating any real error as fatal. */
778 safe_write (desc, ptr, len, out_fname)
785 int written = write (desc, ptr, len);
788 int errno_val = errno;
790 if (errno_val == EINTR)
793 fprintf (stderr, "%s: error writing file `%s': %s\n",
794 pname, shortpath (NULL, out_fname), my_strerror (errno_val));
802 /* Get setup to recover in case the edit we are about to do goes awry. */
807 saved_clean_read_ptr = clean_read_ptr;
808 saved_repl_write_ptr = repl_write_ptr;
811 /* Call this routine to recover our previous state whenever something looks
812 too confusing in the source code we are trying to edit. */
817 clean_read_ptr = saved_clean_read_ptr;
818 repl_write_ptr = saved_repl_write_ptr;
821 /* Return true if the given character is a valid identifier character. */
827 return (ISALNUM (ch) || (ch == '_') || (ch == '$'));
830 /* Give a message indicating the proper way to invoke this program and then
831 exit with non-zero status. */
837 fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
839 #else /* !defined (UNPROTOIZE) */
840 fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
842 #endif /* !defined (UNPROTOIZE) */
843 exit (FATAL_EXIT_CODE);
846 /* Return true if the given filename (assumed to be an absolute filename)
847 designates a file residing anywhere beneath any one of the "system"
848 include directories. */
851 in_system_include_dir (path)
854 struct default_include *p;
857 abort (); /* Must be an absolutized filename. */
859 for (p = include_defaults; p->fname; p++)
860 if (!strncmp (path, p->fname, strlen (p->fname))
861 && path[strlen (p->fname)] == '/')
867 /* Return true if the given filename designates a file that the user has
868 read access to and for which the user has write access to the containing
872 file_could_be_converted (const char *path)
874 char *const dir_name = (char *) alloca (strlen (path) + 1);
876 if (my_access (path, R_OK))
880 char *dir_last_slash;
882 strcpy (dir_name, path);
883 dir_last_slash = strrchr (dir_name, '/');
885 *dir_last_slash = '\0';
887 abort (); /* Should have been an absolutized filename. */
890 if (my_access (path, W_OK))
896 /* Return true if the given filename designates a file that we are allowed
897 to modify. Files which we should not attempt to modify are (a) "system"
898 include files, and (b) files which the user doesn't have write access to,
899 and (c) files which reside in directories which the user doesn't have
900 write access to. Unless requested to be quiet, give warnings about
901 files that we will not try to convert for one reason or another. An
902 exception is made for "system" include files, which we never try to
903 convert and for which we don't issue the usual warnings. */
906 file_normally_convertible (const char *path)
908 char *const dir_name = alloca (strlen (path) + 1);
910 if (in_system_include_dir (path))
914 char *dir_last_slash;
916 strcpy (dir_name, path);
917 dir_last_slash = strrchr (dir_name, '/');
919 *dir_last_slash = '\0';
921 abort (); /* Should have been an absolutized filename. */
924 if (my_access (path, R_OK))
927 fprintf (stderr, "%s: warning: no read access for file `%s'\n",
928 pname, shortpath (NULL, path));
932 if (my_access (path, W_OK))
935 fprintf (stderr, "%s: warning: no write access for file `%s'\n",
936 pname, shortpath (NULL, path));
940 if (my_access (dir_name, W_OK))
943 fprintf (stderr, "%s: warning: no write access for dir containing `%s'\n",
944 pname, shortpath (NULL, path));
954 /* Return true if the given file_info struct refers to the special SYSCALLS.c.X
955 file. Return false otherwise. */
958 is_syscalls_file (fi_p)
959 const file_info *fi_p;
961 char const *f = fi_p->hash_entry->symbol;
962 size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
963 return sysl <= fl && strcmp (f + fl - sysl, syscalls_filename) == 0;
966 #endif /* !defined (UNPROTOIZE) */
968 /* Check to see if this file will need to have anything done to it on this
969 run. If there is nothing in the given file which both needs conversion
970 and for which we have the necessary stuff to do the conversion, return
971 false. Otherwise, return true.
973 Note that (for protoize) it is only valid to call this function *after*
974 the connections between declarations and definitions have all been made
975 by connect_defs_and_decs. */
978 needs_to_be_converted (file_p)
979 const file_info *file_p;
981 const def_dec_info *ddp;
985 if (is_syscalls_file (file_p))
988 #endif /* !defined (UNPROTOIZE) */
990 for (ddp = file_p->defs_decs; ddp; ddp = ddp->next_in_file)
996 /* ... and if we a protoizing and this function is in old style ... */
998 /* ... and if this a definition or is a decl with an associated def ... */
999 && (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
1001 #else /* defined (UNPROTOIZE) */
1003 /* ... and if we are unprotoizing and this function is in new style ... */
1006 #endif /* defined (UNPROTOIZE) */
1008 /* ... then the containing file needs converting. */
1013 /* Return 1 if the file name NAME is in a directory
1014 that should be converted. */
1017 directory_specified_p (name)
1020 struct string_list *p;
1022 for (p = directory_list; p; p = p->next)
1023 if (!strncmp (name, p->name, strlen (p->name))
1024 && name[strlen (p->name)] == '/')
1026 const char *q = name + strlen (p->name) + 1;
1028 /* If there are more slashes, it's in a subdir, so
1029 this match doesn't count. */
1041 /* Return 1 if the file named NAME should be excluded from conversion. */
1044 file_excluded_p (name)
1047 struct string_list *p;
1048 int len = strlen (name);
1050 for (p = exclude_list; p; p = p->next)
1051 if (!strcmp (name + len - strlen (p->name), p->name)
1052 && name[len - strlen (p->name) - 1] == '/')
1058 /* Construct a new element of a string_list.
1059 STRING is the new element value, and REST holds the remaining elements. */
1061 static struct string_list *
1062 string_list_cons (string, rest)
1064 struct string_list *rest;
1066 struct string_list *temp
1067 = (struct string_list *) xmalloc (sizeof (struct string_list));
1070 temp->name = string;
1074 /* ??? The GNU convention for mentioning function args in its comments
1075 is to capitalize them. So change "hash_tab_p" to HASH_TAB_P below.
1076 Likewise for all the other functions. */
1078 /* Given a hash table, apply some function to each node in the table. The
1079 table to traverse is given as the "hash_tab_p" argument, and the
1080 function to be applied to each node in the table is given as "func"
1084 visit_each_hash_node (hash_tab_p, func)
1085 const hash_table_entry *hash_tab_p;
1088 const hash_table_entry *primary;
1090 for (primary = hash_tab_p; primary < &hash_tab_p[HASH_TABLE_SIZE]; primary++)
1091 if (primary->symbol)
1093 hash_table_entry *second;
1096 for (second = primary->hash_next; second; second = second->hash_next)
1101 /* Initialize all of the fields of a new hash table entry, pointed
1102 to by the "p" parameter. Note that the space to hold the entry
1103 is assumed to have already been allocated before this routine is
1106 static hash_table_entry *
1108 hash_table_entry *p;
1111 p->hash_next = NULL;
1112 p->symbol = savestring (s, strlen (s));
1118 /* Look for a particular function name or filename in the particular
1119 hash table indicated by "hash_tab_p". If the name is not in the
1120 given hash table, add it. Either way, return a pointer to the
1121 hash table entry for the given name. */
1123 static hash_table_entry *
1124 lookup (hash_tab_p, search_symbol)
1125 hash_table_entry *hash_tab_p;
1126 const char *search_symbol;
1129 const char *search_symbol_char_p = search_symbol;
1130 hash_table_entry *p;
1132 while (*search_symbol_char_p)
1133 hash_value += *search_symbol_char_p++;
1134 hash_value &= hash_mask;
1135 p = &hash_tab_p[hash_value];
1137 return add_symbol (p, search_symbol);
1138 if (!strcmp (p->symbol, search_symbol))
1140 while (p->hash_next)
1143 if (!strcmp (p->symbol, search_symbol))
1146 p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
1148 return add_symbol (p, search_symbol);
1151 /* Throw a def/dec record on the junk heap.
1153 Also, since we are not using this record anymore, free up all of the
1154 stuff it pointed to. */
1160 xfree (p->ansi_decl);
1164 const f_list_chain_item * curr;
1165 const f_list_chain_item * next;
1167 for (curr = p->f_list_chain; curr; curr = next)
1169 next = curr->chain_next;
1173 #endif /* !defined (UNPROTOIZE) */
1178 /* Unexpand as many macro symbol as we can find.
1180 If the given line must be unexpanded, make a copy of it in the heap and
1181 return a pointer to the unexpanded copy. Otherwise return NULL. */
1184 unexpand_if_needed (aux_info_line)
1185 const char *aux_info_line;
1187 static char *line_buf = 0;
1188 static int line_buf_size = 0;
1189 const unexpansion *unexp_p;
1190 int got_unexpanded = 0;
1192 char *copy_p = line_buf;
1196 line_buf_size = 1024;
1197 line_buf = (char *) xmalloc (line_buf_size);
1202 /* Make a copy of the input string in line_buf, expanding as necessary. */
1204 for (s = aux_info_line; *s != '\n'; )
1206 for (unexp_p = unexpansions; unexp_p->expanded; unexp_p++)
1208 const char *in_p = unexp_p->expanded;
1209 size_t len = strlen (in_p);
1211 if (*s == *in_p && !strncmp (s, in_p, len) && !is_id_char (s[len]))
1213 int size = strlen (unexp_p->contracted);
1215 if (copy_p + size - line_buf >= line_buf_size)
1217 int offset = copy_p - line_buf;
1219 line_buf_size += size;
1220 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1221 copy_p = line_buf + offset;
1223 strcpy (copy_p, unexp_p->contracted);
1226 /* Assume the there will not be another replacement required
1227 within the text just replaced. */
1230 goto continue_outer;
1233 if (copy_p - line_buf == line_buf_size)
1235 int offset = copy_p - line_buf;
1237 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1238 copy_p = line_buf + offset;
1243 if (copy_p + 2 - line_buf >= line_buf_size)
1245 int offset = copy_p - line_buf;
1247 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1248 copy_p = line_buf + offset;
1253 return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0);
1256 /* Return the absolutized filename for the given relative
1257 filename. Note that if that filename is already absolute, it may
1258 still be returned in a modified form because this routine also
1259 eliminates redundant slashes and single dots and eliminates double
1260 dots to get a shortest possible filename from the given input
1261 filename. The absolutization of relative filenames is made by
1262 assuming that the given filename is to be taken as relative to
1263 the first argument (cwd) or to the current directory if cwd is
1267 abspath (cwd, rel_filename)
1269 const char *rel_filename;
1271 /* Setup the current working directory as needed. */
1272 const char *cwd2 = (cwd) ? cwd : cwd_buffer;
1273 char *const abs_buffer
1274 = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
1275 char *endp = abs_buffer;
1278 /* Copy the filename (possibly preceded by the current working
1279 directory name) into the absolutization buffer. */
1284 if (rel_filename[0] != '/')
1287 while ((*endp++ = *src_p++))
1289 *(endp-1) = '/'; /* overwrite null */
1291 src_p = rel_filename;
1292 while ((*endp++ = *src_p++))
1296 /* Now make a copy of abs_buffer into abs_buffer, shortening the
1297 filename (by taking out slashes and dots) as we go. */
1299 outp = inp = abs_buffer;
1300 *outp++ = *inp++; /* copy first slash */
1303 *outp++ = *inp++; /* copy second slash */
1309 else if (inp[0] == '/' && outp[-1] == '/')
1314 else if (inp[0] == '.' && outp[-1] == '/')
1318 else if (inp[1] == '/')
1323 else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
1325 inp += (inp[2] == '/') ? 3 : 2;
1327 while (outp >= abs_buffer && *outp != '/')
1329 if (outp < abs_buffer)
1331 /* Catch cases like /.. where we try to backup to a
1332 point above the absolute root of the logical file
1335 fprintf (stderr, "%s: invalid file name: %s\n",
1336 pname, rel_filename);
1337 exit (FATAL_EXIT_CODE);
1346 /* On exit, make sure that there is a trailing null, and make sure that
1347 the last character of the returned string is *not* a slash. */
1350 if (outp[-1] == '/')
1353 /* Make a copy (in the heap) of the stuff left in the absolutization
1354 buffer and return a pointer to the copy. */
1356 return savestring (abs_buffer, outp - abs_buffer);
1359 /* Given a filename (and possibly a directory name from which the filename
1360 is relative) return a string which is the shortest possible
1361 equivalent for the corresponding full (absolutized) filename. The
1362 shortest possible equivalent may be constructed by converting the
1363 absolutized filename to be a relative filename (i.e. relative to
1364 the actual current working directory). However if a relative filename
1365 is longer, then the full absolute filename is returned.
1369 Note that "simple-minded" conversion of any given type of filename (either
1370 relative or absolute) may not result in a valid equivalent filename if any
1371 subpart of the original filename is actually a symbolic link. */
1374 shortpath (cwd, filename)
1376 const char *filename;
1380 char *cwd_p = cwd_buffer;
1382 int unmatched_slash_count = 0;
1383 size_t filename_len = strlen (filename);
1385 path_p = abspath (cwd, filename);
1386 rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
1388 while (*cwd_p && (*cwd_p == *path_p))
1393 if (!*cwd_p && (!*path_p || *path_p == '/')) /* whole pwd matched */
1395 if (!*path_p) /* input *is* the current path! */
1406 while (*cwd_p != '/') /* backup to last slash */
1413 unmatched_slash_count++;
1416 /* Find out how many directory levels in cwd were *not* matched. */
1418 if (*cwd_p++ == '/')
1419 unmatched_slash_count++;
1421 /* Now we know how long the "short name" will be.
1422 Reject it if longer than the input. */
1423 if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
1426 /* For each of them, put a `../' at the beginning of the short name. */
1427 while (unmatched_slash_count--)
1429 /* Give up if the result gets to be longer
1430 than the absolute path name. */
1431 if (rel_buffer + filename_len <= rel_buf_p + 3)
1438 /* Then tack on the unmatched part of the desired file's name. */
1441 if (rel_buffer + filename_len <= rel_buf_p)
1444 while ((*rel_buf_p++ = *path_p++));
1447 if (*(rel_buf_p-1) == '/')
1448 *--rel_buf_p = '\0';
1453 /* Lookup the given filename in the hash table for filenames. If it is a
1454 new one, then the hash table info pointer will be null. In this case,
1455 we create a new file_info record to go with the filename, and we initialize
1456 that record with some reasonable values. */
1458 /* FILENAME was const, but that causes a warning on AIX when calling stat.
1459 That is probably a bug in AIX, but might as well avoid the warning. */
1462 find_file (filename, do_not_stat)
1466 hash_table_entry *hash_entry_p;
1468 hash_entry_p = lookup (filename_primary, filename);
1469 if (hash_entry_p->fip)
1470 return hash_entry_p->fip;
1473 struct stat stat_buf;
1474 file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
1476 /* If we cannot get status on any given source file, give a warning
1477 and then just set its time of last modification to infinity. */
1480 stat_buf.st_mtime = (time_t) 0;
1483 if (my_stat (filename, &stat_buf) == -1)
1485 int errno_val = errno;
1486 fprintf (stderr, "%s: %s: can't get status: %s\n",
1487 pname, shortpath (NULL, filename),
1488 my_strerror (errno_val));
1489 stat_buf.st_mtime = (time_t) -1;
1493 hash_entry_p->fip = file_p;
1494 file_p->hash_entry = hash_entry_p;
1495 file_p->defs_decs = NULL;
1496 file_p->mtime = stat_buf.st_mtime;
1501 /* Generate a fatal error because some part of the aux_info file is
1505 aux_info_corrupted ()
1507 fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",
1508 pname, current_aux_info_lineno);
1509 exit (FATAL_EXIT_CODE);
1512 /* ??? This comment is vague. Say what the condition is for. */
1513 /* Check to see that a condition is true. This is kind of like an assert. */
1516 check_aux_info (cond)
1520 aux_info_corrupted ();
1523 /* Given a pointer to the closing right parenthesis for a particular formals
1524 list (in an aux_info file) find the corresponding left parenthesis and
1525 return a pointer to it. */
1528 find_corresponding_lparen (p)
1534 for (paren_depth = 1, q = p-1; paren_depth; q--)
1549 /* Given a line from an aux info file, and a time at which the aux info
1550 file it came from was created, check to see if the item described in
1551 the line comes from a file which has been modified since the aux info
1552 file was created. If so, return non-zero, else return zero. */
1555 referenced_file_is_newer (l, aux_info_mtime)
1557 time_t aux_info_mtime;
1563 check_aux_info (l[0] == '/');
1564 check_aux_info (l[1] == '*');
1565 check_aux_info (l[2] == ' ');
1568 const char *filename_start = p = l + 3;
1572 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1573 strncpy (filename, filename_start, (size_t) (p - filename_start));
1574 filename[p-filename_start] = '\0';
1577 /* Call find_file to find the file_info record associated with the file
1578 which contained this particular def or dec item. Note that this call
1579 may cause a new file_info record to be created if this is the first time
1580 that we have ever known about this particular file. */
1582 fi_p = find_file (abspath (invocation_filename, filename), 0);
1584 return (fi_p->mtime > aux_info_mtime);
1587 /* Given a line of info from the aux_info file, create a new
1588 def_dec_info record to remember all of the important information about
1589 a function definition or declaration.
1591 Link this record onto the list of such records for the particular file in
1592 which it occurred in proper (descending) line number order (for now).
1594 If there is an identical record already on the list for the file, throw
1595 this one away. Doing so takes care of the (useless and troublesome)
1596 duplicates which are bound to crop up due to multiple inclusions of any
1597 given individual header file.
1599 Finally, link the new def_dec record onto the list of such records
1600 pertaining to this particular function name. */
1603 save_def_or_dec (l, is_syscalls)
1608 const char *semicolon_p;
1609 def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
1612 def_dec_p->written = 0;
1613 #endif /* !defined (UNPROTOIZE) */
1615 /* Start processing the line by picking off 5 pieces of information from
1616 the left hand end of the line. These are filename, line number,
1617 new/old/implicit flag (new = ANSI prototype format), definition or
1618 declaration flag, and extern/static flag). */
1620 check_aux_info (l[0] == '/');
1621 check_aux_info (l[1] == '*');
1622 check_aux_info (l[2] == ' ');
1625 const char *filename_start = p = l + 3;
1630 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1631 strncpy (filename, filename_start, (size_t) (p - filename_start));
1632 filename[p-filename_start] = '\0';
1634 /* Call find_file to find the file_info record associated with the file
1635 which contained this particular def or dec item. Note that this call
1636 may cause a new file_info record to be created if this is the first time
1637 that we have ever known about this particular file.
1639 Note that we started out by forcing all of the base source file names
1640 (i.e. the names of the aux_info files with the .X stripped off) into the
1641 filenames hash table, and we simultaneously setup file_info records for
1642 all of these base file names (even if they may be useless later).
1643 The file_info records for all of these "base" file names (properly)
1644 act as file_info records for the "original" (i.e. un-included) files
1645 which were submitted to gcc for compilation (when the -aux-info
1646 option was used). */
1648 def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);
1652 const char *line_number_start = ++p;
1653 char line_number[10];
1657 strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
1658 line_number[p-line_number_start] = '\0';
1659 def_dec_p->line = atoi (line_number);
1662 /* Check that this record describes a new-style, old-style, or implicit
1663 definition or declaration. */
1665 p++; /* Skip over the `:'. */
1666 check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
1668 /* Is this a new style (ANSI prototyped) definition or declaration? */
1670 def_dec_p->prototyped = (*p == 'N');
1674 /* Is this an implicit declaration? */
1676 def_dec_p->is_implicit = (*p == 'I');
1678 #endif /* !defined (UNPROTOIZE) */
1682 check_aux_info ((*p == 'C') || (*p == 'F'));
1684 /* Is this item a function definition (F) or a declaration (C). Note that
1685 we treat item taken from the syscalls file as though they were function
1686 definitions regardless of what the stuff in the file says. */
1688 def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);
1691 def_dec_p->definition = 0; /* Fill this in later if protoizing. */
1692 #endif /* !defined (UNPROTOIZE) */
1694 check_aux_info (*p++ == ' ');
1695 check_aux_info (*p++ == '*');
1696 check_aux_info (*p++ == '/');
1697 check_aux_info (*p++ == ' ');
1700 check_aux_info ((!strncmp (p, "static", 6)) || (!strncmp (p, "extern", 6)));
1701 #else /* !defined (UNPROTOIZE) */
1702 if (!strncmp (p, "static", 6))
1703 def_dec_p->is_static = -1;
1704 else if (!strncmp (p, "extern", 6))
1705 def_dec_p->is_static = 0;
1707 check_aux_info (0); /* Didn't find either `extern' or `static'. */
1708 #endif /* !defined (UNPROTOIZE) */
1711 const char *ansi_start = p;
1713 p += 6; /* Pass over the "static" or "extern". */
1715 /* We are now past the initial stuff. Search forward from here to find
1716 the terminating semicolon that should immediately follow the entire
1717 ANSI format function declaration. */
1724 /* Make a copy of the ansi declaration part of the line from the aux_info
1727 def_dec_p->ansi_decl
1728 = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
1730 /* Backup and point at the final right paren of the final argument list. */
1735 def_dec_p->f_list_chain = NULL;
1736 #endif /* !defined (UNPROTOIZE) */
1738 while (p != ansi_start && (p[-1] == ' ' || p[-1] == '\t')) p--;
1741 free_def_dec (def_dec_p);
1746 /* Now isolate a whole set of formal argument lists, one-by-one. Normally,
1747 there will only be one list to isolate, but there could be more. */
1749 def_dec_p->f_list_count = 0;
1753 const char *left_paren_p = find_corresponding_lparen (p);
1756 f_list_chain_item *cip
1757 = (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
1760 = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
1762 /* Add the new chain item at the head of the current list. */
1764 cip->chain_next = def_dec_p->f_list_chain;
1765 def_dec_p->f_list_chain = cip;
1767 #endif /* !defined (UNPROTOIZE) */
1768 def_dec_p->f_list_count++;
1770 p = left_paren_p - 2;
1772 /* p must now point either to another right paren, or to the last
1773 character of the name of the function that was declared/defined.
1774 If p points to another right paren, then this indicates that we
1775 are dealing with multiple formals lists. In that case, there
1776 really should be another right paren preceding this right paren. */
1781 check_aux_info (*--p == ')');
1786 const char *past_fn = p + 1;
1788 check_aux_info (*past_fn == ' ');
1790 /* Scan leftwards over the identifier that names the function. */
1792 while (is_id_char (*p))
1796 /* p now points to the leftmost character of the function name. */
1799 char *fn_string = (char *) alloca (past_fn - p + 1);
1801 strncpy (fn_string, p, (size_t) (past_fn - p));
1802 fn_string[past_fn-p] = '\0';
1803 def_dec_p->hash_entry = lookup (function_name_primary, fn_string);
1807 /* Look at all of the defs and decs for this function name that we have
1808 collected so far. If there is already one which is at the same
1809 line number in the same file, then we can discard this new def_dec_info
1812 As an extra assurance that any such pair of (nominally) identical
1813 function declarations are in fact identical, we also compare the
1814 ansi_decl parts of the lines from the aux_info files just to be on
1817 This comparison will fail if (for instance) the user was playing
1818 messy games with the preprocessor which ultimately causes one
1819 function declaration in one header file to look differently when
1820 that file is included by two (or more) other files. */
1823 const def_dec_info *other;
1825 for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func)
1827 if (def_dec_p->line == other->line && def_dec_p->file == other->file)
1829 if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
1831 fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n",
1832 def_dec_p->file->hash_entry->symbol,
1834 def_dec_p->hash_entry->symbol);
1835 exit (FATAL_EXIT_CODE);
1837 free_def_dec (def_dec_p);
1845 /* If we are doing unprotoizing, we must now setup the pointers that will
1846 point to the K&R name list and to the K&R argument declarations list.
1848 Note that if this is only a function declaration, then we should not
1849 expect to find any K&R style formals list following the ANSI-style
1850 formals list. This is because GCC knows that such information is
1851 useless in the case of function declarations (function definitions
1852 are a different story however).
1854 Since we are unprotoizing, we don't need any such lists anyway.
1855 All we plan to do is to delete all characters between ()'s in any
1858 def_dec_p->formal_names = NULL;
1859 def_dec_p->formal_decls = NULL;
1861 if (def_dec_p->is_func_def)
1864 check_aux_info (*++p == ' ');
1865 check_aux_info (*++p == '/');
1866 check_aux_info (*++p == '*');
1867 check_aux_info (*++p == ' ');
1868 check_aux_info (*++p == '(');
1871 const char *kr_names_start = ++p; /* Point just inside '('. */
1875 p--; /* point to closing right paren */
1877 /* Make a copy of the K&R parameter names list. */
1879 def_dec_p->formal_names
1880 = dupnstr (kr_names_start, (size_t) (p - kr_names_start));
1883 check_aux_info (*++p == ' ');
1886 /* p now points to the first character of the K&R style declarations
1887 list (if there is one) or to the star-slash combination that ends
1888 the comment in which such lists get embedded. */
1890 /* Make a copy of the K&R formal decls list and set the def_dec record
1893 if (*p == '*') /* Are there no K&R declarations? */
1895 check_aux_info (*++p == '/');
1896 def_dec_p->formal_decls = "";
1900 const char *kr_decls_start = p;
1902 while (p[0] != '*' || p[1] != '/')
1906 check_aux_info (*p == ' ');
1908 def_dec_p->formal_decls
1909 = dupnstr (kr_decls_start, (size_t) (p - kr_decls_start));
1912 /* Handle a special case. If we have a function definition marked as
1913 being in "old" style, and if its formal names list is empty, then
1914 it may actually have the string "void" in its real formals list
1915 in the original source code. Just to make sure, we will get setup
1916 to convert such things anyway.
1918 This kludge only needs to be here because of an insurmountable
1919 problem with generating .X files. */
1921 if (!def_dec_p->prototyped && !*def_dec_p->formal_names)
1922 def_dec_p->prototyped = 1;
1925 /* Since we are unprotoizing, if this item is already in old (K&R) style,
1926 we can just ignore it. If that is true, throw away the itme now. */
1928 if (!def_dec_p->prototyped)
1930 free_def_dec (def_dec_p);
1934 #endif /* defined (UNPROTOIZE) */
1936 /* Add this record to the head of the list of records pertaining to this
1937 particular function name. */
1939 def_dec_p->next_for_func = def_dec_p->hash_entry->ddip;
1940 def_dec_p->hash_entry->ddip = def_dec_p;
1942 /* Add this new def_dec_info record to the sorted list of def_dec_info
1943 records for this file. Note that we don't have to worry about duplicates
1944 (caused by multiple inclusions of header files) here because we have
1945 already eliminated duplicates above. */
1947 if (!def_dec_p->file->defs_decs)
1949 def_dec_p->file->defs_decs = def_dec_p;
1950 def_dec_p->next_in_file = NULL;
1954 int line = def_dec_p->line;
1955 const def_dec_info *prev = NULL;
1956 const def_dec_info *curr = def_dec_p->file->defs_decs;
1957 const def_dec_info *next = curr->next_in_file;
1959 while (next && (line < curr->line))
1963 next = next->next_in_file;
1965 if (line >= curr->line)
1967 def_dec_p->next_in_file = curr;
1969 ((NONCONST def_dec_info *) prev)->next_in_file = def_dec_p;
1971 def_dec_p->file->defs_decs = def_dec_p;
1973 else /* assert (next == NULL); */
1975 ((NONCONST def_dec_info *) curr)->next_in_file = def_dec_p;
1976 /* assert (next == NULL); */
1977 def_dec_p->next_in_file = next;
1982 /* Set up the vector COMPILE_PARAMS which is the argument list for running GCC.
1983 Also set input_file_name_index and aux_info_file_name_index
1984 to the indices of the slots where the file names should go. */
1986 /* We initialize the vector by removing -g, -O, -S, -c, and -o options,
1987 and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
1990 munge_compile_params (params_list)
1991 const char *params_list;
1993 /* Build up the contents in a temporary vector
1994 that is so big that to has to be big enough. */
1995 const char **temp_params
1996 = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
1997 int param_count = 0;
2000 temp_params[param_count++] = compiler_file_name;
2003 while (ISSPACE ((const unsigned char)*params_list))
2007 param = params_list;
2008 while (*params_list && !ISSPACE ((const unsigned char)*params_list))
2010 if (param[0] != '-')
2011 temp_params[param_count++]
2012 = dupnstr (param, (size_t) (params_list - param));
2021 break; /* Don't copy these. */
2023 while (ISSPACE ((const unsigned char)*params_list))
2026 && !ISSPACE ((const unsigned char)*params_list))
2030 temp_params[param_count++]
2031 = dupnstr (param, (size_t) (params_list - param));
2037 temp_params[param_count++] = "-aux-info";
2039 /* Leave room for the aux-info file name argument. */
2040 aux_info_file_name_index = param_count;
2041 temp_params[param_count++] = NULL;
2043 temp_params[param_count++] = "-S";
2044 temp_params[param_count++] = "-o";
2045 temp_params[param_count++] = "/dev/null";
2047 /* Leave room for the input file name argument. */
2048 input_file_name_index = param_count;
2049 temp_params[param_count++] = NULL;
2050 /* Terminate the list. */
2051 temp_params[param_count++] = NULL;
2053 /* Make a copy of the compile_params in heap space. */
2056 = (const char **) xmalloc (sizeof (char *) * (param_count+1));
2057 memcpy (compile_params, temp_params, sizeof (char *) * param_count);
2060 /* Do a recompilation for the express purpose of generating a new aux_info
2061 file to go with a specific base source file.
2063 The result is a boolean indicating success. */
2066 gen_aux_info_file (base_filename)
2067 const char *base_filename;
2069 if (!input_file_name_index)
2070 munge_compile_params ("");
2072 /* Store the full source file name in the argument vector. */
2073 compile_params[input_file_name_index] = shortpath (NULL, base_filename);
2074 /* Add .X to source file name to get aux-info file name. */
2075 compile_params[aux_info_file_name_index]
2076 = savestring2 (compile_params[input_file_name_index],
2077 strlen (compile_params[input_file_name_index]),
2082 fprintf (stderr, "%s: compiling `%s'\n",
2083 pname, compile_params[input_file_name_index]);
2086 char *errmsg_fmt, *errmsg_arg;
2087 int wait_status, pid;
2088 char *temp_base = choose_temp_base ();
2090 pid = pexecute (compile_params[0], (char * const *) compile_params,
2091 pname, temp_base, &errmsg_fmt, &errmsg_arg,
2092 PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH);
2096 int errno_val = errno;
2097 fprintf (stderr, "%s: ", pname);
2098 fprintf (stderr, errmsg_fmt, errmsg_arg);
2099 fprintf (stderr, ": %s\n", my_strerror (errno_val));
2103 pid = pwait (pid, &wait_status, 0);
2106 fprintf (stderr, "%s: wait: %s\n", pname, my_strerror (errno));
2109 if (WIFSIGNALED (wait_status))
2111 fprintf (stderr, "%s: subprocess got fatal signal %d\n",
2112 pname, WTERMSIG (wait_status));
2115 if (WIFEXITED (wait_status))
2117 if (WEXITSTATUS (wait_status) != 0)
2119 fprintf (stderr, "%s: %s exited with status %d\n",
2120 pname, compile_params[0], WEXITSTATUS (wait_status));
2129 /* Read in all of the information contained in a single aux_info file.
2130 Save all of the important stuff for later. */
2133 process_aux_info_file (base_source_filename, keep_it, is_syscalls)
2134 const char *base_source_filename;
2138 size_t base_len = strlen (base_source_filename);
2139 char * aux_info_filename
2140 = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
2141 char *aux_info_base;
2142 char *aux_info_limit;
2143 char *aux_info_relocated_name;
2144 const char *aux_info_second_line;
2145 time_t aux_info_mtime;
2146 size_t aux_info_size;
2149 /* Construct the aux_info filename from the base source filename. */
2151 strcpy (aux_info_filename, base_source_filename);
2152 strcat (aux_info_filename, aux_info_suffix);
2154 /* Check that the aux_info file exists and is readable. If it does not
2155 exist, try to create it (once only). */
2157 /* If file doesn't exist, set must_create.
2158 Likewise if it exists and we can read it but it is obsolete.
2159 Otherwise, report an error. */
2162 /* Come here with must_create set to 1 if file is out of date. */
2165 if (my_access (aux_info_filename, R_OK) == -1)
2167 if (errno == ENOENT)
2171 fprintf (stderr, "%s: warning: missing SYSCALLS file `%s'\n",
2172 pname, aux_info_filename);
2179 int errno_val = errno;
2180 fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
2181 pname, shortpath (NULL, aux_info_filename),
2182 my_strerror (errno_val));
2187 #if 0 /* There is code farther down to take care of this. */
2191 stat (aux_info_file_name, &s1);
2192 stat (base_source_file_name, &s2);
2193 if (s2.st_mtime > s1.st_mtime)
2198 /* If we need a .X file, create it, and verify we can read it. */
2201 if (!gen_aux_info_file (base_source_filename))
2206 if (my_access (aux_info_filename, R_OK) == -1)
2208 int errno_val = errno;
2209 fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
2210 pname, shortpath (NULL, aux_info_filename),
2211 my_strerror (errno_val));
2218 struct stat stat_buf;
2220 /* Get some status information about this aux_info file. */
2222 if (my_stat (aux_info_filename, &stat_buf) == -1)
2224 int errno_val = errno;
2225 fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
2226 pname, shortpath (NULL, aux_info_filename),
2227 my_strerror (errno_val));
2232 /* Check on whether or not this aux_info file is zero length. If it is,
2233 then just ignore it and return. */
2235 if ((aux_info_size = stat_buf.st_size) == 0)
2238 /* Get the date/time of last modification for this aux_info file and
2239 remember it. We will have to check that any source files that it
2240 contains information about are at least this old or older. */
2242 aux_info_mtime = stat_buf.st_mtime;
2246 /* Compare mod time with the .c file; update .X file if obsolete.
2247 The code later on can fail to check the .c file
2248 if it did not directly define any functions. */
2250 if (my_stat (base_source_filename, &stat_buf) == -1)
2252 int errno_val = errno;
2253 fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
2254 pname, shortpath (NULL, base_source_filename),
2255 my_strerror (errno_val));
2259 if (stat_buf.st_mtime > aux_info_mtime)
2270 /* Open the aux_info file. */
2272 if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1)
2274 int errno_val = errno;
2275 fprintf (stderr, "%s: can't open aux info file `%s' for reading: %s\n",
2276 pname, shortpath (NULL, aux_info_filename),
2277 my_strerror (errno_val));
2281 /* Allocate space to hold the aux_info file in memory. */
2283 aux_info_base = xmalloc (aux_info_size + 1);
2284 aux_info_limit = aux_info_base + aux_info_size;
2285 *aux_info_limit = '\0';
2287 /* Read the aux_info file into memory. */
2289 if (safe_read (aux_info_file, aux_info_base, aux_info_size) !=
2290 (int) aux_info_size)
2292 int errno_val = errno;
2293 fprintf (stderr, "%s: error reading aux info file `%s': %s\n",
2294 pname, shortpath (NULL, aux_info_filename),
2295 my_strerror (errno_val));
2296 free (aux_info_base);
2297 close (aux_info_file);
2301 /* Close the aux info file. */
2303 if (close (aux_info_file))
2305 int errno_val = errno;
2306 fprintf (stderr, "%s: error closing aux info file `%s': %s\n",
2307 pname, shortpath (NULL, aux_info_filename),
2308 my_strerror (errno_val));
2309 free (aux_info_base);
2310 close (aux_info_file);
2315 /* Delete the aux_info file (unless requested not to). If the deletion
2316 fails for some reason, don't even worry about it. */
2318 if (must_create && !keep_it)
2319 if (my_unlink (aux_info_filename) == -1)
2321 int errno_val = errno;
2322 fprintf (stderr, "%s: can't delete aux info file `%s': %s\n",
2323 pname, shortpath (NULL, aux_info_filename),
2324 my_strerror (errno_val));
2327 /* Save a pointer into the first line of the aux_info file which
2328 contains the filename of the directory from which the compiler
2329 was invoked when the associated source file was compiled.
2330 This information is used later to help create complete
2331 filenames out of the (potentially) relative filenames in
2332 the aux_info file. */
2335 char *p = aux_info_base;
2342 invocation_filename = p; /* Save a pointer to first byte of path. */
2347 while (*p++ != '\n')
2349 aux_info_second_line = p;
2350 aux_info_relocated_name = 0;
2351 if (invocation_filename[0] != '/')
2353 /* INVOCATION_FILENAME is relative;
2354 append it to BASE_SOURCE_FILENAME's dir. */
2356 aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
2357 strcpy (aux_info_relocated_name, base_source_filename);
2358 dir_end = strrchr (aux_info_relocated_name, '/');
2362 dir_end = aux_info_relocated_name;
2363 strcpy (dir_end, invocation_filename);
2364 invocation_filename = aux_info_relocated_name;
2370 const char *aux_info_p;
2372 /* Do a pre-pass on the lines in the aux_info file, making sure that all
2373 of the source files referenced in there are at least as old as this
2374 aux_info file itself. If not, go back and regenerate the aux_info
2375 file anew. Don't do any of this for the syscalls file. */
2379 current_aux_info_lineno = 2;
2381 for (aux_info_p = aux_info_second_line; *aux_info_p; )
2383 if (referenced_file_is_newer (aux_info_p, aux_info_mtime))
2385 free (aux_info_base);
2386 xfree (aux_info_relocated_name);
2387 if (keep_it && my_unlink (aux_info_filename) == -1)
2389 int errno_val = errno;
2390 fprintf (stderr, "%s: can't delete file `%s': %s\n",
2391 pname, shortpath (NULL, aux_info_filename),
2392 my_strerror (errno_val));
2399 /* Skip over the rest of this line to start of next line. */
2401 while (*aux_info_p != '\n')
2404 current_aux_info_lineno++;
2408 /* Now do the real pass on the aux_info lines. Save their information in
2409 the in-core data base. */
2411 current_aux_info_lineno = 2;
2413 for (aux_info_p = aux_info_second_line; *aux_info_p;)
2415 char *unexpanded_line = unexpand_if_needed (aux_info_p);
2417 if (unexpanded_line)
2419 save_def_or_dec (unexpanded_line, is_syscalls);
2420 free (unexpanded_line);
2423 save_def_or_dec (aux_info_p, is_syscalls);
2425 /* Skip over the rest of this line and get to start of next line. */
2427 while (*aux_info_p != '\n')
2430 current_aux_info_lineno++;
2434 free (aux_info_base);
2435 xfree (aux_info_relocated_name);
2440 /* Check an individual filename for a .c suffix. If the filename has this
2441 suffix, rename the file such that its suffix is changed to .C. This
2442 function implements the -C option. */
2446 const hash_table_entry *hp;
2448 const char *filename = hp->symbol;
2449 int last_char_index = strlen (filename) - 1;
2450 char *const new_filename = (char *) alloca (strlen (filename) + 1);
2452 /* Note that we don't care here if the given file was converted or not. It
2453 is possible that the given file was *not* converted, simply because there
2454 was nothing in it which actually required conversion. Even in this case,
2455 we want to do the renaming. Note that we only rename files with the .c
2458 if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.')
2461 strcpy (new_filename, filename);
2462 new_filename[last_char_index] = 'C';
2464 if (my_link (filename, new_filename) == -1)
2466 int errno_val = errno;
2467 fprintf (stderr, "%s: warning: can't link file `%s' to `%s': %s\n",
2468 pname, shortpath (NULL, filename),
2469 shortpath (NULL, new_filename), my_strerror (errno_val));
2474 if (my_unlink (filename) == -1)
2476 int errno_val = errno;
2477 fprintf (stderr, "%s: warning: can't delete file `%s': %s\n",
2478 pname, shortpath (NULL, filename), my_strerror (errno_val));
2484 #endif /* !defined (UNPROTOIZE) */
2486 /* Take the list of definitions and declarations attached to a particular
2487 file_info node and reverse the order of the list. This should get the
2488 list into an order such that the item with the lowest associated line
2489 number is nearest the head of the list. When these lists are originally
2490 built, they are in the opposite order. We want to traverse them in
2491 normal line number order later (i.e. lowest to highest) so reverse the
2495 reverse_def_dec_list (hp)
2496 const hash_table_entry *hp;
2498 file_info *file_p = hp->fip;
2499 def_dec_info *prev = NULL;
2500 def_dec_info *current = (def_dec_info *)file_p->defs_decs;
2503 return; /* no list to reverse */
2506 if (! (current = (def_dec_info *)current->next_in_file))
2507 return; /* can't reverse a single list element */
2509 prev->next_in_file = NULL;
2513 def_dec_info *next = (def_dec_info *)current->next_in_file;
2515 current->next_in_file = prev;
2520 file_p->defs_decs = prev;
2525 /* Find the (only?) extern definition for a particular function name, starting
2526 from the head of the linked list of entries for the given name. If we
2527 cannot find an extern definition for the given function name, issue a
2528 warning and scrounge around for the next best thing, i.e. an extern
2529 function declaration with a prototype attached to it. Note that we only
2530 allow such substitutions for extern declarations and never for static
2531 declarations. That's because the only reason we allow them at all is
2532 to let un-prototyped function declarations for system-supplied library
2533 functions get their prototypes from our own extra SYSCALLS.c.X file which
2534 contains all of the correct prototypes for system functions. */
2536 static const def_dec_info *
2537 find_extern_def (head, user)
2538 const def_dec_info *head;
2539 const def_dec_info *user;
2541 const def_dec_info *dd_p;
2542 const def_dec_info *extern_def_p = NULL;
2543 int conflict_noted = 0;
2545 /* Don't act too stupid here. Somebody may try to convert an entire system
2546 in one swell fwoop (rather than one program at a time, as should be done)
2547 and in that case, we may find that there are multiple extern definitions
2548 of a given function name in the entire set of source files that we are
2549 converting. If however one of these definitions resides in exactly the
2550 same source file as the reference we are trying to satisfy then in that
2551 case it would be stupid for us to fail to realize that this one definition
2552 *must* be the precise one we are looking for.
2554 To make sure that we don't miss an opportunity to make this "same file"
2555 leap of faith, we do a prescan of the list of records relating to the
2556 given function name, and we look (on this first scan) *only* for a
2557 definition of the function which is in the same file as the reference
2558 we are currently trying to satisfy. */
2560 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2561 if (dd_p->is_func_def && !dd_p->is_static && dd_p->file == user->file)
2564 /* Now, since we have not found a definition in the same file as the
2565 reference, we scan the list again and consider all possibilities from
2566 all files. Here we may get conflicts with the things listed in the
2567 SYSCALLS.c.X file, but if that happens it only means that the source
2568 code being converted contains its own definition of a function which
2569 could have been supplied by libc.a. In such cases, we should avoid
2570 issuing the normal warning, and defer to the definition given in the
2573 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2574 if (dd_p->is_func_def && !dd_p->is_static)
2576 if (!extern_def_p) /* Previous definition? */
2577 extern_def_p = dd_p; /* Remember the first definition found. */
2580 /* Ignore definition just found if it came from SYSCALLS.c.X. */
2582 if (is_syscalls_file (dd_p->file))
2585 /* Quietly replace the definition previously found with the one
2586 just found if the previous one was from SYSCALLS.c.X. */
2588 if (is_syscalls_file (extern_def_p->file))
2590 extern_def_p = dd_p;
2594 /* If we get here, then there is a conflict between two function
2595 declarations for the same function, both of which came from the
2598 if (!conflict_noted) /* first time we noticed? */
2601 fprintf (stderr, "%s: conflicting extern definitions of '%s'\n",
2602 pname, head->hash_entry->symbol);
2605 fprintf (stderr, "%s: declarations of '%s' will not be converted\n",
2606 pname, head->hash_entry->symbol);
2607 fprintf (stderr, "%s: conflict list for '%s' follows:\n",
2608 pname, head->hash_entry->symbol);
2609 fprintf (stderr, "%s: %s(%d): %s\n",
2611 shortpath (NULL, extern_def_p->file->hash_entry->symbol),
2612 extern_def_p->line, extern_def_p->ansi_decl);
2616 fprintf (stderr, "%s: %s(%d): %s\n",
2618 shortpath (NULL, dd_p->file->hash_entry->symbol),
2619 dd_p->line, dd_p->ansi_decl);
2623 /* We want to err on the side of caution, so if we found multiple conflicting
2624 definitions for the same function, treat this as being that same as if we
2625 had found no definitions (i.e. return NULL). */
2632 /* We have no definitions for this function so do the next best thing.
2633 Search for an extern declaration already in prototype form. */
2635 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2636 if (!dd_p->is_func_def && !dd_p->is_static && dd_p->prototyped)
2638 extern_def_p = dd_p; /* save a pointer to the definition */
2640 fprintf (stderr, "%s: warning: using formals list from %s(%d) for function `%s'\n",
2642 shortpath (NULL, dd_p->file->hash_entry->symbol),
2643 dd_p->line, dd_p->hash_entry->symbol);
2647 /* Gripe about unprototyped function declarations that we found no
2648 corresponding definition (or other source of prototype information)
2651 Gripe even if the unprototyped declaration we are worried about
2652 exists in a file in one of the "system" include directories. We
2653 can gripe about these because we should have at least found a
2654 corresponding (pseudo) definition in the SYSCALLS.c.X file. If we
2655 didn't, then that means that the SYSCALLS.c.X file is missing some
2656 needed prototypes for this particular system. That is worth telling
2661 const char *file = user->file->hash_entry->symbol;
2664 if (in_system_include_dir (file))
2666 /* Why copy this string into `needed' at all?
2667 Why not just use user->ansi_decl without copying? */
2668 char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
2671 strcpy (needed, user->ansi_decl);
2672 p = (NONCONST char *) substr (needed, user->hash_entry->symbol)
2673 + strlen (user->hash_entry->symbol) + 2;
2674 /* Avoid having ??? in the string. */
2680 fprintf (stderr, "%s: %d: `%s' used but missing from SYSCALLS\n",
2681 shortpath (NULL, file), user->line,
2682 needed+7); /* Don't print "extern " */
2686 fprintf (stderr, "%s: %d: warning: no extern definition for `%s'\n",
2687 shortpath (NULL, file), user->line,
2688 user->hash_entry->symbol);
2692 return extern_def_p;
2695 /* Find the (only?) static definition for a particular function name in a
2696 given file. Here we get the function-name and the file info indirectly
2697 from the def_dec_info record pointer which is passed in. */
2699 static const def_dec_info *
2700 find_static_definition (user)
2701 const def_dec_info *user;
2703 const def_dec_info *head = user->hash_entry->ddip;
2704 const def_dec_info *dd_p;
2705 int num_static_defs = 0;
2706 const def_dec_info *static_def_p = NULL;
2708 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2709 if (dd_p->is_func_def && dd_p->is_static && (dd_p->file == user->file))
2711 static_def_p = dd_p; /* save a pointer to the definition */
2714 if (num_static_defs == 0)
2717 fprintf (stderr, "%s: warning: no static definition for `%s' in file `%s'\n",
2718 pname, head->hash_entry->symbol,
2719 shortpath (NULL, user->file->hash_entry->symbol));
2721 else if (num_static_defs > 1)
2723 fprintf (stderr, "%s: multiple static defs of `%s' in file `%s'\n",
2724 pname, head->hash_entry->symbol,
2725 shortpath (NULL, user->file->hash_entry->symbol));
2728 return static_def_p;
2731 /* Find good prototype style formal argument lists for all of the function
2732 declarations which didn't have them before now.
2734 To do this we consider each function name one at a time. For each function
2735 name, we look at the items on the linked list of def_dec_info records for
2736 that particular name.
2738 Somewhere on this list we should find one (and only one) def_dec_info
2739 record which represents the actual function definition, and this record
2740 should have a nice formal argument list already associated with it.
2742 Thus, all we have to do is to connect up all of the other def_dec_info
2743 records for this particular function name to the special one which has
2744 the full-blown formals list.
2746 Of course it is a little more complicated than just that. See below for
2750 connect_defs_and_decs (hp)
2751 const hash_table_entry *hp;
2753 const def_dec_info *dd_p;
2754 const def_dec_info *extern_def_p = NULL;
2755 int first_extern_reference = 1;
2757 /* Traverse the list of definitions and declarations for this particular
2758 function name. For each item on the list, if it is a function
2759 definition (either old style or new style) then GCC has already been
2760 kind enough to produce a prototype for us, and it is associated with
2761 the item already, so declare the item as its own associated "definition".
2763 Also, for each item which is only a function declaration, but which
2764 nonetheless has its own prototype already (obviously supplied by the user)
2765 declare the item as its own definition.
2767 Note that when/if there are multiple user-supplied prototypes already
2768 present for multiple declarations of any given function, these multiple
2769 prototypes *should* all match exactly with one another and with the
2770 prototype for the actual function definition. We don't check for this
2771 here however, since we assume that the compiler must have already done
2772 this consistency checking when it was creating the .X files. */
2774 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2775 if (dd_p->prototyped)
2776 ((NONCONST def_dec_info *) dd_p)->definition = dd_p;
2778 /* Traverse the list of definitions and declarations for this particular
2779 function name. For each item on the list, if it is an extern function
2780 declaration and if it has no associated definition yet, go try to find
2781 the matching extern definition for the declaration.
2783 When looking for the matching function definition, warn the user if we
2786 If we find more that one function definition also issue a warning.
2788 Do the search for the matching definition only once per unique function
2789 name (and only when absolutely needed) so that we can avoid putting out
2790 redundant warning messages, and so that we will only put out warning
2791 messages when there is actually a reference (i.e. a declaration) for
2792 which we need to find a matching definition. */
2794 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2795 if (!dd_p->is_func_def && !dd_p->is_static && !dd_p->definition)
2797 if (first_extern_reference)
2799 extern_def_p = find_extern_def (hp->ddip, dd_p);
2800 first_extern_reference = 0;
2802 ((NONCONST def_dec_info *) dd_p)->definition = extern_def_p;
2805 /* Traverse the list of definitions and declarations for this particular
2806 function name. For each item on the list, if it is a static function
2807 declaration and if it has no associated definition yet, go try to find
2808 the matching static definition for the declaration within the same file.
2810 When looking for the matching function definition, warn the user if we
2811 fail to find one in the same file with the declaration, and refuse to
2812 convert this kind of cross-file static function declaration. After all,
2813 this is stupid practice and should be discouraged.
2815 We don't have to worry about the possibility that there is more than one
2816 matching function definition in the given file because that would have
2817 been flagged as an error by the compiler.
2819 Do the search for the matching definition only once per unique
2820 function-name/source-file pair (and only when absolutely needed) so that
2821 we can avoid putting out redundant warning messages, and so that we will
2822 only put out warning messages when there is actually a reference (i.e. a
2823 declaration) for which we actually need to find a matching definition. */
2825 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2826 if (!dd_p->is_func_def && dd_p->is_static && !dd_p->definition)
2828 const def_dec_info *dd_p2;
2829 const def_dec_info *static_def;
2831 /* We have now found a single static declaration for which we need to
2832 find a matching definition. We want to minimize the work (and the
2833 number of warnings), so we will find an appropriate (matching)
2834 static definition for this declaration, and then distribute it
2835 (as the definition for) any and all other static declarations
2836 for this function name which occur within the same file, and which
2837 do not already have definitions.
2839 Note that a trick is used here to prevent subsequent attempts to
2840 call find_static_definition for a given function-name & file
2841 if the first such call returns NULL. Essentially, we convert
2842 these NULL return values to -1, and put the -1 into the definition
2843 field for each other static declaration from the same file which
2844 does not already have an associated definition.
2845 This makes these other static declarations look like they are
2846 actually defined already when the outer loop here revisits them
2847 later on. Thus, the outer loop will skip over them. Later, we
2848 turn the -1's back to NULL's. */
2850 ((NONCONST def_dec_info *) dd_p)->definition =
2851 (static_def = find_static_definition (dd_p))
2853 : (const def_dec_info *) -1;
2855 for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
2856 if (!dd_p2->is_func_def && dd_p2->is_static
2857 && !dd_p2->definition && (dd_p2->file == dd_p->file))
2858 ((NONCONST def_dec_info *)dd_p2)->definition = dd_p->definition;
2861 /* Convert any dummy (-1) definitions we created in the step above back to
2862 NULL's (as they should be). */
2864 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2865 if (dd_p->definition == (def_dec_info *) -1)
2866 ((NONCONST def_dec_info *) dd_p)->definition = NULL;
2869 #endif /* !defined (UNPROTOIZE) */
2871 /* Give a pointer into the clean text buffer, return a number which is the
2872 original source line number that the given pointer points into. */
2875 identify_lineno (clean_p)
2876 const char *clean_p;
2881 for (scan_p = clean_text_base; scan_p <= clean_p; scan_p++)
2882 if (*scan_p == '\n')
2887 /* Issue an error message and give up on doing this particular edit. */
2890 declare_source_confusing (clean_p)
2891 const char *clean_p;
2896 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2897 shortpath (NULL, convert_filename), last_known_line_number);
2899 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2900 shortpath (NULL, convert_filename),
2901 identify_lineno (clean_p));
2903 longjmp (source_confusion_recovery, 1);
2906 /* Check that a condition which is expected to be true in the original source
2907 code is in fact true. If not, issue an error message and give up on
2908 converting this particular source file. */
2911 check_source (cond, clean_p)
2913 const char *clean_p;
2916 declare_source_confusing (clean_p);
2919 /* If we think of the in-core cleaned text buffer as a memory mapped
2920 file (with the variable last_known_line_start acting as sort of a
2921 file pointer) then we can imagine doing "seeks" on the buffer. The
2922 following routine implements a kind of "seek" operation for the in-core
2923 (cleaned) copy of the source file. When finished, it returns a pointer to
2924 the start of a given (numbered) line in the cleaned text buffer.
2926 Note that protoize only has to "seek" in the forward direction on the
2927 in-core cleaned text file buffers, and it never needs to back up.
2929 This routine is made a little bit faster by remembering the line number
2930 (and pointer value) supplied (and returned) from the previous "seek".
2931 This prevents us from always having to start all over back at the top
2932 of the in-core cleaned buffer again. */
2938 if (n < last_known_line_number)
2941 while (n > last_known_line_number)
2943 while (*last_known_line_start != '\n')
2944 check_source (++last_known_line_start < clean_text_limit, 0);
2945 last_known_line_start++;
2946 last_known_line_number++;
2948 return last_known_line_start;
2951 /* Given a pointer to a character in the cleaned text buffer, return a pointer
2952 to the next non-whitespace character which follows it. */
2955 forward_to_next_token_char (ptr)
2958 for (++ptr; ISSPACE ((const unsigned char)*ptr);
2959 check_source (++ptr < clean_text_limit, 0))
2964 /* Copy a chunk of text of length `len' and starting at `str' to the current
2965 output buffer. Note that all attempts to add stuff to the current output
2966 buffer ultimately go through here. */
2969 output_bytes (str, len)
2973 if ((repl_write_ptr + 1) + len >= repl_text_limit)
2975 size_t new_size = (repl_text_limit - repl_text_base) << 1;
2976 char *new_buf = (char *) xrealloc (repl_text_base, new_size);
2978 repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
2979 repl_text_base = new_buf;
2980 repl_text_limit = new_buf + new_size;
2982 memcpy (repl_write_ptr + 1, str, len);
2983 repl_write_ptr += len;
2986 /* Copy all bytes (except the trailing null) of a null terminated string to
2987 the current output buffer. */
2993 output_bytes (str, strlen (str));
2996 /* Copy some characters from the original text buffer to the current output
2999 This routine takes a pointer argument `p' which is assumed to be a pointer
3000 into the cleaned text buffer. The bytes which are copied are the `original'
3001 equivalents for the set of bytes between the last value of `clean_read_ptr'
3002 and the argument value `p'.
3004 The set of bytes copied however, comes *not* from the cleaned text buffer,
3005 but rather from the direct counterparts of these bytes within the original
3008 Thus, when this function is called, some bytes from the original text
3009 buffer (which may include original comments and preprocessing directives)
3010 will be copied into the output buffer.
3012 Note that the request implied when this routine is called includes the
3013 byte pointed to by the argument pointer `p'. */
3019 size_t copy_length = (size_t) (p - clean_read_ptr);
3020 const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
3022 if (copy_length == 0)
3025 output_bytes (copy_start, copy_length);
3029 /* Given a pointer to a def_dec_info record which represents some form of
3030 definition of a function (perhaps a real definition, or in lieu of that
3031 perhaps just a declaration with a full prototype) return true if this
3032 function is one which we should avoid converting. Return false
3036 other_variable_style_function (ansi_header)
3037 const char *ansi_header;
3041 /* See if we have a stdarg function, or a function which has stdarg style
3042 parameters or a stdarg style return type. */
3044 return substr (ansi_header, "...") != 0;
3046 #else /* !defined (UNPROTOIZE) */
3048 /* See if we have a varargs function, or a function which has varargs style
3049 parameters or a varargs style return type. */
3052 int len = strlen (varargs_style_indicator);
3054 for (p = ansi_header; p; )
3056 const char *candidate;
3058 if ((candidate = substr (p, varargs_style_indicator)) == 0)
3061 if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
3067 #endif /* !defined (UNPROTOIZE) */
3070 /* Do the editing operation specifically for a function "declaration". Note
3071 that editing for function "definitions" are handled in a separate routine
3075 edit_fn_declaration (def_dec_p, clean_text_p)
3076 const def_dec_info *def_dec_p;
3077 const char *volatile clean_text_p;
3079 const char *start_formals;
3080 const char *end_formals;
3081 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3082 size_t func_name_len = strlen (function_to_edit);
3083 const char *end_of_fn_name;
3087 const f_list_chain_item *this_f_list_chain_item;
3088 const def_dec_info *definition = def_dec_p->definition;
3090 /* If we are protoizing, and if we found no corresponding definition for
3091 this particular function declaration, then just leave this declaration
3092 exactly as it is. */
3097 /* If we are protoizing, and if the corresponding definition that we found
3098 for this particular function declaration defined an old style varargs
3099 function, then we want to issue a warning and just leave this function
3100 declaration unconverted. */
3102 if (other_variable_style_function (definition->ansi_decl))
3105 fprintf (stderr, "%s: %d: warning: varargs function declaration not converted\n",
3106 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3111 #endif /* !defined (UNPROTOIZE) */
3113 /* Setup here to recover from confusing source code detected during this
3114 particular "edit". */
3117 if (setjmp (source_confusion_recovery))
3119 restore_pointers ();
3120 fprintf (stderr, "%s: declaration of function `%s' not converted\n",
3121 pname, function_to_edit);
3125 /* We are editing a function declaration. The line number we did a seek to
3126 contains the comma or semicolon which follows the declaration. Our job
3127 now is to scan backwards looking for the function name. This name *must*
3128 be followed by open paren (ignoring whitespace, of course). We need to
3129 replace everything between that open paren and the corresponding closing
3130 paren. If we are protoizing, we need to insert the prototype-style
3131 formals lists. If we are unprotoizing, we need to just delete everything
3132 between the pairs of opening and closing parens. */
3134 /* First move up to the end of the line. */
3136 while (*clean_text_p != '\n')
3137 check_source (++clean_text_p < clean_text_limit, 0);
3138 clean_text_p--; /* Point to just before the newline character. */
3140 /* Now we can scan backwards for the function name. */
3146 /* Scan leftwards until we find some character which can be
3147 part of an identifier. */
3149 while (!is_id_char (*clean_text_p))
3150 check_source (--clean_text_p > clean_read_ptr, 0);
3152 /* Scan backwards until we find a char that cannot be part of an
3155 while (is_id_char (*clean_text_p))
3156 check_source (--clean_text_p > clean_read_ptr, 0);
3158 /* Having found an "id break", see if the following id is the one
3159 that we are looking for. If so, then exit from this loop. */
3161 if (!strncmp (clean_text_p+1, function_to_edit, func_name_len))
3163 char ch = *(clean_text_p + 1 + func_name_len);
3165 /* Must also check to see that the name in the source text
3166 ends where it should (in order to prevent bogus matches
3167 on similar but longer identifiers. */
3169 if (! is_id_char (ch))
3170 break; /* exit from loop */
3174 /* We have now found the first perfect match for the function name in
3175 our backward search. This may or may not be the actual function
3176 name at the start of the actual function declaration (i.e. we could
3177 have easily been mislead). We will try to avoid getting fooled too
3178 often by looking forward for the open paren which should follow the
3179 identifier we just found. We ignore whitespace while hunting. If
3180 the next non-whitespace byte we see is *not* an open left paren,
3181 then we must assume that we have been fooled and we start over
3182 again accordingly. Note that there is no guarantee, that even if
3183 we do see the open paren, that we are in the right place.
3184 Programmers do the strangest things sometimes! */
3186 end_of_fn_name = clean_text_p + strlen (def_dec_p->hash_entry->symbol);
3187 start_formals = forward_to_next_token_char (end_of_fn_name);
3189 while (*start_formals != '(');
3191 /* start_of_formals now points to the opening left paren which immediately
3192 follows the name of the function. */
3194 /* Note that there may be several formals lists which need to be modified
3195 due to the possibility that the return type of this function is a
3196 pointer-to-function type. If there are several formals lists, we
3197 convert them in left-to-right order here. */
3200 this_f_list_chain_item = definition->f_list_chain;
3201 #endif /* !defined (UNPROTOIZE) */
3208 end_formals = start_formals + 1;
3210 for (; depth; check_source (++end_formals < clean_text_limit, 0))
3212 switch (*end_formals)
3225 /* end_formals now points to the closing right paren of the formals
3226 list whose left paren is pointed to by start_formals. */
3228 /* Now, if we are protoizing, we insert the new ANSI-style formals list
3229 attached to the associated definition of this function. If however
3230 we are unprotoizing, then we simply delete any formals list which
3233 output_up_to (start_formals);
3235 if (this_f_list_chain_item)
3237 output_string (this_f_list_chain_item->formals_list);
3238 this_f_list_chain_item = this_f_list_chain_item->chain_next;
3243 fprintf (stderr, "%s: warning: too many parameter lists in declaration of `%s'\n",
3244 pname, def_dec_p->hash_entry->symbol);
3245 check_source (0, end_formals); /* leave the declaration intact */
3247 #endif /* !defined (UNPROTOIZE) */
3248 clean_read_ptr = end_formals - 1;
3250 /* Now see if it looks like there may be another formals list associated
3251 with the function declaration that we are converting (following the
3252 formals list that we just converted. */
3255 const char *another_r_paren = forward_to_next_token_char (end_formals);
3257 if ((*another_r_paren != ')')
3258 || (*(start_formals = forward_to_next_token_char (another_r_paren)) != '('))
3261 if (this_f_list_chain_item)
3264 fprintf (stderr, "\n%s: warning: too few parameter lists in declaration of `%s'\n",
3265 pname, def_dec_p->hash_entry->symbol);
3266 check_source (0, start_formals); /* leave the decl intact */
3268 #endif /* !defined (UNPROTOIZE) */
3274 /* There does appear to be yet another formals list, so loop around
3275 again, and convert it also. */
3279 /* Edit a whole group of formals lists, starting with the rightmost one
3280 from some set of formals lists. This routine is called once (from the
3281 outside) for each function declaration which is converted. It is
3282 recursive however, and it calls itself once for each remaining formal
3283 list that lies to the left of the one it was originally called to work
3284 on. Thus, a whole set gets done in right-to-left order.
3286 This routine returns non-zero if it thinks that it should not be trying
3287 to convert this particular function definition (because the name of the
3288 function doesn't match the one expected). */
3291 edit_formals_lists (end_formals, f_list_count, def_dec_p)
3292 const char *end_formals;
3293 unsigned int f_list_count;
3294 const def_dec_info *def_dec_p;
3296 const char *start_formals;
3299 start_formals = end_formals - 1;
3301 for (; depth; check_source (--start_formals > clean_read_ptr, 0))
3303 switch (*start_formals)
3315 /* start_formals now points to the opening left paren of the formals list. */
3321 const char *next_end;
3323 /* There should be more formal lists to the left of here. */
3325 next_end = start_formals - 1;
3326 check_source (next_end > clean_read_ptr, 0);
3327 while (ISSPACE ((const unsigned char)*next_end))
3328 check_source (--next_end > clean_read_ptr, 0);
3329 check_source (*next_end == ')', next_end);
3330 check_source (--next_end > clean_read_ptr, 0);
3331 check_source (*next_end == ')', next_end);
3332 if (edit_formals_lists (next_end, f_list_count, def_dec_p))
3336 /* Check that the function name in the header we are working on is the same
3337 as the one we would expect to find. If not, issue a warning and return
3340 if (f_list_count == 0)
3342 const char *expected = def_dec_p->hash_entry->symbol;
3343 const char *func_name_start;
3344 const char *func_name_limit;
3345 size_t func_name_len;
3347 for (func_name_limit = start_formals-1;
3348 ISSPACE ((const unsigned char)*func_name_limit); )
3349 check_source (--func_name_limit > clean_read_ptr, 0);
3351 for (func_name_start = func_name_limit++;
3352 is_id_char (*func_name_start);
3354 check_source (func_name_start > clean_read_ptr, 0);
3356 func_name_len = func_name_limit - func_name_start;
3357 if (func_name_len == 0)
3358 check_source (0, func_name_start);
3359 if (func_name_len != strlen (expected)
3360 || strncmp (func_name_start, expected, func_name_len))
3362 fprintf (stderr, "%s: %d: warning: found `%s' but expected `%s'\n",
3363 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3364 identify_lineno (func_name_start),
3365 dupnstr (func_name_start, func_name_len),
3371 output_up_to (start_formals);
3374 if (f_list_count == 0)
3375 output_string (def_dec_p->formal_names);
3376 #else /* !defined (UNPROTOIZE) */
3378 unsigned f_list_depth;
3379 const f_list_chain_item *flci_p = def_dec_p->f_list_chain;
3381 /* At this point, the current value of f_list count says how many
3382 links we have to follow through the f_list_chain to get to the
3383 particular formals list that we need to output next. */
3385 for (f_list_depth = 0; f_list_depth < f_list_count; f_list_depth++)
3386 flci_p = flci_p->chain_next;
3387 output_string (flci_p->formals_list);
3389 #endif /* !defined (UNPROTOIZE) */
3391 clean_read_ptr = end_formals - 1;
3395 /* Given a pointer to a byte in the clean text buffer which points to
3396 the beginning of a line that contains a "follower" token for a
3397 function definition header, do whatever is necessary to find the
3398 right closing paren for the rightmost formals list of the function
3399 definition header. */
3402 find_rightmost_formals_list (clean_text_p)
3403 const char *clean_text_p;
3405 const char *end_formals;
3407 /* We are editing a function definition. The line number we did a seek
3408 to contains the first token which immediately follows the entire set of
3409 formals lists which are part of this particular function definition
3412 Our job now is to scan leftwards in the clean text looking for the
3413 right-paren which is at the end of the function header's rightmost
3416 If we ignore whitespace, this right paren should be the first one we
3417 see which is (ignoring whitespace) immediately followed either by the
3418 open curly-brace beginning the function body or by an alphabetic
3419 character (in the case where the function definition is in old (K&R)
3420 style and there are some declarations of formal parameters). */
3422 /* It is possible that the right paren we are looking for is on the
3423 current line (together with its following token). Just in case that
3424 might be true, we start out here by skipping down to the right end of
3425 the current line before starting our scan. */
3427 for (end_formals = clean_text_p; *end_formals != '\n'; end_formals++)
3433 /* Now scan backwards while looking for the right end of the rightmost
3434 formals list associated with this function definition. */
3438 const char *l_brace_p;
3440 /* Look leftward and try to find a right-paren. */
3442 while (*end_formals != ')')
3444 if (ISSPACE ((unsigned char)*end_formals))
3445 while (ISSPACE ((unsigned char)*end_formals))
3446 check_source (--end_formals > clean_read_ptr, 0);
3448 check_source (--end_formals > clean_read_ptr, 0);
3451 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3452 /* Since we are unprotoizing an ANSI-style (prototyped) function
3453 definition, there had better not be anything (except whitespace)
3454 between the end of the ANSI formals list and the beginning of the
3455 function body (i.e. the '{'). */
3457 check_source (ch == '{', l_brace_p);
3460 #else /* !defined (UNPROTOIZE) */
3462 /* Now scan backwards while looking for the right end of the rightmost
3463 formals list associated with this function definition. */
3468 const char *l_brace_p;
3470 /* Look leftward and try to find a right-paren. */
3472 while (*end_formals != ')')
3474 if (ISSPACE ((const unsigned char)*end_formals))
3475 while (ISSPACE ((const unsigned char)*end_formals))
3476 check_source (--end_formals > clean_read_ptr, 0);
3478 check_source (--end_formals > clean_read_ptr, 0);
3481 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3483 /* Since it is possible that we found a right paren before the starting
3484 '{' of the body which IS NOT the one at the end of the real K&R
3485 formals list (say for instance, we found one embedded inside one of
3486 the old K&R formal parameter declarations) we have to check to be
3487 sure that this is in fact the right paren that we were looking for.
3489 The one we were looking for *must* be followed by either a '{' or
3490 by an alphabetic character, while others *cannot* validly be followed
3491 by such characters. */
3493 if ((ch == '{') || ISALPHA ((unsigned char)ch))
3496 /* At this point, we have found a right paren, but we know that it is
3497 not the one we were looking for, so backup one character and keep
3500 check_source (--end_formals > clean_read_ptr, 0);
3503 #endif /* !defined (UNPROTOIZE) */
3510 /* Insert into the output file a totally new declaration for a function
3511 which (up until now) was being called from within the current block
3512 without having been declared at any point such that the declaration
3513 was visible (i.e. in scope) at the point of the call.
3515 We need to add in explicit declarations for all such function calls
3516 in order to get the full benefit of prototype-based function call
3517 parameter type checking. */
3520 add_local_decl (def_dec_p, clean_text_p)
3521 const def_dec_info *def_dec_p;
3522 const char *clean_text_p;
3524 const char *start_of_block;
3525 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3527 /* Don't insert new local explicit declarations unless explicitly requested
3533 /* Setup here to recover from confusing source code detected during this
3534 particular "edit". */
3537 if (setjmp (source_confusion_recovery))
3539 restore_pointers ();
3540 fprintf (stderr, "%s: local declaration for function `%s' not inserted\n",
3541 pname, function_to_edit);
3545 /* We have already done a seek to the start of the line which should
3546 contain *the* open curly brace which begins the block in which we need
3547 to insert an explicit function declaration (to replace the implicit one).
3549 Now we scan that line, starting from the left, until we find the
3550 open curly brace we are looking for. Note that there may actually be
3551 multiple open curly braces on the given line, but we will be happy
3552 with the leftmost one no matter what. */
3554 start_of_block = clean_text_p;
3555 while (*start_of_block != '{' && *start_of_block != '\n')
3556 check_source (++start_of_block < clean_text_limit, 0);
3558 /* Note that the line from the original source could possibly
3559 contain *no* open curly braces! This happens if the line contains
3560 a macro call which expands into a chunk of text which includes a
3561 block (and that block's associated open and close curly braces).
3562 In cases like this, we give up, issue a warning, and do nothing. */
3564 if (*start_of_block != '{')
3568 "\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
3569 def_dec_p->file->hash_entry->symbol, def_dec_p->line,
3570 def_dec_p->hash_entry->symbol);
3574 /* Figure out what a nice (pretty) indentation would be for the new
3575 declaration we are adding. In order to do this, we must scan forward
3576 from the '{' until we find the first line which starts with some
3577 non-whitespace characters (i.e. real "token" material). */
3580 const char *ep = forward_to_next_token_char (start_of_block) - 1;
3583 /* Now we have ep pointing at the rightmost byte of some existing indent
3584 stuff. At least that is the hope.
3586 We can now just scan backwards and find the left end of the existing
3587 indentation string, and then copy it to the output buffer. */
3589 for (sp = ep; ISSPACE ((const unsigned char)*sp) && *sp != '\n'; sp--)
3592 /* Now write out the open { which began this block, and any following
3593 trash up to and including the last byte of the existing indent that
3598 /* Now we go ahead and insert the new declaration at this point.
3600 If the definition of the given function is in the same file that we
3601 are currently editing, and if its full ANSI declaration normally
3602 would start with the keyword `extern', suppress the `extern'. */
3605 const char *decl = def_dec_p->definition->ansi_decl;
3607 if ((*decl == 'e') && (def_dec_p->file == def_dec_p->definition->file))
3609 output_string (decl);
3612 /* Finally, write out a new indent string, just like the preceding one
3613 that we found. This will typically include a newline as the first
3614 character of the indent string. */
3616 output_bytes (sp, (size_t) (ep - sp) + 1);
3620 /* Given a pointer to a file_info record, and a pointer to the beginning
3621 of a line (in the clean text buffer) which is assumed to contain the
3622 first "follower" token for the first function definition header in the
3623 given file, find a good place to insert some new global function
3624 declarations (which will replace scattered and imprecise implicit ones)
3625 and then insert the new explicit declaration at that point in the file. */
3628 add_global_decls (file_p, clean_text_p)
3629 const file_info *file_p;
3630 const char *clean_text_p;
3632 const def_dec_info *dd_p;
3635 /* Setup here to recover from confusing source code detected during this
3636 particular "edit". */
3639 if (setjmp (source_confusion_recovery))
3641 restore_pointers ();
3642 fprintf (stderr, "%s: global declarations for file `%s' not inserted\n",
3643 pname, shortpath (NULL, file_p->hash_entry->symbol));
3647 /* Start by finding a good location for adding the new explicit function
3648 declarations. To do this, we scan backwards, ignoring whitespace
3649 and comments and other junk until we find either a semicolon, or until
3650 we hit the beginning of the file. */
3652 scan_p = find_rightmost_formals_list (clean_text_p);
3655 if (scan_p < clean_text_base)
3657 check_source (scan_p > clean_read_ptr, 0);
3662 /* scan_p now points either to a semicolon, or to just before the start
3663 of the whole file. */
3665 /* Now scan forward for the first non-whitespace character. In theory,
3666 this should be the first character of the following function definition
3667 header. We will put in the added declarations just prior to that. */
3670 while (ISSPACE ((const unsigned char)*scan_p))
3674 output_up_to (scan_p);
3676 /* Now write out full prototypes for all of the things that had been
3677 implicitly declared in this file (but only those for which we were
3678 actually able to find unique matching definitions). Avoid duplicates
3679 by marking things that we write out as we go. */
3682 int some_decls_added = 0;
3684 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3685 if (dd_p->is_implicit && dd_p->definition && !dd_p->definition->written)
3687 const char *decl = dd_p->definition->ansi_decl;
3689 /* If the function for which we are inserting a declaration is
3690 actually defined later in the same file, then suppress the
3691 leading `extern' keyword (if there is one). */
3693 if (*decl == 'e' && (dd_p->file == dd_p->definition->file))
3696 output_string ("\n");
3697 output_string (decl);
3698 some_decls_added = 1;
3699 ((NONCONST def_dec_info *) dd_p->definition)->written = 1;
3701 if (some_decls_added)
3702 output_string ("\n\n");
3705 /* Unmark all of the definitions that we just marked. */
3707 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3708 if (dd_p->definition)
3709 ((NONCONST def_dec_info *) dd_p->definition)->written = 0;
3712 #endif /* !defined (UNPROTOIZE) */
3714 /* Do the editing operation specifically for a function "definition". Note
3715 that editing operations for function "declarations" are handled by a
3716 separate routine above. */
3719 edit_fn_definition (def_dec_p, clean_text_p)
3720 const def_dec_info *def_dec_p;
3721 const char *clean_text_p;
3723 const char *end_formals;
3724 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3726 /* Setup here to recover from confusing source code detected during this
3727 particular "edit". */
3730 if (setjmp (source_confusion_recovery))
3732 restore_pointers ();
3733 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3734 pname, function_to_edit);
3738 end_formals = find_rightmost_formals_list (clean_text_p);
3740 /* end_of_formals now points to the closing right paren of the rightmost
3741 formals list which is actually part of the `header' of the function
3742 definition that we are converting. */
3744 /* If the header of this function definition looks like it declares a
3745 function with a variable number of arguments, and if the way it does
3746 that is different from that way we would like it (i.e. varargs vs.
3747 stdarg) then issue a warning and leave the header unconverted. */
3749 if (other_variable_style_function (def_dec_p->ansi_decl))
3752 fprintf (stderr, "%s: %d: warning: definition of %s not converted\n",
3753 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3754 identify_lineno (end_formals),
3756 output_up_to (end_formals);
3760 if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
3762 restore_pointers ();
3763 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3764 pname, function_to_edit);
3768 /* Have to output the last right paren because this never gets flushed by
3769 edit_formals_list. */
3771 output_up_to (end_formals);
3776 const char *semicolon_p;
3777 const char *limit_p;
3779 int had_newlines = 0;
3781 /* Now write out the K&R style formal declarations, one per line. */
3783 decl_p = def_dec_p->formal_decls;
3784 limit_p = decl_p + strlen (decl_p);
3785 for (;decl_p < limit_p; decl_p = semicolon_p + 2)
3787 for (semicolon_p = decl_p; *semicolon_p != ';'; semicolon_p++)
3789 output_string ("\n");
3790 output_string (indent_string);
3791 output_bytes (decl_p, (size_t) ((semicolon_p + 1) - decl_p));
3794 /* If there are no newlines between the end of the formals list and the
3795 start of the body, we should insert one now. */
3797 for (scan_p = end_formals+1; *scan_p != '{'; )
3799 if (*scan_p == '\n')
3804 check_source (++scan_p < clean_text_limit, 0);
3807 output_string ("\n");
3809 #else /* !defined (UNPROTOIZE) */
3810 /* If we are protoizing, there may be some flotsam & jetsam (like comments
3811 and preprocessing directives) after the old formals list but before
3812 the following { and we would like to preserve that stuff while effectively
3813 deleting the existing K&R formal parameter declarations. We do so here
3814 in a rather tricky way. Basically, we white out any stuff *except*
3815 the comments/pp-directives in the original text buffer, then, if there
3816 is anything in this area *other* than whitespace, we output it. */
3818 const char *end_formals_orig;
3819 const char *start_body;
3820 const char *start_body_orig;
3822 const char *scan_orig;
3823 int have_flotsam = 0;
3824 int have_newlines = 0;
3826 for (start_body = end_formals + 1; *start_body != '{';)
3827 check_source (++start_body < clean_text_limit, 0);
3829 end_formals_orig = orig_text_base + (end_formals - clean_text_base);
3830 start_body_orig = orig_text_base + (start_body - clean_text_base);
3831 scan = end_formals + 1;
3832 scan_orig = end_formals_orig + 1;
3833 for (; scan < start_body; scan++, scan_orig++)
3835 if (*scan == *scan_orig)
3837 have_newlines |= (*scan_orig == '\n');
3838 /* Leave identical whitespace alone. */
3839 if (!ISSPACE ((const unsigned char)*scan_orig))
3840 *((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
3846 output_bytes (end_formals_orig + 1,
3847 (size_t) (start_body_orig - end_formals_orig) - 1);
3850 output_string ("\n");
3852 output_string (" ");
3853 clean_read_ptr = start_body - 1;
3855 #endif /* !defined (UNPROTOIZE) */
3858 /* Clean up the clean text buffer. Do this by converting comments and
3859 preprocessing directives into spaces. Also convert line continuations
3860 into whitespace. Also, whiteout string and character literals. */
3863 do_cleaning (new_clean_text_base, new_clean_text_limit)
3864 char *new_clean_text_base;
3865 char *new_clean_text_limit;
3868 int non_whitespace_since_newline = 0;
3870 for (scan_p = new_clean_text_base; scan_p < new_clean_text_limit; scan_p++)
3874 case '/': /* Handle comments. */
3875 if (scan_p[1] != '*')
3877 non_whitespace_since_newline = 1;
3881 while (scan_p[1] != '/' || scan_p[0] != '*')
3883 if (!ISSPACE ((const unsigned char)*scan_p))
3885 if (++scan_p >= new_clean_text_limit)
3892 case '#': /* Handle pp directives. */
3893 if (non_whitespace_since_newline)
3896 while (scan_p[1] != '\n' || scan_p[0] == '\\')
3898 if (!ISSPACE ((const unsigned char)*scan_p))
3900 if (++scan_p >= new_clean_text_limit)
3906 case '\'': /* Handle character literals. */
3907 non_whitespace_since_newline = 1;
3908 while (scan_p[1] != '\'' || scan_p[0] == '\\')
3910 if (scan_p[0] == '\\'
3911 && !ISSPACE ((const unsigned char)scan_p[1]))
3913 if (!ISSPACE ((const unsigned char)*scan_p))
3915 if (++scan_p >= new_clean_text_limit)
3921 case '"': /* Handle string literals. */
3922 non_whitespace_since_newline = 1;
3923 while (scan_p[1] != '"' || scan_p[0] == '\\')
3925 if (scan_p[0] == '\\'
3926 && !ISSPACE ((const unsigned char)scan_p[1]))
3928 if (!ISSPACE ((const unsigned char)*scan_p))
3930 if (++scan_p >= new_clean_text_limit)
3933 if (!ISSPACE ((const unsigned char)*scan_p))
3938 case '\\': /* Handle line continuations. */
3939 if (scan_p[1] != '\n')
3945 non_whitespace_since_newline = 0; /* Reset. */
3954 break; /* Whitespace characters. */
3958 non_whitespace_since_newline = 1;
3964 /* Given a pointer to the closing right parenthesis for a particular formals
3965 list (in the clean text buffer) find the corresponding left parenthesis
3966 and return a pointer to it. */
3969 careful_find_l_paren (p)
3975 for (paren_depth = 1, q = p-1; paren_depth; check_source (--q >= clean_text_base, 0))
3990 /* Scan the clean text buffer for cases of function definitions that we
3991 don't really know about because they were preprocessed out when the
3992 aux info files were created.
3994 In this version of protoize/unprotoize we just give a warning for each
3995 one found. A later version may be able to at least unprotoize such
3998 Note that we may easily find all function definitions simply by
3999 looking for places where there is a left paren which is (ignoring
4000 whitespace) immediately followed by either a left-brace or by an
4001 upper or lower case letter. Whenever we find this combination, we
4002 have also found a function definition header.
4004 Finding function *declarations* using syntactic clues is much harder.
4005 I will probably try to do this in a later version though. */
4008 scan_for_missed_items (file_p)
4009 const file_info *file_p;
4011 static const char *scan_p;
4012 const char *limit = clean_text_limit - 3;
4013 static const char *backup_limit;
4015 backup_limit = clean_text_base - 1;
4017 for (scan_p = clean_text_base; scan_p < limit; scan_p++)
4021 static const char *last_r_paren;
4022 const char *ahead_p;
4024 last_r_paren = scan_p;
4026 for (ahead_p = scan_p + 1; ISSPACE ((const unsigned char)*ahead_p); )
4027 check_source (++ahead_p < limit, limit);
4029 scan_p = ahead_p - 1;
4031 if (ISALPHA ((const unsigned char)*ahead_p) || *ahead_p == '{')
4033 const char *last_l_paren;
4034 const int lineno = identify_lineno (ahead_p);
4036 if (setjmp (source_confusion_recovery))
4039 /* We know we have a function definition header. Now skip
4040 leftwards over all of its associated formals lists. */
4044 last_l_paren = careful_find_l_paren (last_r_paren);
4045 for (last_r_paren = last_l_paren-1;
4046 ISSPACE ((const unsigned char)*last_r_paren); )
4047 check_source (--last_r_paren >= backup_limit, backup_limit);
4049 while (*last_r_paren == ')');
4051 if (is_id_char (*last_r_paren))
4053 const char *id_limit = last_r_paren + 1;
4054 const char *id_start;
4056 const def_dec_info *dd_p;
4058 for (id_start = id_limit-1; is_id_char (*id_start); )
4059 check_source (--id_start >= backup_limit, backup_limit);
4061 backup_limit = id_start;
4062 if ((id_length = (size_t) (id_limit - id_start)) == 0)
4066 char *func_name = (char *) alloca (id_length + 1);
4067 static const char * const stmt_keywords[]
4068 = { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
4069 const char * const *stmt_keyword;
4071 strncpy (func_name, id_start, id_length);
4072 func_name[id_length] = '\0';
4074 /* We must check here to see if we are actually looking at
4075 a statement rather than an actual function call. */
4077 for (stmt_keyword = stmt_keywords; *stmt_keyword; stmt_keyword++)
4078 if (!strcmp (func_name, *stmt_keyword))
4082 fprintf (stderr, "%s: found definition of `%s' at %s(%d)\n",
4085 shortpath (NULL, file_p->hash_entry->symbol),
4086 identify_lineno (id_start));
4088 /* We really should check for a match of the function name
4089 here also, but why bother. */
4091 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
4092 if (dd_p->is_func_def && dd_p->line == lineno)
4095 /* If we make it here, then we did not know about this
4096 function definition. */
4098 fprintf (stderr, "%s: %d: warning: `%s' excluded by preprocessing\n",
4099 shortpath (NULL, file_p->hash_entry->symbol),
4100 identify_lineno (id_start), func_name);
4101 fprintf (stderr, "%s: function definition not converted\n",
4111 /* Do all editing operations for a single source file (either a "base" file
4112 or an "include" file). To do this we read the file into memory, keep a
4113 virgin copy there, make another cleaned in-core copy of the original file
4114 (i.e. one in which all of the comments and preprocessing directives have
4115 been replaced with whitespace), then use these two in-core copies of the
4116 file to make a new edited in-core copy of the file. Finally, rename the
4117 original file (as a way of saving it), and then write the edited version
4118 of the file from core to a disk file of the same name as the original.
4120 Note that the trick of making a copy of the original sans comments &
4121 preprocessing directives make the editing a whole lot easier. */
4125 const hash_table_entry *hp;
4127 struct stat stat_buf;
4128 const file_info *file_p = hp->fip;
4129 char *new_orig_text_base;
4130 char *new_orig_text_limit;
4131 char *new_clean_text_base;
4132 char *new_clean_text_limit;
4135 int first_definition_in_file;
4137 /* If we are not supposed to be converting this file, or if there is
4138 nothing in there which needs converting, just skip this file. */
4140 if (!needs_to_be_converted (file_p))
4143 convert_filename = file_p->hash_entry->symbol;
4145 /* Convert a file if it is in a directory where we want conversion
4146 and the file is not excluded. */
4148 if (!directory_specified_p (convert_filename)
4149 || file_excluded_p (convert_filename))
4153 /* Don't even mention "system" include files unless we are
4154 protoizing. If we are protoizing, we mention these as a
4155 gentle way of prodding the user to convert his "system"
4156 include files to prototype format. */
4157 && !in_system_include_dir (convert_filename)
4158 #endif /* defined (UNPROTOIZE) */
4160 fprintf (stderr, "%s: `%s' not converted\n",
4161 pname, shortpath (NULL, convert_filename));
4165 /* Let the user know what we are up to. */
4168 fprintf (stderr, "%s: would convert file `%s'\n",
4169 pname, shortpath (NULL, convert_filename));
4171 fprintf (stderr, "%s: converting file `%s'\n",
4172 pname, shortpath (NULL, convert_filename));
4175 /* Find out the size (in bytes) of the original file. */
4177 /* The cast avoids an erroneous warning on AIX. */
4178 if (my_stat ((char *)convert_filename, &stat_buf) == -1)
4180 int errno_val = errno;
4181 fprintf (stderr, "%s: can't get status for file `%s': %s\n",
4182 pname, shortpath (NULL, convert_filename),
4183 my_strerror (errno_val));
4186 orig_size = stat_buf.st_size;
4188 /* Allocate a buffer to hold the original text. */
4190 orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
4191 orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
4193 /* Allocate a buffer to hold the cleaned-up version of the original text. */
4195 clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
4196 clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
4197 clean_read_ptr = clean_text_base - 1;
4199 /* Allocate a buffer that will hopefully be large enough to hold the entire
4200 converted output text. As an initial guess for the maximum size of the
4201 output buffer, use 125% of the size of the original + some extra. This
4202 buffer can be expanded later as needed. */
4204 repl_size = orig_size + (orig_size >> 2) + 4096;
4205 repl_text_base = (char *) xmalloc (repl_size + 2);
4206 repl_text_limit = repl_text_base + repl_size - 1;
4207 repl_write_ptr = repl_text_base - 1;
4212 /* Open the file to be converted in READ ONLY mode. */
4214 if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1)
4216 int errno_val = errno;
4217 fprintf (stderr, "%s: can't open file `%s' for reading: %s\n",
4218 pname, shortpath (NULL, convert_filename),
4219 my_strerror (errno_val));
4223 /* Read the entire original source text file into the original text buffer
4224 in one swell fwoop. Then figure out where the end of the text is and
4225 make sure that it ends with a newline followed by a null. */
4227 if (safe_read (input_file, new_orig_text_base, orig_size) !=
4230 int errno_val = errno;
4232 fprintf (stderr, "\n%s: error reading input file `%s': %s\n",
4233 pname, shortpath (NULL, convert_filename),
4234 my_strerror (errno_val));
4241 if (orig_size == 0 || orig_text_limit[-1] != '\n')
4243 *new_orig_text_limit++ = '\n';
4247 /* Create the cleaned up copy of the original text. */
4249 memcpy (new_clean_text_base, orig_text_base,
4250 (size_t) (orig_text_limit - orig_text_base));
4251 do_cleaning (new_clean_text_base, new_clean_text_limit);
4256 size_t clean_size = orig_text_limit - orig_text_base;
4257 char *const clean_filename = (char *) alloca (strlen (convert_filename) + 6 + 1);
4259 /* Open (and create) the clean file. */
4261 strcpy (clean_filename, convert_filename);
4262 strcat (clean_filename, ".clean");
4263 if ((clean_file = creat (clean_filename, 0666)) == -1)
4265 int errno_val = errno;
4266 fprintf (stderr, "%s: can't create/open clean file `%s': %s\n",
4267 pname, shortpath (NULL, clean_filename),
4268 my_strerror (errno_val));
4272 /* Write the clean file. */
4274 safe_write (clean_file, new_clean_text_base, clean_size, clean_filename);
4280 /* Do a simplified scan of the input looking for things that were not
4281 mentioned in the aux info files because of the fact that they were
4282 in a region of the source which was preprocessed-out (via #if or
4285 scan_for_missed_items (file_p);
4287 /* Setup to do line-oriented forward seeking in the clean text buffer. */
4289 last_known_line_number = 1;
4290 last_known_line_start = clean_text_base;
4292 /* Now get down to business and make all of the necessary edits. */
4295 const def_dec_info *def_dec_p;
4297 first_definition_in_file = 1;
4298 def_dec_p = file_p->defs_decs;
4299 for (; def_dec_p; def_dec_p = def_dec_p->next_in_file)
4301 const char *clean_text_p = seek_to_line (def_dec_p->line);
4303 /* clean_text_p now points to the first character of the line which
4304 contains the `terminator' for the declaration or definition that
4305 we are about to process. */
4309 if (global_flag && def_dec_p->is_func_def && first_definition_in_file)
4311 add_global_decls (def_dec_p->file, clean_text_p);
4312 first_definition_in_file = 0;
4315 /* Don't edit this item if it is already in prototype format or if it
4316 is a function declaration and we have found no corresponding
4319 if (def_dec_p->prototyped
4320 || (!def_dec_p->is_func_def && !def_dec_p->definition))
4323 #endif /* !defined (UNPROTOIZE) */
4325 if (def_dec_p->is_func_def)
4326 edit_fn_definition (def_dec_p, clean_text_p);
4329 if (def_dec_p->is_implicit)
4330 add_local_decl (def_dec_p, clean_text_p);
4332 #endif /* !defined (UNPROTOIZE) */
4333 edit_fn_declaration (def_dec_p, clean_text_p);
4337 /* Finalize things. Output the last trailing part of the original text. */
4339 output_up_to (clean_text_limit - 1);
4341 /* If this is just a test run, stop now and just deallocate the buffers. */
4345 free (new_orig_text_base);
4346 free (new_clean_text_base);
4347 free (repl_text_base);
4351 /* Change the name of the original input file. This is just a quick way of
4352 saving the original file. */
4357 = (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
4359 strcpy (new_filename, convert_filename);
4360 strcat (new_filename, save_suffix);
4361 if (my_link (convert_filename, new_filename) == -1)
4363 int errno_val = errno;
4364 if (errno_val == EEXIST)
4367 fprintf (stderr, "%s: warning: file `%s' already saved in `%s'\n",
4369 shortpath (NULL, convert_filename),
4370 shortpath (NULL, new_filename));
4374 fprintf (stderr, "%s: can't link file `%s' to `%s': %s\n",
4376 shortpath (NULL, convert_filename),
4377 shortpath (NULL, new_filename),
4378 my_strerror (errno_val));
4384 if (my_unlink (convert_filename) == -1)
4386 int errno_val = errno;
4387 fprintf (stderr, "%s: can't delete file `%s': %s\n",
4388 pname, shortpath (NULL, convert_filename),
4389 my_strerror (errno_val));
4396 /* Open (and create) the output file. */
4398 if ((output_file = creat (convert_filename, 0666)) == -1)
4400 int errno_val = errno;
4401 fprintf (stderr, "%s: can't create/open output file `%s': %s\n",
4402 pname, shortpath (NULL, convert_filename),
4403 my_strerror (errno_val));
4407 /* Write the output file. */
4410 unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
4412 safe_write (output_file, repl_text_base, out_size, convert_filename);
4415 close (output_file);
4418 /* Deallocate the conversion buffers. */
4420 free (new_orig_text_base);
4421 free (new_clean_text_base);
4422 free (repl_text_base);
4424 /* Change the mode of the output file to match the original file. */
4426 /* The cast avoids an erroneous warning on AIX. */
4427 if (my_chmod ((char *)convert_filename, stat_buf.st_mode) == -1)
4429 int errno_val = errno;
4430 fprintf (stderr, "%s: can't change mode of file `%s': %s\n",
4431 pname, shortpath (NULL, convert_filename),
4432 my_strerror (errno_val));
4435 /* Note: We would try to change the owner and group of the output file
4436 to match those of the input file here, except that may not be a good
4437 thing to do because it might be misleading. Also, it might not even
4438 be possible to do that (on BSD systems with quotas for instance). */
4441 /* Do all of the individual steps needed to do the protoization (or
4442 unprotoization) of the files referenced in the aux_info files given
4443 in the command line. */
4448 const char * const *base_pp;
4449 const char * const * const end_pps
4450 = &base_source_filenames[n_base_source_files];
4454 #endif /* !defined (UNPROTOIZE) */
4456 /* One-by-one, check (and create if necessary), open, and read all of the
4457 stuff in each aux_info file. After reading each aux_info file, the
4458 aux_info_file just read will be automatically deleted unless the
4459 keep_flag is set. */
4461 for (base_pp = base_source_filenames; base_pp < end_pps; base_pp++)
4462 process_aux_info_file (*base_pp, keep_flag, 0);
4466 /* Also open and read the special SYSCALLS.c aux_info file which gives us
4467 the prototypes for all of the standard system-supplied functions. */
4469 if (nondefault_syscalls_dir)
4471 syscalls_absolute_filename
4472 = (char *) xmalloc (strlen (nondefault_syscalls_dir)
4473 + sizeof (syscalls_filename) + 1);
4474 strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
4478 syscalls_absolute_filename
4479 = (char *) xmalloc (strlen (default_syscalls_dir)
4480 + sizeof (syscalls_filename) + 1);
4481 strcpy (syscalls_absolute_filename, default_syscalls_dir);
4484 syscalls_len = strlen (syscalls_absolute_filename);
4485 if (*(syscalls_absolute_filename + syscalls_len - 1) != '/')
4487 *(syscalls_absolute_filename + syscalls_len++) = '/';
4488 *(syscalls_absolute_filename + syscalls_len) = '\0';
4490 strcat (syscalls_absolute_filename, syscalls_filename);
4492 /* Call process_aux_info_file in such a way that it does not try to
4493 delete the SYSCALLS aux_info file. */
4495 process_aux_info_file (syscalls_absolute_filename, 1, 1);
4497 #endif /* !defined (UNPROTOIZE) */
4499 /* When we first read in all of the information from the aux_info files
4500 we saved in it descending line number order, because that was likely to
4501 be faster. Now however, we want the chains of def & dec records to
4502 appear in ascending line number order as we get further away from the
4503 file_info record that they hang from. The following line causes all of
4504 these lists to be rearranged into ascending line number order. */
4506 visit_each_hash_node (filename_primary, reverse_def_dec_list);
4510 /* Now do the "real" work. The following line causes each declaration record
4511 to be "visited". For each of these nodes, an attempt is made to match
4512 up the function declaration with a corresponding function definition,
4513 which should have a full prototype-format formals list with it. Once
4514 these match-ups are made, the conversion of the function declarations
4515 to prototype format can be made. */
4517 visit_each_hash_node (function_name_primary, connect_defs_and_decs);
4519 #endif /* !defined (UNPROTOIZE) */
4521 /* Now convert each file that can be converted (and needs to be). */
4523 visit_each_hash_node (filename_primary, edit_file);
4527 /* If we are working in cplusplus mode, try to rename all .c files to .C
4528 files. Don't panic if some of the renames don't work. */
4530 if (cplusplus_flag && !nochange_flag)
4531 visit_each_hash_node (filename_primary, rename_c_file);
4533 #endif /* !defined (UNPROTOIZE) */
4536 static struct option longopts[] =
4538 {"version", 0, 0, 'V'},
4539 {"file_name", 0, 0, 'p'},
4540 {"quiet", 0, 0, 'q'},
4541 {"silent", 0, 0, 'q'},
4542 {"force", 0, 0, 'f'},
4543 {"keep", 0, 0, 'k'},
4544 {"nosave", 0, 0, 'N'},
4545 {"nochange", 0, 0, 'n'},
4546 {"compiler-options", 1, 0, 'c'},
4547 {"exclude", 1, 0, 'x'},
4548 {"directory", 1, 0, 'd'},
4550 {"indent", 1, 0, 'i'},
4552 {"local", 0, 0, 'l'},
4553 {"global", 0, 0, 'g'},
4555 {"syscalls-dir", 1, 0, 'B'},
4567 const char *params = "";
4569 pname = strrchr (argv[0], '/');
4570 pname = pname ? pname+1 : argv[0];
4572 cwd_buffer = getpwd ();
4575 fprintf (stderr, "%s: cannot get working directory: %s\n",
4576 pname, my_strerror(errno));
4577 exit (FATAL_EXIT_CODE);
4580 /* By default, convert the files in the current directory. */
4581 directory_list = string_list_cons (cwd_buffer, NULL);
4583 while ((c = getopt_long (argc, argv,
4587 "B:c:Cd:gklnNp:qvVx:",
4589 longopts, &longind)) != EOF)
4591 if (c == 0) /* Long option. */
4592 c = longopts[longind].val;
4596 compiler_file_name = optarg;
4600 = string_list_cons (abspath (NULL, optarg), directory_list);
4603 exclude_list = string_list_cons (optarg, exclude_list);
4633 indent_string = optarg;
4635 #else /* !defined (UNPROTOIZE) */
4646 nondefault_syscalls_dir = optarg;
4648 #endif /* !defined (UNPROTOIZE) */
4654 /* Set up compile_params based on -p and -c options. */
4655 munge_compile_params (params);
4657 n_base_source_files = argc - optind;
4659 /* Now actually make a list of the base source filenames. */
4661 base_source_filenames
4662 = (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
4663 n_base_source_files = 0;
4664 for (; optind < argc; optind++)
4666 const char *path = abspath (NULL, argv[optind]);
4667 int len = strlen (path);
4669 if (path[len-1] == 'c' && path[len-2] == '.')
4670 base_source_filenames[n_base_source_files++] = path;
4673 fprintf (stderr, "%s: input file names must have .c suffixes: %s\n",
4674 pname, shortpath (NULL, path));
4680 /* We are only interested in the very first identifier token in the
4681 definition of `va_list', so if there is more junk after that first
4682 identifier token, delete it from the `varargs_style_indicator'. */
4686 for (cp = varargs_style_indicator;
4687 ISALNUM ((const unsigned char)*cp) || *cp == '_'; cp++)
4690 varargs_style_indicator = savestring (varargs_style_indicator,
4691 cp - varargs_style_indicator);
4693 #endif /* !defined (UNPROTOIZE) */
4700 fprintf (stderr, "%s: %s\n", pname, version_string);
4704 exit (errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);