1 /* Protoize program - Original version by Ron Guilmette at MCC.
3 Copyright (C) 1989, 1992 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 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. */
63 #include <sys/types.h>
73 /* Include getopt.h for the sake of getopt_long.
74 We don't need the declaration of getopt, and it could conflict
75 with something from a system header file, so effectively nullify that. */
76 #define getopt getopt_loser
81 extern char *sys_errlist[];
82 extern char *version_string;
84 /* Systems which are compatible only with POSIX 1003.1-1988 (but *not*
85 with POSIX 1003.1-1990), e.g. Ultrix 4.2, might not have
86 const qualifiers in the prototypes in the system include files.
87 Unfortunately, this can lead to GCC issuing lots of warnings for
88 calls to the following functions. To eliminate these warnings we
89 provide the following #defines. */
91 #define my_access(file,flag) access((char *)file, flag)
92 #define my_stat(file,pkt) stat((char *)file, pkt)
93 #define my_execvp(prog,argv) execvp((char *)prog, (char **)argv)
94 #define my_link(file1, file2) link((char *)file1, (char *)file2)
95 #define my_unlink(file) unlink((char *)file)
96 #define my_open(file, mode, flag) open((char *)file, mode, flag)
97 #define my_chmod(file, mode) chmod((char *)file, mode)
99 extern char *getpwd ();
101 /* Aliases for pointers to void.
102 These were made to facilitate compilation with old brain-dead DEC C
103 compilers which didn't properly grok `void*' types. */
106 typedef void * pointer_type;
107 typedef const void * const_pointer_type;
109 typedef char * pointer_type;
110 typedef char * const_pointer_type;
121 #else /* !defined(POSIX) */
123 #define R_OK 4 /* Test for Read permission */
124 #define W_OK 2 /* Test for Write permission */
125 #define X_OK 1 /* Test for eXecute permission */
126 #define F_OK 0 /* Test for existence of File */
131 /* Declaring stat or __flsbuf with a prototype
132 causes conflicts with system headers on some systems. */
135 extern VOLATILE void abort ();
139 #if 0 /* These conflict with stdio.h on some systems. */
140 extern int fprintf (FILE *, const char *, ...);
141 extern int printf (const char *, ...);
142 extern int open (const char *, int, ...);
145 extern pointer_type malloc ();
146 extern pointer_type realloc ();
151 extern int fflush ();
157 extern int unlink ();
158 extern int access ();
159 extern int execvp ();
161 extern int setjmp ();
164 extern void longjmp ();
167 extern char * strcat ();
168 extern int strcmp ();
169 extern char * strcpy ();
170 #if 0 /* size_t from sys/types.h may fail to match GCC.
171 If so, we would get a warning from this. */
172 extern size_t strlen ()
174 extern int strncmp ();
175 extern char * strncpy ();
176 extern char * rindex ();
178 /* Fork is not declared because the declaration caused a conflict
180 #if !(defined (USG) || defined (VMS))
182 #endif /* (defined (USG) || defined (VMS)) */
184 #endif /* !defined (POSIX) */
186 /* Look for these where the `const' qualifier is intentionally cast aside. */
190 /* Define a STRINGIFY macro that's right for ANSI or traditional C. */
193 #define STRINGIFY(STRING) #STRING
195 #define STRINGIFY(STRING) "STRING"
198 /* Define a default place to find the SYSCALLS.X file. */
200 #ifndef STD_PROTO_DIR
201 #define STD_PROTO_DIR "/usr/local/lib"
202 #endif /* !defined (STD_PROTO_DIR) */
204 /* Suffix of aux_info files. */
206 static const char * const aux_info_suffix = ".X";
208 /* String to attach to filenames for saved versions of original files. */
210 static const char * const save_suffix = ".save";
214 /* File name of the file which contains descriptions of standard system
215 routines. Note that we never actually do anything with this file per se,
216 but we do read in its corresponding aux_info file. */
218 static const char syscalls_filename[] = "SYSCALLS.c";
220 /* Default place to find the above file. */
222 static const char * const default_syscalls_dir = STD_PROTO_DIR;
224 /* Variable to hold the complete absolutized filename of the SYSCALLS.c.X
227 static char * syscalls_absolute_filename;
229 #endif /* !defined (UNPROTOIZE) */
231 /* Type of the structure that holds information about macro unexpansions. */
233 struct unexpansion_struct {
234 const char *expanded;
235 const char *contracted;
237 typedef struct unexpansion_struct unexpansion;
239 /* A table of conversions that may need to be made for some (stupid) older
240 operating systems where these types are preprocessor macros rather than
241 typedefs (as they really ought to be).
243 WARNING: The contracted forms must be as small (or smaller) as the
244 expanded forms, or else havoc will ensue. */
246 static const unexpansion unexpansions[] = {
247 { "struct _iobuf", "FILE" },
251 /* The number of "primary" slots in the hash tables for filenames and for
252 function names. This can be as big or as small as you like, except that
253 it must be a power of two. */
255 #define HASH_TABLE_SIZE (1 << 9)
257 /* Bit mask to use when computing hash values. */
259 static const int hash_mask = (HASH_TABLE_SIZE - 1);
261 /* Make a table of default system include directories
262 just as it is done in cccp.c. */
264 #ifndef STANDARD_INCLUDE_DIR
265 #define STANDARD_INCLUDE_DIR "/usr/include"
268 #ifndef LOCAL_INCLUDE_DIR
269 #define LOCAL_INCLUDE_DIR "/usr/local/include"
272 struct default_include { const char *fname; int cplusplus; } include_defaults[]
273 #ifdef INCLUDE_DEFAULTS
277 /* Pick up GNU C++ specific include files. */
278 { GPLUSPLUS_INCLUDE_DIR, 1},
279 { GCC_INCLUDE_DIR, 0},
280 { TOOL_INCLUDE_DIR, 0},
282 /* For cross-compilation, this dir name is generated
283 automatically in Makefile.in. */
284 { CROSS_INCLUDE_DIR, 0 },
285 #else /* not CROSS_COMPILE */
286 { LOCAL_INCLUDE_DIR, 0},
287 /* Some systems have an extra dir of include files. */
288 #ifdef SYSTEM_INCLUDE_DIR
289 { SYSTEM_INCLUDE_DIR, 0},
291 { STANDARD_INCLUDE_DIR, 0},
292 #endif /* not CROSS_COMPILE */
295 #endif /* no INCLUDE_DEFAULTS */
297 /* Datatype for lists of directories or filenames. */
301 struct string_list *next;
304 /* List of directories in which files should be converted. */
306 struct string_list *directory_list;
308 /* List of file names which should not be converted.
309 A file is excluded if the end of its name, following a /,
310 matches one of the names in this list. */
312 struct string_list *exclude_list;
314 /* The name of the other style of variable-number-of-parameters functions
315 (i.e. the style that we want to leave unconverted because we don't yet
316 know how to convert them to this style. This string is used in warning
319 /* Also define here the string that we can search for in the parameter lists
320 taken from the .X files which will unambiguously indicate that we have
321 found a varargs style function. */
324 static const char * const other_var_style = "stdarg";
325 #else /* !defined (UNPROTOIZE) */
326 static const char * const other_var_style = "varargs";
327 /* Note that this is a string containing the expansion of va_alist.
328 But in `main' we discard all but the first token. */
329 static const char *varargs_style_indicator = STRINGIFY (va_alist);
330 #endif /* !defined (UNPROTOIZE) */
332 /* The following two types are used to create hash tables. In this program,
333 there are two hash tables which are used to store and quickly lookup two
334 different classes of strings. The first type of strings stored in the
335 first hash table are absolute filenames of files which protoize needs to
336 know about. The second type of strings (stored in the second hash table)
337 are function names. It is this second class of strings which really
338 inspired the use of the hash tables, because there may be a lot of them. */
340 typedef struct hash_table_entry_struct hash_table_entry;
342 /* Do some typedefs so that we don't have to write "struct" so often. */
344 typedef struct def_dec_info_struct def_dec_info;
345 typedef struct file_info_struct file_info;
346 typedef struct f_list_chain_item_struct f_list_chain_item;
348 /* In the struct below, note that the "_info" field has two different uses
349 depending on the type of hash table we are in (i.e. either the filenames
350 hash table or the function names hash table). In the filenames hash table
351 the info fields of the entries point to the file_info struct which is
352 associated with each filename (1 per filename). In the function names
353 hash table, the info field points to the head of a singly linked list of
354 def_dec_info entries which are all defs or decs of the function whose
355 name is pointed to by the "symbol" field. Keeping all of the defs/decs
356 for a given function name on a special list specifically for that function
357 name makes it quick and easy to find out all of the important information
358 about a given (named) function. */
360 struct hash_table_entry_struct {
361 hash_table_entry * hash_next; /* -> to secondary entries */
362 const char * symbol; /* -> to the hashed string */
364 const def_dec_info * _ddip;
368 #define ddip _info._ddip
369 #define fip _info._fip
371 /* Define a type specifically for our two hash tables. */
373 typedef hash_table_entry hash_table[HASH_TABLE_SIZE];
375 /* The following struct holds all of the important information about any
376 single filename (e.g. file) which we need to know about. */
378 struct file_info_struct {
379 const hash_table_entry * hash_entry; /* -> to associated hash entry */
380 const def_dec_info * defs_decs; /* -> to chain of defs/decs */
381 time_t mtime; /* Time of last modification. */
384 /* Due to the possibility that functions may return pointers to functions,
385 (which may themselves have their own parameter lists) and due to the
386 fact that returned pointers-to-functions may be of type "pointer-to-
387 function-returning-pointer-to-function" (ad nauseum) we have to keep
388 an entire chain of ANSI style formal parameter lists for each function.
390 Normally, for any given function, there will only be one formals list
391 on the chain, but you never know.
393 Note that the head of each chain of formals lists is pointed to by the
394 `f_list_chain' field of the corresponding def_dec_info record.
396 For any given chain, the item at the head of the chain is the *leftmost*
397 parameter list seen in the actual C language function declaration. If
398 there are other members of the chain, then these are linked in left-to-right
399 order from the head of the chain. */
401 struct f_list_chain_item_struct {
402 const f_list_chain_item * chain_next; /* -> to next item on chain */
403 const char * formals_list; /* -> to formals list string */
406 /* The following struct holds all of the important information about any
407 single function definition or declaration which we need to know about.
408 Note that for unprotoize we don't need to know very much because we
409 never even create records for stuff that we don't intend to convert
410 (like for instance defs and decs which are already in old K&R format
411 and "implicit" function declarations). */
413 struct def_dec_info_struct {
414 const def_dec_info * next_in_file; /* -> to rest of chain for file */
415 file_info * file; /* -> file_info for containing file */
416 int line; /* source line number of def/dec */
417 const char * ansi_decl; /* -> left end of ansi decl */
418 hash_table_entry * hash_entry; /* -> hash entry for function name */
419 unsigned int is_func_def; /* = 0 means this is a declaration */
420 const def_dec_info * next_for_func; /* -> to rest of chain for func name */
421 unsigned int f_list_count; /* count of formals lists we expect */
422 char prototyped; /* = 0 means already prototyped */
424 const f_list_chain_item * f_list_chain; /* -> chain of formals lists */
425 const def_dec_info * definition; /* -> def/dec containing related def */
426 char is_static; /* = 0 means visibility is "extern" */
427 char is_implicit; /* != 0 for implicit func decl's */
428 char written; /* != 0 means written for implicit */
429 #else /* !defined (UNPROTOIZE) */
430 const char * formal_names; /* -> to list of names of formals */
431 const char * formal_decls; /* -> to string of formal declarations */
432 #endif /* !defined (UNPROTOIZE) */
435 /* Pointer to the tail component of the filename by which this program was
436 invoked. Used everywhere in error and warning messages. */
438 static const char *pname;
440 /* Error counter. Will be non-zero if we should give up at the next convenient
443 static int errors = 0;
446 /* ??? These comments should say what the flag mean as well as the options
449 /* File name to use for running gcc. Allows GCC 2 to be named
450 something other than gcc. */
451 static const char *compiler_file_name = "gcc";
453 static int version_flag = 0; /* Print our version number. */
454 static int quiet_flag = 0; /* Don't print messages normally. */
455 static int nochange_flag = 0; /* Don't convert, just say what files
456 we would have converted. */
457 static int nosave_flag = 0; /* Don't save the old version. */
458 static int keep_flag = 0; /* Don't delete the .X files. */
459 static const char ** compile_params = 0; /* Option string for gcc. */
461 static const char *indent_string = " "; /* Indentation for newly
462 inserted parm decls. */
463 #else /* !defined (UNPROTOIZE) */
464 static int local_flag = 0; /* Insert new local decls (when?). */
465 static int global_flag = 0; /* set by -g option */
466 static int cplusplus_flag = 0; /* Rename converted files to *.C. */
467 static const char* nondefault_syscalls_dir = 0; /* Dir to look for
469 #endif /* !defined (UNPROTOIZE) */
471 /* An index into the compile_params array where we should insert the source
472 file name when we are ready to exec the C compiler. A zero value indicates
473 that we have not yet called munge_compile_params. */
475 static int input_file_name_index = 0;
477 /* An index into the compile_params array where we should insert the filename
478 for the aux info file, when we run the C compiler. */
479 static int aux_info_file_name_index = 0;
481 /* Count of command line arguments which were "filename" arguments. */
483 static int n_base_source_files = 0;
485 /* Points to a malloc'ed list of pointers to all of the filenames of base
486 source files which were specified on the command line. */
488 static const char **base_source_filenames;
490 /* Line number of the line within the current aux_info file that we
491 are currently processing. Used for error messages in case the prototypes
492 info file is corrupted somehow. */
494 static int current_aux_info_lineno;
496 /* Pointer to the name of the source file currently being converted. */
498 static const char *convert_filename;
500 /* Pointer to relative root string (taken from aux_info file) which indicates
501 where directory the user was in when he did the compilation step that
502 produced the containing aux_info file. */
504 static const char *invocation_filename;
506 /* Pointer to the base of the input buffer that holds the original text for the
507 source file currently being converted. */
509 static const char *orig_text_base;
511 /* Pointer to the byte just beyond the end of the input buffer that holds the
512 original text for the source file currently being converted. */
514 static const char *orig_text_limit;
516 /* Pointer to the base of the input buffer that holds the cleaned text for the
517 source file currently being converted. */
519 static const char *clean_text_base;
521 /* Pointer to the byte just beyond the end of the input buffer that holds the
522 cleaned text for the source file currently being converted. */
524 static const char *clean_text_limit;
526 /* Pointer to the last byte in the cleaned text buffer that we have already
527 (virtually) copied to the output buffer (or decided to ignore). */
529 static const char * clean_read_ptr;
531 /* Pointer to the base of the output buffer that holds the replacement text
532 for the source file currently being converted. */
534 static char *repl_text_base;
536 /* Pointer to the byte just beyond the end of the output buffer that holds the
537 replacement text for the source file currently being converted. */
539 static char *repl_text_limit;
541 /* Pointer to the last byte which has been stored into the output buffer.
542 The next byte to be stored should be stored just past where this points
545 static char * repl_write_ptr;
547 /* Pointer into the cleaned text buffer for the source file we are currently
548 converting. This points to the first character of the line that we last
549 did a "seek_to_line" to (see below). */
551 static const char *last_known_line_start;
553 /* Number of the line (in the cleaned text buffer) that we last did a
554 "seek_to_line" to. Will be one if we just read a new source file
555 into the cleaned text buffer. */
557 static int last_known_line_number;
559 /* The filenames hash table. */
561 static hash_table filename_primary;
563 /* The function names hash table. */
565 static hash_table function_name_primary;
567 /* The place to keep the recovery address which is used only in cases where
568 we get hopelessly confused by something in the cleaned original text. */
570 static jmp_buf source_confusion_recovery;
572 /* A pointer to the current directory filename (used by abspath). */
574 static char *cwd_buffer;
576 /* A place to save the read pointer until we are sure that an individual
577 attempt at editing will succeed. */
579 static const char * saved_clean_read_ptr;
581 /* A place to save the write pointer until we are sure that an individual
582 attempt at editing will succeed. */
584 static char * saved_repl_write_ptr;
586 /* Forward declaration. */
588 static const char *shortpath ();
590 /* Allocate some space, but check that the allocation was successful. */
591 /* alloca.c uses this, so don't make it static. */
599 rv = malloc (byte_count);
602 fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
604 return 0; /* avoid warnings */
610 /* Reallocate some space, but check that the reallocation was successful. */
613 xrealloc (old_space, byte_count)
614 pointer_type old_space;
619 rv = realloc (old_space, byte_count);
622 fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
624 return 0; /* avoid warnings */
630 /* Deallocate the area pointed to by an arbitrary pointer, but first, strip
631 the `const' qualifier from it and also make sure that the pointer value
636 const_pointer_type p;
639 free ((NONCONST pointer_type) p);
642 /* Make a copy of a string INPUT with size SIZE. */
645 savestring (input, size)
649 char *output = (char *) xmalloc (size + 1);
650 strcpy (output, input);
654 /* Make a copy of the concatenation of INPUT1 and INPUT2. */
657 savestring2 (input1, size1, input2, size2)
663 char *output = (char *) xmalloc (size1 + size2 + 1);
664 strcpy (output, input1);
665 strcpy (&output[size1], input2);
669 /* More 'friendly' abort that prints the line and file.
670 config.h can #define abort fancy_abort if you like that sort of thing. */
675 fprintf (stderr, "%s: internal abort\n", pname);
679 /* Make a duplicate of a given string in a newly allocated area. */
685 return strcpy ((char *) xmalloc (strlen (s) + 1), s);
688 /* Make a duplicate of the first N bytes of a given string in a newly
696 char *ret_val = strncpy ((char *) xmalloc (n + 1), s, n);
702 /* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
703 does not occur within s1. Assume neither s1 nor s2 are null pointers. */
708 const char *const s2;
716 for (p1 = s1, p2 = s2; c = *p2; p1++, p2++)
726 /* Get setup to recover in case the edit we are about to do goes awry. */
731 saved_clean_read_ptr = clean_read_ptr;
732 saved_repl_write_ptr = repl_write_ptr;
735 /* Call this routine to recover our previous state whenever something looks
736 too confusing in the source code we are trying to edit. */
741 clean_read_ptr = saved_clean_read_ptr;
742 repl_write_ptr = saved_repl_write_ptr;
745 /* Return true if the given character is a legal identifier character. */
751 return (isalnum (ch) || (ch == '_') || (ch == '$'));
754 /* Give a message indicating the proper way to invoke this program and then
755 exit with non-zero status. */
761 fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
763 #else /* !defined (UNPROTOIZE) */
764 fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <diname> ] [ filename ... ]'\n",
766 #endif /* !defined (UNPROTOIZE) */
770 /* Return true if the given filename (assumed to be an absolute filename)
771 designates a file residing anywhere beneath any one of the "system"
772 include directories. */
775 in_system_include_dir (path)
778 struct default_include *p;
781 abort (); /* Must be an absolutized filename. */
783 for (p = include_defaults; p->fname; p++)
784 if (!strncmp (path, p->fname, strlen (p->fname))
785 && path[strlen (p->fname)] == '/')
791 /* Return true if the given filename designates a file that the user has
792 read access to and for which the user has write access to the containing
796 file_could_be_converted (const char *path)
798 char *const dir_name = (char *) alloca (strlen (path) + 1);
800 if (my_access (path, R_OK))
804 char *dir_last_slash;
806 strcpy (dir_name, path);
807 dir_last_slash = rindex (dir_name, '/');
809 *dir_last_slash = '\0';
811 abort (); /* Should have been an absolutized filename. */
814 if (my_access (path, W_OK))
820 /* Return true if the given filename designates a file that we are allowed
821 to modify. Files which we should not attempt to modify are (a) "system"
822 include files, and (b) files which the user doesn't have write access to,
823 and (c) files which reside in directories which the user doesn't have
824 write access to. Unless requested to be quiet, give warnings about
825 files that we will not try to convert for one reason or another. An
826 exception is made for "system" include files, which we never try to
827 convert and for which we don't issue the usual warnings. */
830 file_normally_convertible (const char *path)
832 char *const dir_name = alloca (strlen (path) + 1);
834 if (in_system_include_dir (path))
838 char *dir_last_slash;
840 strcpy (dir_name, path);
841 dir_last_slash = rindex (dir_name, '/');
843 *dir_last_slash = '\0';
845 abort (); /* Should have been an absolutized filename. */
848 if (my_access (path, R_OK))
851 fprintf (stderr, "%s: warning: no read access for file `%s'\n",
852 pname, shortpath (NULL, path));
856 if (my_access (path, W_OK))
859 fprintf (stderr, "%s: warning: no write access for file `%s'\n",
860 pname, shortpath (NULL, path));
864 if (my_access (dir_name, W_OK))
867 fprintf (stderr, "%s: warning: no write access for dir containing `%s'\n",
868 pname, shortpath (NULL, path));
878 /* Return true if the given file_info struct refers to the special SYSCALLS.c.X
879 file. Return false otherwise. */
882 is_syscalls_file (fi_p)
883 const file_info *fi_p;
885 char const *f = fi_p->hash_entry->symbol;
886 size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
887 return sysl <= fl && strcmp (f + fl - sysl, syscalls_filename) == 0;
890 #endif /* !defined (UNPROTOIZE) */
892 /* Check to see if this file will need to have anything done to it on this
893 run. If there is nothing in the given file which both needs conversion
894 and for which we have the necessary stuff to do the conversion, return
895 false. Otherwise, return true.
897 Note that (for protoize) it is only valid to call this function *after*
898 the connections between declarations and definitions have all been made
899 by connect_defs_and_decs. */
902 needs_to_be_converted (file_p)
903 const file_info *file_p;
905 const def_dec_info *ddp;
909 if (is_syscalls_file (file_p))
912 #endif /* !defined (UNPROTOIZE) */
914 for (ddp = file_p->defs_decs; ddp; ddp = ddp->next_in_file)
920 /* ... and if we a protoizing and this function is in old style ... */
922 /* ... and if this a definition or is a decl with an associated def ... */
923 && (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
925 #else /* defined (UNPROTOIZE) */
927 /* ... and if we are unprotoizing and this function is in new style ... */
930 #endif /* defined (UNPROTOIZE) */
932 /* ... then the containing file needs converting. */
937 /* Return 1 if the file name NAME is in a directory
938 that should be converted. */
941 directory_specified_p (name)
944 struct string_list *p;
946 for (p = directory_list; p; p = p->next)
947 if (!strncmp (name, p->name, strlen (p->name))
948 && name[strlen (p->name)] == '/')
950 const char *q = name + strlen (p->name) + 1;
952 /* If there are more slashes, it's in a subdir, so
953 this match doesn't count. */
965 /* Return 1 if the file named NAME should be excluded from conversion. */
968 file_excluded_p (name)
971 struct string_list *p;
972 int len = strlen (name);
974 for (p = exclude_list; p; p = p->next)
975 if (!strcmp (name + len - strlen (p->name), p->name)
976 && name[len - strlen (p->name) - 1] == '/')
982 /* Construct a new element of a string_list.
983 STRING is the new element value, and REST holds the remaining elements. */
985 static struct string_list *
986 string_list_cons (string, rest)
988 struct string_list *rest;
990 struct string_list *temp
991 = (struct string_list *) xmalloc (sizeof (struct string_list));
998 /* ??? The GNU convention for mentioning function args in its comments
999 is to capitalize them. So change "hash_tab_p" to HASH_TAB_P below.
1000 Likewise for all the other functions. */
1002 /* Given a hash table, apply some function to each node in the table. The
1003 table to traverse is given as the "hash_tab_p" argument, and the
1004 function to be applied to each node in the table is given as "func"
1008 visit_each_hash_node (hash_tab_p, func)
1009 const hash_table_entry *hash_tab_p;
1012 const hash_table_entry *primary;
1014 for (primary = hash_tab_p; primary < &hash_tab_p[HASH_TABLE_SIZE]; primary++)
1015 if (primary->symbol)
1017 hash_table_entry *second;
1020 for (second = primary->hash_next; second; second = second->hash_next)
1025 /* Initialize all of the fields of a new hash table entry, pointed
1026 to by the "p" parameter. Note that the space to hold the entry
1027 is assumed to have already been allocated before this routine is
1030 static hash_table_entry *
1032 hash_table_entry *p;
1035 p->hash_next = NULL;
1036 p->symbol = dupstr (s);
1042 /* Look for a particular function name or filename in the particular
1043 hash table indicated by "hash_tab_p". If the name is not in the
1044 given hash table, add it. Either way, return a pointer to the
1045 hash table entry for the given name. */
1047 static hash_table_entry *
1048 lookup (hash_tab_p, search_symbol)
1049 hash_table_entry *hash_tab_p;
1050 const char *search_symbol;
1053 const char *search_symbol_char_p = search_symbol;
1054 hash_table_entry *p;
1056 while (*search_symbol_char_p)
1057 hash_value += *search_symbol_char_p++;
1058 hash_value &= hash_mask;
1059 p = &hash_tab_p[hash_value];
1061 return add_symbol (p, search_symbol);
1062 if (!strcmp (p->symbol, search_symbol))
1064 while (p->hash_next)
1067 if (!strcmp (p->symbol, search_symbol))
1070 p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
1072 return add_symbol (p, search_symbol);
1075 /* Throw a def/dec record on the junk heap.
1077 Also, since we are not using this record anymore, free up all of the
1078 stuff it pointed to. */
1084 xfree (p->ansi_decl);
1088 const f_list_chain_item * curr;
1089 const f_list_chain_item * next;
1091 for (curr = p->f_list_chain; curr; curr = next)
1093 next = curr->chain_next;
1097 #endif /* !defined (UNPROTOIZE) */
1102 /* Unexpand as many macro symbol as we can find.
1104 If the given line must be unexpanded, make a copy of it in the heap and
1105 return a pointer to the unexpanded copy. Otherwise return NULL. */
1108 unexpand_if_needed (aux_info_line)
1109 const char *aux_info_line;
1111 static char *line_buf = 0;
1112 static int line_buf_size = 0;
1113 const unexpansion* unexp_p;
1114 int got_unexpanded = 0;
1116 char *copy_p = line_buf;
1120 line_buf_size = 1024;
1121 line_buf = (char *) xmalloc (line_buf_size);
1126 /* Make a copy of the input string in line_buf, expanding as necessary. */
1128 for (s = aux_info_line; *s != '\n'; )
1130 for (unexp_p = unexpansions; unexp_p->expanded; unexp_p++)
1132 const char *in_p = unexp_p->expanded;
1133 size_t len = strlen (in_p);
1135 if (*s == *in_p && !strncmp (s, in_p, len) && !is_id_char (s[len]))
1137 int size = strlen (unexp_p->contracted);
1139 if (copy_p + size - line_buf >= line_buf_size)
1141 int offset = copy_p - line_buf;
1143 line_buf_size += size;
1144 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1145 copy_p = line_buf + offset;
1147 strcpy (copy_p, unexp_p->contracted);
1150 /* Assume the there will not be another replacement required
1151 within the text just replaced. */
1154 goto continue_outer;
1157 if (copy_p - line_buf == line_buf_size)
1159 int offset = copy_p - line_buf;
1161 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1162 copy_p = line_buf + offset;
1167 if (copy_p + 2 - line_buf >= line_buf_size)
1169 int offset = copy_p - line_buf;
1171 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1172 copy_p = line_buf + offset;
1177 return (got_unexpanded ? dupstr (line_buf) : 0);
1180 /* Return the absolutized filename for the given relative
1181 filename. Note that if that filename is already absolute, it may
1182 still be returned in a modified form because this routine also
1183 eliminates redundant slashes and single dots and eliminates double
1184 dots to get a shortest possible filename from the given input
1185 filename. The absolutization of relative filenames is made by
1186 assuming that the given filename is to be taken as relative to
1187 the first argument (cwd) or to the current directory if cwd is
1191 abspath (cwd, rel_filename)
1193 const char *rel_filename;
1195 /* Setup the current working directory as needed. */
1196 const char *cwd2 = (cwd) ? cwd : cwd_buffer;
1197 char *const abs_buffer
1198 = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
1199 char *endp = abs_buffer;
1202 /* Copy the filename (possibly preceded by the current working
1203 directory name) into the absolutization buffer. */
1208 if (rel_filename[0] != '/')
1211 while (*endp++ = *src_p++)
1213 *(endp-1) = '/'; /* overwrite null */
1215 src_p = rel_filename;
1216 while (*endp++ = *src_p++)
1220 /* Now make a copy of abs_buffer into abs_buffer, shortening the
1221 filename (by taking out slashes and dots) as we go. */
1223 outp = inp = abs_buffer;
1224 *outp++ = *inp++; /* copy first slash */
1227 *outp++ = *inp++; /* copy second slash */
1233 else if (inp[0] == '/' && outp[-1] == '/')
1238 else if (inp[0] == '.' && outp[-1] == '/')
1242 else if (inp[1] == '/')
1247 else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
1249 inp += (inp[2] == '/') ? 3 : 2;
1251 while (outp >= abs_buffer && *outp != '/')
1253 if (outp < abs_buffer)
1255 /* Catch cases like /.. where we try to backup to a
1256 point above the absolute root of the logical file
1259 fprintf (stderr, "%s: invalid file name: %s\n",
1260 pname, rel_filename);
1270 /* On exit, make sure that there is a trailing null, and make sure that
1271 the last character of the returned string is *not* a slash. */
1274 if (outp[-1] == '/')
1277 /* Make a copy (in the heap) of the stuff left in the absolutization
1278 buffer and return a pointer to the copy. */
1280 return dupstr (abs_buffer);
1283 /* Given a filename (and possibly a directory name from which the filename
1284 is relative) return a string which is the shortest possible
1285 equivalent for the corresponding full (absolutized) filename. The
1286 shortest possible equivalent may be constructed by converting the
1287 absolutized filename to be a relative filename (i.e. relative to
1288 the actual current working directory). However if a relative filename
1289 is longer, then the full absolute filename is returned.
1293 Note that "simple-minded" conversion of any given type of filename (either
1294 relative or absolute) may not result in a valid equivalent filename if any
1295 subpart of the original filename is actually a symbolic link. */
1298 shortpath (cwd, filename)
1300 const char *filename;
1304 char *cwd_p = cwd_buffer;
1306 int unmatched_slash_count = 0;
1307 size_t filename_len = strlen (filename);
1309 path_p = abspath (cwd, filename);
1310 rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
1312 while (*cwd_p && (*cwd_p == *path_p))
1317 if (!*cwd_p && (!*path_p || *path_p == '/')) /* whole pwd matched */
1319 if (!*path_p) /* input *is* the current path! */
1330 while (*cwd_p != '/') /* backup to last slash */
1337 unmatched_slash_count++;
1340 /* Find out how many directory levels in cwd were *not* matched. */
1342 if (*cwd_p++ == '/')
1343 unmatched_slash_count++;
1345 /* Now we know how long the "short name" will be.
1346 Reject it if longer than the input. */
1347 if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
1350 /* For each of them, put a `../' at the beginning of the short name. */
1351 while (unmatched_slash_count--)
1353 /* Give up if the result gets to be longer
1354 than the absolute path name. */
1355 if (rel_buffer + filename_len <= rel_buf_p + 3)
1362 /* Then tack on the unmatched part of the desired file's name. */
1365 if (rel_buffer + filename_len <= rel_buf_p)
1368 while (*rel_buf_p++ = *path_p++);
1371 if (*(rel_buf_p-1) == '/')
1372 *--rel_buf_p = '\0';
1377 /* Lookup the given filename in the hash table for filenames. If it is a
1378 new one, then the hash table info pointer will be null. In this case,
1379 we create a new file_info record to go with the filename, and we initialize
1380 that record with some reasonable values. */
1382 /* FILENAME was const, but that causes a warning on AIX when calling stat.
1383 That is probably a bug in AIX, but might as well avoid the warning. */
1386 find_file (filename, do_not_stat)
1390 hash_table_entry *hash_entry_p;
1392 hash_entry_p = lookup (filename_primary, filename);
1393 if (hash_entry_p->fip)
1394 return hash_entry_p->fip;
1397 struct stat stat_buf;
1398 file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
1400 /* If we cannot get status on any given source file, give a warning
1401 and then just set its time of last modification to infinity. */
1404 stat_buf.st_mtime = (time_t) 0;
1407 if (my_stat (filename, &stat_buf) == -1)
1409 fprintf (stderr, "%s: %s: can't get status: %s\n",
1410 pname, shortpath (NULL, filename), sys_errlist[errno]);
1411 stat_buf.st_mtime = (time_t) -1;
1415 hash_entry_p->fip = file_p;
1416 file_p->hash_entry = hash_entry_p;
1417 file_p->defs_decs = NULL;
1418 file_p->mtime = stat_buf.st_mtime;
1423 /* Generate a fatal error because some part of the aux_info file is
1427 aux_info_corrupted ()
1429 fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",
1430 pname, current_aux_info_lineno);
1434 /* ??? This comment is vague. Say what the condition is for. */
1435 /* Check to see that a condition is true. This is kind of like an assert. */
1438 check_aux_info (cond)
1442 aux_info_corrupted ();
1445 /* Given a pointer to the closing right parenthesis for a particular formals
1446 list (in an aux_info file) find the corresponding left parenthesis and
1447 return a pointer to it. */
1450 find_corresponding_lparen (p)
1456 for (paren_depth = 1, q = p-1; paren_depth; q--)
1471 /* Given a line from an aux info file, and a time at which the aux info
1472 file it came from was created, check to see if the item described in
1473 the line comes from a file which has been modified since the aux info
1474 file was created. If so, return non-zero, else return zero. */
1477 referenced_file_is_newer (l, aux_info_mtime)
1479 time_t aux_info_mtime;
1485 check_aux_info (l[0] == '/');
1486 check_aux_info (l[1] == '*');
1487 check_aux_info (l[2] == ' ');
1490 const char *filename_start = p = l + 3;
1494 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1495 strncpy (filename, filename_start, (size_t) (p - filename_start));
1496 filename[p-filename_start] = '\0';
1499 /* Call find_file to find the file_info record associated with the file
1500 which contained this particular def or dec item. Note that this call
1501 may cause a new file_info record to be created if this is the first time
1502 that we have ever known about this particular file. */
1504 fi_p = find_file (abspath (invocation_filename, filename), 0);
1506 return (fi_p->mtime > aux_info_mtime);
1509 /* Given a line of info from the aux_info file, create a new
1510 def_dec_info record to remember all of the important information about
1511 a function definition or declaration.
1513 Link this record onto the list of such records for the particular file in
1514 which it occurred in proper (descending) line number order (for now).
1516 If there is an identical record already on the list for the file, throw
1517 this one away. Doing so takes care of the (useless and troublesome)
1518 duplicates which are bound to crop up due to multiple inclusions of any
1519 given individual header file.
1521 Finally, link the new def_dec record onto the list of such records
1522 pertaining to this particular function name. */
1525 save_def_or_dec (l, is_syscalls)
1530 const char *semicolon_p;
1531 def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
1534 def_dec_p->written = 0;
1535 #endif /* !defined (UNPROTOIZE) */
1537 /* Start processing the line by picking off 5 pieces of information from
1538 the left hand end of the line. These are filename, line number,
1539 new/old/implicit flag (new = ANSI prototype format), definition or
1540 declaration flag, and extern/static flag). */
1542 check_aux_info (l[0] == '/');
1543 check_aux_info (l[1] == '*');
1544 check_aux_info (l[2] == ' ');
1547 const char *filename_start = p = l + 3;
1552 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1553 strncpy (filename, filename_start, (size_t) (p - filename_start));
1554 filename[p-filename_start] = '\0';
1556 /* Call find_file to find the file_info record associated with the file
1557 which contained this particular def or dec item. Note that this call
1558 may cause a new file_info record to be created if this is the first time
1559 that we have ever known about this particular file.
1561 Note that we started out by forcing all of the base source file names
1562 (i.e. the names of the aux_info files with the .X stripped off) into the
1563 filenames hash table, and we simultaneously setup file_info records for
1564 all of these base file names (even if they may be useless later).
1565 The file_info records for all of these "base" file names (properly)
1566 act as file_info records for the "original" (i.e. un-included) files
1567 which were submitted to gcc for compilation (when the -aux-info
1568 option was used). */
1570 def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);
1574 const char *line_number_start = ++p;
1575 char line_number[10];
1579 strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
1580 line_number[p-line_number_start] = '\0';
1581 def_dec_p->line = atoi (line_number);
1584 /* Check that this record describes a new-style, old-style, or implicit
1585 definition or declaration. */
1587 p++; /* Skip over the `:'. */
1588 check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
1590 /* Is this a new style (ANSI prototyped) definition or declaration? */
1592 def_dec_p->prototyped = (*p == 'N');
1596 /* Is this an implicit declaration? */
1598 def_dec_p->is_implicit = (*p == 'I');
1600 #endif /* !defined (UNPROTOIZE) */
1604 check_aux_info ((*p == 'C') || (*p == 'F'));
1606 /* Is this item a function definition (F) or a declaration (C). Note that
1607 we treat item taken from the syscalls file as though they were function
1608 definitions regardless of what the stuff in the file says. */
1610 def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);
1613 def_dec_p->definition = 0; /* Fill this in later if protoizing. */
1614 #endif /* !defined (UNPROTOIZE) */
1616 check_aux_info (*p++ == ' ');
1617 check_aux_info (*p++ == '*');
1618 check_aux_info (*p++ == '/');
1619 check_aux_info (*p++ == ' ');
1622 check_aux_info ((!strncmp (p, "static", 6)) || (!strncmp (p, "extern", 6)));
1623 #else /* !defined (UNPROTOIZE) */
1624 if (!strncmp (p, "static", 6))
1625 def_dec_p->is_static = -1;
1626 else if (!strncmp (p, "extern", 6))
1627 def_dec_p->is_static = 0;
1629 check_aux_info (0); /* Didn't find either `extern' or `static'. */
1630 #endif /* !defined (UNPROTOIZE) */
1633 const char *ansi_start = p;
1635 p += 6; /* Pass over the "static" or "extern". */
1637 /* We are now past the initial stuff. Search forward from here to find
1638 the terminating semicolon that should immediately follow the entire
1639 ANSI format function declaration. */
1646 /* Make a copy of the ansi declaration part of the line from the aux_info
1649 def_dec_p->ansi_decl
1650 = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
1653 /* Backup and point at the final right paren of the final argument list. */
1657 /* Now isolate a whole set of formal argument lists, one-by-one. Normally,
1658 there will only be one list to isolate, but there could be more. */
1660 def_dec_p->f_list_count = 0;
1663 def_dec_p->f_list_chain = NULL;
1664 #endif /* !defined (UNPROTOIZE) */
1668 const char *left_paren_p = find_corresponding_lparen (p);
1671 f_list_chain_item *cip =
1672 (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
1675 = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
1677 /* Add the new chain item at the head of the current list. */
1679 cip->chain_next = def_dec_p->f_list_chain;
1680 def_dec_p->f_list_chain = cip;
1682 #endif /* !defined (UNPROTOIZE) */
1683 def_dec_p->f_list_count++;
1685 p = left_paren_p - 2;
1687 /* p must now point either to another right paren, or to the last
1688 character of the name of the function that was declared/defined.
1689 If p points to another right paren, then this indicates that we
1690 are dealing with multiple formals lists. In that case, there
1691 really should be another right paren preceding this right paren. */
1696 check_aux_info (*--p == ')');
1701 const char *past_fn = p + 1;
1703 check_aux_info (*past_fn == ' ');
1705 /* Scan leftwards over the identifier that names the function. */
1707 while (is_id_char (*p))
1711 /* p now points to the leftmost character of the function name. */
1714 char *fn_string = (char *) alloca (past_fn - p + 1);
1716 strncpy (fn_string, p, (size_t) (past_fn - p));
1717 fn_string[past_fn-p] = '\0';
1718 def_dec_p->hash_entry = lookup (function_name_primary, fn_string);
1722 /* Look at all of the defs and decs for this function name that we have
1723 collected so far. If there is already one which is at the same
1724 line number in the same file, then we can discard this new def_dec_info
1727 As an extra assurance that any such pair of (nominally) identical
1728 function declarations are in fact identical, we also compare the
1729 ansi_decl parts of the lines from the aux_info files just to be on
1732 This comparison will fail if (for instance) the user was playing
1733 messy games with the preprocessor which ultimately causes one
1734 function declaration in one header file to look differently when
1735 that file is included by two (or more) other files. */
1738 const def_dec_info *other;
1740 for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func)
1742 if (def_dec_p->line == other->line && def_dec_p->file == other->file)
1744 if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
1746 fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n",
1747 def_dec_p->file->hash_entry->symbol,
1749 def_dec_p->hash_entry->symbol);
1752 free_def_dec (def_dec_p);
1760 /* If we are doing unprotoizing, we must now setup the pointers that will
1761 point to the K&R name list and to the K&R argument declarations list.
1763 Note that if this is only a function declaration, then we should not
1764 expect to find any K&R style formals list following the ANSI-style
1765 formals list. This is because GCC knows that such information is
1766 useless in the case of function declarations (function definitions
1767 are a different story however).
1769 Since we are unprotoizing, we don't need any such lists anyway.
1770 All we plan to do is to delete all characters between ()'s in any
1773 def_dec_p->formal_names = NULL;
1774 def_dec_p->formal_decls = NULL;
1776 if (def_dec_p->is_func_def)
1779 check_aux_info (*++p == ' ');
1780 check_aux_info (*++p == '/');
1781 check_aux_info (*++p == '*');
1782 check_aux_info (*++p == ' ');
1783 check_aux_info (*++p == '(');
1786 const char *kr_names_start = ++p; /* Point just inside '('. */
1790 p--; /* point to closing right paren */
1792 /* Make a copy of the K&R parameter names list. */
1794 def_dec_p->formal_names
1795 = dupnstr (kr_names_start, (size_t) (p - kr_names_start));
1798 check_aux_info (*++p == ' ');
1801 /* p now points to the first character of the K&R style declarations
1802 list (if there is one) or to the star-slash combination that ends
1803 the comment in which such lists get embedded. */
1805 /* Make a copy of the K&R formal decls list and set the def_dec record
1808 if (*p == '*') /* Are there no K&R declarations? */
1810 check_aux_info (*++p == '/');
1811 def_dec_p->formal_decls = "";
1815 const char *kr_decls_start = p;
1817 while (p[0] != '*' || p[1] != '/')
1821 check_aux_info (*p == ' ');
1823 def_dec_p->formal_decls
1824 = dupnstr (kr_decls_start, (size_t) (p - kr_decls_start));
1827 /* Handle a special case. If we have a function definition marked as
1828 being in "old" style, and if it's formal names list is empty, then
1829 it may actually have the string "void" in its real formals list
1830 in the original source code. Just to make sure, we will get setup
1831 to convert such things anyway.
1833 This kludge only needs to be here because of an insurmountable
1834 problem with generating .X files. */
1836 if (!def_dec_p->prototyped && !*def_dec_p->formal_names)
1837 def_dec_p->prototyped = 1;
1840 /* Since we are unprotoizing, if this item is already in old (K&R) style,
1841 we can just ignore it. If that is true, throw away the itme now. */
1843 if (!def_dec_p->prototyped)
1845 free_def_dec (def_dec_p);
1849 #endif /* defined (UNPROTOIZE) */
1851 /* Add this record to the head of the list of records pertaining to this
1852 particular function name. */
1854 def_dec_p->next_for_func = def_dec_p->hash_entry->ddip;
1855 def_dec_p->hash_entry->ddip = def_dec_p;
1857 /* Add this new def_dec_info record to the sorted list of def_dec_info
1858 records for this file. Note that we don't have to worry about duplicates
1859 (caused by multiple inclusions of header files) here because we have
1860 already eliminated duplicates above. */
1862 if (!def_dec_p->file->defs_decs)
1864 def_dec_p->file->defs_decs = def_dec_p;
1865 def_dec_p->next_in_file = NULL;
1869 int line = def_dec_p->line;
1870 const def_dec_info *prev = NULL;
1871 const def_dec_info *curr = def_dec_p->file->defs_decs;
1872 const def_dec_info *next = curr->next_in_file;
1874 while (next && (line < curr->line))
1878 next = next->next_in_file;
1880 if (line >= curr->line)
1882 def_dec_p->next_in_file = curr;
1884 ((NONCONST def_dec_info *) prev)->next_in_file = def_dec_p;
1886 def_dec_p->file->defs_decs = def_dec_p;
1888 else /* assert (next == NULL); */
1890 ((NONCONST def_dec_info *) curr)->next_in_file = def_dec_p;
1891 /* assert (next == NULL); */
1892 def_dec_p->next_in_file = next;
1897 /* Set up the vector COMPILE_PARAMS which is the argument list for running GCC.
1898 Also set input_file_name_index and aux_info_file_name_index
1899 to the indices of the slots where the file names should go. */
1901 /* We initialize the vector by removing -g, -O, -S, -c, and -o options,
1902 and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
1905 munge_compile_params (params_list)
1906 const char *params_list;
1908 /* Build up the contents in a temporary vector
1909 that is so big that to has to be big enough. */
1910 const char **temp_params
1911 = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
1912 int param_count = 0;
1915 temp_params[param_count++] = compiler_file_name;
1918 while (isspace (*params_list))
1922 param = params_list;
1923 while (*params_list && !isspace (*params_list))
1925 if (param[0] != '-')
1926 temp_params[param_count++]
1927 = dupnstr (param, (size_t) (params_list - param));
1936 break; /* Don't copy these. */
1938 while (isspace (*params_list))
1940 while (*params_list && !isspace (*params_list))
1944 temp_params[param_count++]
1945 = dupnstr (param, (size_t) (params_list - param));
1951 temp_params[param_count++] = "-aux-info";
1953 /* Leave room for the aux-info file name argument. */
1954 aux_info_file_name_index = param_count;
1955 temp_params[param_count++] = NULL;
1957 temp_params[param_count++] = "-S";
1958 temp_params[param_count++] = "-o";
1959 temp_params[param_count++] = "/dev/null";
1961 /* Leave room for the input file name argument. */
1962 input_file_name_index = param_count;
1963 temp_params[param_count++] = NULL;
1964 /* Terminate the list. */
1965 temp_params[param_count++] = NULL;
1967 /* Make a copy of the compile_params in heap space. */
1970 = (const char **) xmalloc (sizeof (char *) * (param_count+1));
1971 memcpy (compile_params, temp_params, sizeof (char *) * param_count);
1974 /* Do a recompilation for the express purpose of generating a new aux_info
1975 file to go with a specific base source file. */
1978 gen_aux_info_file (base_filename)
1979 const char *base_filename;
1983 if (!input_file_name_index)
1984 munge_compile_params ("");
1986 /* Store the full source file name in the argument vector. */
1987 compile_params[input_file_name_index] = shortpath (NULL, base_filename);
1988 /* Add .X to source file name to get aux-info file name. */
1989 compile_params[aux_info_file_name_index]
1990 = savestring2 (compile_params[input_file_name_index],
1991 strlen (compile_params[input_file_name_index]),
1996 fprintf (stderr, "%s: compiling `%s'\n",
1997 pname, compile_params[input_file_name_index]);
1999 if (child_pid = fork ())
2001 if (child_pid == -1)
2003 fprintf (stderr, "%s: could not fork process: %s\n",
2004 pname, sys_errlist[errno]);
2009 /* Print out the command line that the other process is now executing. */
2015 fputs ("\t", stderr);
2016 for (arg = compile_params; *arg; arg++)
2018 fputs (*arg, stderr);
2019 fputc (' ', stderr);
2021 fputc ('\n', stderr);
2029 if (wait (&wait_status) == -1)
2031 fprintf (stderr, "%s: wait failed: %s\n",
2032 pname, sys_errlist[errno]);
2035 if ((wait_status & 0x7F) != 0)
2037 fprintf (stderr, "%s: subprocess got fatal signal %d",
2038 pname, (wait_status & 0x7F));
2041 if (((wait_status & 0xFF00) >> 8) != 0)
2043 fprintf (stderr, "%s: %s exited with status %d\n",
2044 pname, base_filename, ((wait_status & 0xFF00) >> 8));
2052 if (my_execvp (compile_params[0], (char *const *) compile_params))
2054 int e = errno, f = fileno (stderr);
2055 write (f, pname, strlen (pname));
2057 write (f, compile_params[0], strlen (compile_params[0]));
2059 write (f, sys_errlist[e], strlen (sys_errlist[e]));
2063 return 1; /* Never executed. */
2067 /* Read in all of the information contained in a single aux_info file.
2068 Save all of the important stuff for later. */
2071 process_aux_info_file (base_source_filename, keep_it, is_syscalls)
2072 const char *base_source_filename;
2076 size_t base_len = strlen (base_source_filename);
2077 char * aux_info_filename
2078 = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
2079 char *aux_info_base;
2080 char *aux_info_limit;
2081 char *aux_info_relocated_name;
2082 const char *aux_info_second_line;
2083 time_t aux_info_mtime;
2084 size_t aux_info_size;
2087 /* Construct the aux_info filename from the base source filename. */
2089 strcpy (aux_info_filename, base_source_filename);
2090 strcat (aux_info_filename, aux_info_suffix);
2092 /* Check that the aux_info file exists and is readable. If it does not
2093 exist, try to create it (once only). */
2095 /* If file doesn't exist, set must_create.
2096 Likewise if it exists and we can read it but it is obsolete.
2097 Otherwise, report an error. */
2100 /* Come here with must_create set to 1 if file is out of date. */
2103 if (my_access (aux_info_filename, R_OK) == -1)
2105 if (errno == ENOENT)
2109 fprintf (stderr, "%s: warning: missing SYSCALLS file `%s'\n",
2110 pname, aux_info_filename);
2117 fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
2118 pname, shortpath (NULL, aux_info_filename),
2119 sys_errlist[errno]);
2124 #if 0 /* There is code farther down to take care of this. */
2128 stat (aux_info_file_name, &s1);
2129 stat (base_source_file_name, &s2);
2130 if (s2.st_mtime > s1.st_mtime)
2135 /* If we need a .X file, create it, and verify we can read it. */
2138 if (!gen_aux_info_file (base_source_filename))
2143 if (my_access (aux_info_filename, R_OK) == -1)
2145 fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
2146 pname, shortpath (NULL, aux_info_filename),
2147 sys_errlist[errno]);
2154 struct stat stat_buf;
2156 /* Get some status information about this aux_info file. */
2158 if (my_stat (aux_info_filename, &stat_buf) == -1)
2160 fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
2161 pname, shortpath (NULL, aux_info_filename),
2162 sys_errlist[errno]);
2167 /* Check on whether or not this aux_info file is zero length. If it is,
2168 then just ignore it and return. */
2170 if ((aux_info_size = stat_buf.st_size) == 0)
2173 /* Get the date/time of last modification for this aux_info file and
2174 remember it. We will have to check that any source files that it
2175 contains information about are at least this old or older. */
2177 aux_info_mtime = stat_buf.st_mtime;
2181 /* Compare mod time with the .c file; update .X file if obsolete.
2182 The code later on can fail to check the .c file
2183 if it did not directly define any functions. */
2185 if (my_stat (base_source_filename, &stat_buf) == -1)
2187 fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
2188 pname, shortpath (NULL, base_source_filename),
2189 sys_errlist[errno]);
2193 if (stat_buf.st_mtime > aux_info_mtime)
2204 /* Open the aux_info file. */
2206 if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1)
2208 fprintf (stderr, "%s: can't open aux info file `%s' for reading: %s\n",
2209 pname, shortpath (NULL, aux_info_filename),
2210 sys_errlist[errno]);
2214 /* Allocate space to hold the aux_info file in memory. */
2216 aux_info_base = xmalloc (aux_info_size + 1);
2217 aux_info_limit = aux_info_base + aux_info_size;
2218 *aux_info_limit = '\0';
2220 /* Read the aux_info file into memory. */
2222 if (read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
2224 fprintf (stderr, "%s: error reading aux info file `%s': %s\n",
2225 pname, shortpath (NULL, aux_info_filename),
2226 sys_errlist[errno]);
2227 free (aux_info_base);
2228 close (aux_info_file);
2232 /* Close the aux info file. */
2234 if (close (aux_info_file))
2236 fprintf (stderr, "%s: error closing aux info file `%s': %s\n",
2237 pname, shortpath (NULL, aux_info_filename),
2238 sys_errlist[errno]);
2239 free (aux_info_base);
2240 close (aux_info_file);
2245 /* Delete the aux_info file (unless requested not to). If the deletion
2246 fails for some reason, don't even worry about it. */
2248 if (must_create && !keep_it)
2249 if (my_unlink (aux_info_filename) == -1)
2250 fprintf (stderr, "%s: can't delete aux info file `%s': %s\n",
2251 pname, shortpath (NULL, aux_info_filename),
2252 sys_errlist[errno]);
2254 /* Save a pointer into the first line of the aux_info file which
2255 contains the filename of the directory from which the compiler
2256 was invoked when the associated source file was compiled.
2257 This information is used later to help create complete
2258 filenames out of the (potentially) relative filenames in
2259 the aux_info file. */
2262 char *p = aux_info_base;
2269 invocation_filename = p; /* Save a pointer to first byte of path. */
2274 while (*p++ != '\n')
2276 aux_info_second_line = p;
2277 aux_info_relocated_name = 0;
2278 if (invocation_filename[0] != '/')
2280 /* INVOCATION_FILENAME is relative;
2281 append it to BASE_SOURCE_FILENAME's dir. */
2283 aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
2284 strcpy (aux_info_relocated_name, base_source_filename);
2285 dir_end = rindex (aux_info_relocated_name, '/');
2289 dir_end = aux_info_relocated_name;
2290 strcpy (dir_end, invocation_filename);
2291 invocation_filename = aux_info_relocated_name;
2297 const char *aux_info_p;
2299 /* Do a pre-pass on the lines in the aux_info file, making sure that all
2300 of the source files referenced in there are at least as old as this
2301 aux_info file itself. If not, go back and regenerate the aux_info
2302 file anew. Don't do any of this for the syscalls file. */
2306 current_aux_info_lineno = 2;
2308 for (aux_info_p = aux_info_second_line; *aux_info_p; )
2310 if (referenced_file_is_newer (aux_info_p, aux_info_mtime))
2312 free (aux_info_base);
2313 xfree (aux_info_relocated_name);
2314 if (keep_it && my_unlink (aux_info_filename) == -1)
2316 fprintf (stderr, "%s: can't delete file `%s': %s\n",
2317 pname, shortpath (NULL, aux_info_filename),
2318 sys_errlist[errno]);
2324 /* Skip over the rest of this line to start of next line. */
2326 while (*aux_info_p != '\n')
2329 current_aux_info_lineno++;
2333 /* Now do the real pass on the aux_info lines. Save their information in
2334 the in-core data base. */
2336 current_aux_info_lineno = 2;
2338 for (aux_info_p = aux_info_second_line; *aux_info_p;)
2340 char *unexpanded_line = unexpand_if_needed (aux_info_p);
2342 if (unexpanded_line)
2344 save_def_or_dec (unexpanded_line, is_syscalls);
2345 free (unexpanded_line);
2348 save_def_or_dec (aux_info_p, is_syscalls);
2350 /* Skip over the rest of this line and get to start of next line. */
2352 while (*aux_info_p != '\n')
2355 current_aux_info_lineno++;
2359 free (aux_info_base);
2360 xfree (aux_info_relocated_name);
2365 /* Check an individual filename for a .c suffix. If the filename has this
2366 suffix, rename the file such that its suffix is changed to .C. This
2367 function implements the -C option. */
2371 const hash_table_entry *hp;
2373 const char *filename = hp->symbol;
2374 int last_char_index = strlen (filename) - 1;
2375 char *const new_filename = (char *) alloca (strlen (filename) + 1);
2377 /* Note that we don't care here if the given file was converted or not. It
2378 is possible that the given file was *not* converted, simply because there
2379 was nothing in it which actually required conversion. Even in this case,
2380 we want to do the renaming. Note that we only rename files with the .c
2383 if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.')
2386 strcpy (new_filename, filename);
2387 new_filename[last_char_index] = 'C';
2389 if (my_link (filename, new_filename) == -1)
2391 fprintf (stderr, "%s: warning: can't link file `%s' to `%s': %s\n",
2392 pname, shortpath (NULL, filename),
2393 shortpath (NULL, new_filename), sys_errlist[errno]);
2398 if (my_unlink (filename) == -1)
2400 fprintf (stderr, "%s: warning: can't delete file `%s': %s\n",
2401 pname, shortpath (NULL, filename), sys_errlist[errno]);
2407 #endif /* !defined (UNPROTOIZE) */
2409 /* Take the list of definitions and declarations attached to a particular
2410 file_info node and reverse the order of the list. This should get the
2411 list into an order such that the item with the lowest associated line
2412 number is nearest the head of the list. When these lists are originally
2413 built, they are in the opposite order. We want to traverse them in
2414 normal line number order later (i.e. lowest to highest) so reverse the
2418 reverse_def_dec_list (hp)
2419 const hash_table_entry *hp;
2421 file_info *file_p = hp->fip;
2422 const def_dec_info *prev = NULL;
2423 const def_dec_info *current = file_p->defs_decs;
2425 if (!( current = file_p->defs_decs))
2426 return; /* no list to reverse */
2429 if (! (current = current->next_in_file))
2430 return; /* can't reverse a single list element */
2432 ((NONCONST def_dec_info *) prev)->next_in_file = NULL;
2436 const def_dec_info *next = current->next_in_file;
2438 ((NONCONST def_dec_info *) current)->next_in_file = prev;
2443 file_p->defs_decs = prev;
2448 /* Find the (only?) extern definition for a particular function name, starting
2449 from the head of the linked list of entries for the given name. If we
2450 cannot find an extern definition for the given function name, issue a
2451 warning and scrounge around for the next best thing, i.e. an extern
2452 function declaration with a prototype attached to it. Note that we only
2453 allow such substitutions for extern declarations and never for static
2454 declarations. That's because the only reason we allow them at all is
2455 to let un-prototyped function declarations for system-supplied library
2456 functions get their prototypes from our own extra SYSCALLS.c.X file which
2457 contains all of the correct prototypes for system functions. */
2459 static const def_dec_info *
2460 find_extern_def (head, user)
2461 const def_dec_info *head;
2462 const def_dec_info *user;
2464 const def_dec_info *dd_p;
2465 const def_dec_info *extern_def_p = NULL;
2466 int conflict_noted = 0;
2468 /* Don't act too stupid here. Somebody may try to convert an entire system
2469 in one swell fwoop (rather than one program at a time, as should be done)
2470 and in that case, we may find that there are multiple extern definitions
2471 of a given function name in the entire set of source files that we are
2472 converting. If however one of these definitions resides in exactly the
2473 same source file as the reference we are trying to satisfy then in that
2474 case it would be stupid for us to fail to realize that this one definition
2475 *must* be the precise one we are looking for.
2477 To make sure that we don't miss an opportunity to make this "same file"
2478 leap of faith, we do a prescan of the list of records relating to the
2479 given function name, and we look (on this first scan) *only* for a
2480 definition of the function which is in the same file as the reference
2481 we are currently trying to satisfy. */
2483 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2484 if (dd_p->is_func_def && !dd_p->is_static && dd_p->file == user->file)
2487 /* Now, since we have not found a definition in the same file as the
2488 reference, we scan the list again and consider all possibilities from
2489 all files. Here we may get conflicts with the things listed in the
2490 SYSCALLS.c.X file, but if that happens it only means that the source
2491 code being converted contains its own definition of a function which
2492 could have been supplied by libc.a. In such cases, we should avoid
2493 issuing the normal warning, and defer to the definition given in the
2496 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2497 if (dd_p->is_func_def && !dd_p->is_static)
2499 if (!extern_def_p) /* Previous definition? */
2500 extern_def_p = dd_p; /* Remember the first definition found. */
2503 /* Ignore definition just found if it came from SYSCALLS.c.X. */
2505 if (is_syscalls_file (dd_p->file))
2508 /* Quietly replace the definition previously found with the one
2509 just found if the previous one was from SYSCALLS.c.X. */
2511 if (is_syscalls_file (extern_def_p->file))
2513 extern_def_p = dd_p;
2517 /* If we get here, then there is a conflict between two function
2518 declarations for the same function, both of which came from the
2521 if (!conflict_noted) /* first time we noticed? */
2524 fprintf (stderr, "%s: conflicting extern definitions of '%s'\n",
2525 pname, head->hash_entry->symbol);
2528 fprintf (stderr, "%s: declarations of '%s' will not be converted\n",
2529 pname, head->hash_entry->symbol);
2530 fprintf (stderr, "%s: conflict list for '%s' follows:\n",
2531 pname, head->hash_entry->symbol);
2532 fprintf (stderr, "%s: %s(%d): %s\n",
2534 shortpath (NULL, extern_def_p->file->hash_entry->symbol),
2535 extern_def_p->line, extern_def_p->ansi_decl);
2539 fprintf (stderr, "%s: %s(%d): %s\n",
2541 shortpath (NULL, dd_p->file->hash_entry->symbol),
2542 dd_p->line, dd_p->ansi_decl);
2546 /* We want to err on the side of caution, so if we found multiple conflicting
2547 definitions for the same function, treat this as being that same as if we
2548 had found no definitions (i.e. return NULL). */
2555 /* We have no definitions for this function so do the next best thing.
2556 Search for an extern declaration already in prototype form. */
2558 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2559 if (!dd_p->is_func_def && !dd_p->is_static && dd_p->prototyped)
2561 extern_def_p = dd_p; /* save a pointer to the definition */
2563 fprintf (stderr, "%s: warning: using formals list from %s(%d) for function `%s'\n",
2565 shortpath (NULL, dd_p->file->hash_entry->symbol),
2566 dd_p->line, dd_p->hash_entry->symbol);
2570 /* Gripe about unprototyped function declarations that we found no
2571 corresponding definition (or other source of prototype information)
2574 Gripe even if the unprototyped declaration we are worried about
2575 exists in a file in one of the "system" include directories. We
2576 can gripe about these because we should have at least found a
2577 corresponding (pseudo) definition in the SYSCALLS.c.X file. If we
2578 didn't, then that means that the SYSCALLS.c.X file is missing some
2579 needed prototypes for this particular system. That is worth telling
2584 const char *file = user->file->hash_entry->symbol;
2587 if (in_system_include_dir (file))
2589 /* Why copy this string into `needed' at all?
2590 Why not just use user->ansi_decl without copying? */
2591 char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
2594 strcpy (needed, user->ansi_decl);
2595 p = (NONCONST char *) substr (needed, user->hash_entry->symbol)
2596 + strlen (user->hash_entry->symbol) + 2;
2597 /* Avoid having ??? in the string. */
2603 fprintf (stderr, "%s: %d: `%s' used but missing from SYSCALLS\n",
2604 shortpath (NULL, file), user->line,
2605 needed+7); /* Don't print "extern " */
2609 fprintf (stderr, "%s: %d: warning: no extern definition for `%s'\n",
2610 shortpath (NULL, file), user->line,
2611 user->hash_entry->symbol);
2615 return extern_def_p;
2618 /* Find the (only?) static definition for a particular function name in a
2619 given file. Here we get the function-name and the file info indirectly
2620 from the def_dec_info record pointer which is passed in. */
2622 static const def_dec_info *
2623 find_static_definition (user)
2624 const def_dec_info *user;
2626 const def_dec_info *head = user->hash_entry->ddip;
2627 const def_dec_info *dd_p;
2628 int num_static_defs = 0;
2629 const def_dec_info *static_def_p = NULL;
2631 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2632 if (dd_p->is_func_def && dd_p->is_static && (dd_p->file == user->file))
2634 static_def_p = dd_p; /* save a pointer to the definition */
2637 if (num_static_defs == 0)
2640 fprintf (stderr, "%s: warning: no static definition for `%s' in file `%s'\n",
2641 pname, head->hash_entry->symbol,
2642 shortpath (NULL, user->file->hash_entry->symbol));
2644 else if (num_static_defs > 1)
2646 fprintf (stderr, "%s: multiple static defs of `%s' in file `%s'\n",
2647 pname, head->hash_entry->symbol,
2648 shortpath (NULL, user->file->hash_entry->symbol));
2651 return static_def_p;
2654 /* Find good prototype style formal argument lists for all of the function
2655 declarations which didn't have them before now.
2657 To do this we consider each function name one at a time. For each function
2658 name, we look at the items on the linked list of def_dec_info records for
2659 that particular name.
2661 Somewhere on this list we should find one (and only one) def_dec_info
2662 record which represents the actual function definition, and this record
2663 should have a nice formal argument list already associated with it.
2665 Thus, all we have to do is to connect up all of the other def_dec_info
2666 records for this particular function name to the special one which has
2667 the full-blown formals list.
2669 Of course it is a little more complicated than just that. See below for
2673 connect_defs_and_decs (hp)
2674 const hash_table_entry *hp;
2676 const def_dec_info *dd_p;
2677 const def_dec_info *extern_def_p = NULL;
2678 int first_extern_reference = 1;
2680 /* Traverse the list of definitions and declarations for this particular
2681 function name. For each item on the list, if it is a function
2682 definition (either old style or new style) then GCC has already been
2683 kind enough to produce a prototype for us, and it is associated with
2684 the item already, so declare the item as its own associated "definition".
2686 Also, for each item which is only a function declaration, but which
2687 nonetheless has its own prototype already (obviously supplied by the user)
2688 declare the item as it's own definition.
2690 Note that when/if there are multiple user-supplied prototypes already
2691 present for multiple declarations of any given function, these multiple
2692 prototypes *should* all match exactly with one another and with the
2693 prototype for the actual function definition. We don't check for this
2694 here however, since we assume that the compiler must have already done
2695 this consistency checking when it was creating the .X files. */
2697 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2698 if (dd_p->prototyped)
2699 ((NONCONST def_dec_info *) dd_p)->definition = dd_p;
2701 /* Traverse the list of definitions and declarations for this particular
2702 function name. For each item on the list, if it is an extern function
2703 declaration and if it has no associated definition yet, go try to find
2704 the matching extern definition for the declaration.
2706 When looking for the matching function definition, warn the user if we
2709 If we find more that one function definition also issue a warning.
2711 Do the search for the matching definition only once per unique function
2712 name (and only when absolutely needed) so that we can avoid putting out
2713 redundant warning messages, and so that we will only put out warning
2714 messages when there is actually a reference (i.e. a declaration) for
2715 which we need to find a matching definition. */
2717 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2718 if (!dd_p->is_func_def && !dd_p->is_static && !dd_p->definition)
2720 if (first_extern_reference)
2722 extern_def_p = find_extern_def (hp->ddip, dd_p);
2723 first_extern_reference = 0;
2725 ((NONCONST def_dec_info *) dd_p)->definition = extern_def_p;
2728 /* Traverse the list of definitions and declarations for this particular
2729 function name. For each item on the list, if it is a static function
2730 declaration and if it has no associated definition yet, go try to find
2731 the matching static definition for the declaration within the same file.
2733 When looking for the matching function definition, warn the user if we
2734 fail to find one in the same file with the declaration, and refuse to
2735 convert this kind of cross-file static function declaration. After all,
2736 this is stupid practice and should be discouraged.
2738 We don't have to worry about the possibility that there is more than one
2739 matching function definition in the given file because that would have
2740 been flagged as an error by the compiler.
2742 Do the search for the matching definition only once per unique
2743 function-name/source-file pair (and only when absolutely needed) so that
2744 we can avoid putting out redundant warning messages, and so that we will
2745 only put out warning messages when there is actually a reference (i.e. a
2746 declaration) for which we actually need to find a matching definition. */
2748 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2749 if (!dd_p->is_func_def && dd_p->is_static && !dd_p->definition)
2751 const def_dec_info *dd_p2;
2752 const def_dec_info *static_def;
2754 /* We have now found a single static declaration for which we need to
2755 find a matching definition. We want to minimize the work (and the
2756 number of warnings), so we will find an appropriate (matching)
2757 static definition for this declaration, and then distribute it
2758 (as the definition for) any and all other static declarations
2759 for this function name which occur within the same file, and which
2760 do not already have definitions.
2762 Note that a trick is used here to prevent subsequent attempts to
2763 call find_static_definition for a given function-name & file
2764 if the first such call returns NULL. Essentially, we convert
2765 these NULL return values to -1, and put the -1 into the definition
2766 field for each other static declaration from the same file which
2767 does not already have an associated definition.
2768 This makes these other static declarations look like they are
2769 actually defined already when the outer loop here revisits them
2770 later on. Thus, the outer loop will skip over them. Later, we
2771 turn the -1's back to NULL's. */
2773 ((NONCONST def_dec_info *) dd_p)->definition =
2774 (static_def = find_static_definition (dd_p))
2776 : (const def_dec_info *) -1;
2778 for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
2779 if (!dd_p2->is_func_def && dd_p2->is_static
2780 && !dd_p2->definition && (dd_p2->file == dd_p->file))
2781 ((NONCONST def_dec_info *)dd_p2)->definition = dd_p->definition;
2784 /* Convert any dummy (-1) definitions we created in the step above back to
2785 NULL's (as they should be). */
2787 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2788 if (dd_p->definition == (def_dec_info *) -1)
2789 ((NONCONST def_dec_info *) dd_p)->definition = NULL;
2792 #endif /* !defined (UNPROTOIZE) */
2794 /* Give a pointer into the clean text buffer, return a number which is the
2795 original source line number that the given pointer points into. */
2798 identify_lineno (clean_p)
2799 const char *clean_p;
2804 for (scan_p = clean_text_base; scan_p <= clean_p; scan_p++)
2805 if (*scan_p == '\n')
2810 /* Issue an error message and give up on doing this particular edit. */
2813 declare_source_confusing (clean_p)
2814 const char *clean_p;
2819 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2820 shortpath (NULL, convert_filename), last_known_line_number);
2822 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2823 shortpath (NULL, convert_filename),
2824 identify_lineno (clean_p));
2826 longjmp (source_confusion_recovery, 1);
2829 /* Check that a condition which is expected to be true in the original source
2830 code is in fact true. If not, issue an error message and give up on
2831 converting this particular source file. */
2834 check_source (cond, clean_p)
2836 const char *clean_p;
2839 declare_source_confusing (clean_p);
2842 /* If we think of the in-core cleaned text buffer as a memory mapped
2843 file (with the variable last_known_line_start acting as sort of a
2844 file pointer) then we can imagine doing "seeks" on the buffer. The
2845 following routine implements a kind of "seek" operation for the in-core
2846 (cleaned) copy of the source file. When finished, it returns a pointer to
2847 the start of a given (numbered) line in the cleaned text buffer.
2849 Note that protoize only has to "seek" in the forward direction on the
2850 in-core cleaned text file buffers, and it never needs to back up.
2852 This routine is made a little bit faster by remembering the line number
2853 (and pointer value) supplied (and returned) from the previous "seek".
2854 This prevents us from always having to start all over back at the top
2855 of the in-core cleaned buffer again. */
2861 if (n < last_known_line_number)
2864 while (n > last_known_line_number)
2866 while (*last_known_line_start != '\n')
2867 check_source (++last_known_line_start < clean_text_limit, 0);
2868 last_known_line_start++;
2869 last_known_line_number++;
2871 return last_known_line_start;
2874 /* Given a pointer to a character in the cleaned text buffer, return a pointer
2875 to the next non-whitepace character which follows it. */
2878 forward_to_next_token_char (ptr)
2881 for (++ptr; isspace (*ptr); check_source (++ptr < clean_text_limit, 0))
2886 /* Copy a chunk of text of length `len' and starting at `str' to the current
2887 output buffer. Note that all attempts to add stuff to the current output
2888 buffer ultimately go through here. */
2891 output_bytes (str, len)
2895 if ((repl_write_ptr + 1) + len >= repl_text_limit)
2897 size_t new_size = (repl_text_limit - repl_text_base) << 1;
2898 char *new_buf = (char *) xrealloc (repl_text_base, new_size);
2900 repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
2901 repl_text_base = new_buf;
2902 repl_text_limit = new_buf + new_size;
2904 memcpy (repl_write_ptr + 1, str, len);
2905 repl_write_ptr += len;
2908 /* Copy all bytes (except the trailing null) of a null terminated string to
2909 the current output buffer. */
2915 output_bytes (str, strlen (str));
2918 /* Copy some characters from the original text buffer to the current output
2921 This routine takes a pointer argument `p' which is assumed to be a pointer
2922 into the cleaned text buffer. The bytes which are copied are the `original'
2923 equivalents for the set of bytes between the last value of `clean_read_ptr'
2924 and the argument value `p'.
2926 The set of bytes copied however, comes *not* from the cleaned text buffer,
2927 but rather from the direct counterparts of these bytes within the original
2930 Thus, when this function is called, some bytes from the original text
2931 buffer (which may include original comments and preprocessing directives)
2932 will be copied into the output buffer.
2934 Note that the request implide when this routine is called includes the
2935 byte pointed to by the argument pointer `p'. */
2941 size_t copy_length = (size_t) (p - clean_read_ptr);
2942 const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
2944 if (copy_length == 0)
2947 output_bytes (copy_start, copy_length);
2951 /* Given a pointer to a def_dec_info record which represents some form of
2952 definition of a function (perhaps a real definition, or in lieu of that
2953 perhaps just a declaration with a full prototype) return true if this
2954 function is one which we should avoid converting. Return false
2958 other_variable_style_function (ansi_header)
2959 const char *ansi_header;
2963 /* See if we have a stdarg function, or a function which has stdarg style
2964 parameters or a stdarg style return type. */
2966 return (int) substr (ansi_header, "...");
2968 #else /* !defined (UNPROTOIZE) */
2970 /* See if we have a varargs function, or a function which has varargs style
2971 parameters or a varargs style return type. */
2974 int len = strlen (varargs_style_indicator);
2976 for (p = ansi_header; p; )
2978 const char *candidate;
2980 if ((candidate = substr (p, varargs_style_indicator)) == 0)
2983 if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
2989 #endif /* !defined (UNPROTOIZE) */
2992 /* Do the editing operation specifically for a function "declaration". Note
2993 that editing for function "definitions" are handled in a separate routine
2997 edit_fn_declaration (def_dec_p, clean_text_p)
2998 const def_dec_info *def_dec_p;
2999 const char *volatile clean_text_p;
3001 const char *start_formals;
3002 const char *end_formals;
3003 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3004 size_t func_name_len = strlen (function_to_edit);
3005 const char *end_of_fn_name;
3009 const f_list_chain_item *this_f_list_chain_item;
3010 const def_dec_info *definition = def_dec_p->definition;
3012 /* If we are protoizing, and if we found no corresponding definition for
3013 this particular function declaration, then just leave this declaration
3014 exactly as it is. */
3019 /* If we are protoizing, and if the corresponding definition that we found
3020 for this particular function declaration defined an old style varargs
3021 function, then we want to issue a warning and just leave this function
3022 declaration unconverted. */
3024 if (other_variable_style_function (definition->ansi_decl))
3027 fprintf (stderr, "%s: %d: warning: varargs function declaration not converted\n",
3028 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3033 #endif /* !defined (UNPROTOIZE) */
3035 /* Setup here to recover from confusing source code detected during this
3036 particular "edit". */
3039 if (setjmp (source_confusion_recovery))
3041 restore_pointers ();
3042 fprintf (stderr, "%s: declaration of function `%s' not converted\n",
3043 pname, function_to_edit);
3047 /* We are editing a function declaration. The line number we did a seek to
3048 contains the comma or semicolon which follows the declaration. Our job
3049 now is to scan backwards looking for the function name. This name *must*
3050 be followed by open paren (ignoring whitespace, of course). We need to
3051 replace everything between that open paren and the corresponding closing
3052 paren. If we are protoizing, we need to insert the prototype-style
3053 formals lists. If we are unprotoizing, we need to just delete everything
3054 between the pairs of opening and closing parens. */
3056 /* First move up to the end of the line. */
3058 while (*clean_text_p != '\n')
3059 check_source (++clean_text_p < clean_text_limit, 0);
3060 clean_text_p--; /* Point to just before the newline character. */
3062 /* Now we can scan backwards for the function name. */
3068 /* Scan leftwards until we find some character which can be
3069 part of an identifier. */
3071 while (!is_id_char (*clean_text_p))
3072 check_source (--clean_text_p > clean_read_ptr, 0);
3074 /* Scan backwards until we find a char that cannot be part of an
3077 while (is_id_char (*clean_text_p))
3078 check_source (--clean_text_p > clean_read_ptr, 0);
3080 /* Having found an "id break", see if the following id is the one
3081 that we are looking for. If so, then exit from this loop. */
3083 if (!strncmp (clean_text_p+1, function_to_edit, func_name_len))
3085 char ch = *(clean_text_p + 1 + func_name_len);
3087 /* Must also check to see that the name in the source text
3088 ends where it should (in order to prevent bogus matches
3089 on similar but longer identifiers. */
3091 if (! is_id_char (ch))
3092 break; /* exit from loop */
3096 /* We have now found the first perfect match for the function name in
3097 our backward search. This may or may not be the actual function
3098 name at the start of the actual function declaration (i.e. we could
3099 have easily been mislead). We will try to avoid getting fooled too
3100 often by looking forward for the open paren which should follow the
3101 identifier we just found. We ignore whitespace while hunting. If
3102 the next non-whitespace byte we see is *not* an open left paren,
3103 then we must assume that we have been fooled and we start over
3104 again accordingly. Note that there is no guarantee, that even if
3105 we do see the open paren, that we are in the right place.
3106 Programmers do the strangest things sometimes! */
3108 end_of_fn_name = clean_text_p + strlen (def_dec_p->hash_entry->symbol);
3109 start_formals = forward_to_next_token_char (end_of_fn_name);
3111 while (*start_formals != '(');
3113 /* start_of_formals now points to the opening left paren which immediately
3114 follows the name of the function. */
3116 /* Note that there may be several formals lists which need to be modified
3117 due to the possibility that the return type of this function is a
3118 pointer-to-function type. If there are several formals lists, we
3119 convert them in left-to-right order here. */
3122 this_f_list_chain_item = definition->f_list_chain;
3123 #endif /* !defined (UNPROTOIZE) */
3130 end_formals = start_formals + 1;
3132 for (; depth; check_source (++end_formals < clean_text_limit, 0))
3134 switch (*end_formals)
3147 /* end_formals now points to the closing right paren of the formals
3148 list whose left paren is pointed to by start_formals. */
3150 /* Now, if we are protoizing, we insert the new ANSI-style formals list
3151 attached to the associated definition of this function. If however
3152 we are unprotoizing, then we simply delete any formals list which
3155 output_up_to (start_formals);
3157 if (this_f_list_chain_item)
3159 output_string (this_f_list_chain_item->formals_list);
3160 this_f_list_chain_item = this_f_list_chain_item->chain_next;
3165 fprintf (stderr, "%s: warning: too many parameter lists in declaration of `%s'\n",
3166 pname, def_dec_p->hash_entry->symbol);
3167 check_source (0, end_formals); /* leave the declaration intact */
3169 #endif /* !defined (UNPROTOIZE) */
3170 clean_read_ptr = end_formals - 1;
3172 /* Now see if it looks like there may be another formals list associated
3173 with the function declaration that we are converting (following the
3174 formals list that we just converted. */
3177 const char *another_r_paren = forward_to_next_token_char (end_formals);
3179 if ((*another_r_paren != ')')
3180 || (*(start_formals = forward_to_next_token_char (another_r_paren)) != '('))
3183 if (this_f_list_chain_item)
3186 fprintf (stderr, "\n%s: warning: too few parameter lists in declaration of `%s'\n",
3187 pname, def_dec_p->hash_entry->symbol);
3188 check_source (0, start_formals); /* leave the decl intact */
3190 #endif /* !defined (UNPROTOIZE) */
3196 /* There does appear to be yet another formals list, so loop around
3197 again, and convert it also. */
3201 /* Edit a whole group of formals lists, starting with the rightmost one
3202 from some set of formals lists. This routine is called once (from the
3203 outside) for each function declaration which is converted. It is
3204 recursive however, and it calls itself once for each remaining formal
3205 list that lies to the left of the one it was originally called to work
3206 on. Thus, a whole set gets done in right-to-left order.
3208 This routine returns non-zero if it thinks that it should not be trying
3209 to convert this particular function definition (because the name of the
3210 function doesn't match the one expected). */
3213 edit_formals_lists (end_formals, f_list_count, def_dec_p)
3214 const char *end_formals;
3215 unsigned int f_list_count;
3216 const def_dec_info *def_dec_p;
3218 const char *start_formals;
3221 start_formals = end_formals - 1;
3223 for (; depth; check_source (--start_formals > clean_read_ptr, 0))
3225 switch (*start_formals)
3237 /* start_formals now points to the opening left paren of the formals list. */
3243 const char *next_end;
3245 /* There should be more formal lists to the left of here. */
3247 next_end = start_formals - 1;
3248 check_source (next_end > clean_read_ptr, 0);
3249 while (isspace (*next_end))
3250 check_source (--next_end > clean_read_ptr, 0);
3251 check_source (*next_end == ')', next_end);
3252 check_source (--next_end > clean_read_ptr, 0);
3253 check_source (*next_end == ')', next_end);
3254 if (edit_formals_lists (next_end, f_list_count, def_dec_p))
3258 /* Check that the function name in the header we are working on is the same
3259 as the one we would expect to find. If not, issue a warning and return
3262 if (f_list_count == 0)
3264 const char *expected = def_dec_p->hash_entry->symbol;
3265 const char *func_name_start;
3266 const char *func_name_limit;
3267 size_t func_name_len;
3269 for (func_name_limit = start_formals-1; isspace (*func_name_limit); )
3270 check_source (--func_name_limit > clean_read_ptr, 0);
3272 for (func_name_start = func_name_limit++;
3273 is_id_char (*func_name_start);
3275 check_source (func_name_start > clean_read_ptr, 0);
3277 func_name_len = func_name_limit - func_name_start;
3278 if (func_name_len == 0)
3279 check_source (0, func_name_start);
3280 if (func_name_len != strlen (expected)
3281 || strncmp (func_name_start, expected, func_name_len))
3283 fprintf (stderr, "%s: %d: warning: found `%s' but expected `%s'\n",
3284 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3285 identify_lineno (func_name_start),
3286 dupnstr (func_name_start, func_name_len),
3292 output_up_to (start_formals);
3295 if (f_list_count == 0)
3296 output_string (def_dec_p->formal_names);
3297 #else /* !defined (UNPROTOIZE) */
3299 unsigned f_list_depth;
3300 const f_list_chain_item *flci_p = def_dec_p->f_list_chain;
3302 /* At this point, the current value of f_list count says how many
3303 links we have to follow through the f_list_chain to get to the
3304 particular formals list that we need to output next. */
3306 for (f_list_depth = 0; f_list_depth < f_list_count; f_list_depth++)
3307 flci_p = flci_p->chain_next;
3308 output_string (flci_p->formals_list);
3310 #endif /* !defined (UNPROTOIZE) */
3312 clean_read_ptr = end_formals - 1;
3316 /* Given a pointer to a byte in the clean text buffer which points to the
3317 beginning of a line that contains a "follower" token for a function
3318 definition header, do whatever is necessary to find the right closing
3319 paren for the rightmost formals list of the function definition header.
3323 find_rightmost_formals_list (clean_text_p)
3324 const char *clean_text_p;
3326 const char *end_formals;
3328 /* We are editing a function definition. The line number we did a seek
3329 to contains the first token which immediately follows the entire set of
3330 formals lists which are part of this particular function definition
3333 Our job now is to scan leftwards in the clean text looking for the
3334 right-paren which is at the end of the function header's rightmost
3337 If we ignore whitespace, this right paren should be the first one we
3338 see which is (ignoring whitespace) immediately followed either by the
3339 open curly-brace beginning the function body or by an alphabetic
3340 character (in the case where the function definition is in old (K&R)
3341 style and there are some declarations of formal parameters). */
3343 /* It is possible that the right paren we are looking for is on the
3344 current line (together with its following token). Just in case that
3345 might be true, we start out here by skipping down to the right end of
3346 the current line before starting our scan. */
3348 for (end_formals = clean_text_p; *end_formals != '\n'; end_formals++)
3354 /* Now scan backwards while looking for the right end of the rightmost
3355 formals list associated with this function definition. */
3359 const char *l_brace_p;
3361 /* Look leftward and try to find a right-paren. */
3363 while (*end_formals != ')')
3365 if (isspace (*end_formals))
3366 while (isspace (*end_formals))
3367 check_source (--end_formals > clean_read_ptr, 0);
3369 check_source (--end_formals > clean_read_ptr, 0);
3372 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3373 /* Since we are unprotoizing an ANSI-style (prototyped) function
3374 definition, there had better not be anything (except whitespace)
3375 between the end of the ANSI formals list and the beginning of the
3376 function body (i.e. the '{'). */
3378 check_source (ch == '{', l_brace_p);
3381 #else /* !defined (UNPROTOIZE) */
3383 /* Now scan backwards while looking for the right end of the rightmost
3384 formals list associated with this function definition. */
3389 const char *l_brace_p;
3391 /* Look leftward and try to find a right-paren. */
3393 while (*end_formals != ')')
3395 if (isspace (*end_formals))
3396 while (isspace (*end_formals))
3397 check_source (--end_formals > clean_read_ptr, 0);
3399 check_source (--end_formals > clean_read_ptr, 0);
3402 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3404 /* Since it is possible that we found a right paren before the starting
3405 '{' of the body which IS NOT the one at the end of the real K&R
3406 formals list (say for instance, we found one embedded inside one of
3407 the old K&R formal parameter declarations) we have to check to be
3408 sure that this is in fact the right paren that we were looking for.
3410 The one we were looking for *must* be followed by either a '{' or
3411 by an alphabetic character, while others *cannot* legally be followed
3412 by such characters. */
3414 if ((ch == '{') || isalpha (ch))
3417 /* At this point, we have found a right paren, but we know that it is
3418 not the one we were looking for, so backup one character and keep
3421 check_source (--end_formals > clean_read_ptr, 0);
3424 #endif /* !defined (UNPROTOIZE) */
3431 /* Insert into the output file a totally new declaration for a function
3432 which (up until now) was being called from within the current block
3433 without having been declared at any point such that the declaration
3434 was visible (i.e. in scope) at the point of the call.
3436 We need to add in explicit declarations for all such function calls
3437 in order to get the full benefit of prototype-based function call
3438 parameter type checking. */
3441 add_local_decl (def_dec_p, clean_text_p)
3442 const def_dec_info *def_dec_p;
3443 const char *clean_text_p;
3445 const char *start_of_block;
3446 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3448 /* Don't insert new local explicit declarations unless explicitly requested
3454 /* Setup here to recover from confusing source code detected during this
3455 particular "edit". */
3458 if (setjmp (source_confusion_recovery))
3460 restore_pointers ();
3461 fprintf (stderr, "%s: local declaration for function `%s' not inserted\n",
3462 pname, function_to_edit);
3466 /* We have already done a seek to the start of the line which should
3467 contain *the* open curly brace which begins the block in which we need
3468 to insert an explicit function declaration (to replace the implicit one).
3470 Now we scan that line, starting from the left, until we find the
3471 open curly brace we are looking for. Note that there may actually be
3472 multiple open curly braces on the given line, but we will be happy
3473 with the leftmost one no matter what. */
3475 start_of_block = clean_text_p;
3476 while (*start_of_block != '{' && *start_of_block != '\n')
3477 check_source (++start_of_block < clean_text_limit, 0);
3479 /* Note that the line from the original source could possibly
3480 contain *no* open curly braces! This happens if the line contains
3481 a macro call which expands into a chunk of text which includes a
3482 block (and that block's associated open and close curly braces).
3483 In cases like this, we give up, issue a warning, and do nothing. */
3485 if (*start_of_block != '{')
3489 "\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
3490 def_dec_p->file->hash_entry->symbol, def_dec_p->line,
3491 def_dec_p->hash_entry->symbol);
3495 /* Figure out what a nice (pretty) indentation would be for the new
3496 declaration we are adding. In order to do this, we must scan forward
3497 from the '{' until we find the first line which starts with some
3498 non-whitespace characters (i.e. real "token" material). */
3501 const char *ep = forward_to_next_token_char (start_of_block) - 1;
3504 /* Now we have ep pointing at the rightmost byte of some existing indent
3505 stuff. At least that is the hope.
3507 We can now just scan backwards and find the left end of the existing
3508 indentation string, and then copy it to the output buffer. */
3510 for (sp = ep; isspace (*sp) && *sp != '\n'; sp--)
3513 /* Now write out the open { which began this block, and any following
3514 trash up to and including the last byte of the existing indent that
3519 /* Now we go ahead and insert the new declaration at this point.
3521 If the definition of the given function is in the same file that we
3522 are currently editing, and if its full ANSI declaration normally
3523 would start with the keyword `extern', suppress the `extern'. */
3526 const char *decl = def_dec_p->definition->ansi_decl;
3528 if ((*decl == 'e') && (def_dec_p->file == def_dec_p->definition->file))
3530 output_string (decl);
3533 /* Finally, write out a new indent string, just like the preceding one
3534 that we found. This will typically include a newline as the first
3535 character of the indent string. */
3537 output_bytes (sp, (size_t) (ep - sp) + 1);
3541 /* Given a pointer to a file_info record, and a pointer to the beginning
3542 of a line (in the clean text buffer) which is assumed to contain the
3543 first "follower" token for the first function definition header in the
3544 given file, find a good place to insert some new global function
3545 declarations (which will replace scattered and imprecise implicit ones)
3546 and then insert the new explicit declaration at that point in the file. */
3549 add_global_decls (file_p, clean_text_p)
3550 const file_info *file_p;
3551 const char *clean_text_p;
3553 const def_dec_info *dd_p;
3556 /* Setup here to recover from confusing source code detected during this
3557 particular "edit". */
3560 if (setjmp (source_confusion_recovery))
3562 restore_pointers ();
3563 fprintf (stderr, "%s: global declarations for file `%s' not inserted\n",
3564 pname, shortpath (NULL, file_p->hash_entry->symbol));
3568 /* Start by finding a good location for adding the new explicit function
3569 declarations. To do this, we scan backwards, ignoring whitespace
3570 and comments and other junk until we find either a semicolon, or until
3571 we hit the beginning of the file. */
3573 scan_p = find_rightmost_formals_list (clean_text_p);
3576 if (scan_p < clean_text_base)
3578 check_source (scan_p > clean_read_ptr, 0);
3583 /* scan_p now points either to a semicolon, or to just before the start
3584 of the whole file. */
3586 /* Now scan forward for the first non-whitespace character. In theory,
3587 this should be the first character of the following function definition
3588 header. We will put in the added declarations just prior to that. */
3591 while (isspace (*scan_p))
3595 output_up_to (scan_p);
3597 /* Now write out full prototypes for all of the things that had been
3598 implicitly declared in this file (but only those for which we were
3599 actually able to find unique matching definitions). Avoid duplicates
3600 by marking things that we write out as we go. */
3603 int some_decls_added = 0;
3605 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3606 if (dd_p->is_implicit && dd_p->definition && !dd_p->definition->written)
3608 const char *decl = dd_p->definition->ansi_decl;
3610 /* If the function for which we are inserting a declaration is
3611 actually defined later in the same file, then suppress the
3612 leading `extern' keyword (if there is one). */
3614 if (*decl == 'e' && (dd_p->file == dd_p->definition->file))
3617 output_string ("\n");
3618 output_string (decl);
3619 some_decls_added = 1;
3620 ((NONCONST def_dec_info *) dd_p->definition)->written = 1;
3622 if (some_decls_added)
3623 output_string ("\n\n");
3626 /* Unmark all of the definitions that we just marked. */
3628 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3629 if (dd_p->definition)
3630 ((NONCONST def_dec_info *) dd_p->definition)->written = 0;
3633 #endif /* !defined (UNPROTOIZE) */
3635 /* Do the editing operation specifically for a function "definition". Note
3636 that editing operations for function "declarations" are handled by a
3637 separate routine above. */
3640 edit_fn_definition (def_dec_p, clean_text_p)
3641 const def_dec_info *def_dec_p;
3642 const char *clean_text_p;
3644 const char *end_formals;
3645 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3647 /* Setup here to recover from confusing source code detected during this
3648 particular "edit". */
3651 if (setjmp (source_confusion_recovery))
3653 restore_pointers ();
3654 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3655 pname, function_to_edit);
3659 end_formals = find_rightmost_formals_list (clean_text_p);
3661 /* end_of_formals now points to the closing right paren of the rightmost
3662 formals list which is actually part of the `header' of the function
3663 definition that we are converting. */
3665 /* If the header of this function definition looks like it declares a
3666 function with a variable number of arguments, and if the way it does
3667 that is different from that way we would like it (i.e. varargs vs.
3668 stdarg) then issue a warning and leave the header unconverted. */
3670 if (other_variable_style_function (def_dec_p->ansi_decl))
3673 fprintf (stderr, "%s: %d: warning: definition of %s not converted\n",
3674 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3675 identify_lineno (end_formals),
3677 output_up_to (end_formals);
3681 if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
3683 restore_pointers ();
3684 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3685 pname, function_to_edit);
3689 /* Have to output the last right paren because this never gets flushed by
3690 edit_formals_list. */
3692 output_up_to (end_formals);
3697 const char *semicolon_p;
3698 const char *limit_p;
3700 int had_newlines = 0;
3702 /* Now write out the K&R style formal declarations, one per line. */
3704 decl_p = def_dec_p->formal_decls;
3705 limit_p = decl_p + strlen (decl_p);
3706 for (;decl_p < limit_p; decl_p = semicolon_p + 2)
3708 for (semicolon_p = decl_p; *semicolon_p != ';'; semicolon_p++)
3710 output_string ("\n");
3711 output_string (indent_string);
3712 output_bytes (decl_p, (size_t) ((semicolon_p + 1) - decl_p));
3715 /* If there are no newlines between the end of the formals list and the
3716 start of the body, we should insert one now. */
3718 for (scan_p = end_formals+1; *scan_p != '{'; )
3720 if (*scan_p == '\n')
3725 check_source (++scan_p < clean_text_limit, 0);
3728 output_string ("\n");
3730 #else /* !defined (UNPROTOIZE) */
3731 /* If we are protoizing, there may be some flotsum & jetsum (like comments
3732 and preprocessing directives) after the old formals list but before
3733 the following { and we would like to preserve that stuff while effectively
3734 deleting the existing K&R formal parameter declarations. We do so here
3735 in a rather tricky way. Basically, we white out any stuff *except*
3736 the comments/pp-directives in the original text buffer, then, if there
3737 is anything in this area *other* than whitespace, we output it. */
3739 const char *end_formals_orig;
3740 const char *start_body;
3741 const char *start_body_orig;
3743 const char *scan_orig;
3744 int have_flotsum = 0;
3745 int have_newlines = 0;
3747 for (start_body = end_formals + 1; *start_body != '{';)
3748 check_source (++start_body < clean_text_limit, 0);
3750 end_formals_orig = orig_text_base + (end_formals - clean_text_base);
3751 start_body_orig = orig_text_base + (start_body - clean_text_base);
3752 scan = end_formals + 1;
3753 scan_orig = end_formals_orig + 1;
3754 for (; scan < start_body; scan++, scan_orig++)
3756 if (*scan == *scan_orig)
3758 have_newlines |= (*scan_orig == '\n');
3759 /* Leave identical whitespace alone. */
3760 if (!isspace (*scan_orig))
3761 *((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
3767 output_bytes (end_formals_orig + 1,
3768 (size_t) (start_body_orig - end_formals_orig) - 1);
3771 output_string ("\n");
3773 output_string (" ");
3774 clean_read_ptr = start_body - 1;
3776 #endif /* !defined (UNPROTOIZE) */
3779 /* Clean up the clean text buffer. Do this by converting comments and
3780 preprocessor directives into spaces. Also convert line continuations
3781 into whitespace. Also, whiteout string and character literals. */
3784 do_cleaning (new_clean_text_base, new_clean_text_limit)
3785 char *new_clean_text_base;
3786 char *new_clean_text_limit;
3789 int non_whitespace_since_newline = 0;
3791 for (scan_p = new_clean_text_base; scan_p < new_clean_text_limit; scan_p++)
3795 case '/': /* Handle comments. */
3796 if (scan_p[1] != '*')
3798 non_whitespace_since_newline = 1;
3802 while (scan_p[1] != '/' || scan_p[0] != '*')
3804 if (!isspace (*scan_p))
3806 if (++scan_p >= new_clean_text_limit)
3813 case '#': /* Handle pp directives. */
3814 if (non_whitespace_since_newline)
3817 while (scan_p[1] != '\n' || scan_p[0] == '\\')
3819 if (!isspace (*scan_p))
3821 if (++scan_p >= new_clean_text_limit)
3827 case '\'': /* Handle character literals. */
3828 non_whitespace_since_newline = 1;
3829 while (scan_p[1] != '\'' || scan_p[0] == '\\')
3831 if (scan_p[0] == '\\' && !isspace (scan_p[1]))
3833 if (!isspace (*scan_p))
3835 if (++scan_p >= new_clean_text_limit)
3841 case '"': /* Handle string literals. */
3842 non_whitespace_since_newline = 1;
3843 while (scan_p[1] != '"' || scan_p[0] == '\\')
3845 if (scan_p[0] == '\\' && !isspace (scan_p[1]))
3847 if (!isspace (*scan_p))
3849 if (++scan_p >= new_clean_text_limit)
3855 case '\\': /* Handle line continuations. */
3856 if (scan_p[1] != '\n')
3862 non_whitespace_since_newline = 0; /* Reset. */
3871 break; /* Whitespace characters. */
3875 non_whitespace_since_newline = 1;
3881 /* Given a pointer to the closing right parenthesis for a particular formals
3882 list (in the clean text buffer) find the corresponding left parenthesis
3883 and return a pointer to it. */
3886 careful_find_l_paren (p)
3892 for (paren_depth = 1, q = p-1; paren_depth; check_source (--q >= clean_text_base, 0))
3907 /* Scan the clean text buffer for cases of function definitions that we
3908 don't really know about because they were preprocessed out when the
3909 aux info files were created.
3911 In this version of protoize/unprotoize we just give a warning for each
3912 one found. A later version may be able to at least unprotoize such
3915 Note that we may easily find all function definitions simply by
3916 looking for places where there is a left paren which is (ignoring
3917 whitespace) immediately followed by either a left-brace or by an
3918 upper or lower case letter. Whenever we find this combination, we
3919 have also found a function definition header.
3921 Finding function *declarations* using syntactic clues is much harder.
3922 I will probably try to do this in a later version though. */
3925 scan_for_missed_items (file_p)
3926 const file_info *file_p;
3928 static const char *scan_p;
3929 const char *limit = clean_text_limit - 3;
3930 static const char *backup_limit;
3932 backup_limit = clean_text_base - 1;
3934 for (scan_p = clean_text_base; scan_p < limit; scan_p++)
3938 static const char *last_r_paren;
3939 const char *ahead_p;
3941 last_r_paren = scan_p;
3943 for (ahead_p = scan_p + 1; isspace (*ahead_p); )
3944 check_source (++ahead_p < limit, limit);
3946 scan_p = ahead_p - 1;
3948 if (isalpha (*ahead_p) || *ahead_p == '{')
3950 const char *last_l_paren;
3951 const int lineno = identify_lineno (ahead_p);
3953 if (setjmp (source_confusion_recovery))
3956 /* We know we have a function definition header. Now skip
3957 leftwards over all of its associated formals lists. */
3961 last_l_paren = careful_find_l_paren (last_r_paren);
3962 for (last_r_paren = last_l_paren-1; isspace (*last_r_paren); )
3963 check_source (--last_r_paren >= backup_limit, backup_limit);
3965 while (*last_r_paren == ')');
3967 if (is_id_char (*last_r_paren))
3969 const char *id_limit = last_r_paren + 1;
3970 const char *id_start;
3972 const def_dec_info *dd_p;
3974 for (id_start = id_limit-1; is_id_char (*id_start); )
3975 check_source (--id_start >= backup_limit, backup_limit);
3977 backup_limit = id_start;
3978 if ((id_length = (size_t) (id_limit - id_start)) == 0)
3982 char *func_name = (char *) alloca (id_length + 1);
3983 static const char * const stmt_keywords[]
3984 = { "if", "while", "for", "switch", "return", 0 };
3985 const char * const *stmt_keyword;
3987 strncpy (func_name, id_start, id_length);
3988 func_name[id_length] = '\0';
3990 /* We must check here to see if we are actually looking at
3991 a statement rather than an actual function call. */
3993 for (stmt_keyword = stmt_keywords; *stmt_keyword; stmt_keyword++)
3994 if (!strcmp (func_name, *stmt_keyword))
3998 fprintf (stderr, "%s: found definition of `%s' at %s(%d)\n",
4001 shortpath (NULL, file_p->hash_entry->symbol),
4002 identify_lineno (id_start));
4004 /* We really should check for a match of the function name
4005 here also, but why bother. */
4007 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
4008 if (dd_p->is_func_def && dd_p->line == lineno)
4011 /* If we make it here, then we did not know about this
4012 function definition. */
4014 fprintf (stderr, "%s: %d: warning: `%s' excluded by preprocessing\n",
4015 shortpath (NULL, file_p->hash_entry->symbol),
4016 identify_lineno (id_start), func_name);
4017 fprintf (stderr, "%s: function definition not converted\n",
4027 /* Do all editing operations for a single source file (either a "base" file
4028 or an "include" file). To do this we read the file into memory, keep a
4029 virgin copy there, make another cleaned in-core copy of the original file
4030 (i.e. one in which all of the comments and preprocessor directives have
4031 been replaced with whitespace), then use these two in-core copies of the
4032 file to make a new edited in-core copy of the file. Finally, rename the
4033 original file (as a way of saving it), and then write the edited version
4034 of the file from core to a disk file of the same name as the original.
4036 Note that the trick of making a copy of the original sans comments &
4037 preprocessor directives make the editing a whole lot easier. */
4041 const hash_table_entry *hp;
4043 struct stat stat_buf;
4044 const file_info *file_p = hp->fip;
4045 char *new_orig_text_base;
4046 char *new_orig_text_limit;
4047 char *new_clean_text_base;
4048 char *new_clean_text_limit;
4051 int first_definition_in_file;
4053 /* If we are not supposed to be converting this file, or if there is
4054 nothing in there which needs converting, just skip this file. */
4056 if (!needs_to_be_converted (file_p))
4059 convert_filename = file_p->hash_entry->symbol;
4061 /* Convert a file if it is in a directory where we want conversion
4062 and the file is not excluded. */
4064 if (!directory_specified_p (convert_filename)
4065 || file_excluded_p (convert_filename))
4069 /* Don't even mention "system" include files unless we are
4070 protoizing. If we are protoizing, we mention these as a
4071 gentle way of prodding the user to convert his "system"
4072 include files to prototype format. */
4073 && !in_system_include_dir (convert_filename)
4074 #endif /* defined (UNPROTOIZE) */
4076 fprintf (stderr, "%s: `%s' not converted\n",
4077 pname, shortpath (NULL, convert_filename));
4081 /* Let the user know what we are up to. */
4084 fprintf (stderr, "%s: would convert file `%s'\n",
4085 pname, shortpath (NULL, convert_filename));
4087 fprintf (stderr, "%s: converting file `%s'\n",
4088 pname, shortpath (NULL, convert_filename));
4091 /* Find out the size (in bytes) of the original file. */
4093 /* The cast avoids an erroneous warning on AIX. */
4094 if (my_stat ((char *)convert_filename, &stat_buf) == -1)
4096 fprintf (stderr, "%s: can't get status for file `%s': %s\n",
4097 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4100 orig_size = stat_buf.st_size;
4102 /* Allocate a buffer to hold the original text. */
4104 orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
4105 orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
4107 /* Allocate a buffer to hold the cleaned-up version of the original text. */
4109 clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
4110 clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
4111 clean_read_ptr = clean_text_base - 1;
4113 /* Allocate a buffer that will hopefully be large enough to hold the entire
4114 converted output text. As an initial guess for the maximum size of the
4115 output buffer, use 125% of the size of the original + some extra. This
4116 buffer can be expanded later as needed. */
4118 repl_size = orig_size + (orig_size >> 2) + 4096;
4119 repl_text_base = (char *) xmalloc (repl_size + 2);
4120 repl_text_limit = repl_text_base + repl_size - 1;
4121 repl_write_ptr = repl_text_base - 1;
4126 /* Open the file to be converted in READ ONLY mode. */
4128 if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1)
4130 fprintf (stderr, "%s: can't open file `%s' for reading: %s\n",
4131 pname, shortpath (NULL, convert_filename),
4132 sys_errlist[errno]);
4136 /* Read the entire original source text file into the original text buffer
4137 in one swell fwoop. Then figure out where the end of the text is and
4138 make sure that it ends with a newline followed by a null. */
4140 if (read (input_file, new_orig_text_base, orig_size) != orig_size)
4143 fprintf (stderr, "\n%s: error reading input file `%s': %s\n",
4144 pname, shortpath (NULL, convert_filename),
4145 sys_errlist[errno]);
4152 if (orig_size == 0 || orig_text_limit[-1] != '\n')
4154 *new_orig_text_limit++ = '\n';
4158 /* Create the cleaned up copy of the original text. */
4160 memcpy (new_clean_text_base, orig_text_base,
4161 (size_t) (orig_text_limit - orig_text_base));
4162 do_cleaning (new_clean_text_base, new_clean_text_limit);
4167 size_t clean_size = orig_text_limit - orig_text_base;
4168 char *const clean_filename = (char *) alloca (strlen (convert_filename) + 6 + 1);
4170 /* Open (and create) the clean file. */
4172 strcpy (clean_filename, convert_filename);
4173 strcat (clean_filename, ".clean");
4174 if ((clean_file = creat (clean_filename, 0666)) == -1)
4176 fprintf (stderr, "%s: can't create/open clean file `%s': %s\n",
4177 pname, shortpath (NULL, clean_filename),
4178 sys_errlist[errno]);
4182 /* Write the clean file. */
4184 if (write (clean_file, new_clean_text_base, clean_size) != clean_size)
4185 fprintf (stderr, "%s: error writing file `%s': %s\n",
4186 pname, shortpath (NULL, clean_filename), sys_errlist[errno]);
4192 /* Do a simplified scan of the input looking for things that were not
4193 mentioned in the aux info files because of the fact that they were
4194 in a region of the source which was preprocessed-out (via #if or
4197 scan_for_missed_items (file_p);
4199 /* Setup to do line-oriented forward seeking in the clean text buffer. */
4201 last_known_line_number = 1;
4202 last_known_line_start = clean_text_base;
4204 /* Now get down to business and make all of the necessary edits. */
4207 const def_dec_info *def_dec_p;
4209 first_definition_in_file = 1;
4210 def_dec_p = file_p->defs_decs;
4211 for (; def_dec_p; def_dec_p = def_dec_p->next_in_file)
4213 const char *clean_text_p = seek_to_line (def_dec_p->line);
4215 /* clean_text_p now points to the first character of the line which
4216 contains the `terminator' for the declaration or definition that
4217 we are about to process. */
4221 if (global_flag && def_dec_p->is_func_def && first_definition_in_file)
4223 add_global_decls (def_dec_p->file, clean_text_p);
4224 first_definition_in_file = 0;
4227 /* Don't edit this item if it is already in prototype format or if it
4228 is a function declaration and we have found no corresponding
4231 if (def_dec_p->prototyped
4232 || (!def_dec_p->is_func_def && !def_dec_p->definition))
4235 #endif /* !defined (UNPROTOIZE) */
4237 if (def_dec_p->is_func_def)
4238 edit_fn_definition (def_dec_p, clean_text_p);
4241 if (def_dec_p->is_implicit)
4242 add_local_decl (def_dec_p, clean_text_p);
4244 #endif /* !defined (UNPROTOIZE) */
4245 edit_fn_declaration (def_dec_p, clean_text_p);
4249 /* Finalize things. Output the last trailing part of the original text. */
4251 output_up_to (clean_text_limit - 1);
4253 /* If this is just a test run, stop now and just deallocate the buffers. */
4257 free (new_orig_text_base);
4258 free (new_clean_text_base);
4259 free (repl_text_base);
4263 /* Change the name of the original input file. This is just a quick way of
4264 saving the original file. */
4268 char *new_filename =
4269 (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
4271 strcpy (new_filename, convert_filename);
4272 strcat (new_filename, save_suffix);
4273 if (my_link (convert_filename, new_filename) == -1)
4275 if (errno == EEXIST)
4278 fprintf (stderr, "%s: warning: file `%s' already saved in `%s'\n",
4280 shortpath (NULL, convert_filename),
4281 shortpath (NULL, new_filename));
4285 fprintf (stderr, "%s: can't link file `%s' to `%s': %s\n",
4287 shortpath (NULL, convert_filename),
4288 shortpath (NULL, new_filename),
4289 sys_errlist[errno]);
4295 if (my_unlink (convert_filename) == -1)
4297 fprintf (stderr, "%s: can't delete file `%s': %s\n",
4298 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4305 /* Open (and create) the output file. */
4307 if ((output_file = creat (convert_filename, 0666)) == -1)
4309 fprintf (stderr, "%s: can't create/open output file `%s': %s\n",
4310 pname, shortpath (NULL, convert_filename),
4311 sys_errlist[errno]);
4315 /* Write the output file. */
4318 unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
4320 if (write (output_file, repl_text_base, out_size) != out_size)
4321 fprintf (stderr, "%s: error writing file `%s': %s\n",
4322 pname, shortpath (NULL, convert_filename),
4323 sys_errlist[errno]);
4326 close (output_file);
4329 /* Deallocate the conversion buffers. */
4331 free (new_orig_text_base);
4332 free (new_clean_text_base);
4333 free (repl_text_base);
4335 /* Change the mode of the output file to match the original file. */
4337 /* The cast avoids an erroneous warning on AIX. */
4338 if (my_chmod ((char *)convert_filename, stat_buf.st_mode) == -1)
4339 fprintf (stderr, "%s: can't change mode of file `%s': %s\n",
4340 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4342 /* Note: We would try to change the owner and group of the output file
4343 to match those of the input file here, except that may not be a good
4344 thing to do because it might be misleading. Also, it might not even
4345 be possible to do that (on BSD systems with quotas for instance). */
4348 /* Do all of the individual steps needed to do the protoization (or
4349 unprotoization) of the files referenced in the aux_info files given
4350 in the command line. */
4355 const char * const *base_pp;
4356 const char * const * const end_pps
4357 = &base_source_filenames[n_base_source_files];
4361 #endif /* !defined (UNPROTOIZE) */
4363 /* One-by-one, check (and create if necessary), open, and read all of the
4364 stuff in each aux_info file. After reading each aux_info file, the
4365 aux_info_file just read will be automatically deleted unless the
4366 keep_flag is set. */
4368 for (base_pp = base_source_filenames; base_pp < end_pps; base_pp++)
4369 process_aux_info_file (*base_pp, keep_flag, 0);
4373 /* Also open and read the special SYSCALLS.c aux_info file which gives us
4374 the prototypes for all of the standard system-supplied functions. */
4376 if (nondefault_syscalls_dir)
4378 syscalls_absolute_filename
4379 = (char *) xmalloc (strlen (nondefault_syscalls_dir)
4380 + sizeof (syscalls_filename) + 1);
4381 strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
4385 syscalls_absolute_filename
4386 = (char *) xmalloc (strlen (default_syscalls_dir)
4387 + sizeof (syscalls_filename) + 1);
4388 strcpy (syscalls_absolute_filename, default_syscalls_dir);
4391 syscalls_len = strlen (syscalls_absolute_filename);
4392 if (*(syscalls_absolute_filename + syscalls_len - 1) != '/')
4394 *(syscalls_absolute_filename + syscalls_len++) = '/';
4395 *(syscalls_absolute_filename + syscalls_len) = '\0';
4397 strcat (syscalls_absolute_filename, syscalls_filename);
4399 /* Call process_aux_info_file in such a way that it does not try to
4400 delete the SYSCALLS aux_info file. */
4402 process_aux_info_file (syscalls_absolute_filename, 1, 1);
4404 #endif /* !defined (UNPROTOIZE) */
4406 /* When we first read in all of the information from the aux_info files
4407 we saved in it descending line number order, because that was likely to
4408 be faster. Now however, we want the chains of def & dec records to
4409 appear in ascending line number order as we get further away from the
4410 file_info record that they hang from. The following line causes all of
4411 these lists to be rearranged into ascending line number order. */
4413 visit_each_hash_node (filename_primary, reverse_def_dec_list);
4417 /* Now do the "real" work. The following line causes each declaration record
4418 to be "visited". For each of these nodes, an attempt is made to match
4419 up the function declaration with a corresponding function definition,
4420 which should have a full prototype-format formals list with it. Once
4421 these match-ups are made, the conversion of the function declarations
4422 to prototype format can be made. */
4424 visit_each_hash_node (function_name_primary, connect_defs_and_decs);
4426 #endif /* !defined (UNPROTOIZE) */
4428 /* Now convert each file that can be converted (and needs to be). */
4430 visit_each_hash_node (filename_primary, edit_file);
4434 /* If we are working in cplusplus mode, try to rename all .c files to .C
4435 files. Don't panic if some of the renames don't work. */
4437 if (cplusplus_flag && !nochange_flag)
4438 visit_each_hash_node (filename_primary, rename_c_file);
4440 #endif /* !defined (UNPROTOIZE) */
4443 static struct option longopts[] =
4445 {"version", 0, 0, 'V'},
4446 {"file_name", 0, 0, 'p'},
4447 {"quiet", 0, 0, 'q'},
4448 {"silent", 0, 0, 'q'},
4449 {"force", 0, 0, 'f'},
4450 {"keep", 0, 0, 'k'},
4451 {"nosave", 0, 0, 'N'},
4452 {"nochange", 0, 0, 'n'},
4453 {"compiler-options", 1, 0, 'c'},
4454 {"exclude", 1, 0, 'x'},
4455 {"directory", 1, 0, 'd'},
4457 {"indent", 1, 0, 'i'},
4459 {"local", 0, 0, 'l'},
4460 {"global", 0, 0, 'g'},
4462 {"syscalls-dir", 1, 0, 'B'},
4474 const char *params = "";
4476 pname = rindex (argv[0], '/');
4477 pname = pname ? pname+1 : argv[0];
4479 cwd_buffer = getpwd ();
4482 fprintf (stderr, "%s: cannot get working directory: %s\n",
4483 pname, sys_errlist[errno]);
4487 /* By default, convert the files in the current directory. */
4488 directory_list = string_list_cons (cwd_buffer, NULL);
4490 while ((c = getopt_long (argc, argv,
4494 "B:c:Cd:gklnNp:qvVx:",
4496 longopts, &longind)) != EOF)
4498 if (c == 0) /* Long option. */
4499 c = longopts[longind].val;
4503 compiler_file_name = optarg;
4507 = string_list_cons (abspath (NULL, optarg), directory_list);
4510 exclude_list = string_list_cons (optarg, exclude_list);
4540 indent_string = optarg;
4542 #else /* !defined (UNPROTOIZE) */
4553 nondefault_syscalls_dir = optarg;
4555 #endif /* !defined (UNPROTOIZE) */
4561 /* Set up compile_params based on -p and -c options. */
4562 munge_compile_params (params);
4564 n_base_source_files = argc - optind;
4566 /* Now actually make a list of the base source filenames. */
4568 base_source_filenames =
4569 (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
4570 n_base_source_files = 0;
4571 for (; optind < argc; optind++)
4573 const char *path = abspath (NULL, argv[optind]);
4574 int len = strlen (path);
4576 if (path[len-1] == 'c' && path[len-2] == '.')
4577 base_source_filenames[n_base_source_files++] = path;
4580 fprintf (stderr, "%s: input file names must have .c suffixes: %s\n",
4581 pname, shortpath (NULL, path));
4587 /* We are only interested in the very first identifier token in the
4588 definition of `va_list', so if there is more junk after that first
4589 identifier token, delete it from the `varargs_style_indicator'. */
4593 for (cp = varargs_style_indicator; isalnum (*cp) || *cp == '_'; cp++)
4596 varargs_style_indicator = savestring (varargs_style_indicator,
4597 cp - varargs_style_indicator);
4599 #endif /* !defined (UNPROTOIZE) */
4606 fprintf (stderr, "%s: %s\n", pname, version_string);