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>
70 #if ! defined (USG) || defined (SVR4)
76 /* Include getopt.h for the sake of getopt_long.
77 We don't need the declaration of getopt, and it could conflict
78 with something from a system header file, so effectively nullify that. */
79 #define getopt getopt_loser
83 extern char *sys_errlist[];
84 extern char *version_string;
86 /* Systems which are compatible only with POSIX 1003.1-1988 (but *not*
87 with POSIX 1003.1-1990), e.g. Ultrix 4.2, might not have
88 const qualifiers in the prototypes in the system include files.
89 Unfortunately, this can lead to GCC issuing lots of warnings for
90 calls to the following functions. To eliminate these warnings we
91 provide the following #defines. */
93 #define my_access(file,flag) access((char *)file, flag)
94 #define my_stat(file,pkt) stat((char *)file, pkt)
95 #define my_execvp(prog,argv) execvp((char *)prog, (char **)argv)
96 #define my_link(file1, file2) link((char *)file1, (char *)file2)
97 #define my_unlink(file) unlink((char *)file)
98 #define my_open(file, mode, flag) open((char *)file, mode, flag)
99 #define my_chmod(file, mode) chmod((char *)file, mode)
101 extern char *getpwd ();
103 /* Aliases for pointers to void.
104 These were made to facilitate compilation with old brain-dead DEC C
105 compilers which didn't properly grok `void*' types. */
108 typedef void * pointer_type;
109 typedef const void * const_pointer_type;
111 typedef char * pointer_type;
112 typedef char * const_pointer_type;
123 #else /* !defined(POSIX) */
125 #define R_OK 4 /* Test for Read permission */
126 #define W_OK 2 /* Test for Write permission */
127 #define X_OK 1 /* Test for eXecute permission */
128 #define F_OK 0 /* Test for existence of File */
133 /* Declaring stat or __flsbuf with a prototype
134 causes conflicts with system headers on some systems. */
137 extern VOLATILE void abort ();
141 #if 0 /* These conflict with stdio.h on some systems. */
142 extern int fprintf (FILE *, const char *, ...);
143 extern int printf (const char *, ...);
144 extern int open (const char *, int, ...);
147 extern pointer_type malloc ();
148 extern pointer_type realloc ();
153 extern int fflush ();
159 extern int unlink ();
160 extern int access ();
161 extern int execvp ();
163 extern int setjmp ();
166 extern void longjmp ();
169 extern char * strcat ();
170 extern int strcmp ();
171 extern char * strcpy ();
172 #if 0 /* size_t from sys/types.h may fail to match GCC.
173 If so, we would get a warning from this. */
174 extern size_t strlen ()
176 extern int strncmp ();
177 extern char * strncpy ();
178 extern char * strrchr ();
180 /* Fork is not declared because the declaration caused a conflict
182 #if !(defined (USG) || defined (VMS))
184 #endif /* (defined (USG) || defined (VMS)) */
186 #endif /* !defined (POSIX) */
188 /* Look for these where the `const' qualifier is intentionally cast aside. */
192 /* Define a STRINGIFY macro that's right for ANSI or traditional C. */
195 #define STRINGIFY(STRING) #STRING
197 #define STRINGIFY(STRING) "STRING"
200 /* POSIX systems will not have definitions for WIFEXITED or WEXITSTATUS.
201 Define them correctly and so that they work for all environments. */
204 #define WIFEXITED(status_word) ((*((int *)&status_word) & 0xff) == 0x00)
207 #define WEXITSTATUS(status_word) ((*((int *)&status_word) & 0xff00) >> 8)
209 /* Define a default place to find the SYSCALLS.X file. */
211 #ifndef STD_PROTO_DIR
212 #define STD_PROTO_DIR "/usr/local/lib"
213 #endif /* !defined (STD_PROTO_DIR) */
215 /* Suffix of aux_info files. */
217 static const char * const aux_info_suffix = ".X";
219 /* String to attach to filenames for saved versions of original files. */
221 static const char * const save_suffix = ".save";
225 /* File name of the file which contains descriptions of standard system
226 routines. Note that we never actually do anything with this file per se,
227 but we do read in its corresponding aux_info file. */
229 static const char syscalls_filename[] = "SYSCALLS.c";
231 /* Default place to find the above file. */
233 static const char * const default_syscalls_dir = STD_PROTO_DIR;
235 /* Variable to hold the complete absolutized filename of the SYSCALLS.c.X
238 static char * syscalls_absolute_filename;
240 #endif /* !defined (UNPROTOIZE) */
242 /* Type of the structure that holds information about macro unexpansions. */
244 struct unexpansion_struct {
245 const char *expanded;
246 const char *contracted;
248 typedef struct unexpansion_struct unexpansion;
250 /* A table of conversions that may need to be made for some (stupid) older
251 operating systems where these types are preprocessor macros rather than
252 typedefs (as they really ought to be).
254 WARNING: The contracted forms must be as small (or smaller) as the
255 expanded forms, or else havoc will ensue. */
257 static const unexpansion unexpansions[] = {
258 { "struct _iobuf", "FILE" },
262 /* The number of "primary" slots in the hash tables for filenames and for
263 function names. This can be as big or as small as you like, except that
264 it must be a power of two. */
266 #define HASH_TABLE_SIZE (1 << 9)
268 /* Bit mask to use when computing hash values. */
270 static const int hash_mask = (HASH_TABLE_SIZE - 1);
272 /* Make a table of default system include directories
273 just as it is done in cccp.c. */
275 #ifndef STANDARD_INCLUDE_DIR
276 #define STANDARD_INCLUDE_DIR "/usr/include"
279 #ifndef LOCAL_INCLUDE_DIR
280 #define LOCAL_INCLUDE_DIR "/usr/local/include"
283 struct default_include { const char *fname; int cplusplus; } include_defaults[]
284 #ifdef INCLUDE_DEFAULTS
288 /* Pick up GNU C++ specific include files. */
289 { GPLUSPLUS_INCLUDE_DIR, 1},
290 { GCC_INCLUDE_DIR, 0},
292 /* For cross-compilation, this dir name is generated
293 automatically in Makefile.in. */
294 { CROSS_INCLUDE_DIR, 0 },
295 #else /* not CROSS_COMPILE */
296 { LOCAL_INCLUDE_DIR, 0},
297 /* Some systems have an extra dir of include files. */
298 #ifdef SYSTEM_INCLUDE_DIR
299 { SYSTEM_INCLUDE_DIR, 0},
301 { STANDARD_INCLUDE_DIR, 0},
302 #endif /* not CROSS_COMPILE */
305 #endif /* no INCLUDE_DEFAULTS */
307 /* Datatype for lists of directories or filenames. */
311 struct string_list *next;
314 /* List of directories in which files should be converted. */
316 struct string_list *directory_list;
318 /* List of file names which should not be converted.
319 A file is excluded if the end of its name, following a /,
320 matches one of the names in this list. */
322 struct string_list *exclude_list;
324 /* The name of the other style of variable-number-of-parameters functions
325 (i.e. the style that we want to leave unconverted because we don't yet
326 know how to convert them to this style. This string is used in warning
329 /* Also define here the string that we can search for in the parameter lists
330 taken from the .X files which will unambiguously indicate that we have
331 found a varargs style function. */
334 static const char * const other_var_style = "stdarg";
335 #else /* !defined (UNPROTOIZE) */
336 static const char * const other_var_style = "varargs";
337 /* Note that this is a string containing the expansion of va_alist.
338 But in `main' we discard all but the first token. */
339 static const char *varargs_style_indicator = STRINGIFY (va_alist);
340 #endif /* !defined (UNPROTOIZE) */
342 /* The following two types are used to create hash tables. In this program,
343 there are two hash tables which are used to store and quickly lookup two
344 different classes of strings. The first type of strings stored in the
345 first hash table are absolute filenames of files which protoize needs to
346 know about. The second type of strings (stored in the second hash table)
347 are function names. It is this second class of strings which really
348 inspired the use of the hash tables, because there may be a lot of them. */
350 typedef struct hash_table_entry_struct hash_table_entry;
352 /* Do some typedefs so that we don't have to write "struct" so often. */
354 typedef struct def_dec_info_struct def_dec_info;
355 typedef struct file_info_struct file_info;
356 typedef struct f_list_chain_item_struct f_list_chain_item;
358 /* In the struct below, note that the "_info" field has two different uses
359 depending on the type of hash table we are in (i.e. either the filenames
360 hash table or the function names hash table). In the filenames hash table
361 the info fields of the entries point to the file_info struct which is
362 associated with each filename (1 per filename). In the function names
363 hash table, the info field points to the head of a singly linked list of
364 def_dec_info entries which are all defs or decs of the function whose
365 name is pointed to by the "symbol" field. Keeping all of the defs/decs
366 for a given function name on a special list specifically for that function
367 name makes it quick and easy to find out all of the important information
368 about a given (named) function. */
370 struct hash_table_entry_struct {
371 hash_table_entry * hash_next; /* -> to secondary entries */
372 const char * symbol; /* -> to the hashed string */
374 const def_dec_info * _ddip;
378 #define ddip _info._ddip
379 #define fip _info._fip
381 /* Define a type specifically for our two hash tables. */
383 typedef hash_table_entry hash_table[HASH_TABLE_SIZE];
385 /* The following struct holds all of the important information about any
386 single filename (e.g. file) which we need to know about. */
388 struct file_info_struct {
389 const hash_table_entry * hash_entry; /* -> to associated hash entry */
390 const def_dec_info * defs_decs; /* -> to chain of defs/decs */
391 time_t mtime; /* Time of last modification. */
394 /* Due to the possibility that functions may return pointers to functions,
395 (which may themselves have their own parameter lists) and due to the
396 fact that returned pointers-to-functions may be of type "pointer-to-
397 function-returning-pointer-to-function" (ad nauseum) we have to keep
398 an entire chain of ANSI style formal parameter lists for each function.
400 Normally, for any given function, there will only be one formals list
401 on the chain, but you never know.
403 Note that the head of each chain of formals lists is pointed to by the
404 `f_list_chain' field of the corresponding def_dec_info record.
406 For any given chain, the item at the head of the chain is the *leftmost*
407 parameter list seen in the actual C language function declaration. If
408 there are other members of the chain, then these are linked in left-to-right
409 order from the head of the chain. */
411 struct f_list_chain_item_struct {
412 const f_list_chain_item * chain_next; /* -> to next item on chain */
413 const char * formals_list; /* -> to formals list string */
416 /* The following struct holds all of the important information about any
417 single function definition or declaration which we need to know about.
418 Note that for unprotoize we don't need to know very much because we
419 never even create records for stuff that we don't intend to convert
420 (like for instance defs and decs which are already in old K&R format
421 and "implicit" function declarations). */
423 struct def_dec_info_struct {
424 const def_dec_info * next_in_file; /* -> to rest of chain for file */
425 file_info * file; /* -> file_info for containing file */
426 int line; /* source line number of def/dec */
427 const char * ansi_decl; /* -> left end of ansi decl */
428 hash_table_entry * hash_entry; /* -> hash entry for function name */
429 unsigned int is_func_def; /* = 0 means this is a declaration */
430 const def_dec_info * next_for_func; /* -> to rest of chain for func name */
431 unsigned int f_list_count; /* count of formals lists we expect */
432 char prototyped; /* = 0 means already prototyped */
434 const f_list_chain_item * f_list_chain; /* -> chain of formals lists */
435 const def_dec_info * definition; /* -> def/dec containing related def */
436 char is_static; /* = 0 means visibility is "extern" */
437 char is_implicit; /* != 0 for implicit func decl's */
438 char written; /* != 0 means written for implicit */
439 #else /* !defined (UNPROTOIZE) */
440 const char * formal_names; /* -> to list of names of formals */
441 const char * formal_decls; /* -> to string of formal declarations */
442 #endif /* !defined (UNPROTOIZE) */
445 /* Pointer to the tail component of the filename by which this program was
446 invoked. Used everywhere in error and warning messages. */
448 static const char *pname;
450 /* Error counter. Will be non-zero if we should give up at the next convenient
453 static int errors = 0;
456 /* ??? These comments should say what the flag mean as well as the options
459 /* File name to use for running gcc. Allows GCC 2 to be named
460 something other than gcc. */
461 static const char *compiler_file_name = "gcc";
463 static int version_flag = 0; /* Print our version number. */
464 static int quiet_flag = 0; /* Don't print messages normally. */
465 static int nochange_flag = 0; /* Don't convert, just say what files
466 we would have converted. */
467 static int nosave_flag = 0; /* Don't save the old version. */
468 static int keep_flag = 0; /* Don't delete the .X files. */
469 static const char ** compile_params = 0; /* Option string for gcc. */
471 static const char *indent_string = " "; /* Indentation for newly
472 inserted parm decls. */
473 #else /* !defined (UNPROTOIZE) */
474 static int local_flag = 0; /* Insert new local decls (when?). */
475 static int global_flag = 0; /* set by -g option */
476 static int cplusplus_flag = 0; /* Rename converted files to *.C. */
477 static const char* nondefault_syscalls_dir = 0; /* Dir to look for
479 #endif /* !defined (UNPROTOIZE) */
481 /* An index into the compile_params array where we should insert the source
482 file name when we are ready to exec the C compiler. A zero value indicates
483 that we have not yet called munge_compile_params. */
485 static int input_file_name_index = 0;
487 /* An index into the compile_params array where we should insert the filename
488 for the aux info file, when we run the C compiler. */
489 static int aux_info_file_name_index = 0;
491 /* Count of command line arguments which were "filename" arguments. */
493 static int n_base_source_files = 0;
495 /* Points to a malloc'ed list of pointers to all of the filenames of base
496 source files which were specified on the command line. */
498 static const char **base_source_filenames;
500 /* Line number of the line within the current aux_info file that we
501 are currently processing. Used for error messages in case the prototypes
502 info file is corrupted somehow. */
504 static int current_aux_info_lineno;
506 /* Pointer to the name of the source file currently being converted. */
508 static const char *convert_filename;
510 /* Pointer to relative root string (taken from aux_info file) which indicates
511 where directory the user was in when he did the compilation step that
512 produced the containing aux_info file. */
514 static const char *invocation_filename;
516 /* Pointer to the base of the input buffer that holds the original text for the
517 source file currently being converted. */
519 static const char *orig_text_base;
521 /* Pointer to the byte just beyond the end of the input buffer that holds the
522 original text for the source file currently being converted. */
524 static const char *orig_text_limit;
526 /* Pointer to the base of the input buffer that holds the cleaned text for the
527 source file currently being converted. */
529 static const char *clean_text_base;
531 /* Pointer to the byte just beyond the end of the input buffer that holds the
532 cleaned text for the source file currently being converted. */
534 static const char *clean_text_limit;
536 /* Pointer to the last byte in the cleaned text buffer that we have already
537 (virtually) copied to the output buffer (or decided to ignore). */
539 static const char * clean_read_ptr;
541 /* Pointer to the base of the output buffer that holds the replacement text
542 for the source file currently being converted. */
544 static char *repl_text_base;
546 /* Pointer to the byte just beyond the end of the output buffer that holds the
547 replacement text for the source file currently being converted. */
549 static char *repl_text_limit;
551 /* Pointer to the last byte which has been stored into the output buffer.
552 The next byte to be stored should be stored just past where this points
555 static char * repl_write_ptr;
557 /* Pointer into the cleaned text buffer for the source file we are currently
558 converting. This points to the first character of the line that we last
559 did a "seek_to_line" to (see below). */
561 static const char *last_known_line_start;
563 /* Number of the line (in the cleaned text buffer) that we last did a
564 "seek_to_line" to. Will be one if we just read a new source file
565 into the cleaned text buffer. */
567 static int last_known_line_number;
569 /* The filenames hash table. */
571 static hash_table filename_primary;
573 /* The function names hash table. */
575 static hash_table function_name_primary;
577 /* The place to keep the recovery address which is used only in cases where
578 we get hopelessly confused by something in the cleaned original text. */
580 static jmp_buf source_confusion_recovery;
582 /* A pointer to the current directory filename (used by abspath). */
584 static char *cwd_buffer;
586 /* A place to save the read pointer until we are sure that an individual
587 attempt at editing will succeed. */
589 static const char * saved_clean_read_ptr;
591 /* A place to save the write pointer until we are sure that an individual
592 attempt at editing will succeed. */
594 static char * saved_repl_write_ptr;
596 /* Forward declaration. */
598 static const char *shortpath ();
600 /* Allocate some space, but check that the allocation was successful. */
601 /* alloca.c uses this, so don't make it static. */
609 rv = malloc (byte_count);
612 fprintf (stderr, "\n%s: fatal error: can't allocate %u more bytes of memory\n",
615 return 0; /* avoid warnings */
621 /* Reallocate some space, but check that the reallocation was successful. */
624 xrealloc (old_space, byte_count)
625 pointer_type old_space;
630 rv = realloc (old_space, byte_count);
633 fprintf (stderr, "\n%s: fatal error: can't allocate %u more bytes of memory\n",
636 return 0; /* avoid warnings */
642 /* Deallocate the area pointed to by an arbitrary pointer, but first, strip
643 the `const' qualifier from it and also make sure that the pointer value
648 const_pointer_type p;
651 free ((NONCONST pointer_type) p);
654 /* Make a copy of a string INPUT with size SIZE. */
657 savestring (input, size)
661 char *output = (char *) xmalloc (size + 1);
662 strcpy (output, input);
666 /* Make a copy of the concatenation of INPUT1 and INPUT2. */
669 savestring2 (input1, size1, input2, size2)
675 char *output = (char *) xmalloc (size1 + size2 + 1);
676 strcpy (output, input1);
677 strcpy (&output[size1], input2);
681 /* More 'friendly' abort that prints the line and file.
682 config.h can #define abort fancy_abort if you like that sort of thing. */
687 fprintf (stderr, "%s: internal abort\n", pname);
691 /* Make a duplicate of a given string in a newly allocated area. */
697 return strcpy ((char *) xmalloc (strlen (s) + 1), s);
700 /* Make a duplicate of the first N bytes of a given string in a newly
708 char *ret_val = strncpy ((char *) xmalloc (n + 1), s, n);
714 /* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
715 does not occur within s1. Assume neither s1 nor s2 are null pointers. */
720 const char *const s2;
728 for (p1 = s1, p2 = s2; c = *p2; p1++, p2++)
738 /* Get setup to recover in case the edit we are about to do goes awry. */
743 saved_clean_read_ptr = clean_read_ptr;
744 saved_repl_write_ptr = repl_write_ptr;
747 /* Call this routine to recover our previous state whenever something looks
748 too confusing in the source code we are trying to edit. */
753 clean_read_ptr = saved_clean_read_ptr;
754 repl_write_ptr = saved_repl_write_ptr;
757 /* Return true if the given character is a legal identifier character. */
763 return (isalnum (ch) || (ch == '_') || (ch == '$'));
766 /* Give a message indicating the proper way to invoke this program and then
767 exit with non-zero status. */
773 fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
775 #else /* !defined (UNPROTOIZE) */
776 fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <diname> ] [ filename ... ]'\n",
778 #endif /* !defined (UNPROTOIZE) */
782 /* Return true if the given filename (assumed to be an absolute filename)
783 designates a file residing anywhere beneath any one of the "system"
784 include directories. */
787 in_system_include_dir (path)
790 struct default_include *p;
793 abort (); /* Must be an absolutized filename. */
795 for (p = include_defaults; p->fname; p++)
796 if (!strncmp (path, p->fname, strlen (p->fname))
797 && path[strlen (p->fname)] == '/')
803 /* Return true if the given filename designates a file that the user has
804 read access to and for which the user has write access to the containing
808 file_could_be_converted (const char *path)
810 char *const dir_name = (char *) alloca (strlen (path) + 1);
812 if (my_access (path, R_OK))
816 char *dir_last_slash;
818 strcpy (dir_name, path);
819 dir_last_slash = strrchr (dir_name, '/');
821 *dir_last_slash = '\0';
823 abort (); /* Should have been an absolutized filename. */
826 if (my_access (path, W_OK))
832 /* Return true if the given filename designates a file that we are allowed
833 to modify. Files which we should not attempt to modify are (a) "system"
834 include files, and (b) files which the user doesn't have write access to,
835 and (c) files which reside in directories which the user doesn't have
836 write access to. Unless requested to be quiet, give warnings about
837 files that we will not try to convert for one reason or another. An
838 exception is made for "system" include files, which we never try to
839 convert and for which we don't issue the usual warnings. */
842 file_normally_convertible (const char *path)
844 char *const dir_name = alloca (strlen (path) + 1);
846 if (in_system_include_dir (path))
850 char *dir_last_slash;
852 strcpy (dir_name, path);
853 dir_last_slash = strrchr (dir_name, '/');
855 *dir_last_slash = '\0';
857 abort (); /* Should have been an absolutized filename. */
860 if (my_access (path, R_OK))
863 fprintf (stderr, "%s: warning: no read access for file `%s'\n",
864 pname, shortpath (NULL, path));
868 if (my_access (path, W_OK))
871 fprintf (stderr, "%s: warning: no write access for file `%s'\n",
872 pname, shortpath (NULL, path));
876 if (my_access (dir_name, W_OK))
879 fprintf (stderr, "%s: warning: no write access for dir containing `%s'\n",
880 pname, shortpath (NULL, path));
890 /* Return true if the given file_info struct refers to the special SYSCALLS.c.X
891 file. Return false otherwise. */
894 is_syscalls_file (fi_p)
895 const file_info *fi_p;
897 char const *f = fi_p->hash_entry->symbol;
898 size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
899 return sysl <= fl && strcmp (f + fl - sysl, syscalls_filename) == 0;
902 #endif /* !defined (UNPROTOIZE) */
904 /* Check to see if this file will need to have anything done to it on this
905 run. If there is nothing in the given file which both needs conversion
906 and for which we have the necessary stuff to do the conversion, return
907 false. Otherwise, return true.
909 Note that (for protoize) it is only valid to call this function *after*
910 the connections between declarations and definitions have all been made
911 by connect_defs_and_decs. */
914 needs_to_be_converted (file_p)
915 const file_info *file_p;
917 const def_dec_info *ddp;
921 if (is_syscalls_file (file_p))
924 #endif /* !defined (UNPROTOIZE) */
926 for (ddp = file_p->defs_decs; ddp; ddp = ddp->next_in_file)
932 /* ... and if we a protoizing and this function is in old style ... */
934 /* ... and if this a definition or is a decl with an associated def ... */
935 && (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
937 #else /* defined (UNPROTOIZE) */
939 /* ... and if we are unprotoizing and this function is in new style ... */
942 #endif /* defined (UNPROTOIZE) */
944 /* ... then the containing file needs converting. */
949 /* Return 1 if the file name NAME is in a directory
950 that should be converted. */
953 directory_specified_p (name)
956 struct string_list *p;
958 for (p = directory_list; p; p = p->next)
959 if (!strncmp (name, p->name, strlen (p->name))
960 && name[strlen (p->name)] == '/')
962 const char *q = name + strlen (p->name) + 1;
964 /* If there are more slashes, it's in a subdir, so
965 this match doesn't count. */
977 /* Return 1 if the file named NAME should be excluded from conversion. */
980 file_excluded_p (name)
983 struct string_list *p;
984 int len = strlen (name);
986 for (p = exclude_list; p; p = p->next)
987 if (!strcmp (name + len - strlen (p->name), p->name)
988 && name[len - strlen (p->name) - 1] == '/')
994 /* Construct a new element of a string_list.
995 STRING is the new element value, and REST holds the remaining elements. */
997 static struct string_list *
998 string_list_cons (string, rest)
1000 struct string_list *rest;
1002 struct string_list *temp
1003 = (struct string_list *) xmalloc (sizeof (struct string_list));
1006 temp->name = string;
1010 /* ??? The GNU convention for mentioning function args in its comments
1011 is to capitalize them. So change "hash_tab_p" to HASH_TAB_P below.
1012 Likewise for all the other functions. */
1014 /* Given a hash table, apply some function to each node in the table. The
1015 table to traverse is given as the "hash_tab_p" argument, and the
1016 function to be applied to each node in the table is given as "func"
1020 visit_each_hash_node (hash_tab_p, func)
1021 const hash_table_entry *hash_tab_p;
1024 const hash_table_entry *primary;
1026 for (primary = hash_tab_p; primary < &hash_tab_p[HASH_TABLE_SIZE]; primary++)
1027 if (primary->symbol)
1029 hash_table_entry *second;
1032 for (second = primary->hash_next; second; second = second->hash_next)
1037 /* Initialize all of the fields of a new hash table entry, pointed
1038 to by the "p" parameter. Note that the space to hold the entry
1039 is assumed to have already been allocated before this routine is
1042 static hash_table_entry *
1044 hash_table_entry *p;
1047 p->hash_next = NULL;
1048 p->symbol = dupstr (s);
1054 /* Look for a particular function name or filename in the particular
1055 hash table indicated by "hash_tab_p". If the name is not in the
1056 given hash table, add it. Either way, return a pointer to the
1057 hash table entry for the given name. */
1059 static hash_table_entry *
1060 lookup (hash_tab_p, search_symbol)
1061 hash_table_entry *hash_tab_p;
1062 const char *search_symbol;
1065 const char *search_symbol_char_p = search_symbol;
1066 hash_table_entry *p;
1068 while (*search_symbol_char_p)
1069 hash_value += *search_symbol_char_p++;
1070 hash_value &= hash_mask;
1071 p = &hash_tab_p[hash_value];
1073 return add_symbol (p, search_symbol);
1074 if (!strcmp (p->symbol, search_symbol))
1076 while (p->hash_next)
1079 if (!strcmp (p->symbol, search_symbol))
1082 p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
1084 return add_symbol (p, search_symbol);
1087 /* Throw a def/dec record on the junk heap.
1089 Also, since we are not using this record anymore, free up all of the
1090 stuff it pointed to. */
1096 xfree (p->ansi_decl);
1100 const f_list_chain_item * curr;
1101 const f_list_chain_item * next;
1103 for (curr = p->f_list_chain; curr; curr = next)
1105 next = curr->chain_next;
1109 #endif /* !defined (UNPROTOIZE) */
1114 /* Unexpand as many macro symbol as we can find.
1116 If the given line must be unexpanded, make a copy of it in the heap and
1117 return a pointer to the unexpanded copy. Otherwise return NULL. */
1120 unexpand_if_needed (aux_info_line)
1121 const char *aux_info_line;
1123 static char *line_buf = 0;
1124 static int line_buf_size = 0;
1125 const unexpansion* unexp_p;
1126 int got_unexpanded = 0;
1128 char *copy_p = line_buf;
1132 line_buf_size = 1024;
1133 line_buf = (char *) xmalloc (line_buf_size);
1138 /* Make a copy of the input string in line_buf, expanding as necessary. */
1140 for (s = aux_info_line; *s != '\n'; )
1142 for (unexp_p = unexpansions; unexp_p->expanded; unexp_p++)
1144 const char *in_p = unexp_p->expanded;
1145 size_t len = strlen (in_p);
1147 if (*s == *in_p && !strncmp (s, in_p, len) && !is_id_char (s[len]))
1149 int size = strlen (unexp_p->contracted);
1151 if (copy_p + size - line_buf >= line_buf_size)
1153 int offset = copy_p - line_buf;
1155 line_buf_size += size;
1156 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1157 copy_p = line_buf + offset;
1159 strcpy (copy_p, unexp_p->contracted);
1162 /* Assume the there will not be another replacement required
1163 within the text just replaced. */
1166 goto continue_outer;
1169 if (copy_p - line_buf == line_buf_size)
1171 int offset = copy_p - line_buf;
1173 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1174 copy_p = line_buf + offset;
1179 if (copy_p + 2 - line_buf >= line_buf_size)
1181 int offset = copy_p - line_buf;
1183 line_buf = (char *) xrealloc (line_buf, line_buf_size);
1184 copy_p = line_buf + offset;
1189 return (got_unexpanded ? dupstr (line_buf) : 0);
1192 /* Return the absolutized filename for the given relative
1193 filename. Note that if that filename is already absolute, it may
1194 still be returned in a modified form because this routine also
1195 eliminates redundant slashes and single dots and eliminates double
1196 dots to get a shortest possible filename from the given input
1197 filename. The absolutization of relative filenames is made by
1198 assuming that the given filename is to be taken as relative to
1199 the first argument (cwd) or to the current directory if cwd is
1203 abspath (cwd, rel_filename)
1205 const char *rel_filename;
1207 /* Setup the current working directory as needed. */
1208 const char *cwd2 = (cwd) ? cwd : cwd_buffer;
1209 char *const abs_buffer
1210 = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
1211 char *endp = abs_buffer;
1214 /* Copy the filename (possibly preceded by the current working
1215 directory name) into the absolutization buffer. */
1220 if (rel_filename[0] != '/')
1223 while (*endp++ = *src_p++)
1225 *(endp-1) = '/'; /* overwrite null */
1227 src_p = rel_filename;
1228 while (*endp++ = *src_p++)
1232 /* Now make a copy of abs_buffer into abs_buffer, shortening the
1233 filename (by taking out slashes and dots) as we go. */
1235 outp = inp = abs_buffer;
1236 *outp++ = *inp++; /* copy first slash */
1239 *outp++ = *inp++; /* copy second slash */
1245 else if (inp[0] == '/' && outp[-1] == '/')
1250 else if (inp[0] == '.' && outp[-1] == '/')
1254 else if (inp[1] == '/')
1259 else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
1261 inp += (inp[2] == '/') ? 3 : 2;
1263 while (outp >= abs_buffer && *outp != '/')
1265 if (outp < abs_buffer)
1267 /* Catch cases like /.. where we try to backup to a
1268 point above the absolute root of the logical file
1271 fprintf (stderr, "%s: invalid file name: %s\n",
1272 pname, rel_filename);
1282 /* On exit, make sure that there is a trailing null, and make sure that
1283 the last character of the returned string is *not* a slash. */
1286 if (outp[-1] == '/')
1289 /* Make a copy (in the heap) of the stuff left in the absolutization
1290 buffer and return a pointer to the copy. */
1292 return dupstr (abs_buffer);
1295 /* Given a filename (and possibly a directory name from which the filename
1296 is relative) return a string which is the shortest possible
1297 equivalent for the corresponding full (absolutized) filename. The
1298 shortest possible equivalent may be constructed by converting the
1299 absolutized filename to be a relative filename (i.e. relative to
1300 the actual current working directory). However if a relative filename
1301 is longer, then the full absolute filename is returned.
1305 Note that "simple-minded" conversion of any given type of filename (either
1306 relative or absolute) may not result in a valid equivalent filename if any
1307 subpart of the original filename is actually a symbolic link. */
1310 shortpath (cwd, filename)
1312 const char *filename;
1316 char *cwd_p = cwd_buffer;
1318 int unmatched_slash_count = 0;
1319 size_t filename_len = strlen (filename);
1321 path_p = abspath (cwd, filename);
1322 rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
1324 while (*cwd_p && (*cwd_p == *path_p))
1329 if (!*cwd_p && (!*path_p || *path_p == '/')) /* whole pwd matched */
1331 if (!*path_p) /* input *is* the current path! */
1342 while (*cwd_p != '/') /* backup to last slash */
1349 unmatched_slash_count++;
1352 /* Find out how many directory levels in cwd were *not* matched. */
1354 if (*cwd_p++ == '/')
1355 unmatched_slash_count++;
1357 /* Now we know how long the "short name" will be.
1358 Reject it if longer than the input. */
1359 if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
1362 /* For each of them, put a `../' at the beginning of the short name. */
1363 while (unmatched_slash_count--)
1365 /* Give up if the result gets to be longer
1366 than the absolute path name. */
1367 if (rel_buffer + filename_len <= rel_buf_p + 3)
1374 /* Then tack on the unmatched part of the desired file's name. */
1377 if (rel_buffer + filename_len <= rel_buf_p)
1380 while (*rel_buf_p++ = *path_p++);
1383 if (*(rel_buf_p-1) == '/')
1384 *--rel_buf_p = '\0';
1389 /* Lookup the given filename in the hash table for filenames. If it is a
1390 new one, then the hash table info pointer will be null. In this case,
1391 we create a new file_info record to go with the filename, and we initialize
1392 that record with some reasonable values. */
1394 /* FILENAME was const, but that causes a warning on AIX when calling stat.
1395 That is probably a bug in AIX, but might as well avoid the warning. */
1398 find_file (filename, do_not_stat)
1402 hash_table_entry *hash_entry_p;
1404 hash_entry_p = lookup (filename_primary, filename);
1405 if (hash_entry_p->fip)
1406 return hash_entry_p->fip;
1409 struct stat stat_buf;
1410 file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
1412 /* If we cannot get status on any given source file, give a warning
1413 and then just set its time of last modification to infinity. */
1416 stat_buf.st_mtime = (time_t) 0;
1419 if (my_stat (filename, &stat_buf) == -1)
1421 fprintf (stderr, "%s: error: can't get status of `%s': %s\n",
1422 pname, shortpath (NULL, filename), sys_errlist[errno]);
1423 stat_buf.st_mtime = (time_t) -1;
1427 hash_entry_p->fip = file_p;
1428 file_p->hash_entry = hash_entry_p;
1429 file_p->defs_decs = NULL;
1430 file_p->mtime = stat_buf.st_mtime;
1435 /* Generate a fatal error because some part of the aux_info file is
1439 aux_info_corrupted ()
1441 fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",
1442 pname, current_aux_info_lineno);
1446 /* ??? This comment is vague. Say what the condition is for. */
1447 /* Check to see that a condition is true. This is kind of like an assert. */
1450 check_aux_info (cond)
1454 aux_info_corrupted ();
1457 /* Given a pointer to the closing right parenthesis for a particular formals
1458 list (in a aux_info file) find the corresponding left parenthesis and
1459 return a pointer to it. */
1462 find_corresponding_lparen (p)
1468 for (paren_depth = 1, q = p-1; paren_depth; q--)
1483 /* Given a line from an aux info file, and a time at which the aux info
1484 file it came from was created, check to see if the item described in
1485 the line comes from a file which has been modified since the aux info
1486 file was created. If so, return non-zero, else return zero. */
1489 referenced_file_is_newer (l, aux_info_mtime)
1491 time_t aux_info_mtime;
1497 check_aux_info (l[0] == '/');
1498 check_aux_info (l[1] == '*');
1499 check_aux_info (l[2] == ' ');
1502 const char *filename_start = p = l + 3;
1506 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1507 strncpy (filename, filename_start, (size_t) (p - filename_start));
1508 filename[p-filename_start] = '\0';
1511 /* Call find_file to find the file_info record associated with the file
1512 which contained this particular def or dec item. Note that this call
1513 may cause a new file_info record to be created if this is the first time
1514 that we have ever known about this particular file. */
1516 fi_p = find_file (abspath (invocation_filename, filename), 0);
1518 return (fi_p->mtime > aux_info_mtime);
1521 /* Given a line of info from the aux_info file, create a new
1522 def_dec_info record to remember all of the important information about
1523 a function definition or declaration.
1525 Link this record onto the list of such records for the particular file in
1526 which it occurred in proper (descending) line number order (for now).
1528 If there is an identical record already on the list for the file, throw
1529 this one away. Doing so takes care of the (useless and troublesome)
1530 duplicates which are bound to crop up due to multiple inclusions of any
1531 given individual header file.
1533 Finally, link the new def_dec record onto the list of such records
1534 pertaining to this particular function name. */
1537 save_def_or_dec (l, is_syscalls)
1542 const char *semicolon_p;
1543 def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
1546 def_dec_p->written = 0;
1547 #endif /* !defined (UNPROTOIZE) */
1549 /* Start processing the line by picking off 5 pieces of information from
1550 the left hand end of the line. These are filename, line number,
1551 new/old/implicit flag (new = ANSI prototype format), definition or
1552 declaration flag, and extern/static flag). */
1554 check_aux_info (l[0] == '/');
1555 check_aux_info (l[1] == '*');
1556 check_aux_info (l[2] == ' ');
1559 const char *filename_start = p = l + 3;
1564 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
1565 strncpy (filename, filename_start, (size_t) (p - filename_start));
1566 filename[p-filename_start] = '\0';
1568 /* Call find_file to find the file_info record associated with the file
1569 which contained this particular def or dec item. Note that this call
1570 may cause a new file_info record to be created if this is the first time
1571 that we have ever known about this particular file.
1573 Note that we started out by forcing all of the base source file names
1574 (i.e. the names of the aux_info files with the .X stripped off) into the
1575 filenames hash table, and we simultaneously setup file_info records for
1576 all of these base file names (even if they may be useless later).
1577 The file_info records for all of these "base" file names (properly)
1578 act as file_info records for the "original" (i.e. un-included) files
1579 which were submitted to gcc for compilation (when the -aux-info
1580 option was used). */
1582 def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);
1586 const char *line_number_start = ++p;
1587 char line_number[10];
1591 strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
1592 line_number[p-line_number_start] = '\0';
1593 def_dec_p->line = atoi (line_number);
1596 /* Check that this record describes a new-style, old-style, or implicit
1597 definition or declaration. */
1599 p++; /* Skip over the `:'. */
1600 check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
1602 /* Is this a new style (ANSI prototyped) definition or declaration? */
1604 def_dec_p->prototyped = (*p == 'N');
1608 /* Is this an implicit declaration? */
1610 def_dec_p->is_implicit = (*p == 'I');
1612 #endif /* !defined (UNPROTOIZE) */
1616 check_aux_info ((*p == 'C') || (*p == 'F'));
1618 /* Is this item a function definition (F) or a declaration (C). Note that
1619 we treat item taken from the syscalls file as though they were function
1620 definitions regardless of what the stuff in the file says. */
1622 def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);
1625 def_dec_p->definition = 0; /* Fill this in later if protoizing. */
1626 #endif /* !defined (UNPROTOIZE) */
1628 check_aux_info (*p++ == ' ');
1629 check_aux_info (*p++ == '*');
1630 check_aux_info (*p++ == '/');
1631 check_aux_info (*p++ == ' ');
1634 check_aux_info ((!strncmp (p, "static", 6)) || (!strncmp (p, "extern", 6)));
1635 #else /* !defined (UNPROTOIZE) */
1636 if (!strncmp (p, "static", 6))
1637 def_dec_p->is_static = -1;
1638 else if (!strncmp (p, "extern", 6))
1639 def_dec_p->is_static = 0;
1641 check_aux_info (0); /* Didn't find either `extern' or `static'. */
1642 #endif /* !defined (UNPROTOIZE) */
1645 const char *ansi_start = p;
1647 p += 6; /* Pass over the "static" or "extern". */
1649 /* We are now past the initial stuff. Search forward from here to find
1650 the terminating semicolon that should immediately follow the entire
1651 ANSI format function declaration. */
1658 /* Make a copy of the ansi declaration part of the line from the aux_info
1661 def_dec_p->ansi_decl
1662 = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
1665 /* Backup and point at the final right paren of the final argument list. */
1669 /* Now isolate a whole set of formal argument lists, one-by-one. Normally,
1670 there will only be one list to isolate, but there could be more. */
1672 def_dec_p->f_list_count = 0;
1675 def_dec_p->f_list_chain = NULL;
1676 #endif /* !defined (UNPROTOIZE) */
1680 const char *left_paren_p = find_corresponding_lparen (p);
1683 f_list_chain_item *cip =
1684 (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
1687 = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
1689 /* Add the new chain item at the head of the current list. */
1691 cip->chain_next = def_dec_p->f_list_chain;
1692 def_dec_p->f_list_chain = cip;
1694 #endif /* !defined (UNPROTOIZE) */
1695 def_dec_p->f_list_count++;
1697 p = left_paren_p - 2;
1699 /* p must now point either to another right paren, or to the last
1700 character of the name of the function that was declared/defined.
1701 If p points to another right paren, then this indicates that we
1702 are dealing with multiple formals lists. In that case, there
1703 really should be another right paren preceding this right paren. */
1708 check_aux_info (*--p == ')');
1713 const char *past_fn = p + 1;
1715 check_aux_info (*past_fn == ' ');
1717 /* Scan leftwards over the identifier that names the function. */
1719 while (is_id_char (*p))
1723 /* p now points to the leftmost character of the function name. */
1726 char *fn_string = (char *) alloca (past_fn - p + 1);
1728 strncpy (fn_string, p, (size_t) (past_fn - p));
1729 fn_string[past_fn-p] = '\0';
1730 def_dec_p->hash_entry = lookup (function_name_primary, fn_string);
1734 /* Look at all of the defs and decs for this function name that we have
1735 collected so far. If there is already one which is at the same
1736 line number in the same file, then we can discard this new def_dec_info
1739 As an extra assurance that any such pair of (nominally) identical
1740 function declarations are in fact identical, we also compare the
1741 ansi_decl parts of the lines from the aux_info files just to be on
1744 This comparison will fail if (for instance) the user was playing
1745 messy games with the preprocessor which ultimately causes one
1746 function declaration in one header file to look differently when
1747 that file is included by two (or more) other files. */
1750 const def_dec_info *other;
1752 for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func)
1754 if (def_dec_p->line == other->line && def_dec_p->file == other->file)
1756 if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
1758 fprintf (stderr, "%s: error: declaration of function `%s' at %s(%d) takes different forms\n",
1760 def_dec_p->hash_entry->symbol,
1761 def_dec_p->file->hash_entry->symbol,
1765 free_def_dec (def_dec_p);
1773 /* If we are doing unprotoizing, we must now setup the pointers that will
1774 point to the K&R name list and to the K&R argument declarations list.
1776 Note that if this is only a function declaration, then we should not
1777 expect to find any K&R style formals list following the ANSI-style
1778 formals list. This is because GCC knows that such information is
1779 useless in the case of function declarations (function definitions
1780 are a different story however).
1782 Since we are unprotoizing, we don't need any such lists anyway.
1783 All we plan to do is to delete all characters between ()'s in any
1786 def_dec_p->formal_names = NULL;
1787 def_dec_p->formal_decls = NULL;
1789 if (def_dec_p->is_func_def)
1792 check_aux_info (*++p == ' ');
1793 check_aux_info (*++p == '/');
1794 check_aux_info (*++p == '*');
1795 check_aux_info (*++p == ' ');
1796 check_aux_info (*++p == '(');
1799 const char *kr_names_start = ++p; /* Point just inside '('. */
1803 p--; /* point to closing right paren */
1805 /* Make a copy of the K&R parameter names list. */
1807 def_dec_p->formal_names
1808 = dupnstr (kr_names_start, (size_t) (p - kr_names_start));
1811 check_aux_info (*++p == ' ');
1814 /* p now points to the first character of the K&R style declarations
1815 list (if there is one) or to the star-slash combination that ends
1816 the comment in which such lists get embedded. */
1818 /* Make a copy of the K&R formal decls list and set the def_dec record
1821 if (*p == '*') /* Are there no K&R declarations? */
1823 check_aux_info (*++p == '/');
1824 def_dec_p->formal_decls = "";
1828 const char *kr_decls_start = p;
1830 while (p[0] != '*' || p[1] != '/')
1834 check_aux_info (*p == ' ');
1836 def_dec_p->formal_decls
1837 = dupnstr (kr_decls_start, (size_t) (p - kr_decls_start));
1840 /* Handle a special case. If we have a function definition marked as
1841 being in "old" style, and if it's formal names list is empty, then
1842 it may actually have the string "void" in its real formals list
1843 in the original source code. Just to make sure, we will get setup
1844 to convert such things anyway.
1846 This kludge only needs to be here because of an insurmountable
1847 problem with generating .X files. */
1849 if (!def_dec_p->prototyped && !*def_dec_p->formal_names)
1850 def_dec_p->prototyped = 1;
1853 /* Since we are unprotoizing, if this item is already in old (K&R) style,
1854 we can just ignore it. If that is true, throw away the itme now. */
1856 if (!def_dec_p->prototyped)
1858 free_def_dec (def_dec_p);
1862 #endif /* defined (UNPROTOIZE) */
1864 /* Add this record to the head of the list of records pertaining to this
1865 particular function name. */
1867 def_dec_p->next_for_func = def_dec_p->hash_entry->ddip;
1868 def_dec_p->hash_entry->ddip = def_dec_p;
1870 /* Add this new def_dec_info record to the sorted list of def_dec_info
1871 records for this file. Note that we don't have to worry about duplicates
1872 (caused by multiple inclusions of header files) here because we have
1873 already eliminated duplicates above. */
1875 if (!def_dec_p->file->defs_decs)
1877 def_dec_p->file->defs_decs = def_dec_p;
1878 def_dec_p->next_in_file = NULL;
1882 int line = def_dec_p->line;
1883 const def_dec_info *prev = NULL;
1884 const def_dec_info *curr = def_dec_p->file->defs_decs;
1885 const def_dec_info *next = curr->next_in_file;
1887 while (next && (line < curr->line))
1891 next = next->next_in_file;
1893 if (line >= curr->line)
1895 def_dec_p->next_in_file = curr;
1897 ((NONCONST def_dec_info *) prev)->next_in_file = def_dec_p;
1899 def_dec_p->file->defs_decs = def_dec_p;
1901 else /* assert (next == NULL); */
1903 ((NONCONST def_dec_info *) curr)->next_in_file = def_dec_p;
1904 /* assert (next == NULL); */
1905 def_dec_p->next_in_file = next;
1910 /* Set up the vector COMPILE_PARAMS which is the argument list for running GCC.
1911 Also set input_file_name_index and aux_info_file_name_index
1912 to the indices of the slots where the file names should go. */
1914 /* We initialize the vector by removing -g, -O, -S, -c, and -o options,
1915 and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
1918 munge_compile_params (params_list)
1919 const char *params_list;
1921 /* Build up the contents in a temporary vector
1922 that is so big that to has to be big enough. */
1923 const char **temp_params
1924 = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
1925 int param_count = 0;
1928 temp_params[param_count++] = compiler_file_name;
1931 while (isspace (*params_list))
1935 param = params_list;
1936 while (*params_list && !isspace (*params_list))
1938 if (param[0] != '-')
1939 temp_params[param_count++]
1940 = dupnstr (param, (size_t) (params_list - param));
1949 break; /* Don't copy these. */
1951 while (isspace (*params_list))
1953 while (*params_list && !isspace (*params_list))
1957 temp_params[param_count++]
1958 = dupnstr (param, (size_t) (params_list - param));
1964 temp_params[param_count++] = "-aux-info";
1966 /* Leave room for the aux-info file name argument. */
1967 aux_info_file_name_index = param_count;
1968 temp_params[param_count++] = NULL;
1970 temp_params[param_count++] = "-S";
1971 temp_params[param_count++] = "-o";
1972 temp_params[param_count++] = "/dev/null";
1974 /* Leave room for the input file name argument. */
1975 input_file_name_index = param_count;
1976 temp_params[param_count++] = NULL;
1977 /* Terminate the list. */
1978 temp_params[param_count++] = NULL;
1980 /* Make a copy of the compile_params in heap space. */
1983 = (const char **) xmalloc (sizeof (char *) * (param_count+1));
1984 memcpy (compile_params, temp_params, sizeof (char *) * param_count);
1987 /* Do a recompilation for the express purpose of generating a new aux_info
1988 file to go with a specific base source file. */
1991 gen_aux_info_file (base_filename)
1992 const char *base_filename;
1996 if (!input_file_name_index)
1997 munge_compile_params ("");
1999 /* Store the full source file name in the argument vector. */
2000 compile_params[input_file_name_index] = shortpath (NULL, base_filename);
2001 /* Add .X to source file name to get aux-info file name. */
2002 compile_params[aux_info_file_name_index]
2003 = savestring2 (compile_params[input_file_name_index],
2004 strlen (compile_params[input_file_name_index]),
2009 fprintf (stderr, "%s: compiling `%s'\n",
2010 pname, compile_params[input_file_name_index]);
2012 if (child_pid = fork ())
2014 if (child_pid == -1)
2016 fprintf (stderr, "%s: error: could not fork process: %s\n",
2017 pname, sys_errlist[errno]);
2022 /* Print out the command line that the other process is now executing. */
2028 fputs ("\t", stderr);
2029 for (arg = compile_params; *arg; arg++)
2031 fputs (*arg, stderr);
2032 fputc (' ', stderr);
2034 fputc ('\n', stderr);
2042 if (wait (&wait_status) == -1)
2044 fprintf (stderr, "%s: error: wait for process failed: %s\n",
2045 pname, sys_errlist[errno]);
2048 if (!WIFEXITED (wait_status))
2050 fprintf (stderr, "%s: error: subprocess %ld did not exit\n",
2051 pname, (long) child_pid);
2052 kill (child_pid, 9);
2055 if (WEXITSTATUS (wait_status) != 0)
2057 fprintf (stderr, "%s: error: %s: compilation failed\n",
2058 pname, base_filename);
2066 if (my_execvp (compile_params[0], (char *const *) compile_params))
2068 int e = errno, f = fileno (stderr);
2069 write (f, pname, strlen (pname));
2071 write (f, compile_params[0], strlen (compile_params[0]));
2073 write (f, sys_errlist[e], strlen (sys_errlist[e]));
2077 return 1; /* Never executed. */
2081 /* Read in all of the information contained in a single aux_info file.
2082 Save all of the important stuff for later. */
2085 process_aux_info_file (base_source_filename, keep_it, is_syscalls)
2086 const char *base_source_filename;
2090 size_t base_len = strlen (base_source_filename);
2091 char * aux_info_filename
2092 = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
2093 char *aux_info_base;
2094 char *aux_info_limit;
2095 char *aux_info_relocated_name;
2096 const char *aux_info_second_line;
2097 time_t aux_info_mtime;
2098 size_t aux_info_size;
2100 /* Construct the aux_info filename from the base source filename. */
2102 strcpy (aux_info_filename, base_source_filename);
2103 strcat (aux_info_filename, aux_info_suffix);
2105 /* Check that the aux_info file exists and is readable. If it does not
2106 exist, try to create it (once only). */
2114 if (my_access (aux_info_filename, R_OK) == -1)
2116 if (errno == ENOENT && retries == 0)
2120 fprintf (stderr, "%s: warning: missing SYSCALLS file `%s'\n",
2121 pname, aux_info_filename);
2124 if (!gen_aux_info_file (base_source_filename))
2134 fprintf (stderr, "%s: error: can't read aux info file `%s': %s\n",
2135 pname, shortpath (NULL, aux_info_filename),
2136 sys_errlist[errno]);
2144 struct stat stat_buf;
2146 /* Get some status information about this aux_info file. */
2148 if (my_stat (aux_info_filename, &stat_buf) == -1)
2150 fprintf (stderr, "%s: error: can't get status of aux info file `%s': %s\n",
2151 pname, shortpath (NULL, aux_info_filename),
2152 sys_errlist[errno]);
2157 /* Check on whether or not this aux_info file is zero length. If it is,
2158 then just ignore it and return. */
2160 if ((aux_info_size = stat_buf.st_size) == 0)
2163 /* Get the date/time of last modification for this aux_info file and
2164 remember it. We will have to check that any source files that it
2165 contains information about are at least this old or older. */
2167 aux_info_mtime = stat_buf.st_mtime;
2173 /* Open the aux_info file. */
2175 if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1)
2177 fprintf (stderr, "%s: error: can't open aux info file `%s' for reading: %s\n",
2178 pname, shortpath (NULL, aux_info_filename),
2179 sys_errlist[errno]);
2183 /* Allocate space to hold the aux_info file in memory. */
2185 aux_info_base = xmalloc (aux_info_size + 1);
2186 aux_info_limit = aux_info_base + aux_info_size;
2187 *aux_info_limit = '\0';
2189 /* Read the aux_info file into memory. */
2191 if (read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
2193 fprintf (stderr, "%s: error: while reading aux info file `%s': %s\n",
2194 pname, shortpath (NULL, aux_info_filename),
2195 sys_errlist[errno]);
2196 free (aux_info_base);
2197 close (aux_info_file);
2201 /* Close the aux info file. */
2203 if (close (aux_info_file))
2205 fprintf (stderr, "%s: error: while closing aux info file `%s': %s\n",
2206 pname, shortpath (NULL, aux_info_filename),
2207 sys_errlist[errno]);
2208 free (aux_info_base);
2209 close (aux_info_file);
2214 /* Delete the aux_info file (unless requested not to). If the deletion
2215 fails for some reason, don't even worry about it. */
2218 if (my_unlink (aux_info_filename) == -1)
2219 fprintf (stderr, "%s: error: can't delete aux info file `%s': %s\n",
2220 pname, shortpath (NULL, aux_info_filename),
2221 sys_errlist[errno]);
2223 /* Save a pointer into the first line of the aux_info file which
2224 contains the filename of the directory from which the compiler
2225 was invoked when the associated source file was compiled.
2226 This information is used later to help create complete
2227 filenames out of the (potentially) relative filenames in
2228 the aux_info file. */
2231 char *p = aux_info_base;
2238 invocation_filename = p; /* Save a pointer to first byte of path. */
2243 while (*p++ != '\n')
2245 aux_info_second_line = p;
2246 aux_info_relocated_name = 0;
2247 if (invocation_filename[0] != '/')
2249 /* INVOCATION_FILENAME is relative;
2250 append it to BASE_SOURCE_FILENAME's dir. */
2252 aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
2253 strcpy (aux_info_relocated_name, base_source_filename);
2254 dir_end = strrchr (aux_info_relocated_name, '/');
2258 dir_end = aux_info_relocated_name;
2259 strcpy (dir_end, invocation_filename);
2260 invocation_filename = aux_info_relocated_name;
2266 const char *aux_info_p;
2268 /* Do a pre-pass on the lines in the aux_info file, making sure that all
2269 of the source files referenced in there are at least as old as this
2270 aux_info file itself. If not, go back and regenerate the aux_info
2271 file anew. Don't do any of this for the syscalls file. */
2275 current_aux_info_lineno = 2;
2277 for (aux_info_p = aux_info_second_line; *aux_info_p; )
2279 if (referenced_file_is_newer (aux_info_p, aux_info_mtime))
2281 free (aux_info_base);
2282 xfree (aux_info_relocated_name);
2283 if (keep_it && my_unlink (aux_info_filename) == -1)
2285 fprintf (stderr, "%s: error: can't delete file `%s': %s\n",
2286 pname, shortpath (NULL, aux_info_filename),
2287 sys_errlist[errno]);
2293 /* Skip over the rest of this line to start of next line. */
2295 while (*aux_info_p != '\n')
2298 current_aux_info_lineno++;
2302 /* Now do the real pass on the aux_info lines. Save their information in
2303 the in-core data base. */
2305 current_aux_info_lineno = 2;
2307 for (aux_info_p = aux_info_second_line; *aux_info_p;)
2309 char *unexpanded_line = unexpand_if_needed (aux_info_p);
2311 if (unexpanded_line)
2313 save_def_or_dec (unexpanded_line, is_syscalls);
2314 free (unexpanded_line);
2317 save_def_or_dec (aux_info_p, is_syscalls);
2319 /* Skip over the rest of this line and get to start of next line. */
2321 while (*aux_info_p != '\n')
2324 current_aux_info_lineno++;
2328 free (aux_info_base);
2329 xfree (aux_info_relocated_name);
2334 /* Check an individual filename for a .c suffix. If the filename has this
2335 suffix, rename the file such that its suffix is changed to .C. This
2336 function implements the -C option. */
2340 const hash_table_entry *hp;
2342 const char *filename = hp->symbol;
2343 int last_char_index = strlen (filename) - 1;
2344 char *const new_filename = (char *) alloca (strlen (filename) + 1);
2346 /* Note that we don't care here if the given file was converted or not. It
2347 is possible that the given file was *not* converted, simply because there
2348 was nothing in it which actually required conversion. Even in this case,
2349 we want to do the renaming. Note that we only rename files with the .c
2352 if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.')
2355 strcpy (new_filename, filename);
2356 new_filename[last_char_index] = 'C';
2358 if (my_link (filename, new_filename) == -1)
2360 fprintf (stderr, "%s: warning: can't link file `%s' to `%s': %s\n",
2361 pname, shortpath (NULL, filename),
2362 shortpath (NULL, new_filename), sys_errlist[errno]);
2367 if (my_unlink (filename) == -1)
2369 fprintf (stderr, "%s: warning: can't delete file `%s': %s\n",
2370 pname, shortpath (NULL, filename), sys_errlist[errno]);
2376 #endif /* !defined (UNPROTOIZE) */
2378 /* Take the list of definitions and declarations attached to a particular
2379 file_info node and reverse the order of the list. This should get the
2380 list into an order such that the item with the lowest associated line
2381 number is nearest the head of the list. When these lists are originally
2382 built, they are in the opposite order. We want to traverse them in
2383 normal line number order later (i.e. lowest to highest) so reverse the
2387 reverse_def_dec_list (hp)
2388 const hash_table_entry *hp;
2390 file_info *file_p = hp->fip;
2391 const def_dec_info *prev = NULL;
2392 const def_dec_info *current = file_p->defs_decs;
2394 if (!( current = file_p->defs_decs))
2395 return; /* no list to reverse */
2398 if (! (current = current->next_in_file))
2399 return; /* can't reverse a single list element */
2401 ((NONCONST def_dec_info *) prev)->next_in_file = NULL;
2405 const def_dec_info *next = current->next_in_file;
2407 ((NONCONST def_dec_info *) current)->next_in_file = prev;
2412 file_p->defs_decs = prev;
2417 /* Find the (only?) extern definition for a particular function name, starting
2418 from the head of the linked list of entries for the given name. If we
2419 cannot find an extern definition for the given function name, issue a
2420 warning and scrounge around for the next best thing, i.e. an extern
2421 function declaration with a prototype attached to it. Note that we only
2422 allow such substitutions for extern declarations and never for static
2423 declarations. That's because the only reason we allow them at all is
2424 to let un-prototyped function declarations for system-supplied library
2425 functions get their prototypes from our own extra SYSCALLS.c.X file which
2426 contains all of the correct prototypes for system functions. */
2428 static const def_dec_info *
2429 find_extern_def (head, user)
2430 const def_dec_info *head;
2431 const def_dec_info *user;
2433 const def_dec_info *dd_p;
2434 const def_dec_info *extern_def_p = NULL;
2435 int conflict_noted = 0;
2437 /* Don't act too stupid here. Somebody may try to convert an entire system
2438 in one swell fwoop (rather than one program at a time, as should be done)
2439 and in that case, we may find that there are multiple extern definitions
2440 of a given function name in the entire set of source files that we are
2441 converting. If however one of these definitions resides in exactly the
2442 same source file as the reference we are trying to satisfy then in that
2443 case it would be stupid for us to fail to realize that this one definition
2444 *must* be the precise one we are looking for.
2446 To make sure that we don't miss an opportunity to make this "same file"
2447 leap of faith, we do a prescan of the list of records relating to the
2448 given function name, and we look (on this first scan) *only* for a
2449 definition of the function which is in the same file as the reference
2450 we are currently trying to satisfy. */
2452 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2453 if (dd_p->is_func_def && !dd_p->is_static && dd_p->file == user->file)
2456 /* Now, since we have not found a definition in the same file as the
2457 reference, we scan the list again and consider all possibilities from
2458 all files. Here we may get conflicts with the things listed in the
2459 SYSCALLS.c.X file, but if that happens it only means that the source
2460 code being converted contains its own definition of a function which
2461 could have been supplied by libc.a. In such cases, we should avoid
2462 issuing the normal warning, and defer to the definition given in the
2465 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2466 if (dd_p->is_func_def && !dd_p->is_static)
2468 if (!extern_def_p) /* Previous definition? */
2469 extern_def_p = dd_p; /* Remember the first definition found. */
2472 /* Ignore definition just found if it came from SYSCALLS.c.X. */
2474 if (is_syscalls_file (dd_p->file))
2477 /* Quietly replace the definition previously found with the one
2478 just found if the previous one was from SYSCALLS.c.X. */
2480 if (is_syscalls_file (extern_def_p->file))
2482 extern_def_p = dd_p;
2486 /* If we get here, then there is a conflict between two function
2487 declarations for the same function, both of which came from the
2490 if (!conflict_noted) /* first time we noticed? */
2493 fprintf (stderr, "%s: error: conflicting extern definitions of '%s'\n",
2494 pname, head->hash_entry->symbol);
2497 fprintf (stderr, "%s: declarations of '%s' will not be converted\n",
2498 pname, head->hash_entry->symbol);
2499 fprintf (stderr, "%s: conflict list for '%s' follows:\n",
2500 pname, head->hash_entry->symbol);
2501 fprintf (stderr, "%s: %s(%d): %s\n",
2503 shortpath (NULL, extern_def_p->file->hash_entry->symbol),
2504 extern_def_p->line, extern_def_p->ansi_decl);
2508 fprintf (stderr, "%s: %s(%d): %s\n",
2510 shortpath (NULL, dd_p->file->hash_entry->symbol),
2511 dd_p->line, dd_p->ansi_decl);
2515 /* We want to err on the side of caution, so if we found multiple conflicting
2516 definitions for the same function, treat this as being that same as if we
2517 had found no definitions (i.e. return NULL). */
2524 /* We have no definitions for this function so do the next best thing.
2525 Search for an extern declaration already in prototype form. */
2527 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2528 if (!dd_p->is_func_def && !dd_p->is_static && dd_p->prototyped)
2530 extern_def_p = dd_p; /* save a pointer to the definition */
2532 fprintf (stderr, "%s: warning: using formals list from %s(%d) for function `%s'\n",
2534 shortpath (NULL, dd_p->file->hash_entry->symbol),
2535 dd_p->line, dd_p->hash_entry->symbol);
2539 /* Gripe about unprototyped function declarations that we found no
2540 corresponding definition (or other source of prototype information)
2543 Gripe even if the unprototyped declaration we are worried about
2544 exists in a file in one of the "system" include directories. We
2545 can gripe about these because we should have at least found a
2546 corresponding (pseudo) definition in the SYSCALLS.c.X file. If we
2547 didn't, then that means that the SYSCALLS.c.X file is missing some
2548 needed prototypes for this particular system. That is worth telling
2553 const char *file = user->file->hash_entry->symbol;
2556 if (in_system_include_dir (file))
2558 /* Why copy this string into `needed' at all?
2559 Why not just use user->ansi_decl without copying? */
2560 char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
2563 strcpy (needed, user->ansi_decl);
2564 p = (NONCONST char *) substr (needed, user->hash_entry->symbol)
2565 + strlen (user->hash_entry->symbol) + 2;
2566 /* Avoid having ??? in the string. */
2572 fprintf (stderr, "%s: %d: `%s' used but missing from SYSCALLS\n",
2573 shortpath (NULL, file), user->line,
2574 needed+7); /* Don't print "extern " */
2578 fprintf (stderr, "%s: %d: warning: no extern definition for `%s'\n",
2579 shortpath (NULL, file), user->line,
2580 user->hash_entry->symbol);
2584 return extern_def_p;
2587 /* Find the (only?) static definition for a particular function name in a
2588 given file. Here we get the function-name and the file info indirectly
2589 from the def_dec_info record pointer which is passed in. */
2591 static const def_dec_info *
2592 find_static_definition (user)
2593 const def_dec_info *user;
2595 const def_dec_info *head = user->hash_entry->ddip;
2596 const def_dec_info *dd_p;
2597 int num_static_defs = 0;
2598 const def_dec_info *static_def_p = NULL;
2600 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
2601 if (dd_p->is_func_def && dd_p->is_static && (dd_p->file == user->file))
2603 static_def_p = dd_p; /* save a pointer to the definition */
2606 if (num_static_defs == 0)
2609 fprintf (stderr, "%s: warning: no static definition for `%s' in file `%s'\n",
2610 pname, head->hash_entry->symbol,
2611 shortpath (NULL, user->file->hash_entry->symbol));
2613 else if (num_static_defs > 1)
2615 fprintf (stderr, "%s: error: multiple static defs of `%s' in file `%s'\n",
2616 pname, head->hash_entry->symbol,
2617 shortpath (NULL, user->file->hash_entry->symbol));
2620 return static_def_p;
2623 /* Find good prototype style formal argument lists for all of the function
2624 declarations which didn't have them before now.
2626 To do this we consider each function name one at a time. For each function
2627 name, we look at the items on the linked list of def_dec_info records for
2628 that particular name.
2630 Somewhere on this list we should find one (and only one) def_dec_info
2631 record which represents the actual function definition, and this record
2632 should have a nice formal argument list already associated with it.
2634 Thus, all we have to do is to connect up all of the other def_dec_info
2635 records for this particular function name to the special one which has
2636 the full-blown formals list.
2638 Of course it is a little more complicated than just that. See below for
2642 connect_defs_and_decs (hp)
2643 const hash_table_entry *hp;
2645 const def_dec_info *dd_p;
2646 const def_dec_info *extern_def_p = NULL;
2647 int first_extern_reference = 1;
2649 /* Traverse the list of definitions and declarations for this particular
2650 function name. For each item on the list, if it is a function
2651 definition (either old style or new style) then GCC has already been
2652 kind enough to produce a prototype for us, and it is associated with
2653 the item already, so declare the item as its own associated "definition".
2655 Also, for each item which is only a function declaration, but which
2656 nonetheless has its own prototype already (obviously supplied by the user)
2657 declare the item as it's own definition.
2659 Note that when/if there are multiple user-supplied prototypes already
2660 present for multiple declarations of any given function, these multiple
2661 prototypes *should* all match exactly with one another and with the
2662 prototype for the actual function definition. We don't check for this
2663 here however, since we assume that the compiler must have already done
2664 this consistency checking when it was creating the .X files. */
2666 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2667 if (dd_p->prototyped)
2668 ((NONCONST def_dec_info *) dd_p)->definition = dd_p;
2670 /* Traverse the list of definitions and declarations for this particular
2671 function name. For each item on the list, if it is an extern function
2672 declaration and if it has no associated definition yet, go try to find
2673 the matching extern definition for the declaration.
2675 When looking for the matching function definition, warn the user if we
2678 If we find more that one function definition also issue a warning.
2680 Do the search for the matching definition only once per unique function
2681 name (and only when absolutely needed) so that we can avoid putting out
2682 redundant warning messages, and so that we will only put out warning
2683 messages when there is actually a reference (i.e. a declaration) for
2684 which we need to find a matching definition. */
2686 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2687 if (!dd_p->is_func_def && !dd_p->is_static && !dd_p->definition)
2689 if (first_extern_reference)
2691 extern_def_p = find_extern_def (hp->ddip, dd_p);
2692 first_extern_reference = 0;
2694 ((NONCONST def_dec_info *) dd_p)->definition = extern_def_p;
2697 /* Traverse the list of definitions and declarations for this particular
2698 function name. For each item on the list, if it is a static function
2699 declaration and if it has no associated definition yet, go try to find
2700 the matching static definition for the declaration within the same file.
2702 When looking for the matching function definition, warn the user if we
2703 fail to find one in the same file with the declaration, and refuse to
2704 convert this kind of cross-file static function declaration. After all,
2705 this is stupid practice and should be discouraged.
2707 We don't have to worry about the possibility that there is more than one
2708 matching function definition in the given file because that would have
2709 been flagged as an error by the compiler.
2711 Do the search for the matching definition only once per unique
2712 function-name/source-file pair (and only when absolutely needed) so that
2713 we can avoid putting out redundant warning messages, and so that we will
2714 only put out warning messages when there is actually a reference (i.e. a
2715 declaration) for which we actually 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 const def_dec_info *dd_p2;
2721 const def_dec_info *static_def;
2723 /* We have now found a single static declaration for which we need to
2724 find a matching definition. We want to minimize the work (and the
2725 number of warnings), so we will find an appropriate (matching)
2726 static definition for this declaration, and then distribute it
2727 (as the definition for) any and all other static declarations
2728 for this function name which occur within the same file, and which
2729 do not already have definitions.
2731 Note that a trick is used here to prevent subsequent attempts to
2732 call find_static_definition for a given function-name & file
2733 if the first such call returns NULL. Essentially, we convert
2734 these NULL return values to -1, and put the -1 into the definition
2735 field for each other static declaration from the same file which
2736 does not already have an associated definition.
2737 This makes these other static declarations look like they are
2738 actually defined already when the outer loop here revisits them
2739 later on. Thus, the outer loop will skip over them. Later, we
2740 turn the -1's back to NULL's. */
2742 ((NONCONST def_dec_info *) dd_p)->definition =
2743 (static_def = find_static_definition (dd_p))
2745 : (const def_dec_info *) -1;
2747 for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
2748 if (!dd_p2->is_func_def && dd_p2->is_static
2749 && !dd_p2->definition && (dd_p2->file == dd_p->file))
2750 ((NONCONST def_dec_info *)dd_p2)->definition = dd_p->definition;
2753 /* Convert any dummy (-1) definitions we created in the step above back to
2754 NULL's (as they should be). */
2756 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
2757 if (dd_p->definition == (def_dec_info *) -1)
2758 ((NONCONST def_dec_info *) dd_p)->definition = NULL;
2761 #endif /* !defined (UNPROTOIZE) */
2763 /* Give a pointer into the clean text buffer, return a number which is the
2764 original source line number that the given pointer points into. */
2767 identify_lineno (clean_p)
2768 const char *clean_p;
2773 for (scan_p = clean_text_base; scan_p <= clean_p; scan_p++)
2774 if (*scan_p == '\n')
2779 /* Issue an error message and give up on doing this particular edit. */
2782 declare_source_confusing (clean_p)
2783 const char *clean_p;
2788 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2789 shortpath (NULL, convert_filename), last_known_line_number);
2791 fprintf (stderr, "%s: %d: warning: source too confusing\n",
2792 shortpath (NULL, convert_filename),
2793 identify_lineno (clean_p));
2795 longjmp (source_confusion_recovery, 1);
2798 /* Check that a condition which is expected to be true in the original source
2799 code is in fact true. If not, issue an error message and give up on
2800 converting this particular source file. */
2803 check_source (cond, clean_p)
2805 const char *clean_p;
2808 declare_source_confusing (clean_p);
2811 /* If we think of the in-core cleaned text buffer as a memory mapped
2812 file (with the variable last_known_line_start acting as sort of a
2813 file pointer) then we can imagine doing "seeks" on the buffer. The
2814 following routine implements a kind of "seek" operation for the in-core
2815 (cleaned) copy of the source file. When finished, it returns a pointer to
2816 the start of a given (numbered) line in the cleaned text buffer.
2818 Note that protoize only has to "seek" in the forward direction on the
2819 in-core cleaned text file buffers, and it never needs to back up.
2821 This routine is made a little bit faster by remembering the line number
2822 (and pointer value) supplied (and returned) from the previous "seek".
2823 This prevents us from always having to start all over back at the top
2824 of the in-core cleaned buffer again. */
2830 if (n < last_known_line_number)
2833 while (n > last_known_line_number)
2835 while (*last_known_line_start != '\n')
2836 check_source (++last_known_line_start < clean_text_limit, 0);
2837 last_known_line_start++;
2838 last_known_line_number++;
2840 return last_known_line_start;
2843 /* Given a pointer to a character in the cleaned text buffer, return a pointer
2844 to the next non-whitepace character which follows it. */
2847 forward_to_next_token_char (ptr)
2850 for (++ptr; isspace (*ptr); check_source (++ptr < clean_text_limit, 0))
2855 /* Copy a chunk of text of length `len' and starting at `str' to the current
2856 output buffer. Note that all attempts to add stuff to the current output
2857 buffer ultimately go through here. */
2860 output_bytes (str, len)
2864 if ((repl_write_ptr + 1) + len >= repl_text_limit)
2866 size_t new_size = (repl_text_limit - repl_text_base) << 1;
2867 char *new_buf = (char *) xrealloc (repl_text_base, new_size);
2869 repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
2870 repl_text_base = new_buf;
2871 repl_text_limit = new_buf + new_size;
2873 memcpy (repl_write_ptr + 1, str, len);
2874 repl_write_ptr += len;
2877 /* Copy all bytes (except the trailing null) of a null terminated string to
2878 the current output buffer. */
2884 output_bytes (str, strlen (str));
2887 /* Copy some characters from the original text buffer to the current output
2890 This routine takes a pointer argument `p' which is assumed to be a pointer
2891 into the cleaned text buffer. The bytes which are copied are the `original'
2892 equivalents for the set of bytes between the last value of `clean_read_ptr'
2893 and the argument value `p'.
2895 The set of bytes copied however, comes *not* from the cleaned text buffer,
2896 but rather from the direct counterparts of these bytes within the original
2899 Thus, when this function is called, some bytes from the original text
2900 buffer (which may include original comments and preprocessing directives)
2901 will be copied into the output buffer.
2903 Note that the request implide when this routine is called includes the
2904 byte pointed to by the argument pointer `p'. */
2910 size_t copy_length = (size_t) (p - clean_read_ptr);
2911 const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
2913 if (copy_length == 0)
2916 output_bytes (copy_start, copy_length);
2920 /* Given a pointer to a def_dec_info record which represents some form of
2921 definition of a function (perhaps a real definition, or in lieu of that
2922 perhaps just a declaration with a full prototype) return true if this
2923 function is one which we should avoid converting. Return false
2927 other_variable_style_function (ansi_header)
2928 const char *ansi_header;
2932 /* See if we have a stdarg function, or a function which has stdarg style
2933 parameters or a stdarg style return type. */
2935 return (int) substr (ansi_header, "...");
2937 #else /* !defined (UNPROTOIZE) */
2939 /* See if we have a varargs function, or a function which has varargs style
2940 parameters or a varargs style return type. */
2943 int len = strlen (varargs_style_indicator);
2945 for (p = ansi_header; p; )
2947 const char *candidate;
2949 if ((candidate = substr (p, varargs_style_indicator)) == 0)
2952 if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
2958 #endif /* !defined (UNPROTOIZE) */
2961 /* Do the editing operation specifically for a function "declaration". Note
2962 that editing for function "definitions" are handled in a separate routine
2966 edit_fn_declaration (def_dec_p, clean_text_p)
2967 const def_dec_info *def_dec_p;
2968 const char *volatile clean_text_p;
2970 const char *start_formals;
2971 const char *end_formals;
2972 const char *function_to_edit = def_dec_p->hash_entry->symbol;
2973 size_t func_name_len = strlen (function_to_edit);
2974 const char *end_of_fn_name;
2978 const f_list_chain_item *this_f_list_chain_item;
2979 const def_dec_info *definition = def_dec_p->definition;
2981 /* If we are protoizing, and if we found no corresponding definition for
2982 this particular function declaration, then just leave this declaration
2983 exactly as it is. */
2988 /* If we are protoizing, and if the corresponding definition that we found
2989 for this particular function declaration defined an old style varargs
2990 function, then we want to issue a warning and just leave this function
2991 declaration unconverted. */
2993 if (other_variable_style_function (definition->ansi_decl))
2996 fprintf (stderr, "%s: %d: warning: varargs function declaration not converted\n",
2997 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3002 #endif /* !defined (UNPROTOIZE) */
3004 /* Setup here to recover from confusing source code detected during this
3005 particular "edit". */
3008 if (setjmp (source_confusion_recovery))
3010 restore_pointers ();
3011 fprintf (stderr, "%s: declaration of function `%s' not converted\n",
3012 pname, function_to_edit);
3016 /* We are editing a function declaration. The line number we did a seek to
3017 contains the comma or semicolon which follows the declaration. Our job
3018 now is to scan backwards looking for the function name. This name *must*
3019 be followed by open paren (ignoring whitespace, of course). We need to
3020 replace everything between that open paren and the corresponding closing
3021 paren. If we are protoizing, we need to insert the prototype-style
3022 formals lists. If we are unprotoizing, we need to just delete everything
3023 between the pairs of opening and closing parens. */
3025 /* First move up to the end of the line. */
3027 while (*clean_text_p != '\n')
3028 check_source (++clean_text_p < clean_text_limit, 0);
3029 clean_text_p--; /* Point to just before the newline character. */
3031 /* Now we can scan backwards for the function name. */
3037 /* Scan leftwards until we find some character which can be
3038 part of an identifier. */
3040 while (!is_id_char (*clean_text_p))
3041 check_source (--clean_text_p > clean_read_ptr, 0);
3043 /* Scan backwards until we find a char that cannot be part of an
3046 while (is_id_char (*clean_text_p))
3047 check_source (--clean_text_p > clean_read_ptr, 0);
3049 /* Having found an "id break", see if the following id is the one
3050 that we are looking for. If so, then exit from this loop. */
3052 if (!strncmp (clean_text_p+1, function_to_edit, func_name_len))
3054 char ch = *(clean_text_p + 1 + func_name_len);
3056 /* Must also check to see that the name in the source text
3057 ends where it should (in order to prevent bogus matches
3058 on similar but longer identifiers. */
3060 if (! is_id_char (ch))
3061 break; /* exit from loop */
3065 /* We have now found the first perfect match for the function name in
3066 our backward search. This may or may not be the actual function
3067 name at the start of the actual function declaration (i.e. we could
3068 have easily been mislead). We will try to avoid getting fooled too
3069 often by looking forward for the open paren which should follow the
3070 identifier we just found. We ignore whitespace while hunting. If
3071 the next non-whitespace byte we see is *not* an open left paren,
3072 then we must assume that we have been fooled and we start over
3073 again accordingly. Note that there is no guarantee, that even if
3074 we do see the open paren, that we are in the right place.
3075 Programmers do the strangest things sometimes! */
3077 end_of_fn_name = clean_text_p + strlen (def_dec_p->hash_entry->symbol);
3078 start_formals = forward_to_next_token_char (end_of_fn_name);
3080 while (*start_formals != '(');
3082 /* start_of_formals now points to the opening left paren which immediately
3083 follows the name of the function. */
3085 /* Note that there may be several formals lists which need to be modified
3086 due to the possibility that the return type of this function is a
3087 pointer-to-function type. If there are several formals lists, we
3088 convert them in left-to-right order here. */
3091 this_f_list_chain_item = definition->f_list_chain;
3092 #endif /* !defined (UNPROTOIZE) */
3099 end_formals = start_formals + 1;
3101 for (; depth; check_source (++end_formals < clean_text_limit, 0))
3103 switch (*end_formals)
3116 /* end_formals now points to the closing right paren of the formals
3117 list whose left paren is pointed to by start_formals. */
3119 /* Now, if we are protoizing, we insert the new ANSI-style formals list
3120 attached to the associated definition of this function. If however
3121 we are unprotoizing, then we simply delete any formals list which
3124 output_up_to (start_formals);
3126 if (this_f_list_chain_item)
3128 output_string (this_f_list_chain_item->formals_list);
3129 this_f_list_chain_item = this_f_list_chain_item->chain_next;
3134 fprintf (stderr, "%s: warning: too many parameter lists in declaration of `%s'\n",
3135 pname, def_dec_p->hash_entry->symbol);
3136 check_source (0, end_formals); /* leave the declaration intact */
3138 #endif /* !defined (UNPROTOIZE) */
3139 clean_read_ptr = end_formals - 1;
3141 /* Now see if it looks like there may be another formals list associated
3142 with the function declaration that we are converting (following the
3143 formals list that we just converted. */
3146 const char *another_r_paren = forward_to_next_token_char (end_formals);
3148 if ((*another_r_paren != ')')
3149 || (*(start_formals = forward_to_next_token_char (another_r_paren)) != '('))
3152 if (this_f_list_chain_item)
3155 fprintf (stderr, "\n%s: warning: too few parameter lists in declaration of `%s'\n",
3156 pname, def_dec_p->hash_entry->symbol);
3157 check_source (0, start_formals); /* leave the decl intact */
3159 #endif /* !defined (UNPROTOIZE) */
3165 /* There does appear to be yet another formals list, so loop around
3166 again, and convert it also. */
3170 /* Edit a whole group of formals lists, starting with the rightmost one
3171 from some set of formals lists. This routine is called once (from the
3172 outside) for each function declaration which is converted. It is
3173 recursive however, and it calls itself once for each remaining formal
3174 list that lies to the left of the one it was originally called to work
3175 on. Thus, a whole set gets done in right-to-left order.
3177 This routine returns non-zero if it thinks that it should not be trying
3178 to convert this particular function definition (because the name of the
3179 function doesn't match the one expected). */
3182 edit_formals_lists (end_formals, f_list_count, def_dec_p)
3183 const char *end_formals;
3184 unsigned int f_list_count;
3185 const def_dec_info *def_dec_p;
3187 const char *start_formals;
3190 start_formals = end_formals - 1;
3192 for (; depth; check_source (--start_formals > clean_read_ptr, 0))
3194 switch (*start_formals)
3206 /* start_formals now points to the opening left paren of the formals list. */
3212 const char *next_end;
3214 /* There should be more formal lists to the left of here. */
3216 next_end = start_formals - 1;
3217 check_source (next_end > clean_read_ptr, 0);
3218 while (isspace (*next_end))
3219 check_source (--next_end > clean_read_ptr, 0);
3220 check_source (*next_end == ')', next_end);
3221 check_source (--next_end > clean_read_ptr, 0);
3222 check_source (*next_end == ')', next_end);
3223 if (edit_formals_lists (next_end, f_list_count, def_dec_p))
3227 /* Check that the function name in the header we are working on is the same
3228 as the one we would expect to find. If not, issue a warning and return
3231 if (f_list_count == 0)
3233 const char *expected = def_dec_p->hash_entry->symbol;
3234 const char *func_name_start;
3235 const char *func_name_limit;
3236 size_t func_name_len;
3238 for (func_name_limit = start_formals-1; isspace (*func_name_limit); )
3239 check_source (--func_name_limit > clean_read_ptr, 0);
3241 for (func_name_start = func_name_limit++;
3242 is_id_char (*func_name_start);
3244 check_source (func_name_start > clean_read_ptr, 0);
3246 func_name_len = func_name_limit - func_name_start;
3247 if (func_name_len == 0)
3248 check_source (0, func_name_start);
3249 if (func_name_len != strlen (expected)
3250 || strncmp (func_name_start, expected, func_name_len))
3252 fprintf (stderr, "%s: %d: warning: found `%s' but expected `%s'\n",
3253 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3254 identify_lineno (func_name_start),
3255 dupnstr (func_name_start, func_name_len),
3261 output_up_to (start_formals);
3264 if (f_list_count == 0)
3265 output_string (def_dec_p->formal_names);
3266 #else /* !defined (UNPROTOIZE) */
3268 unsigned f_list_depth;
3269 const f_list_chain_item *flci_p = def_dec_p->f_list_chain;
3271 /* At this point, the current value of f_list count says how many
3272 links we have to follow through the f_list_chain to get to the
3273 particular formals list that we need to output next. */
3275 for (f_list_depth = 0; f_list_depth < f_list_count; f_list_depth++)
3276 flci_p = flci_p->chain_next;
3277 output_string (flci_p->formals_list);
3279 #endif /* !defined (UNPROTOIZE) */
3281 clean_read_ptr = end_formals - 1;
3285 /* Given a pointer to a byte in the clean text buffer which points to the
3286 beginning of a line that contains a "follower" token for a function
3287 definition header, do whatever is necessary to find the right closing
3288 paren for the rightmost formals list of the function definition header.
3292 find_rightmost_formals_list (clean_text_p)
3293 const char *clean_text_p;
3295 const char *end_formals;
3297 /* We are editing a function definition. The line number we did a seek
3298 to contains the first token which immediately follows the entire set of
3299 formals lists which are part of this particular function definition
3302 Our job now is to scan leftwards in the clean text looking for the
3303 right-paren which is at the end of the function header's rightmost
3306 If we ignore whitespace, this right paren should be the first one we
3307 see which is (ignoring whitespace) immediately followed either by the
3308 open curly-brace beginning the function body or by an alphabetic
3309 character (in the case where the function definition is in old (K&R)
3310 style and there are some declarations of formal parameters). */
3312 /* It is possible that the right paren we are looking for is on the
3313 current line (together with its following token). Just in case that
3314 might be true, we start out here by skipping down to the right end of
3315 the current line before starting our scan. */
3317 for (end_formals = clean_text_p; *end_formals != '\n'; end_formals++)
3323 /* Now scan backwards while looking for the right end of the rightmost
3324 formals list associated with this function definition. */
3328 const char *l_brace_p;
3330 /* Look leftward and try to find a right-paren. */
3332 while (*end_formals != ')')
3334 if (isspace (*end_formals))
3335 while (isspace (*end_formals))
3336 check_source (--end_formals > clean_read_ptr, 0);
3338 check_source (--end_formals > clean_read_ptr, 0);
3341 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3342 /* Since we are unprotoizing an ANSI-style (prototyped) function
3343 definition, there had better not be anything (except whitespace)
3344 between the end of the ANSI formals list and the beginning of the
3345 function body (i.e. the '{'). */
3347 check_source (ch == '{', l_brace_p);
3350 #else /* !defined (UNPROTOIZE) */
3352 /* Now scan backwards while looking for the right end of the rightmost
3353 formals list associated with this function definition. */
3358 const char *l_brace_p;
3360 /* Look leftward and try to find a right-paren. */
3362 while (*end_formals != ')')
3364 if (isspace (*end_formals))
3365 while (isspace (*end_formals))
3366 check_source (--end_formals > clean_read_ptr, 0);
3368 check_source (--end_formals > clean_read_ptr, 0);
3371 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
3373 /* Since it is possible that we found a right paren before the starting
3374 '{' of the body which IS NOT the one at the end of the real K&R
3375 formals list (say for instance, we found one embedded inside one of
3376 the old K&R formal parameter declarations) we have to check to be
3377 sure that this is in fact the right paren that we were looking for.
3379 The one we were looking for *must* be followed by either a '{' or
3380 by an alphabetic character, while others *cannot* legally be followed
3381 by such characters. */
3383 if ((ch == '{') || isalpha (ch))
3386 /* At this point, we have found a right paren, but we know that it is
3387 not the one we were looking for, so backup one character and keep
3390 check_source (--end_formals > clean_read_ptr, 0);
3393 #endif /* !defined (UNPROTOIZE) */
3400 /* Insert into the output file a totally new declaration for a function
3401 which (up until now) was being called from within the current block
3402 without having been declared at any point such that the declaration
3403 was visible (i.e. in scope) at the point of the call.
3405 We need to add in explicit declarations for all such function calls
3406 in order to get the full benefit of prototype-based function call
3407 parameter type checking. */
3410 add_local_decl (def_dec_p, clean_text_p)
3411 const def_dec_info *def_dec_p;
3412 const char *clean_text_p;
3414 const char *start_of_block;
3415 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3417 /* Don't insert new local explicit declarations unless explicitly requested
3423 /* Setup here to recover from confusing source code detected during this
3424 particular "edit". */
3427 if (setjmp (source_confusion_recovery))
3429 restore_pointers ();
3430 fprintf (stderr, "%s: local declaration for function `%s' not inserted\n",
3431 pname, function_to_edit);
3435 /* We have already done a seek to the start of the line which should
3436 contain *the* open curly brace which begins the block in which we need
3437 to insert an explicit function declaration (to replace the implicit one).
3439 Now we scan that line, starting from the left, until we find the
3440 open curly brace we are looking for. Note that there may actually be
3441 multiple open curly braces on the given line, but we will be happy
3442 with the leftmost one no matter what. */
3444 start_of_block = clean_text_p;
3445 while (*start_of_block != '{' && *start_of_block != '\n')
3446 check_source (++start_of_block < clean_text_limit, 0);
3448 /* Note that the line from the original source could possibly
3449 contain *no* open curly braces! This happens if the line contains
3450 a macro call which expands into a chunk of text which includes a
3451 block (and that block's associated open and close curly braces).
3452 In cases like this, we give up, issue a warning, and do nothing. */
3454 if (*start_of_block != '{')
3458 "\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
3459 def_dec_p->file->hash_entry->symbol, def_dec_p->line,
3460 def_dec_p->hash_entry->symbol);
3464 /* Figure out what a nice (pretty) indentation would be for the new
3465 declaration we are adding. In order to do this, we must scan forward
3466 from the '{' until we find the first line which starts with some
3467 non-whitespace characters (i.e. real "token" material). */
3470 const char *ep = forward_to_next_token_char (start_of_block) - 1;
3473 /* Now we have ep pointing at the rightmost byte of some existing indent
3474 stuff. At least that is the hope.
3476 We can now just scan backwards and find the left end of the existing
3477 indentation string, and then copy it to the output buffer. */
3479 for (sp = ep; isspace (*sp) && *sp != '\n'; sp--)
3482 /* Now write out the open { which began this block, and any following
3483 trash up to and including the last byte of the existing indent that
3488 /* Now we go ahead and insert the new declaration at this point.
3490 If the definition of the given function is in the same file that we
3491 are currently editing, and if its full ANSI declaration normally
3492 would start with the keyword `extern', suppress the `extern'. */
3495 const char *decl = def_dec_p->definition->ansi_decl;
3497 if ((*decl == 'e') && (def_dec_p->file == def_dec_p->definition->file))
3499 output_string (decl);
3502 /* Finally, write out a new indent string, just like the preceding one
3503 that we found. This will typically include a newline as the first
3504 character of the indent string. */
3506 output_bytes (sp, (size_t) (ep - sp) + 1);
3510 /* Given a pointer to a file_info record, and a pointer to the beginning
3511 of a line (in the clean text buffer) which is assumed to contain the
3512 first "follower" token for the first function definition header in the
3513 given file, find a good place to insert some new global function
3514 declarations (which will replace scattered and imprecise implicit ones)
3515 and then insert the new explicit declaration at that point in the file. */
3518 add_global_decls (file_p, clean_text_p)
3519 const file_info *file_p;
3520 const char *clean_text_p;
3522 const def_dec_info *dd_p;
3525 /* Setup here to recover from confusing source code detected during this
3526 particular "edit". */
3529 if (setjmp (source_confusion_recovery))
3531 restore_pointers ();
3532 fprintf (stderr, "%s: global declarations for file `%s' not inserted\n",
3533 pname, shortpath (NULL, file_p->hash_entry->symbol));
3537 /* Start by finding a good location for adding the new explicit function
3538 declarations. To do this, we scan backwards, ignoring whitespace
3539 and comments and other junk until we find either a semicolon, or until
3540 we hit the beginning of the file. */
3542 scan_p = find_rightmost_formals_list (clean_text_p);
3545 if (scan_p < clean_text_base)
3547 check_source (scan_p > clean_read_ptr, 0);
3552 /* scan_p now points either to a semicolon, or to just before the start
3553 of the whole file. */
3555 /* Now scan forward for the first non-whitespace character. In theory,
3556 this should be the first character of the following function definition
3557 header. We will put in the added declarations just prior to that. */
3560 while (isspace (*scan_p))
3564 output_up_to (scan_p);
3566 /* Now write out full prototypes for all of the things that had been
3567 implicitly declared in this file (but only those for which we were
3568 actually able to find unique matching definitions). Avoid duplicates
3569 by marking things that we write out as we go. */
3572 int some_decls_added = 0;
3574 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3575 if (dd_p->is_implicit && dd_p->definition && !dd_p->definition->written)
3577 const char *decl = dd_p->definition->ansi_decl;
3579 /* If the function for which we are inserting a declaration is
3580 actually defined later in the same file, then suppress the
3581 leading `extern' keyword (if there is one). */
3583 if (*decl == 'e' && (dd_p->file == dd_p->definition->file))
3586 output_string ("\n");
3587 output_string (decl);
3588 some_decls_added = 1;
3589 ((NONCONST def_dec_info *) dd_p->definition)->written = 1;
3591 if (some_decls_added)
3592 output_string ("\n\n");
3595 /* Unmark all of the definitions that we just marked. */
3597 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3598 if (dd_p->definition)
3599 ((NONCONST def_dec_info *) dd_p->definition)->written = 0;
3602 #endif /* !defined (UNPROTOIZE) */
3604 /* Do the editing operation specifically for a function "definition". Note
3605 that editing operations for function "declarations" are handled by a
3606 separate routine above. */
3609 edit_fn_definition (def_dec_p, clean_text_p)
3610 const def_dec_info *def_dec_p;
3611 const char *clean_text_p;
3613 const char *end_formals;
3614 const char *function_to_edit = def_dec_p->hash_entry->symbol;
3616 /* Setup here to recover from confusing source code detected during this
3617 particular "edit". */
3620 if (setjmp (source_confusion_recovery))
3622 restore_pointers ();
3623 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3624 pname, function_to_edit);
3628 end_formals = find_rightmost_formals_list (clean_text_p);
3630 /* end_of_formals now points to the closing right paren of the rightmost
3631 formals list which is actually part of the `header' of the function
3632 definition that we are converting. */
3634 /* If the header of this function definition looks like it declares a
3635 function with a variable number of arguments, and if the way it does
3636 that is different from that way we would like it (i.e. varargs vs.
3637 stdarg) then issue a warning and leave the header unconverted. */
3639 if (other_variable_style_function (def_dec_p->ansi_decl))
3642 fprintf (stderr, "%s: %d: warning: definition of %s not converted\n",
3643 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
3644 identify_lineno (end_formals),
3646 output_up_to (end_formals);
3650 if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
3652 restore_pointers ();
3653 fprintf (stderr, "%s: definition of function `%s' not converted\n",
3654 pname, function_to_edit);
3658 /* Have to output the last right paren because this never gets flushed by
3659 edit_formals_list. */
3661 output_up_to (end_formals);
3666 const char *semicolon_p;
3667 const char *limit_p;
3669 int had_newlines = 0;
3671 /* Now write out the K&R style formal declarations, one per line. */
3673 decl_p = def_dec_p->formal_decls;
3674 limit_p = decl_p + strlen (decl_p);
3675 for (;decl_p < limit_p; decl_p = semicolon_p + 2)
3677 for (semicolon_p = decl_p; *semicolon_p != ';'; semicolon_p++)
3679 output_string ("\n");
3680 output_string (indent_string);
3681 output_bytes (decl_p, (size_t) ((semicolon_p + 1) - decl_p));
3684 /* If there are no newlines between the end of the formals list and the
3685 start of the body, we should insert one now. */
3687 for (scan_p = end_formals+1; *scan_p != '{'; )
3689 if (*scan_p == '\n')
3694 check_source (++scan_p < clean_text_limit, 0);
3697 output_string ("\n");
3699 #else /* !defined (UNPROTOIZE) */
3700 /* If we are protoizing, there may be some flotsum & jetsum (like comments
3701 and preprocessing directives) after the old formals list but before
3702 the following { and we would like to preserve that stuff while effectively
3703 deleting the existing K&R formal parameter declarations. We do so here
3704 in a rather tricky way. Basically, we white out any stuff *except*
3705 the comments/pp-directives in the original text buffer, then, if there
3706 is anything in this area *other* than whitespace, we output it. */
3708 const char *end_formals_orig;
3709 const char *start_body;
3710 const char *start_body_orig;
3712 const char *scan_orig;
3713 int have_flotsum = 0;
3714 int have_newlines = 0;
3716 for (start_body = end_formals + 1; *start_body != '{';)
3717 check_source (++start_body < clean_text_limit, 0);
3719 end_formals_orig = orig_text_base + (end_formals - clean_text_base);
3720 start_body_orig = orig_text_base + (start_body - clean_text_base);
3721 scan = end_formals + 1;
3722 scan_orig = end_formals_orig + 1;
3723 for (; scan < start_body; scan++, scan_orig++)
3725 if (*scan == *scan_orig)
3727 have_newlines |= (*scan_orig == '\n');
3728 /* Leave identical whitespace alone. */
3729 if (!isspace (*scan_orig))
3730 *((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
3736 output_bytes (end_formals_orig + 1,
3737 (size_t) (start_body_orig - end_formals_orig) - 1);
3740 output_string ("\n");
3742 output_string (" ");
3743 clean_read_ptr = start_body - 1;
3745 #endif /* !defined (UNPROTOIZE) */
3748 /* Clean up the clean text buffer. Do this by converting comments and
3749 preprocessor directives into spaces. Also convert line continuations
3750 into whitespace. Also, whiteout string and character literals. */
3753 do_cleaning (new_clean_text_base, new_clean_text_limit)
3754 char *new_clean_text_base;
3755 char *new_clean_text_limit;
3758 int non_whitespace_since_newline = 0;
3760 for (scan_p = new_clean_text_base; scan_p < new_clean_text_limit; scan_p++)
3764 case '/': /* Handle comments. */
3765 if (scan_p[1] != '*')
3767 non_whitespace_since_newline = 1;
3771 while (scan_p[1] != '/' || scan_p[0] != '*')
3773 if (!isspace (*scan_p))
3775 if (++scan_p >= new_clean_text_limit)
3782 case '#': /* Handle pp directives. */
3783 if (non_whitespace_since_newline)
3786 while (scan_p[1] != '\n' || scan_p[0] == '\\')
3788 if (!isspace (*scan_p))
3790 if (++scan_p >= new_clean_text_limit)
3796 case '\'': /* Handle character literals. */
3797 non_whitespace_since_newline = 1;
3798 while (scan_p[1] != '\'' || scan_p[0] == '\\')
3800 if (scan_p[0] == '\\' && !isspace (scan_p[1]))
3802 if (!isspace (*scan_p))
3804 if (++scan_p >= new_clean_text_limit)
3810 case '"': /* Handle string literals. */
3811 non_whitespace_since_newline = 1;
3812 while (scan_p[1] != '"' || scan_p[0] == '\\')
3814 if (scan_p[0] == '\\' && !isspace (scan_p[1]))
3816 if (!isspace (*scan_p))
3818 if (++scan_p >= new_clean_text_limit)
3824 case '\\': /* Handle line continuations. */
3825 if (scan_p[1] != '\n')
3831 non_whitespace_since_newline = 0; /* Reset. */
3840 break; /* Whitespace characters. */
3844 non_whitespace_since_newline = 1;
3850 /* Given a pointer to the closing right parenthesis for a particular formals
3851 list (in the clean text buffer) find the corresponding left parenthesis
3852 and return a pointer to it. */
3855 careful_find_l_paren (p)
3861 for (paren_depth = 1, q = p-1; paren_depth; check_source (--q >= clean_text_base, 0))
3876 /* Scan the clean text buffer for cases of function definitions that we
3877 don't really know about because they were preprocessed out when the
3878 aux info files were created.
3880 In this version of protoize/unprotoize we just give a warning for each
3881 one found. A later version may be able to at least unprotoize such
3884 Note that we may easily find all function definitions simply by
3885 looking for places where there is a left paren which is (ignoring
3886 whitespace) immediately followed by either a left-brace or by an
3887 upper or lower case letter. Whenever we find this combination, we
3888 have also found a function definition header.
3890 Finding function *declarations* using syntactic clues is much harder.
3891 I will probably try to do this in a later version though. */
3894 scan_for_missed_items (file_p)
3895 const file_info *file_p;
3897 static const char *scan_p;
3898 const char *limit = clean_text_limit - 3;
3899 static const char *backup_limit;
3901 backup_limit = clean_text_base - 1;
3903 for (scan_p = clean_text_base; scan_p < limit; scan_p++)
3907 static const char *last_r_paren;
3908 const char *ahead_p;
3910 last_r_paren = scan_p;
3912 for (ahead_p = scan_p + 1; isspace (*ahead_p); )
3913 check_source (++ahead_p < limit, limit);
3915 scan_p = ahead_p - 1;
3917 if (isalpha (*ahead_p) || *ahead_p == '{')
3919 const char *last_l_paren;
3920 const int lineno = identify_lineno (ahead_p);
3922 if (setjmp (source_confusion_recovery))
3925 /* We know we have a function definition header. Now skip
3926 leftwards over all of its associated formals lists. */
3930 last_l_paren = careful_find_l_paren (last_r_paren);
3931 for (last_r_paren = last_l_paren-1; isspace (*last_r_paren); )
3932 check_source (--last_r_paren >= backup_limit, backup_limit);
3934 while (*last_r_paren == ')');
3936 if (is_id_char (*last_r_paren))
3938 const char *id_limit = last_r_paren + 1;
3939 const char *id_start;
3941 const def_dec_info *dd_p;
3943 for (id_start = id_limit-1; is_id_char (*id_start); )
3944 check_source (--id_start >= backup_limit, backup_limit);
3946 backup_limit = id_start;
3947 if ((id_length = (size_t) (id_limit - id_start)) == 0)
3951 char *func_name = (char *) alloca (id_length + 1);
3952 static const char * const stmt_keywords[]
3953 = { "if", "while", "for", "switch", "return", 0 };
3954 const char * const *stmt_keyword;
3956 strncpy (func_name, id_start, id_length);
3957 func_name[id_length] = '\0';
3959 /* We must check here to see if we are actually looking at
3960 a statement rather than an actual function call. */
3962 for (stmt_keyword = stmt_keywords; *stmt_keyword; stmt_keyword++)
3963 if (!strcmp (func_name, *stmt_keyword))
3967 fprintf (stderr, "%s: found definition of `%s' at %s(%d)\n",
3970 shortpath (NULL, file_p->hash_entry->symbol),
3971 identify_lineno (id_start));
3973 /* We really should check for a match of the function name
3974 here also, but why bother. */
3976 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
3977 if (dd_p->is_func_def && dd_p->line == lineno)
3980 /* If we make it here, then we did not know about this
3981 function definition. */
3983 fprintf (stderr, "%s: %d: warning: `%s' excluded by preprocessing\n",
3984 shortpath (NULL, file_p->hash_entry->symbol),
3985 identify_lineno (id_start), func_name);
3986 fprintf (stderr, "%s: function definition not converted\n",
3996 /* Do all editing operations for a single source file (either a "base" file
3997 or an "include" file). To do this we read the file into memory, keep a
3998 virgin copy there, make another cleaned in-core copy of the original file
3999 (i.e. one in which all of the comments and preprocessor directives have
4000 been replaced with whitespace), then use these two in-core copies of the
4001 file to make a new edited in-core copy of the file. Finally, rename the
4002 original file (as a way of saving it), and then write the edited version
4003 of the file from core to a disk file of the same name as the original.
4005 Note that the trick of making a copy of the original sans comments &
4006 preprocessor directives make the editing a whole lot easier. */
4010 const hash_table_entry *hp;
4012 struct stat stat_buf;
4013 const file_info *file_p = hp->fip;
4014 char *new_orig_text_base;
4015 char *new_orig_text_limit;
4016 char *new_clean_text_base;
4017 char *new_clean_text_limit;
4020 int first_definition_in_file;
4022 /* If we are not supposed to be converting this file, or if there is
4023 nothing in there which needs converting, just skip this file. */
4025 if (!needs_to_be_converted (file_p))
4028 convert_filename = file_p->hash_entry->symbol;
4030 /* Convert a file if it is in a directory where we want conversion
4031 and the file is not excluded. */
4033 if (!directory_specified_p (convert_filename)
4034 || file_excluded_p (convert_filename))
4038 /* Don't even mention "system" include files unless we are
4039 protoizing. If we are protoizing, we mention these as a
4040 gentle way of prodding the user to convert his "system"
4041 include files to prototype format. */
4042 && !in_system_include_dir (convert_filename)
4043 #endif /* defined (UNPROTOIZE) */
4045 fprintf (stderr, "%s: `%s' not converted\n",
4046 pname, shortpath (NULL, convert_filename));
4050 /* Let the user know what we are up to. */
4053 fprintf (stderr, "%s: would convert file `%s'\n",
4054 pname, shortpath (NULL, convert_filename));
4056 fprintf (stderr, "%s: converting file `%s'\n",
4057 pname, shortpath (NULL, convert_filename));
4060 /* Find out the size (in bytes) of the original file. */
4062 /* The cast avoids an erroneous warning on AIX. */
4063 if (my_stat ((char *)convert_filename, &stat_buf) == -1)
4065 fprintf (stderr, "%s: error: can't get status for file `%s': %s\n",
4066 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4069 orig_size = stat_buf.st_size;
4071 /* Allocate a buffer to hold the original text. */
4073 orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
4074 orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
4076 /* Allocate a buffer to hold the cleaned-up version of the original text. */
4078 clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
4079 clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
4080 clean_read_ptr = clean_text_base - 1;
4082 /* Allocate a buffer that will hopefully be large enough to hold the entire
4083 converted output text. As an initial guess for the maximum size of the
4084 output buffer, use 125% of the size of the original + some extra. This
4085 buffer can be expanded later as needed. */
4087 repl_size = orig_size + (orig_size >> 2) + 4096;
4088 repl_text_base = (char *) xmalloc (repl_size + 2);
4089 repl_text_limit = repl_text_base + repl_size - 1;
4090 repl_write_ptr = repl_text_base - 1;
4095 /* Open the file to be converted in READ ONLY mode. */
4097 if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1)
4099 fprintf (stderr, "%s: error: can't open file `%s' for reading: %s\n",
4100 pname, shortpath (NULL, convert_filename),
4101 sys_errlist[errno]);
4105 /* Read the entire original source text file into the original text buffer
4106 in one swell fwoop. Then figure out where the end of the text is and
4107 make sure that it ends with a newline followed by a null. */
4109 if (read (input_file, new_orig_text_base, orig_size) != orig_size)
4112 fprintf (stderr, "\n%s: error: while reading input file `%s': %s\n",
4113 pname, shortpath (NULL, convert_filename),
4114 sys_errlist[errno]);
4121 if (orig_size == 0 || orig_text_limit[-1] != '\n')
4123 *new_orig_text_limit++ = '\n';
4127 /* Create the cleaned up copy of the original text. */
4129 memcpy (new_clean_text_base, orig_text_base,
4130 (size_t) (orig_text_limit - orig_text_base));
4131 do_cleaning (new_clean_text_base, new_clean_text_limit);
4136 size_t clean_size = orig_text_limit - orig_text_base;
4137 char *const clean_filename = (char *) alloca (strlen (convert_filename) + 6 + 1);
4139 /* Open (and create) the clean file. */
4141 strcpy (clean_filename, convert_filename);
4142 strcat (clean_filename, ".clean");
4143 if ((clean_file = creat (clean_filename, 0666)) == -1)
4145 fprintf (stderr, "%s: error: can't create/open clean file `%s': %s\n",
4146 pname, shortpath (NULL, clean_filename),
4147 sys_errlist[errno]);
4151 /* Write the clean file. */
4153 if (write (clean_file, new_clean_text_base, clean_size) != clean_size)
4154 fprintf (stderr, "%s: error: while writing file `%s': %s\n",
4155 pname, shortpath (NULL, clean_filename), sys_errlist[errno]);
4161 /* Do a simplified scan of the input looking for things that were not
4162 mentioned in the aux info files because of the fact that they were
4163 in a region of the source which was preprocessed-out (via #if or
4166 scan_for_missed_items (file_p);
4168 /* Setup to do line-oriented forward seeking in the clean text buffer. */
4170 last_known_line_number = 1;
4171 last_known_line_start = clean_text_base;
4173 /* Now get down to business and make all of the necessary edits. */
4176 const def_dec_info *def_dec_p;
4178 first_definition_in_file = 1;
4179 def_dec_p = file_p->defs_decs;
4180 for (; def_dec_p; def_dec_p = def_dec_p->next_in_file)
4182 const char *clean_text_p = seek_to_line (def_dec_p->line);
4184 /* clean_text_p now points to the first character of the line which
4185 contains the `terminator' for the declaration or definition that
4186 we are about to process. */
4190 if (global_flag && def_dec_p->is_func_def && first_definition_in_file)
4192 add_global_decls (def_dec_p->file, clean_text_p);
4193 first_definition_in_file = 0;
4196 /* Don't edit this item if it is already in prototype format or if it
4197 is a function declaration and we have found no corresponding
4200 if (def_dec_p->prototyped
4201 || (!def_dec_p->is_func_def && !def_dec_p->definition))
4204 #endif /* !defined (UNPROTOIZE) */
4206 if (def_dec_p->is_func_def)
4207 edit_fn_definition (def_dec_p, clean_text_p);
4210 if (def_dec_p->is_implicit)
4211 add_local_decl (def_dec_p, clean_text_p);
4213 #endif /* !defined (UNPROTOIZE) */
4214 edit_fn_declaration (def_dec_p, clean_text_p);
4218 /* Finalize things. Output the last trailing part of the original text. */
4220 output_up_to (clean_text_limit - 1);
4222 /* If this is just a test run, stop now and just deallocate the buffers. */
4226 free (new_orig_text_base);
4227 free (new_clean_text_base);
4228 free (repl_text_base);
4232 /* Change the name of the original input file. This is just a quick way of
4233 saving the original file. */
4237 char *new_filename =
4238 (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
4240 strcpy (new_filename, convert_filename);
4241 strcat (new_filename, save_suffix);
4242 if (my_link (convert_filename, new_filename) == -1)
4244 if (errno == EEXIST)
4247 fprintf (stderr, "%s: warning: file `%s' already saved in `%s'\n",
4249 shortpath (NULL, convert_filename),
4250 shortpath (NULL, new_filename));
4254 fprintf (stderr, "%s: error: can't link file `%s' to `%s': %s\n",
4256 shortpath (NULL, convert_filename),
4257 shortpath (NULL, new_filename),
4258 sys_errlist[errno]);
4264 if (my_unlink (convert_filename) == -1)
4266 fprintf (stderr, "%s: error: can't delete file `%s': %s\n",
4267 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4274 /* Open (and create) the output file. */
4276 if ((output_file = creat (convert_filename, 0666)) == -1)
4278 fprintf (stderr, "%s: error: can't create/open output file `%s': %s\n",
4279 pname, shortpath (NULL, convert_filename),
4280 sys_errlist[errno]);
4284 /* Write the output file. */
4287 unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
4289 if (write (output_file, repl_text_base, out_size) != out_size)
4290 fprintf (stderr, "%s: error: while writing file `%s': %s\n",
4291 pname, shortpath (NULL, convert_filename),
4292 sys_errlist[errno]);
4295 close (output_file);
4298 /* Deallocate the conversion buffers. */
4300 free (new_orig_text_base);
4301 free (new_clean_text_base);
4302 free (repl_text_base);
4304 /* Change the mode of the output file to match the original file. */
4306 /* The cast avoids an erroneous warning on AIX. */
4307 if (my_chmod ((char *)convert_filename, stat_buf.st_mode) == -1)
4308 fprintf (stderr, "%s: error: can't change mode of file `%s': %s\n",
4309 pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
4311 /* Note: We would try to change the owner and group of the output file
4312 to match those of the input file here, except that may not be a good
4313 thing to do because it might be misleading. Also, it might not even
4314 be possible to do that (on BSD systems with quotas for instance). */
4317 /* Do all of the individual steps needed to do the protoization (or
4318 unprotoization) of the files referenced in the aux_info files given
4319 in the command line. */
4324 const char * const *base_pp;
4325 const char * const * const end_pps
4326 = &base_source_filenames[n_base_source_files];
4330 #endif /* !defined (UNPROTOIZE) */
4332 /* One-by-one, check (and create if necessary), open, and read all of the
4333 stuff in each aux_info file. After reading each aux_info file, the
4334 aux_info_file just read will be automatically deleted unless the
4335 keep_flag is set. */
4337 for (base_pp = base_source_filenames; base_pp < end_pps; base_pp++)
4338 process_aux_info_file (*base_pp, keep_flag, 0);
4342 /* Also open and read the special SYSCALLS.c aux_info file which gives us
4343 the prototypes for all of the standard system-supplied functions. */
4345 if (nondefault_syscalls_dir)
4347 syscalls_absolute_filename
4348 = (char *) xmalloc (strlen (nondefault_syscalls_dir)
4349 + sizeof (syscalls_filename) + 1);
4350 strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
4354 syscalls_absolute_filename
4355 = (char *) xmalloc (strlen (default_syscalls_dir)
4356 + sizeof (syscalls_filename) + 1);
4357 strcpy (syscalls_absolute_filename, default_syscalls_dir);
4360 syscalls_len = strlen (syscalls_absolute_filename);
4361 if (*(syscalls_absolute_filename + syscalls_len - 1) != '/')
4363 *(syscalls_absolute_filename + syscalls_len++) = '/';
4364 *(syscalls_absolute_filename + syscalls_len) = '\0';
4366 strcat (syscalls_absolute_filename, syscalls_filename);
4368 /* Call process_aux_info_file in such a way that it does not try to
4369 delete the SYSCALLS aux_info file. */
4371 process_aux_info_file (syscalls_absolute_filename, 1, 1);
4373 #endif /* !defined (UNPROTOIZE) */
4375 /* When we first read in all of the information from the aux_info files
4376 we saved in it descending line number order, because that was likely to
4377 be faster. Now however, we want the chains of def & dec records to
4378 appear in ascending line number order as we get further away from the
4379 file_info record that they hang from. The following line causes all of
4380 these lists to be rearranged into ascending line number order. */
4382 visit_each_hash_node (filename_primary, reverse_def_dec_list);
4386 /* Now do the "real" work. The following line causes each declaration record
4387 to be "visited". For each of these nodes, an attempt is made to match
4388 up the function declaration with a corresponding function definition,
4389 which should have a full prototype-format formals list with it. Once
4390 these match-ups are made, the conversion of the function declarations
4391 to prototype format can be made. */
4393 visit_each_hash_node (function_name_primary, connect_defs_and_decs);
4395 #endif /* !defined (UNPROTOIZE) */
4397 /* Now convert each file that can be converted (and needs to be). */
4399 visit_each_hash_node (filename_primary, edit_file);
4403 /* If we are working in cplusplus mode, try to rename all .c files to .C
4404 files. Don't panic if some of the renames don't work. */
4406 if (cplusplus_flag && !nochange_flag)
4407 visit_each_hash_node (filename_primary, rename_c_file);
4409 #endif /* !defined (UNPROTOIZE) */
4412 static struct option longopts[] =
4414 {"version", 0, 0, 'V'},
4415 {"file_name", 0, 0, 'p'},
4416 {"quiet", 0, 0, 'q'},
4417 {"silent", 0, 0, 'q'},
4418 {"force", 0, 0, 'f'},
4419 {"keep", 0, 0, 'k'},
4420 {"nosave", 0, 0, 'N'},
4421 {"nochange", 0, 0, 'n'},
4422 {"compiler-options", 1, 0, 'c'},
4423 {"exclude", 1, 0, 'x'},
4424 {"directory", 1, 0, 'd'},
4426 {"indent", 1, 0, 'i'},
4428 {"local", 0, 0, 'l'},
4429 {"global", 0, 0, 'g'},
4431 {"syscalls-dir", 1, 0, 'B'},
4443 const char *params = "";
4445 pname = strrchr (argv[0], '/');
4446 pname = pname ? pname+1 : argv[0];
4448 cwd_buffer = getpwd ();
4451 fprintf (stderr, "%s: cannot get working directory: %s\n",
4452 pname, sys_errlist[errno]);
4456 /* By default, convert the files in the current directory. */
4457 directory_list = string_list_cons (cwd_buffer, NULL);
4459 while ((c = getopt_long (argc, argv,
4463 "B:c:Cd:gklnNp:qVx:",
4465 longopts, &longind)) != EOF)
4467 if (c == 0) /* Long option. */
4468 c = longopts[longind].val;
4472 compiler_file_name = optarg;
4476 = string_list_cons (abspath (NULL, optarg), directory_list);
4479 exclude_list = string_list_cons (optarg, exclude_list);
4508 indent_string = optarg;
4510 #else /* !defined (UNPROTOIZE) */
4521 nondefault_syscalls_dir = optarg;
4523 #endif /* !defined (UNPROTOIZE) */
4529 /* Set up compile_params based on -p and -c options. */
4530 munge_compile_params (params);
4532 n_base_source_files = argc - optind;
4534 /* Now actually make a list of the base source filenames. */
4536 base_source_filenames =
4537 (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
4538 n_base_source_files = 0;
4539 for (; optind < argc; optind++)
4541 const char *path = abspath (NULL, argv[optind]);
4542 int len = strlen (path);
4544 if (path[len-1] == 'c' && path[len-2] == '.')
4545 base_source_filenames[n_base_source_files++] = path;
4548 fprintf (stderr, "%s: input file names must have .c suffixes: %s\n",
4549 pname, shortpath (NULL, path));
4555 /* We are only interested in the very first identifier token in the
4556 definition of `va_list', so if there is more junk after that first
4557 identifier token, delete it from the `varargs_style_indicator'. */
4561 for (cp = varargs_style_indicator; isalnum (*cp) || *cp == '_'; cp++)
4564 varargs_style_indicator = savestring (varargs_style_indicator,
4565 cp - varargs_style_indicator);
4567 #endif /* !defined (UNPROTOIZE) */
4574 fprintf (stderr, "%s: %s\n", pname, version_string);