00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "intl.h"
00025 #include "cppdefault.h"
00026
00027 #include <setjmp.h>
00028 #include <signal.h>
00029 #if ! defined( SIGCHLD ) && defined( SIGCLD )
00030 # define SIGCHLD SIGCLD
00031 #endif
00032 #ifdef HAVE_UNISTD_H
00033 #include <unistd.h>
00034 #endif
00035 #undef abort
00036 #include "version.h"
00037
00038
00039 #include "getopt.h"
00040
00041
00042 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
00043 #define IS_SAME_PATH_CHAR(a,b) (TOUPPER (a) == TOUPPER (b))
00044 #else
00045 #define IS_SAME_PATH_CHAR(a,b) ((a) == (b))
00046 #endif
00047
00048
00049 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
00050 #define IS_SAME_PATH(a,b) (strcasecmp (a, b) == 0)
00051 #else
00052 #define IS_SAME_PATH(a,b) (strcmp (a, b) == 0)
00053 #endif
00054
00055
00056 #ifdef __MSDOS__
00057 #define AUX_INFO_SUFFIX "X"
00058 #else
00059 #define AUX_INFO_SUFFIX ".X"
00060 #endif
00061
00062
00063 #ifdef __MSDOS__
00064 #define SAVE_SUFFIX "sav"
00065 #else
00066 #define SAVE_SUFFIX ".save"
00067 #endif
00068
00069
00070 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
00071 #define CPLUS_FILE_SUFFIX "cc"
00072 #else
00073 #define CPLUS_FILE_SUFFIX "C"
00074 #endif
00075
00076 static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
00077 static void aux_info_corrupted PARAMS ((void)) ATTRIBUTE_NORETURN;
00078 static void declare_source_confusing PARAMS ((const char *)) ATTRIBUTE_NORETURN;
00079 static const char *shortpath PARAMS ((const char *, const char *));
00080 extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
00081 static void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
00082 static char *savestring PARAMS ((const char *, unsigned int));
00083 static char *dupnstr PARAMS ((const char *, size_t));
00084 static const char *substr PARAMS ((const char *, const char * const));
00085 static int safe_read PARAMS ((int, PTR, int));
00086 static void safe_write PARAMS ((int, PTR, int, const char *));
00087 static void save_pointers PARAMS ((void));
00088 static void restore_pointers PARAMS ((void));
00089 static int is_id_char PARAMS ((int));
00090 static int in_system_include_dir PARAMS ((const char *));
00091 static int directory_specified_p PARAMS ((const char *));
00092 static int file_excluded_p PARAMS ((const char *));
00093 static char *unexpand_if_needed PARAMS ((const char *));
00094 static char *abspath PARAMS ((const char *, const char *));
00095 static int is_abspath PARAMS ((const char *));
00096 static void check_aux_info PARAMS ((int));
00097 static const char *find_corresponding_lparen PARAMS ((const char *));
00098 static int referenced_file_is_newer PARAMS ((const char *, time_t));
00099 static void save_def_or_dec PARAMS ((const char *, int));
00100 static void munge_compile_params PARAMS ((const char *));
00101 static int gen_aux_info_file PARAMS ((const char *));
00102 static void process_aux_info_file PARAMS ((const char *, int, int));
00103 static int identify_lineno PARAMS ((const char *));
00104 static void check_source PARAMS ((int, const char *));
00105 static const char *seek_to_line PARAMS ((int));
00106 static const char *forward_to_next_token_char PARAMS ((const char *));
00107 static void output_bytes PARAMS ((const char *, size_t));
00108 static void output_string PARAMS ((const char *));
00109 static void output_up_to PARAMS ((const char *));
00110 static int other_variable_style_function PARAMS ((const char *));
00111 static const char *find_rightmost_formals_list PARAMS ((const char *));
00112 static void do_cleaning PARAMS ((char *, const char *));
00113 static const char *careful_find_l_paren PARAMS ((const char *));
00114 static void do_processing PARAMS ((void));
00115
00116
00117 #define NONCONST
00118
00119
00120
00121 #ifndef UNPROTOIZE
00122
00123 #ifndef STANDARD_EXEC_PREFIX
00124 #define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
00125 #endif
00126
00127 static const char * const standard_exec_prefix = STANDARD_EXEC_PREFIX;
00128 static const char * const target_machine = DEFAULT_TARGET_MACHINE;
00129 static const char * const target_version = DEFAULT_TARGET_VERSION;
00130
00131 #endif
00132
00133
00134
00135 static const char * const aux_info_suffix = AUX_INFO_SUFFIX;
00136
00137
00138
00139 static const char * const save_suffix = SAVE_SUFFIX;
00140
00141
00142
00143 static const char * const cplus_suffix = CPLUS_FILE_SUFFIX;
00144
00145 #ifndef UNPROTOIZE
00146
00147
00148
00149
00150
00151 static const char syscalls_filename[] = "SYSCALLS.c";
00152
00153
00154
00155 static const char * default_syscalls_dir;
00156
00157
00158
00159
00160 static char * syscalls_absolute_filename;
00161
00162 #endif
00163
00164
00165
00166 struct unexpansion_struct {
00167 const char *const expanded;
00168 const char *const contracted;
00169 };
00170 typedef struct unexpansion_struct unexpansion;
00171
00172
00173
00174
00175
00176
00177
00178
00179 static const unexpansion unexpansions[] = {
00180 { "struct _iobuf", "FILE" },
00181 { 0, 0 }
00182 };
00183
00184
00185
00186
00187
00188 #define HASH_TABLE_SIZE (1 << 9)
00189
00190
00191
00192 static const int hash_mask = (HASH_TABLE_SIZE - 1);
00193
00194
00195
00196 struct string_list
00197 {
00198 const char *name;
00199 struct string_list *next;
00200 };
00201
00202 static struct string_list *string_list_cons PARAMS ((const char *,
00203 struct string_list *));
00204
00205
00206
00207 struct string_list *directory_list;
00208
00209
00210
00211
00212
00213 struct string_list *exclude_list;
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 #ifdef UNPROTOIZE
00225 static const char * const other_var_style = "stdarg";
00226 #else
00227 static const char * const other_var_style = "varargs";
00228
00229
00230 static const char *varargs_style_indicator = STRINGX (va_alist);
00231 #endif
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 typedef struct hash_table_entry_struct hash_table_entry;
00242
00243
00244
00245 typedef struct def_dec_info_struct def_dec_info;
00246 typedef struct file_info_struct file_info;
00247 typedef struct f_list_chain_item_struct f_list_chain_item;
00248
00249 #ifndef UNPROTOIZE
00250 static int is_syscalls_file PARAMS ((const file_info *));
00251 static void rename_c_file PARAMS ((const hash_table_entry *));
00252 static const def_dec_info *find_extern_def PARAMS ((const def_dec_info *,
00253 const def_dec_info *));
00254 static const def_dec_info *find_static_definition PARAMS ((const def_dec_info *));
00255 static void connect_defs_and_decs PARAMS ((const hash_table_entry *));
00256 static void add_local_decl PARAMS ((const def_dec_info *, const char *));
00257 static void add_global_decls PARAMS ((const file_info *, const char *));
00258 #endif
00259 static int needs_to_be_converted PARAMS ((const file_info *));
00260 static void visit_each_hash_node PARAMS ((const hash_table_entry *,
00261 void (*)(const hash_table_entry *)));
00262 static hash_table_entry *add_symbol PARAMS ((hash_table_entry *, const char *));
00263 static hash_table_entry *lookup PARAMS ((hash_table_entry *, const char *));
00264 static void free_def_dec PARAMS ((def_dec_info *));
00265 static file_info *find_file PARAMS ((const char *, int));
00266 static void reverse_def_dec_list PARAMS ((const hash_table_entry *));
00267 static void edit_fn_declaration PARAMS ((const def_dec_info *, const char *));
00268 static int edit_formals_lists PARAMS ((const char *, unsigned int,
00269 const def_dec_info *));
00270 static void edit_fn_definition PARAMS ((const def_dec_info *, const char *));
00271 static void scan_for_missed_items PARAMS ((const file_info *));
00272 static void edit_file PARAMS ((const hash_table_entry *));
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 struct hash_table_entry_struct {
00287 hash_table_entry * hash_next;
00288 const char * symbol;
00289 union {
00290 const def_dec_info * _ddip;
00291 file_info * _fip;
00292 } _info;
00293 };
00294 #define ddip _info._ddip
00295 #define fip _info._fip
00296
00297
00298
00299 typedef hash_table_entry hash_table[HASH_TABLE_SIZE];
00300
00301
00302
00303
00304 struct file_info_struct {
00305 const hash_table_entry * hash_entry;
00306 const def_dec_info * defs_decs;
00307 time_t mtime;
00308 };
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 struct f_list_chain_item_struct {
00328 const f_list_chain_item * chain_next;
00329 const char * formals_list;
00330 };
00331
00332
00333
00334
00335
00336
00337
00338
00339 struct def_dec_info_struct {
00340 const def_dec_info * next_in_file;
00341 file_info * file;
00342 int line;
00343 const char * ansi_decl;
00344 hash_table_entry * hash_entry;
00345 unsigned int is_func_def;
00346 const def_dec_info * next_for_func;
00347 unsigned int f_list_count;
00348 char prototyped;
00349 #ifndef UNPROTOIZE
00350 const f_list_chain_item * f_list_chain;
00351 const def_dec_info * definition;
00352 char is_static;
00353 char is_implicit;
00354 char written;
00355 #else
00356 const char * formal_names;
00357 const char * formal_decls;
00358 #endif
00359 };
00360
00361
00362
00363
00364 static const char *pname;
00365
00366
00367
00368
00369 static int errors = 0;
00370
00371
00372
00373
00374
00375
00376
00377 static const char *compiler_file_name = "gcc";
00378
00379 static int version_flag = 0;
00380 static int quiet_flag = 0;
00381 static int nochange_flag = 0;
00382
00383 static int nosave_flag = 0;
00384 static int keep_flag = 0;
00385 static const char ** compile_params = 0;
00386 #ifdef UNPROTOIZE
00387 static const char *indent_string = " ";
00388
00389 #else
00390 static int local_flag = 0;
00391 static int global_flag = 0;
00392 static int cplusplus_flag = 0;
00393 static const char *nondefault_syscalls_dir = 0;
00394
00395 #endif
00396
00397
00398
00399
00400
00401 static int input_file_name_index = 0;
00402
00403
00404
00405 static int aux_info_file_name_index = 0;
00406
00407
00408
00409 static int n_base_source_files = 0;
00410
00411
00412
00413
00414 static const char **base_source_filenames;
00415
00416
00417
00418
00419
00420 static int current_aux_info_lineno;
00421
00422
00423
00424 static const char *convert_filename;
00425
00426
00427
00428
00429
00430 static const char *invocation_filename;
00431
00432
00433
00434
00435 static const char *orig_text_base;
00436
00437
00438
00439
00440 static const char *orig_text_limit;
00441
00442
00443
00444
00445 static const char *clean_text_base;
00446
00447
00448
00449
00450 static const char *clean_text_limit;
00451
00452
00453
00454
00455 static const char * clean_read_ptr;
00456
00457
00458
00459
00460 static char *repl_text_base;
00461
00462
00463
00464
00465 static char *repl_text_limit;
00466
00467
00468
00469
00470
00471 static char * repl_write_ptr;
00472
00473
00474
00475
00476
00477 static const char *last_known_line_start;
00478
00479
00480
00481
00482
00483 static int last_known_line_number;
00484
00485
00486
00487 static hash_table filename_primary;
00488
00489
00490
00491 static hash_table function_name_primary;
00492
00493
00494
00495
00496 static jmp_buf source_confusion_recovery;
00497
00498
00499
00500 static char *cwd_buffer;
00501
00502
00503
00504
00505 static const char * saved_clean_read_ptr;
00506
00507
00508
00509
00510 static char * saved_repl_write_ptr;
00511
00512
00513 static void
00514 notice VPARAMS ((const char *msgid, ...))
00515 {
00516 VA_OPEN (ap, msgid);
00517 VA_FIXEDARG (ap, const char *, msgid);
00518
00519 vfprintf (stderr, _(msgid), ap);
00520 VA_CLOSE (ap);
00521 }
00522
00523
00524
00525
00526 static char *
00527 savestring (input, size)
00528 const char *input;
00529 unsigned int size;
00530 {
00531 char *output = (char *) xmalloc (size + 1);
00532 strcpy (output, input);
00533 return output;
00534 }
00535
00536
00537
00538
00539 void
00540 fancy_abort ()
00541 {
00542 notice ("%s: internal abort\n", pname);
00543 exit (FATAL_EXIT_CODE);
00544 }
00545
00546
00547
00548
00549 static char *
00550 dupnstr (s, n)
00551 const char *s;
00552 size_t n;
00553 {
00554 char *ret_val = (char *) xmalloc (n + 1);
00555
00556 strncpy (ret_val, s, n);
00557 ret_val[n] = '\0';
00558 return ret_val;
00559 }
00560
00561
00562
00563
00564 static const char *
00565 substr (s1, s2)
00566 const char *s1;
00567 const char *const s2;
00568 {
00569 for (; *s1 ; s1++)
00570 {
00571 const char *p1;
00572 const char *p2;
00573 int c;
00574
00575 for (p1 = s1, p2 = s2; (c = *p2); p1++, p2++)
00576 if (*p1 != c)
00577 goto outer;
00578 return s1;
00579 outer:
00580 ;
00581 }
00582 return 0;
00583 }
00584
00585
00586
00587
00588 static int
00589 safe_read (desc, ptr, len)
00590 int desc;
00591 PTR ptr;
00592 int len;
00593 {
00594 int left = len;
00595 while (left > 0) {
00596 int nchars = read (desc, ptr, left);
00597 if (nchars < 0)
00598 {
00599 #ifdef EINTR
00600 if (errno == EINTR)
00601 continue;
00602 #endif
00603 return nchars;
00604 }
00605 if (nchars == 0)
00606 break;
00607
00608 ptr = (char *) ptr + nchars;
00609 left -= nchars;
00610 }
00611 return len - left;
00612 }
00613
00614
00615
00616
00617 static void
00618 safe_write (desc, ptr, len, out_fname)
00619 int desc;
00620 PTR ptr;
00621 int len;
00622 const char *out_fname;
00623 {
00624 while (len > 0) {
00625 int written = write (desc, ptr, len);
00626 if (written < 0)
00627 {
00628 int errno_val = errno;
00629 #ifdef EINTR
00630 if (errno_val == EINTR)
00631 continue;
00632 #endif
00633 notice ("%s: error writing file `%s': %s\n",
00634 pname, shortpath (NULL, out_fname), xstrerror (errno_val));
00635 return;
00636 }
00637
00638 ptr = (char *) ptr + written;
00639 len -= written;
00640 }
00641 }
00642
00643
00644
00645 static void
00646 save_pointers ()
00647 {
00648 saved_clean_read_ptr = clean_read_ptr;
00649 saved_repl_write_ptr = repl_write_ptr;
00650 }
00651
00652
00653
00654
00655 static void
00656 restore_pointers ()
00657 {
00658 clean_read_ptr = saved_clean_read_ptr;
00659 repl_write_ptr = saved_repl_write_ptr;
00660 }
00661
00662
00663
00664 static int
00665 is_id_char (ch)
00666 int ch;
00667 {
00668 return (ISIDNUM (ch) || (ch == '$'));
00669 }
00670
00671
00672
00673
00674 static void
00675 usage ()
00676 {
00677 #ifdef UNPROTOIZE
00678 notice ("%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
00679 pname, pname);
00680 #else
00681 notice ("%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
00682 pname, pname);
00683 #endif
00684 exit (FATAL_EXIT_CODE);
00685 }
00686
00687
00688
00689
00690
00691 static int
00692 in_system_include_dir (path)
00693 const char *path;
00694 {
00695 const struct default_include *p;
00696
00697 if (! is_abspath (path))
00698 abort ();
00699
00700 for (p = cpp_include_defaults; p->fname; p++)
00701 if (!strncmp (path, p->fname, strlen (p->fname))
00702 && IS_DIR_SEPARATOR (path[strlen (p->fname)]))
00703 return 1;
00704 return 0;
00705 }
00706
00707 #if 0
00708
00709
00710
00711
00712 static int
00713 file_could_be_converted (const char *path)
00714 {
00715 char *const dir_name = (char *) alloca (strlen (path) + 1);
00716
00717 if (access (path, R_OK))
00718 return 0;
00719
00720 {
00721 char *dir_last_slash;
00722
00723 strcpy (dir_name, path);
00724 dir_last_slash = strrchr (dir_name, DIR_SEPARATOR);
00725 #ifdef DIR_SEPARATOR_2
00726 {
00727 char *slash;
00728
00729 slash = strrchr (dir_last_slash ? dir_last_slash : dir_name,
00730 DIR_SEPARATOR_2);
00731 if (slash)
00732 dir_last_slash = slash;
00733 }
00734 #endif
00735 if (dir_last_slash)
00736 *dir_last_slash = '\0';
00737 else
00738 abort ();
00739 }
00740
00741 if (access (path, W_OK))
00742 return 0;
00743
00744 return 1;
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 static int
00757 file_normally_convertible (const char *path)
00758 {
00759 char *const dir_name = alloca (strlen (path) + 1);
00760
00761 if (in_system_include_dir (path))
00762 return 0;
00763
00764 {
00765 char *dir_last_slash;
00766
00767 strcpy (dir_name, path);
00768 dir_last_slash = strrchr (dir_name, DIR_SEPARATOR);
00769 #ifdef DIR_SEPARATOR_2
00770 {
00771 char *slash;
00772
00773 slash = strrchr (dir_last_slash ? dir_last_slash : dir_name,
00774 DIR_SEPARATOR_2);
00775 if (slash)
00776 dir_last_slash = slash;
00777 }
00778 #endif
00779 if (dir_last_slash)
00780 *dir_last_slash = '\0';
00781 else
00782 abort ();
00783 }
00784
00785 if (access (path, R_OK))
00786 {
00787 if (!quiet_flag)
00788 notice ("%s: warning: no read access for file `%s'\n",
00789 pname, shortpath (NULL, path));
00790 return 0;
00791 }
00792
00793 if (access (path, W_OK))
00794 {
00795 if (!quiet_flag)
00796 notice ("%s: warning: no write access for file `%s'\n",
00797 pname, shortpath (NULL, path));
00798 return 0;
00799 }
00800
00801 if (access (dir_name, W_OK))
00802 {
00803 if (!quiet_flag)
00804 notice ("%s: warning: no write access for dir containing `%s'\n",
00805 pname, shortpath (NULL, path));
00806 return 0;
00807 }
00808
00809 return 1;
00810 }
00811 #endif
00812
00813 #ifndef UNPROTOIZE
00814
00815
00816
00817
00818 static int
00819 is_syscalls_file (fi_p)
00820 const file_info *fi_p;
00821 {
00822 char const *f = fi_p->hash_entry->symbol;
00823 size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
00824 return sysl <= fl && strcmp (f + fl - sysl, syscalls_filename) == 0;
00825 }
00826
00827 #endif
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 static int
00839 needs_to_be_converted (file_p)
00840 const file_info *file_p;
00841 {
00842 const def_dec_info *ddp;
00843
00844 #ifndef UNPROTOIZE
00845
00846 if (is_syscalls_file (file_p))
00847 return 0;
00848
00849 #endif
00850
00851 for (ddp = file_p->defs_decs; ddp; ddp = ddp->next_in_file)
00852
00853 if (
00854
00855 #ifndef UNPROTOIZE
00856
00857
00858 !ddp->prototyped
00859
00860 && (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
00861
00862 #else
00863
00864
00865 ddp->prototyped
00866
00867 #endif
00868 )
00869
00870 return -1;
00871 return 0;
00872 }
00873
00874
00875
00876
00877 static int
00878 directory_specified_p (name)
00879 const char *name;
00880 {
00881 struct string_list *p;
00882
00883 for (p = directory_list; p; p = p->next)
00884 if (!strncmp (name, p->name, strlen (p->name))
00885 && IS_DIR_SEPARATOR (name[strlen (p->name)]))
00886 {
00887 const char *q = name + strlen (p->name) + 1;
00888
00889
00890
00891 while (*q++)
00892 if (IS_DIR_SEPARATOR (*(q-1)))
00893 goto lose;
00894 return 1;
00895
00896 lose: ;
00897 }
00898
00899 return 0;
00900 }
00901
00902
00903
00904 static int
00905 file_excluded_p (name)
00906 const char *name;
00907 {
00908 struct string_list *p;
00909 int len = strlen (name);
00910
00911 for (p = exclude_list; p; p = p->next)
00912 if (!strcmp (name + len - strlen (p->name), p->name)
00913 && IS_DIR_SEPARATOR (name[len - strlen (p->name) - 1]))
00914 return 1;
00915
00916 return 0;
00917 }
00918
00919
00920
00921
00922 static struct string_list *
00923 string_list_cons (string, rest)
00924 const char *string;
00925 struct string_list *rest;
00926 {
00927 struct string_list *temp
00928 = (struct string_list *) xmalloc (sizeof (struct string_list));
00929
00930 temp->next = rest;
00931 temp->name = string;
00932 return temp;
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 static void
00945 visit_each_hash_node (hash_tab_p, func)
00946 const hash_table_entry *hash_tab_p;
00947 void (*func) PARAMS ((const hash_table_entry *));
00948 {
00949 const hash_table_entry *primary;
00950
00951 for (primary = hash_tab_p; primary < &hash_tab_p[HASH_TABLE_SIZE]; primary++)
00952 if (primary->symbol)
00953 {
00954 hash_table_entry *second;
00955
00956 (*func)(primary);
00957 for (second = primary->hash_next; second; second = second->hash_next)
00958 (*func) (second);
00959 }
00960 }
00961
00962
00963
00964
00965
00966
00967 static hash_table_entry *
00968 add_symbol (p, s)
00969 hash_table_entry *p;
00970 const char *s;
00971 {
00972 p->hash_next = NULL;
00973 p->symbol = xstrdup (s);
00974 p->ddip = NULL;
00975 p->fip = NULL;
00976 return p;
00977 }
00978
00979
00980
00981
00982
00983
00984 static hash_table_entry *
00985 lookup (hash_tab_p, search_symbol)
00986 hash_table_entry *hash_tab_p;
00987 const char *search_symbol;
00988 {
00989 int hash_value = 0;
00990 const char *search_symbol_char_p = search_symbol;
00991 hash_table_entry *p;
00992
00993 while (*search_symbol_char_p)
00994 hash_value += *search_symbol_char_p++;
00995 hash_value &= hash_mask;
00996 p = &hash_tab_p[hash_value];
00997 if (! p->symbol)
00998 return add_symbol (p, search_symbol);
00999 if (!strcmp (p->symbol, search_symbol))
01000 return p;
01001 while (p->hash_next)
01002 {
01003 p = p->hash_next;
01004 if (!strcmp (p->symbol, search_symbol))
01005 return p;
01006 }
01007 p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
01008 p = p->hash_next;
01009 return add_symbol (p, search_symbol);
01010 }
01011
01012
01013
01014
01015
01016
01017 static void
01018 free_def_dec (p)
01019 def_dec_info *p;
01020 {
01021 free ((NONCONST PTR) p->ansi_decl);
01022
01023 #ifndef UNPROTOIZE
01024 {
01025 const f_list_chain_item * curr;
01026 const f_list_chain_item * next;
01027
01028 for (curr = p->f_list_chain; curr; curr = next)
01029 {
01030 next = curr->chain_next;
01031 free ((NONCONST PTR) curr);
01032 }
01033 }
01034 #endif
01035
01036 free (p);
01037 }
01038
01039
01040
01041
01042
01043
01044 static char *
01045 unexpand_if_needed (aux_info_line)
01046 const char *aux_info_line;
01047 {
01048 static char *line_buf = 0;
01049 static int line_buf_size = 0;
01050 const unexpansion *unexp_p;
01051 int got_unexpanded = 0;
01052 const char *s;
01053 char *copy_p = line_buf;
01054
01055 if (line_buf == 0)
01056 {
01057 line_buf_size = 1024;
01058 line_buf = (char *) xmalloc (line_buf_size);
01059 }
01060
01061 copy_p = line_buf;
01062
01063
01064
01065 for (s = aux_info_line; *s != '\n'; )
01066 {
01067 for (unexp_p = unexpansions; unexp_p->expanded; unexp_p++)
01068 {
01069 const char *in_p = unexp_p->expanded;
01070 size_t len = strlen (in_p);
01071
01072 if (*s == *in_p && !strncmp (s, in_p, len) && !is_id_char (s[len]))
01073 {
01074 int size = strlen (unexp_p->contracted);
01075 got_unexpanded = 1;
01076 if (copy_p + size - line_buf >= line_buf_size)
01077 {
01078 int offset = copy_p - line_buf;
01079 line_buf_size *= 2;
01080 line_buf_size += size;
01081 line_buf = (char *) xrealloc (line_buf, line_buf_size);
01082 copy_p = line_buf + offset;
01083 }
01084 strcpy (copy_p, unexp_p->contracted);
01085 copy_p += size;
01086
01087
01088
01089
01090 s += len;
01091 goto continue_outer;
01092 }
01093 }
01094 if (copy_p - line_buf == line_buf_size)
01095 {
01096 int offset = copy_p - line_buf;
01097 line_buf_size *= 2;
01098 line_buf = (char *) xrealloc (line_buf, line_buf_size);
01099 copy_p = line_buf + offset;
01100 }
01101 *copy_p++ = *s++;
01102 continue_outer: ;
01103 }
01104 if (copy_p + 2 - line_buf >= line_buf_size)
01105 {
01106 int offset = copy_p - line_buf;
01107 line_buf_size *= 2;
01108 line_buf = (char *) xrealloc (line_buf, line_buf_size);
01109 copy_p = line_buf + offset;
01110 }
01111 *copy_p++ = '\n';
01112 *copy_p = '\0';
01113
01114 return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0);
01115 }
01116
01117
01118
01119 static int
01120 is_abspath (path)
01121 const char *path;
01122 {
01123 return (IS_DIR_SEPARATOR (path[0])
01124 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01125
01126 || (path[0] && path[1] == ':' && IS_DIR_SEPARATOR (path[2]))
01127 #endif
01128 );
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 static char *
01142 abspath (cwd, rel_filename)
01143 const char *cwd;
01144 const char *rel_filename;
01145 {
01146
01147 const char *const cwd2 = (cwd) ? cwd : cwd_buffer;
01148 char *const abs_buffer
01149 = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
01150 char *endp = abs_buffer;
01151 char *outp, *inp;
01152
01153
01154
01155
01156 {
01157 const char *src_p;
01158
01159 if (! is_abspath (rel_filename))
01160 {
01161 src_p = cwd2;
01162 while ((*endp++ = *src_p++))
01163 continue;
01164 *(endp-1) = DIR_SEPARATOR;
01165 }
01166 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01167 else if (IS_DIR_SEPARATOR (rel_filename[0]))
01168 {
01169
01170
01171
01172
01173 *endp++ = cwd2[0];
01174 *endp++ = cwd2[1];
01175 }
01176 #endif
01177 src_p = rel_filename;
01178 while ((*endp++ = *src_p++))
01179 continue;
01180 }
01181
01182
01183
01184
01185 outp = inp = abs_buffer;
01186 *outp++ = *inp++;
01187 #if defined (apollo) || defined (_WIN32) || defined (__INTERIX)
01188 if (IS_DIR_SEPARATOR (inp[0]))
01189 *outp++ = *inp++;
01190 #endif
01191 for (;;)
01192 {
01193 if (!inp[0])
01194 break;
01195 else if (IS_DIR_SEPARATOR (inp[0]) && IS_DIR_SEPARATOR (outp[-1]))
01196 {
01197 inp++;
01198 continue;
01199 }
01200 else if (inp[0] == '.' && IS_DIR_SEPARATOR (outp[-1]))
01201 {
01202 if (!inp[1])
01203 break;
01204 else if (IS_DIR_SEPARATOR (inp[1]))
01205 {
01206 inp += 2;
01207 continue;
01208 }
01209 else if ((inp[1] == '.') && (inp[2] == 0
01210 || IS_DIR_SEPARATOR (inp[2])))
01211 {
01212 inp += (IS_DIR_SEPARATOR (inp[2])) ? 3 : 2;
01213 outp -= 2;
01214 while (outp >= abs_buffer && ! IS_DIR_SEPARATOR (*outp))
01215 outp--;
01216 if (outp < abs_buffer)
01217 {
01218
01219
01220
01221
01222 notice ("%s: invalid file name: %s\n",
01223 pname, rel_filename);
01224 exit (FATAL_EXIT_CODE);
01225 }
01226 *++outp = '\0';
01227 continue;
01228 }
01229 }
01230 *outp++ = *inp++;
01231 }
01232
01233
01234
01235
01236 *outp = '\0';
01237 if (IS_DIR_SEPARATOR (outp[-1]))
01238 *--outp = '\0';
01239
01240
01241
01242
01243 return savestring (abs_buffer, outp - abs_buffer);
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static const char *
01261 shortpath (cwd, filename)
01262 const char *cwd;
01263 const char *filename;
01264 {
01265 char *rel_buffer;
01266 char *rel_buf_p;
01267 char *cwd_p = cwd_buffer;
01268 char *path_p;
01269 int unmatched_slash_count = 0;
01270 size_t filename_len = strlen (filename);
01271
01272 path_p = abspath (cwd, filename);
01273 rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
01274
01275 while (*cwd_p && IS_SAME_PATH_CHAR (*cwd_p, *path_p))
01276 {
01277 cwd_p++;
01278 path_p++;
01279 }
01280 if (!*cwd_p && (!*path_p || IS_DIR_SEPARATOR (*path_p)))
01281 {
01282
01283 if (!*path_p)
01284 return ".";
01285 else
01286 return ++path_p;
01287 }
01288 else
01289 {
01290 if (*path_p)
01291 {
01292 --cwd_p;
01293 --path_p;
01294 while (! IS_DIR_SEPARATOR (*cwd_p))
01295 {
01296 --cwd_p;
01297 --path_p;
01298 }
01299 cwd_p++;
01300 path_p++;
01301 unmatched_slash_count++;
01302 }
01303
01304
01305 while (*cwd_p++)
01306 if (IS_DIR_SEPARATOR (*(cwd_p-1)))
01307 unmatched_slash_count++;
01308
01309
01310
01311 if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
01312 return filename;
01313
01314
01315 while (unmatched_slash_count--)
01316 {
01317
01318
01319 if (rel_buffer + filename_len <= rel_buf_p + 3)
01320 return filename;
01321 *rel_buf_p++ = '.';
01322 *rel_buf_p++ = '.';
01323 *rel_buf_p++ = DIR_SEPARATOR;
01324 }
01325
01326
01327 do
01328 {
01329 if (rel_buffer + filename_len <= rel_buf_p)
01330 return filename;
01331 }
01332 while ((*rel_buf_p++ = *path_p++));
01333
01334 --rel_buf_p;
01335 if (IS_DIR_SEPARATOR (*(rel_buf_p-1)))
01336 *--rel_buf_p = '\0';
01337 return rel_buffer;
01338 }
01339 }
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349 static file_info *
01350 find_file (filename, do_not_stat)
01351 const char *filename;
01352 int do_not_stat;
01353 {
01354 hash_table_entry *hash_entry_p;
01355
01356 hash_entry_p = lookup (filename_primary, filename);
01357 if (hash_entry_p->fip)
01358 return hash_entry_p->fip;
01359 else
01360 {
01361 struct stat stat_buf;
01362 file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
01363
01364
01365
01366
01367 if (do_not_stat)
01368 stat_buf.st_mtime = (time_t) 0;
01369 else
01370 {
01371 if (stat (filename, &stat_buf) == -1)
01372 {
01373 int errno_val = errno;
01374 notice ("%s: %s: can't get status: %s\n",
01375 pname, shortpath (NULL, filename),
01376 xstrerror (errno_val));
01377 stat_buf.st_mtime = (time_t) -1;
01378 }
01379 }
01380
01381 hash_entry_p->fip = file_p;
01382 file_p->hash_entry = hash_entry_p;
01383 file_p->defs_decs = NULL;
01384 file_p->mtime = stat_buf.st_mtime;
01385 return file_p;
01386 }
01387 }
01388
01389
01390
01391
01392 static void
01393 aux_info_corrupted ()
01394 {
01395 notice ("\n%s: fatal error: aux info file corrupted at line %d\n",
01396 pname, current_aux_info_lineno);
01397 exit (FATAL_EXIT_CODE);
01398 }
01399
01400
01401
01402
01403 static void
01404 check_aux_info (cond)
01405 int cond;
01406 {
01407 if (! cond)
01408 aux_info_corrupted ();
01409 }
01410
01411
01412
01413
01414
01415 static const char *
01416 find_corresponding_lparen (p)
01417 const char *p;
01418 {
01419 const char *q;
01420 int paren_depth;
01421
01422 for (paren_depth = 1, q = p-1; paren_depth; q--)
01423 {
01424 switch (*q)
01425 {
01426 case ')':
01427 paren_depth++;
01428 break;
01429 case '(':
01430 paren_depth--;
01431 break;
01432 }
01433 }
01434 return ++q;
01435 }
01436
01437
01438
01439
01440
01441
01442 static int
01443 referenced_file_is_newer (l, aux_info_mtime)
01444 const char *l;
01445 time_t aux_info_mtime;
01446 {
01447 const char *p;
01448 file_info *fi_p;
01449 char *filename;
01450
01451 check_aux_info (l[0] == '/');
01452 check_aux_info (l[1] == '*');
01453 check_aux_info (l[2] == ' ');
01454
01455 {
01456 const char *filename_start = p = l + 3;
01457
01458 while (*p != ':'
01459 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01460 || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
01461 #endif
01462 )
01463 p++;
01464 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
01465 strncpy (filename, filename_start, (size_t) (p - filename_start));
01466 filename[p-filename_start] = '\0';
01467 }
01468
01469
01470
01471
01472
01473
01474 fi_p = find_file (abspath (invocation_filename, filename), 0);
01475
01476 return (fi_p->mtime > aux_info_mtime);
01477 }
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 static void
01495 save_def_or_dec (l, is_syscalls)
01496 const char *l;
01497 int is_syscalls;
01498 {
01499 const char *p;
01500 const char *semicolon_p;
01501 def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
01502
01503 #ifndef UNPROTOIZE
01504 def_dec_p->written = 0;
01505 #endif
01506
01507
01508
01509
01510
01511
01512 check_aux_info (l[0] == '/');
01513 check_aux_info (l[1] == '*');
01514 check_aux_info (l[2] == ' ');
01515
01516 {
01517 const char *filename_start = p = l + 3;
01518 char *filename;
01519
01520 while (*p != ':'
01521 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01522 || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
01523 #endif
01524 )
01525 p++;
01526 filename = (char *) alloca ((size_t) (p - filename_start) + 1);
01527 strncpy (filename, filename_start, (size_t) (p - filename_start));
01528 filename[p-filename_start] = '\0';
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544 def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);
01545 }
01546
01547 {
01548 const char *line_number_start = ++p;
01549 char line_number[10];
01550
01551 while (*p != ':'
01552 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
01553 || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
01554 #endif
01555 )
01556 p++;
01557 strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
01558 line_number[p-line_number_start] = '\0';
01559 def_dec_p->line = atoi (line_number);
01560 }
01561
01562
01563
01564
01565 p++;
01566 check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
01567
01568
01569
01570 def_dec_p->prototyped = (*p == 'N');
01571
01572 #ifndef UNPROTOIZE
01573
01574
01575
01576 def_dec_p->is_implicit = (*p == 'I');
01577
01578 #endif
01579
01580 p++;
01581
01582 check_aux_info ((*p == 'C') || (*p == 'F'));
01583
01584
01585
01586
01587
01588 def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);
01589
01590 #ifndef UNPROTOIZE
01591 def_dec_p->definition = 0;
01592 #endif
01593
01594 check_aux_info (*p++ == ' ');
01595 check_aux_info (*p++ == '*');
01596 check_aux_info (*p++ == '/');
01597 check_aux_info (*p++ == ' ');
01598
01599 #ifdef UNPROTOIZE
01600 check_aux_info ((!strncmp (p, "static", 6)) || (!strncmp (p, "extern", 6)));
01601 #else
01602 if (!strncmp (p, "static", 6))
01603 def_dec_p->is_static = -1;
01604 else if (!strncmp (p, "extern", 6))
01605 def_dec_p->is_static = 0;
01606 else
01607 check_aux_info (0);
01608 #endif
01609
01610 {
01611 const char *ansi_start = p;
01612
01613 p += 6;
01614
01615
01616
01617
01618
01619 while (*++p != ';')
01620 continue;
01621
01622 semicolon_p = p;
01623
01624
01625
01626
01627 def_dec_p->ansi_decl
01628 = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
01629
01630
01631
01632 p--;
01633
01634 #ifndef UNPROTOIZE
01635 def_dec_p->f_list_chain = NULL;
01636 #endif
01637
01638 while (p != ansi_start && (p[-1] == ' ' || p[-1] == '\t')) p--;
01639 if (*p != ')')
01640 {
01641 free_def_dec (def_dec_p);
01642 return;
01643 }
01644 }
01645
01646
01647
01648
01649 def_dec_p->f_list_count = 0;
01650
01651 for (;;)
01652 {
01653 const char *left_paren_p = find_corresponding_lparen (p);
01654 #ifndef UNPROTOIZE
01655 {
01656 f_list_chain_item *cip
01657 = (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
01658
01659 cip->formals_list
01660 = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
01661
01662
01663
01664 cip->chain_next = def_dec_p->f_list_chain;
01665 def_dec_p->f_list_chain = cip;
01666 }
01667 #endif
01668 def_dec_p->f_list_count++;
01669
01670 p = left_paren_p - 2;
01671
01672
01673
01674
01675
01676
01677
01678 if (*p != ')')
01679 break;
01680 else
01681 check_aux_info (*--p == ')');
01682 }
01683
01684
01685 {
01686 const char *past_fn = p + 1;
01687
01688 check_aux_info (*past_fn == ' ');
01689
01690
01691
01692 while (is_id_char (*p))
01693 p--;
01694 p++;
01695
01696
01697
01698 {
01699 char *fn_string = (char *) alloca (past_fn - p + 1);
01700
01701 strncpy (fn_string, p, (size_t) (past_fn - p));
01702 fn_string[past_fn-p] = '\0';
01703 def_dec_p->hash_entry = lookup (function_name_primary, fn_string);
01704 }
01705 }
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722 {
01723 const def_dec_info *other;
01724
01725 for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func)
01726 {
01727 if (def_dec_p->line == other->line && def_dec_p->file == other->file)
01728 {
01729 if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
01730 {
01731 notice ("%s:%d: declaration of function `%s' takes different forms\n",
01732 def_dec_p->file->hash_entry->symbol,
01733 def_dec_p->line,
01734 def_dec_p->hash_entry->symbol);
01735 exit (FATAL_EXIT_CODE);
01736 }
01737 free_def_dec (def_dec_p);
01738 return;
01739 }
01740 }
01741 }
01742
01743 #ifdef UNPROTOIZE
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 def_dec_p->formal_names = NULL;
01759 def_dec_p->formal_decls = NULL;
01760
01761 if (def_dec_p->is_func_def)
01762 {
01763 p = semicolon_p;
01764 check_aux_info (*++p == ' ');
01765 check_aux_info (*++p == '/');
01766 check_aux_info (*++p == '*');
01767 check_aux_info (*++p == ' ');
01768 check_aux_info (*++p == '(');
01769
01770 {
01771 const char *kr_names_start = ++p;
01772
01773 while (*p++ != ')')
01774 continue;
01775 p--;
01776
01777
01778
01779 def_dec_p->formal_names
01780 = dupnstr (kr_names_start, (size_t) (p - kr_names_start));
01781 }
01782
01783 check_aux_info (*++p == ' ');
01784 p++;
01785
01786
01787
01788
01789
01790
01791
01792
01793 if (*p == '*')
01794 {
01795 check_aux_info (*++p == '/');
01796 def_dec_p->formal_decls = "";
01797 }
01798 else
01799 {
01800 const char *kr_decls_start = p;
01801
01802 while (p[0] != '*' || p[1] != '/')
01803 p++;
01804 p--;
01805
01806 check_aux_info (*p == ' ');
01807
01808 def_dec_p->formal_decls
01809 = dupnstr (kr_decls_start, (size_t) (p - kr_decls_start));
01810 }
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821 if (!def_dec_p->prototyped && !*def_dec_p->formal_names)
01822 def_dec_p->prototyped = 1;
01823 }
01824
01825
01826
01827
01828 if (!def_dec_p->prototyped)
01829 {
01830 free_def_dec (def_dec_p);
01831 return;
01832 }
01833
01834 #endif
01835
01836
01837
01838
01839 def_dec_p->next_for_func = def_dec_p->hash_entry->ddip;
01840 def_dec_p->hash_entry->ddip = def_dec_p;
01841
01842
01843
01844
01845
01846
01847 if (!def_dec_p->file->defs_decs)
01848 {
01849 def_dec_p->file->defs_decs = def_dec_p;
01850 def_dec_p->next_in_file = NULL;
01851 }
01852 else
01853 {
01854 int line = def_dec_p->line;
01855 const def_dec_info *prev = NULL;
01856 const def_dec_info *curr = def_dec_p->file->defs_decs;
01857 const def_dec_info *next = curr->next_in_file;
01858
01859 while (next && (line < curr->line))
01860 {
01861 prev = curr;
01862 curr = next;
01863 next = next->next_in_file;
01864 }
01865 if (line >= curr->line)
01866 {
01867 def_dec_p->next_in_file = curr;
01868 if (prev)
01869 ((NONCONST def_dec_info *) prev)->next_in_file = def_dec_p;
01870 else
01871 def_dec_p->file->defs_decs = def_dec_p;
01872 }
01873 else
01874 {
01875 ((NONCONST def_dec_info *) curr)->next_in_file = def_dec_p;
01876
01877 def_dec_p->next_in_file = next;
01878 }
01879 }
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
01889 static void
01890 munge_compile_params (params_list)
01891 const char *params_list;
01892 {
01893
01894
01895 const char **temp_params
01896 = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
01897 int param_count = 0;
01898 const char *param;
01899 struct stat st;
01900
01901 temp_params[param_count++] = compiler_file_name;
01902 for (;;)
01903 {
01904 while (ISSPACE ((const unsigned char)*params_list))
01905 params_list++;
01906 if (!*params_list)
01907 break;
01908 param = params_list;
01909 while (*params_list && !ISSPACE ((const unsigned char)*params_list))
01910 params_list++;
01911 if (param[0] != '-')
01912 temp_params[param_count++]
01913 = dupnstr (param, (size_t) (params_list - param));
01914 else
01915 {
01916 switch (param[1])
01917 {
01918 case 'g':
01919 case 'O':
01920 case 'S':
01921 case 'c':
01922 break;
01923 case 'o':
01924 while (ISSPACE ((const unsigned char)*params_list))
01925 params_list++;
01926 while (*params_list
01927 && !ISSPACE ((const unsigned char)*params_list))
01928 params_list++;
01929 break;
01930 default:
01931 temp_params[param_count++]
01932 = dupnstr (param, (size_t) (params_list - param));
01933 }
01934 }
01935 if (!*params_list)
01936 break;
01937 }
01938 temp_params[param_count++] = "-aux-info";
01939
01940
01941 aux_info_file_name_index = param_count;
01942 temp_params[param_count++] = NULL;
01943
01944 temp_params[param_count++] = "-S";
01945 temp_params[param_count++] = "-o";
01946
01947 if ((stat (HOST_BIT_BUCKET, &st) == 0)
01948 && (!S_ISDIR (st.st_mode))
01949 && (access (HOST_BIT_BUCKET, W_OK) == 0))
01950 temp_params[param_count++] = HOST_BIT_BUCKET;
01951 else
01952
01953
01954
01955 temp_params[param_count++] = "/dev/null";
01956
01957
01958 input_file_name_index = param_count;
01959 temp_params[param_count++] = NULL;
01960
01961 temp_params[param_count++] = NULL;
01962
01963
01964
01965 compile_params
01966 = (const char **) xmalloc (sizeof (char *) * (param_count+1));
01967 memcpy (compile_params, temp_params, sizeof (char *) * param_count);
01968 }
01969
01970
01971
01972
01973
01974
01975 static int
01976 gen_aux_info_file (base_filename)
01977 const char *base_filename;
01978 {
01979 if (!input_file_name_index)
01980 munge_compile_params ("");
01981
01982
01983 compile_params[input_file_name_index] = shortpath (NULL, base_filename);
01984
01985 compile_params[aux_info_file_name_index] =
01986 concat (compile_params[input_file_name_index], aux_info_suffix, NULL);
01987
01988 if (!quiet_flag)
01989 notice ("%s: compiling `%s'\n",
01990 pname, compile_params[input_file_name_index]);
01991
01992 {
01993 char *errmsg_fmt, *errmsg_arg;
01994 int wait_status, pid;
01995
01996 pid = pexecute (compile_params[0], (char * const *) compile_params,
01997 pname, NULL, &errmsg_fmt, &errmsg_arg,
01998 PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH);
01999
02000 if (pid == -1)
02001 {
02002 int errno_val = errno;
02003 fprintf (stderr, "%s: ", pname);
02004 fprintf (stderr, errmsg_fmt, errmsg_arg);
02005 fprintf (stderr, ": %s\n", xstrerror (errno_val));
02006 return 0;
02007 }
02008
02009 pid = pwait (pid, &wait_status, 0);
02010 if (pid == -1)
02011 {
02012 notice ("%s: wait: %s\n", pname, xstrerror (errno));
02013 return 0;
02014 }
02015 if (WIFSIGNALED (wait_status))
02016 {
02017 notice ("%s: subprocess got fatal signal %d\n",
02018 pname, WTERMSIG (wait_status));
02019 return 0;
02020 }
02021 if (WIFEXITED (wait_status))
02022 {
02023 if (WEXITSTATUS (wait_status) != 0)
02024 {
02025 notice ("%s: %s exited with status %d\n",
02026 pname, compile_params[0], WEXITSTATUS (wait_status));
02027 return 0;
02028 }
02029 return 1;
02030 }
02031 abort ();
02032 }
02033 }
02034
02035
02036
02037
02038 static void
02039 process_aux_info_file (base_source_filename, keep_it, is_syscalls)
02040 const char *base_source_filename;
02041 int keep_it;
02042 int is_syscalls;
02043 {
02044 size_t base_len = strlen (base_source_filename);
02045 char * aux_info_filename
02046 = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
02047 char *aux_info_base;
02048 char *aux_info_limit;
02049 char *aux_info_relocated_name;
02050 const char *aux_info_second_line;
02051 time_t aux_info_mtime;
02052 size_t aux_info_size;
02053 int must_create;
02054
02055
02056
02057 strcpy (aux_info_filename, base_source_filename);
02058 strcat (aux_info_filename, aux_info_suffix);
02059
02060
02061
02062
02063
02064
02065
02066 must_create = 0;
02067
02068
02069 start_over: ;
02070
02071 if (access (aux_info_filename, R_OK) == -1)
02072 {
02073 if (errno == ENOENT)
02074 {
02075 if (is_syscalls)
02076 {
02077 notice ("%s: warning: missing SYSCALLS file `%s'\n",
02078 pname, aux_info_filename);
02079 return;
02080 }
02081 must_create = 1;
02082 }
02083 else
02084 {
02085 int errno_val = errno;
02086 notice ("%s: can't read aux info file `%s': %s\n",
02087 pname, shortpath (NULL, aux_info_filename),
02088 xstrerror (errno_val));
02089 errors++;
02090 return;
02091 }
02092 }
02093 #if 0
02094 else
02095 {
02096 struct stat s1, s2;
02097 stat (aux_info_file_name, &s1);
02098 stat (base_source_file_name, &s2);
02099 if (s2.st_mtime > s1.st_mtime)
02100 must_create = 1;
02101 }
02102 #endif
02103
02104
02105 if (must_create)
02106 {
02107 if (!gen_aux_info_file (base_source_filename))
02108 {
02109 errors++;
02110 return;
02111 }
02112 if (access (aux_info_filename, R_OK) == -1)
02113 {
02114 int errno_val = errno;
02115 notice ("%s: can't read aux info file `%s': %s\n",
02116 pname, shortpath (NULL, aux_info_filename),
02117 xstrerror (errno_val));
02118 errors++;
02119 return;
02120 }
02121 }
02122
02123 {
02124 struct stat stat_buf;
02125
02126
02127
02128 if (stat (aux_info_filename, &stat_buf) == -1)
02129 {
02130 int errno_val = errno;
02131 notice ("%s: can't get status of aux info file `%s': %s\n",
02132 pname, shortpath (NULL, aux_info_filename),
02133 xstrerror (errno_val));
02134 errors++;
02135 return;
02136 }
02137
02138
02139
02140
02141 if ((aux_info_size = stat_buf.st_size) == 0)
02142 return;
02143
02144
02145
02146
02147
02148 aux_info_mtime = stat_buf.st_mtime;
02149
02150 if (!is_syscalls)
02151 {
02152
02153
02154
02155
02156 if (stat (base_source_filename, &stat_buf) == -1)
02157 {
02158 int errno_val = errno;
02159 notice ("%s: can't get status of aux info file `%s': %s\n",
02160 pname, shortpath (NULL, base_source_filename),
02161 xstrerror (errno_val));
02162 errors++;
02163 return;
02164 }
02165 if (stat_buf.st_mtime > aux_info_mtime)
02166 {
02167 must_create = 1;
02168 goto start_over;
02169 }
02170 }
02171 }
02172
02173 {
02174 int aux_info_file;
02175 int fd_flags;
02176
02177
02178
02179 fd_flags = O_RDONLY;
02180 #ifdef O_BINARY
02181
02182 fd_flags |= O_BINARY;
02183 #endif
02184 if ((aux_info_file = open (aux_info_filename, fd_flags, 0444 )) == -1)
02185 {
02186 int errno_val = errno;
02187 notice ("%s: can't open aux info file `%s' for reading: %s\n",
02188 pname, shortpath (NULL, aux_info_filename),
02189 xstrerror (errno_val));
02190 return;
02191 }
02192
02193
02194
02195 aux_info_base = xmalloc (aux_info_size + 1);
02196 aux_info_limit = aux_info_base + aux_info_size;
02197 *aux_info_limit = '\0';
02198
02199
02200
02201 if (safe_read (aux_info_file, aux_info_base, aux_info_size) !=
02202 (int) aux_info_size)
02203 {
02204 int errno_val = errno;
02205 notice ("%s: error reading aux info file `%s': %s\n",
02206 pname, shortpath (NULL, aux_info_filename),
02207 xstrerror (errno_val));
02208 free (aux_info_base);
02209 close (aux_info_file);
02210 return;
02211 }
02212
02213
02214
02215 if (close (aux_info_file))
02216 {
02217 int errno_val = errno;
02218 notice ("%s: error closing aux info file `%s': %s\n",
02219 pname, shortpath (NULL, aux_info_filename),
02220 xstrerror (errno_val));
02221 free (aux_info_base);
02222 close (aux_info_file);
02223 return;
02224 }
02225 }
02226
02227
02228
02229
02230 if (must_create && !keep_it)
02231 if (unlink (aux_info_filename) == -1)
02232 {
02233 int errno_val = errno;
02234 notice ("%s: can't delete aux info file `%s': %s\n",
02235 pname, shortpath (NULL, aux_info_filename),
02236 xstrerror (errno_val));
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246 {
02247 char *p = aux_info_base;
02248
02249 while (*p != ':'
02250 #ifdef HAVE_DOS_BASED_FILE_SYSTEM
02251 || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
02252 #endif
02253 )
02254 p++;
02255 p++;
02256 while (*p == ' ')
02257 p++;
02258 invocation_filename = p;
02259 while (*p != ' ')
02260 p++;
02261 *p++ = DIR_SEPARATOR;
02262 *p++ = '\0';
02263 while (*p++ != '\n')
02264 continue;
02265 aux_info_second_line = p;
02266 aux_info_relocated_name = 0;
02267 if (! is_abspath (invocation_filename))
02268 {
02269
02270
02271 char *dir_end;
02272 aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
02273 strcpy (aux_info_relocated_name, base_source_filename);
02274 dir_end = strrchr (aux_info_relocated_name, DIR_SEPARATOR);
02275 #ifdef DIR_SEPARATOR_2
02276 {
02277 char *slash;
02278
02279 slash = strrchr (dir_end ? dir_end : aux_info_relocated_name,
02280 DIR_SEPARATOR_2);
02281 if (slash)
02282 dir_end = slash;
02283 }
02284 #endif
02285 if (dir_end)
02286 dir_end++;
02287 else
02288 dir_end = aux_info_relocated_name;
02289 strcpy (dir_end, invocation_filename);
02290 invocation_filename = aux_info_relocated_name;
02291 }
02292 }
02293
02294
02295 {
02296 const char *aux_info_p;
02297
02298
02299
02300
02301
02302
02303 if (!is_syscalls)
02304 {
02305 current_aux_info_lineno = 2;
02306
02307 for (aux_info_p = aux_info_second_line; *aux_info_p; )
02308 {
02309 if (referenced_file_is_newer (aux_info_p, aux_info_mtime))
02310 {
02311 free (aux_info_base);
02312 free (aux_info_relocated_name);
02313 if (keep_it && unlink (aux_info_filename) == -1)
02314 {
02315 int errno_val = errno;
02316 notice ("%s: can't delete file `%s': %s\n",
02317 pname, shortpath (NULL, aux_info_filename),
02318 xstrerror (errno_val));
02319 return;
02320 }
02321 must_create = 1;
02322 goto start_over;
02323 }
02324
02325
02326
02327 while (*aux_info_p != '\n')
02328 aux_info_p++;
02329 aux_info_p++;
02330 current_aux_info_lineno++;
02331 }
02332 }
02333
02334
02335
02336
02337 current_aux_info_lineno = 2;
02338
02339 for (aux_info_p = aux_info_second_line; *aux_info_p;)
02340 {
02341 char *unexpanded_line = unexpand_if_needed (aux_info_p);
02342
02343 if (unexpanded_line)
02344 {
02345 save_def_or_dec (unexpanded_line, is_syscalls);
02346 free (unexpanded_line);
02347 }
02348 else
02349 save_def_or_dec (aux_info_p, is_syscalls);
02350
02351
02352
02353 while (*aux_info_p != '\n')
02354 aux_info_p++;
02355 aux_info_p++;
02356 current_aux_info_lineno++;
02357 }
02358 }
02359
02360 free (aux_info_base);
02361 free (aux_info_relocated_name);
02362 }
02363
02364 #ifndef UNPROTOIZE
02365
02366
02367
02368
02369
02370 static void
02371 rename_c_file (hp)
02372 const hash_table_entry *hp;
02373 {
02374 const char *filename = hp->symbol;
02375 int last_char_index = strlen (filename) - 1;
02376 char *const new_filename = (char *) alloca (strlen (filename)
02377 + strlen (cplus_suffix) + 1);
02378
02379
02380
02381
02382
02383
02384
02385 if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.'
02386 || IS_SAME_PATH (syscalls_absolute_filename, filename))
02387 return;
02388
02389 strcpy (new_filename, filename);
02390 strcpy (&new_filename[last_char_index], cplus_suffix);
02391
02392 if (rename (filename, new_filename) == -1)
02393 {
02394 int errno_val = errno;
02395 notice ("%s: warning: can't rename file `%s' to `%s': %s\n",
02396 pname, shortpath (NULL, filename),
02397 shortpath (NULL, new_filename), xstrerror (errno_val));
02398 errors++;
02399 return;
02400 }
02401 }
02402
02403 #endif
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413 static void
02414 reverse_def_dec_list (hp)
02415 const hash_table_entry *hp;
02416 {
02417 file_info *file_p = hp->fip;
02418 def_dec_info *prev = NULL;
02419 def_dec_info *current = (def_dec_info *) file_p->defs_decs;
02420
02421 if (!current)
02422 return;
02423
02424 prev = current;
02425 if (! (current = (def_dec_info *) current->next_in_file))
02426 return;
02427
02428 prev->next_in_file = NULL;
02429
02430 while (current)
02431 {
02432 def_dec_info *next = (def_dec_info *) current->next_in_file;
02433
02434 current->next_in_file = prev;
02435 prev = current;
02436 current = next;
02437 }
02438
02439 file_p->defs_decs = prev;
02440 }
02441
02442 #ifndef UNPROTOIZE
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455 static const def_dec_info *
02456 find_extern_def (head, user)
02457 const def_dec_info *head;
02458 const def_dec_info *user;
02459 {
02460 const def_dec_info *dd_p;
02461 const def_dec_info *extern_def_p = NULL;
02462 int conflict_noted = 0;
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
02480 if (dd_p->is_func_def && !dd_p->is_static && dd_p->file == user->file)
02481 return dd_p;
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
02493 if (dd_p->is_func_def && !dd_p->is_static)
02494 {
02495 if (!extern_def_p)
02496 extern_def_p = dd_p;
02497 else
02498 {
02499
02500
02501 if (is_syscalls_file (dd_p->file))
02502 continue;
02503
02504
02505
02506
02507 if (is_syscalls_file (extern_def_p->file))
02508 {
02509 extern_def_p = dd_p;
02510 continue;
02511 }
02512
02513
02514
02515
02516
02517 if (!conflict_noted)
02518 {
02519 conflict_noted = 1;
02520 notice ("%s: conflicting extern definitions of '%s'\n",
02521 pname, head->hash_entry->symbol);
02522 if (!quiet_flag)
02523 {
02524 notice ("%s: declarations of '%s' will not be converted\n",
02525 pname, head->hash_entry->symbol);
02526 notice ("%s: conflict list for '%s' follows:\n",
02527 pname, head->hash_entry->symbol);
02528 fprintf (stderr, "%s: %s(%d): %s\n",
02529 pname,
02530 shortpath (NULL, extern_def_p->file->hash_entry->symbol),
02531 extern_def_p->line, extern_def_p->ansi_decl);
02532 }
02533 }
02534 if (!quiet_flag)
02535 fprintf (stderr, "%s: %s(%d): %s\n",
02536 pname,
02537 shortpath (NULL, dd_p->file->hash_entry->symbol),
02538 dd_p->line, dd_p->ansi_decl);
02539 }
02540 }
02541
02542
02543
02544
02545
02546 if (conflict_noted)
02547 return NULL;
02548
02549 if (!extern_def_p)
02550 {
02551
02552
02553
02554 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
02555 if (!dd_p->is_func_def && !dd_p->is_static && dd_p->prototyped)
02556 {
02557 extern_def_p = dd_p;
02558 if (!quiet_flag)
02559 notice ("%s: warning: using formals list from %s(%d) for function `%s'\n",
02560 pname,
02561 shortpath (NULL, dd_p->file->hash_entry->symbol),
02562 dd_p->line, dd_p->hash_entry->symbol);
02563 break;
02564 }
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578 if (!extern_def_p)
02579 {
02580 const char *file = user->file->hash_entry->symbol;
02581
02582 if (!quiet_flag)
02583 if (in_system_include_dir (file))
02584 {
02585
02586
02587 char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
02588 char *p;
02589
02590 strcpy (needed, user->ansi_decl);
02591 p = (NONCONST char *) substr (needed, user->hash_entry->symbol)
02592 + strlen (user->hash_entry->symbol) + 2;
02593
02594 *p++ = '?';
02595 *p++ = '?';
02596 *p++ = '?';
02597 strcpy (p, ");");
02598
02599 notice ("%s: %d: `%s' used but missing from SYSCALLS\n",
02600 shortpath (NULL, file), user->line,
02601 needed+7);
02602 }
02603 #if 0
02604 else
02605 notice ("%s: %d: warning: no extern definition for `%s'\n",
02606 shortpath (NULL, file), user->line,
02607 user->hash_entry->symbol);
02608 #endif
02609 }
02610 }
02611 return extern_def_p;
02612 }
02613
02614
02615
02616
02617
02618 static const def_dec_info *
02619 find_static_definition (user)
02620 const def_dec_info *user;
02621 {
02622 const def_dec_info *head = user->hash_entry->ddip;
02623 const def_dec_info *dd_p;
02624 int num_static_defs = 0;
02625 const def_dec_info *static_def_p = NULL;
02626
02627 for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
02628 if (dd_p->is_func_def && dd_p->is_static && (dd_p->file == user->file))
02629 {
02630 static_def_p = dd_p;
02631 num_static_defs++;
02632 }
02633 if (num_static_defs == 0)
02634 {
02635 if (!quiet_flag)
02636 notice ("%s: warning: no static definition for `%s' in file `%s'\n",
02637 pname, head->hash_entry->symbol,
02638 shortpath (NULL, user->file->hash_entry->symbol));
02639 }
02640 else if (num_static_defs > 1)
02641 {
02642 notice ("%s: multiple static defs of `%s' in file `%s'\n",
02643 pname, head->hash_entry->symbol,
02644 shortpath (NULL, user->file->hash_entry->symbol));
02645 return NULL;
02646 }
02647 return static_def_p;
02648 }
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668 static void
02669 connect_defs_and_decs (hp)
02670 const hash_table_entry *hp;
02671 {
02672 const def_dec_info *dd_p;
02673 const def_dec_info *extern_def_p = NULL;
02674 int first_extern_reference = 1;
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
02694 if (dd_p->prototyped)
02695 ((NONCONST def_dec_info *) dd_p)->definition = dd_p;
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
02714 if (!dd_p->is_func_def && !dd_p->is_static && !dd_p->definition)
02715 {
02716 if (first_extern_reference)
02717 {
02718 extern_def_p = find_extern_def (hp->ddip, dd_p);
02719 first_extern_reference = 0;
02720 }
02721 ((NONCONST def_dec_info *) dd_p)->definition = extern_def_p;
02722 }
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
02745 if (!dd_p->is_func_def && dd_p->is_static && !dd_p->definition)
02746 {
02747 const def_dec_info *dd_p2;
02748 const def_dec_info *static_def;
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769 ((NONCONST def_dec_info *) dd_p)->definition =
02770 (static_def = find_static_definition (dd_p))
02771 ? static_def
02772 : (const def_dec_info *) -1;
02773
02774 for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
02775 if (!dd_p2->is_func_def && dd_p2->is_static
02776 && !dd_p2->definition && (dd_p2->file == dd_p->file))
02777 ((NONCONST def_dec_info *) dd_p2)->definition = dd_p->definition;
02778 }
02779
02780
02781
02782
02783 for (dd_p = hp->ddip; dd_p; dd_p = dd_p->next_for_func)
02784 if (dd_p->definition == (def_dec_info *) -1)
02785 ((NONCONST def_dec_info *) dd_p)->definition = NULL;
02786 }
02787
02788 #endif
02789
02790
02791
02792
02793 static int
02794 identify_lineno (clean_p)
02795 const char *clean_p;
02796 {
02797 int line_num = 1;
02798 const char *scan_p;
02799
02800 for (scan_p = clean_text_base; scan_p <= clean_p; scan_p++)
02801 if (*scan_p == '\n')
02802 line_num++;
02803 return line_num;
02804 }
02805
02806
02807
02808 static void
02809 declare_source_confusing (clean_p)
02810 const char *clean_p;
02811 {
02812 if (!quiet_flag)
02813 {
02814 if (clean_p == 0)
02815 notice ("%s: %d: warning: source too confusing\n",
02816 shortpath (NULL, convert_filename), last_known_line_number);
02817 else
02818 notice ("%s: %d: warning: source too confusing\n",
02819 shortpath (NULL, convert_filename),
02820 identify_lineno (clean_p));
02821 }
02822 longjmp (source_confusion_recovery, 1);
02823 }
02824
02825
02826
02827
02828
02829 static void
02830 check_source (cond, clean_p)
02831 int cond;
02832 const char *clean_p;
02833 {
02834 if (!cond)
02835 declare_source_confusing (clean_p);
02836 }
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853 static const char *
02854 seek_to_line (n)
02855 int n;
02856 {
02857 if (n < last_known_line_number)
02858 abort ();
02859
02860 while (n > last_known_line_number)
02861 {
02862 while (*last_known_line_start != '\n')
02863 check_source (++last_known_line_start < clean_text_limit, 0);
02864 last_known_line_start++;
02865 last_known_line_number++;
02866 }
02867 return last_known_line_start;
02868 }
02869
02870
02871
02872
02873 static const char *
02874 forward_to_next_token_char (ptr)
02875 const char *ptr;
02876 {
02877 for (++ptr; ISSPACE ((const unsigned char)*ptr);
02878 check_source (++ptr < clean_text_limit, 0))
02879 continue;
02880 return ptr;
02881 }
02882
02883
02884
02885
02886
02887 static void
02888 output_bytes (str, len)
02889 const char *str;
02890 size_t len;
02891 {
02892 if ((repl_write_ptr + 1) + len >= repl_text_limit)
02893 {
02894 size_t new_size = (repl_text_limit - repl_text_base) << 1;
02895 char *new_buf = (char *) xrealloc (repl_text_base, new_size);
02896
02897 repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
02898 repl_text_base = new_buf;
02899 repl_text_limit = new_buf + new_size;
02900 }
02901 memcpy (repl_write_ptr + 1, str, len);
02902 repl_write_ptr += len;
02903 }
02904
02905
02906
02907
02908 static void
02909 output_string (str)
02910 const char *str;
02911 {
02912 output_bytes (str, strlen (str));
02913 }
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934 static void
02935 output_up_to (p)
02936 const char *p;
02937 {
02938 size_t copy_length = (size_t) (p - clean_read_ptr);
02939 const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
02940
02941 if (copy_length == 0)
02942 return;
02943
02944 output_bytes (copy_start, copy_length);
02945 clean_read_ptr = p;
02946 }
02947
02948
02949
02950
02951
02952
02953
02954 static int
02955 other_variable_style_function (ansi_header)
02956 const char *ansi_header;
02957 {
02958 #ifdef UNPROTOIZE
02959
02960
02961
02962
02963 return substr (ansi_header, "...") != 0;
02964
02965 #else
02966
02967
02968
02969
02970 const char *p;
02971 int len = strlen (varargs_style_indicator);
02972
02973 for (p = ansi_header; p; )
02974 {
02975 const char *candidate;
02976
02977 if ((candidate = substr (p, varargs_style_indicator)) == 0)
02978 return 0;
02979 else
02980 if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
02981 return 1;
02982 else
02983 p = candidate + 1;
02984 }
02985 return 0;
02986 #endif
02987 }
02988
02989
02990
02991
02992
02993 static void
02994 edit_fn_declaration (def_dec_p, clean_text_p)
02995 const def_dec_info *def_dec_p;
02996 const char *volatile clean_text_p;
02997 {
02998 const char *start_formals;
02999 const char *end_formals;
03000 const char *function_to_edit = def_dec_p->hash_entry->symbol;
03001 size_t func_name_len = strlen (function_to_edit);
03002 const char *end_of_fn_name;
03003
03004 #ifndef UNPROTOIZE
03005
03006 const f_list_chain_item *this_f_list_chain_item;
03007 const def_dec_info *definition = def_dec_p->definition;
03008
03009
03010
03011
03012
03013 if (!definition)
03014 return;
03015
03016
03017
03018
03019
03020
03021 if (other_variable_style_function (definition->ansi_decl))
03022 {
03023 if (!quiet_flag)
03024 notice ("%s: %d: warning: varargs function declaration not converted\n",
03025 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
03026 def_dec_p->line);
03027 return;
03028 }
03029
03030 #endif
03031
03032
03033
03034
03035 save_pointers ();
03036 if (setjmp (source_confusion_recovery))
03037 {
03038 restore_pointers ();
03039 notice ("%s: declaration of function `%s' not converted\n",
03040 pname, function_to_edit);
03041 return;
03042 }
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055 while (*clean_text_p != '\n')
03056 check_source (++clean_text_p < clean_text_limit, 0);
03057 clean_text_p--;
03058
03059
03060
03061 do
03062 {
03063 for (;;)
03064 {
03065
03066
03067
03068 while (!is_id_char (*clean_text_p))
03069 check_source (--clean_text_p > clean_read_ptr, 0);
03070
03071
03072
03073
03074 while (is_id_char (*clean_text_p))
03075 check_source (--clean_text_p > clean_read_ptr, 0);
03076
03077
03078
03079
03080 if (!strncmp (clean_text_p+1, function_to_edit, func_name_len))
03081 {
03082 char ch = *(clean_text_p + 1 + func_name_len);
03083
03084
03085
03086
03087
03088 if (! is_id_char (ch))
03089 break;
03090 }
03091 }
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105 end_of_fn_name = clean_text_p + strlen (def_dec_p->hash_entry->symbol);
03106 start_formals = forward_to_next_token_char (end_of_fn_name);
03107 }
03108 while (*start_formals != '(');
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118 #ifndef UNPROTOIZE
03119 this_f_list_chain_item = definition->f_list_chain;
03120 #endif
03121
03122 for (;;)
03123 {
03124 {
03125 int depth;
03126
03127 end_formals = start_formals + 1;
03128 depth = 1;
03129 for (; depth; check_source (++end_formals < clean_text_limit, 0))
03130 {
03131 switch (*end_formals)
03132 {
03133 case '(':
03134 depth++;
03135 break;
03136 case ')':
03137 depth--;
03138 break;
03139 }
03140 }
03141 end_formals--;
03142 }
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152 output_up_to (start_formals);
03153 #ifndef UNPROTOIZE
03154 if (this_f_list_chain_item)
03155 {
03156 output_string (this_f_list_chain_item->formals_list);
03157 this_f_list_chain_item = this_f_list_chain_item->chain_next;
03158 }
03159 else
03160 {
03161 if (!quiet_flag)
03162 notice ("%s: warning: too many parameter lists in declaration of `%s'\n",
03163 pname, def_dec_p->hash_entry->symbol);
03164 check_source (0, end_formals);
03165 }
03166 #endif
03167 clean_read_ptr = end_formals - 1;
03168
03169
03170
03171
03172
03173 {
03174 const char *another_r_paren = forward_to_next_token_char (end_formals);
03175
03176 if ((*another_r_paren != ')')
03177 || (*(start_formals = forward_to_next_token_char (another_r_paren)) != '('))
03178 {
03179 #ifndef UNPROTOIZE
03180 if (this_f_list_chain_item)
03181 {
03182 if (!quiet_flag)
03183 notice ("\n%s: warning: too few parameter lists in declaration of `%s'\n",
03184 pname, def_dec_p->hash_entry->symbol);
03185 check_source (0, start_formals);
03186 }
03187 #endif
03188 break;
03189
03190 }
03191 }
03192
03193
03194
03195 }
03196 }
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209 static int
03210 edit_formals_lists (end_formals, f_list_count, def_dec_p)
03211 const char *end_formals;
03212 unsigned int f_list_count;
03213 const def_dec_info *def_dec_p;
03214 {
03215 const char *start_formals;
03216 int depth;
03217
03218 start_formals = end_formals - 1;
03219 depth = 1;
03220 for (; depth; check_source (--start_formals > clean_read_ptr, 0))
03221 {
03222 switch (*start_formals)
03223 {
03224 case '(':
03225 depth--;
03226 break;
03227 case ')':
03228 depth++;
03229 break;
03230 }
03231 }
03232 start_formals++;
03233
03234
03235
03236 f_list_count--;
03237
03238 if (f_list_count)
03239 {
03240 const char *next_end;
03241
03242
03243
03244 next_end = start_formals - 1;
03245 check_source (next_end > clean_read_ptr, 0);
03246 while (ISSPACE ((const unsigned char)*next_end))
03247 check_source (--next_end > clean_read_ptr, 0);
03248 check_source (*next_end == ')', next_end);
03249 check_source (--next_end > clean_read_ptr, 0);
03250 check_source (*next_end == ')', next_end);
03251 if (edit_formals_lists (next_end, f_list_count, def_dec_p))
03252 return 1;
03253 }
03254
03255
03256
03257
03258
03259 if (f_list_count == 0)
03260 {
03261 const char *expected = def_dec_p->hash_entry->symbol;
03262 const char *func_name_start;
03263 const char *func_name_limit;
03264 size_t func_name_len;
03265
03266 for (func_name_limit = start_formals-1;
03267 ISSPACE ((const unsigned char)*func_name_limit); )
03268 check_source (--func_name_limit > clean_read_ptr, 0);
03269
03270 for (func_name_start = func_name_limit++;
03271 is_id_char (*func_name_start);
03272 func_name_start--)
03273 check_source (func_name_start > clean_read_ptr, 0);
03274 func_name_start++;
03275 func_name_len = func_name_limit - func_name_start;
03276 if (func_name_len == 0)
03277 check_source (0, func_name_start);
03278 if (func_name_len != strlen (expected)
03279 || strncmp (func_name_start, expected, func_name_len))
03280 {
03281 notice ("%s: %d: warning: found `%s' but expected `%s'\n",
03282 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
03283 identify_lineno (func_name_start),
03284 dupnstr (func_name_start, func_name_len),
03285 expected);
03286 return 1;
03287 }
03288 }
03289
03290 output_up_to (start_formals);
03291
03292 #ifdef UNPROTOIZE
03293 if (f_list_count == 0)
03294 output_string (def_dec_p->formal_names);
03295 #else
03296 {
03297 unsigned f_list_depth;
03298 const f_list_chain_item *flci_p = def_dec_p->f_list_chain;
03299
03300
03301
03302
03303
03304 for (f_list_depth = 0; f_list_depth < f_list_count; f_list_depth++)
03305 flci_p = flci_p->chain_next;
03306 output_string (flci_p->formals_list);
03307 }
03308 #endif
03309
03310 clean_read_ptr = end_formals - 1;
03311 return 0;
03312 }
03313
03314
03315
03316
03317
03318
03319
03320 static const char *
03321 find_rightmost_formals_list (clean_text_p)
03322 const char *clean_text_p;
03323 {
03324 const char *end_formals;
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346 for (end_formals = clean_text_p; *end_formals != '\n'; end_formals++)
03347 continue;
03348 end_formals--;
03349
03350 #ifdef UNPROTOIZE
03351
03352
03353
03354
03355 {
03356 char ch;
03357 const char *l_brace_p;
03358
03359
03360
03361 while (*end_formals != ')')
03362 {
03363 if (ISSPACE ((unsigned char)*end_formals))
03364 while (ISSPACE ((unsigned char)*end_formals))
03365 check_source (--end_formals > clean_read_ptr, 0);
03366 else
03367 check_source (--end_formals > clean_read_ptr, 0);
03368 }
03369
03370 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
03371
03372
03373
03374
03375
03376 check_source (ch == '{', l_brace_p);
03377 }
03378
03379 #else
03380
03381
03382
03383
03384 while (1)
03385 {
03386 char ch;
03387 const char *l_brace_p;
03388
03389
03390
03391 while (*end_formals != ')')
03392 {
03393 if (ISSPACE ((const unsigned char)*end_formals))
03394 while (ISSPACE ((const unsigned char)*end_formals))
03395 check_source (--end_formals > clean_read_ptr, 0);
03396 else
03397 check_source (--end_formals > clean_read_ptr, 0);
03398 }
03399
03400 ch = *(l_brace_p = forward_to_next_token_char (end_formals));
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412 if ((ch == '{') || ISALPHA ((unsigned char) ch))
03413 break;
03414
03415
03416
03417
03418
03419 check_source (--end_formals > clean_read_ptr, 0);
03420 }
03421
03422 #endif
03423
03424 return end_formals;
03425 }
03426
03427 #ifndef UNPROTOIZE
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438 static void
03439 add_local_decl (def_dec_p, clean_text_p)
03440 const def_dec_info *def_dec_p;
03441 const char *clean_text_p;
03442 {
03443 const char *start_of_block;
03444 const char *function_to_edit = def_dec_p->hash_entry->symbol;
03445
03446
03447
03448
03449 if (!local_flag)
03450 return;
03451
03452
03453
03454
03455 save_pointers ();
03456 if (setjmp (source_confusion_recovery))
03457 {
03458 restore_pointers ();
03459 notice ("%s: local declaration for function `%s' not inserted\n",
03460 pname, function_to_edit);
03461 return;
03462 }
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473 start_of_block = clean_text_p;
03474 while (*start_of_block != '{' && *start_of_block != '\n')
03475 check_source (++start_of_block < clean_text_limit, 0);
03476
03477
03478
03479
03480
03481
03482
03483 if (*start_of_block != '{')
03484 {
03485 if (!quiet_flag)
03486 notice ("\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
03487 def_dec_p->file->hash_entry->symbol, def_dec_p->line,
03488 def_dec_p->hash_entry->symbol);
03489 return;
03490 }
03491
03492
03493
03494
03495
03496
03497 {
03498 const char *ep = forward_to_next_token_char (start_of_block) - 1;
03499 const char *sp;
03500
03501
03502
03503
03504
03505
03506
03507 for (sp = ep; ISSPACE ((const unsigned char)*sp) && *sp != '\n'; sp--)
03508 continue;
03509
03510
03511
03512
03513
03514 output_up_to (ep);
03515
03516
03517
03518
03519
03520
03521
03522 {
03523 const char *decl = def_dec_p->definition->ansi_decl;
03524
03525 if ((*decl == 'e') && (def_dec_p->file == def_dec_p->definition->file))
03526 decl += 7;
03527 output_string (decl);
03528 }
03529
03530
03531
03532
03533
03534 output_bytes (sp, (size_t) (ep - sp) + 1);
03535 }
03536 }
03537
03538
03539
03540
03541
03542
03543
03544
03545 static void
03546 add_global_decls (file_p, clean_text_p)
03547 const file_info *file_p;
03548 const char *clean_text_p;
03549 {
03550 const def_dec_info *dd_p;
03551 const char *scan_p;
03552
03553
03554
03555
03556 save_pointers ();
03557 if (setjmp (source_confusion_recovery))
03558 {
03559 restore_pointers ();
03560 notice ("%s: global declarations for file `%s' not inserted\n",
03561 pname, shortpath (NULL, file_p->hash_entry->symbol));
03562 return;
03563 }
03564
03565
03566
03567
03568
03569
03570 scan_p = find_rightmost_formals_list (clean_text_p);
03571 for (;; --scan_p)
03572 {
03573 if (scan_p < clean_text_base)
03574 break;
03575 check_source (scan_p > clean_read_ptr, 0);
03576 if (*scan_p == ';')
03577 break;
03578 }
03579
03580
03581
03582
03583
03584
03585
03586
03587 scan_p++;
03588 while (ISSPACE ((const unsigned char)*scan_p))
03589 scan_p++;
03590 scan_p--;
03591
03592 output_up_to (scan_p);
03593
03594
03595
03596
03597
03598
03599 {
03600 int some_decls_added = 0;
03601
03602 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
03603 if (dd_p->is_implicit && dd_p->definition && !dd_p->definition->written)
03604 {
03605 const char *decl = dd_p->definition->ansi_decl;
03606
03607
03608
03609
03610
03611 if (*decl == 'e' && (dd_p->file == dd_p->definition->file))
03612 decl += 7;
03613
03614 output_string ("\n");
03615 output_string (decl);
03616 some_decls_added = 1;
03617 ((NONCONST def_dec_info *) dd_p->definition)->written = 1;
03618 }
03619 if (some_decls_added)
03620 output_string ("\n\n");
03621 }
03622
03623
03624
03625 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
03626 if (dd_p->definition)
03627 ((NONCONST def_dec_info *) dd_p->definition)->written = 0;
03628 }
03629
03630 #endif
03631
03632
03633
03634
03635
03636 static void
03637 edit_fn_definition (def_dec_p, clean_text_p)
03638 const def_dec_info *def_dec_p;
03639 const char *clean_text_p;
03640 {
03641 const char *end_formals;
03642 const char *function_to_edit = def_dec_p->hash_entry->symbol;
03643
03644
03645
03646
03647 save_pointers ();
03648 if (setjmp (source_confusion_recovery))
03649 {
03650 restore_pointers ();
03651 notice ("%s: definition of function `%s' not converted\n",
03652 pname, function_to_edit);
03653 return;
03654 }
03655
03656 end_formals = find_rightmost_formals_list (clean_text_p);
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667 if (other_variable_style_function (def_dec_p->ansi_decl))
03668 {
03669 if (!quiet_flag)
03670 notice ("%s: %d: warning: definition of %s not converted\n",
03671 shortpath (NULL, def_dec_p->file->hash_entry->symbol),
03672 identify_lineno (end_formals),
03673 other_var_style);
03674 output_up_to (end_formals);
03675 return;
03676 }
03677
03678 if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
03679 {
03680 restore_pointers ();
03681 notice ("%s: definition of function `%s' not converted\n",
03682 pname, function_to_edit);
03683 return;
03684 }
03685
03686
03687
03688
03689 output_up_to (end_formals);
03690
03691 #ifdef UNPROTOIZE
03692 {
03693 const char *decl_p;
03694 const char *semicolon_p;
03695 const char *limit_p;
03696 const char *scan_p;
03697 int had_newlines = 0;
03698
03699
03700
03701 decl_p = def_dec_p->formal_decls;
03702 limit_p = decl_p + strlen (decl_p);
03703 for (;decl_p < limit_p; decl_p = semicolon_p + 2)
03704 {
03705 for (semicolon_p = decl_p; *semicolon_p != ';'; semicolon_p++)
03706 continue;
03707 output_string ("\n");
03708 output_string (indent_string);
03709 output_bytes (decl_p, (size_t) ((semicolon_p + 1) - decl_p));
03710 }
03711
03712
03713
03714
03715 for (scan_p = end_formals+1; *scan_p != '{'; )
03716 {
03717 if (*scan_p == '\n')
03718 {
03719 had_newlines = 1;
03720 break;
03721 }
03722 check_source (++scan_p < clean_text_limit, 0);
03723 }
03724 if (!had_newlines)
03725 output_string ("\n");
03726 }
03727 #else
03728
03729
03730
03731
03732
03733
03734
03735 {
03736 const char *end_formals_orig;
03737 const char *start_body;
03738 const char *start_body_orig;
03739 const char *scan;
03740 const char *scan_orig;
03741 int have_flotsam = 0;
03742 int have_newlines = 0;
03743
03744 for (start_body = end_formals + 1; *start_body != '{';)
03745 check_source (++start_body < clean_text_limit, 0);
03746
03747 end_formals_orig = orig_text_base + (end_formals - clean_text_base);
03748 start_body_orig = orig_text_base + (start_body - clean_text_base);
03749 scan = end_formals + 1;
03750 scan_orig = end_formals_orig + 1;
03751 for (; scan < start_body; scan++, scan_orig++)
03752 {
03753 if (*scan == *scan_orig)
03754 {
03755 have_newlines |= (*scan_orig == '\n');
03756
03757 if (!ISSPACE ((const unsigned char)*scan_orig))
03758 *((NONCONST char *) scan_orig) = ' ';
03759 }
03760 else
03761 have_flotsam = 1;
03762 }
03763 if (have_flotsam)
03764 output_bytes (end_formals_orig + 1,
03765 (size_t) (start_body_orig - end_formals_orig) - 1);
03766 else
03767 if (have_newlines)
03768 output_string ("\n");
03769 else
03770 output_string (" ");
03771 clean_read_ptr = start_body - 1;
03772 }
03773 #endif
03774 }
03775
03776
03777
03778
03779
03780 static void
03781 do_cleaning (new_clean_text_base, new_clean_text_limit)
03782 char *new_clean_text_base;
03783 const char *new_clean_text_limit;
03784 {
03785 char *scan_p;
03786 int non_whitespace_since_newline = 0;
03787
03788 for (scan_p = new_clean_text_base; scan_p < new_clean_text_limit; scan_p++)
03789 {
03790 switch (*scan_p)
03791 {
03792 case '/':
03793 if (scan_p[1] != '*')
03794 goto regular;
03795 non_whitespace_since_newline = 1;
03796 scan_p[0] = ' ';
03797 scan_p[1] = ' ';
03798 scan_p += 2;
03799 while (scan_p[1] != '/' || scan_p[0] != '*')
03800 {
03801 if (!ISSPACE ((const unsigned char)*scan_p))
03802 *scan_p = ' ';
03803 if (++scan_p >= new_clean_text_limit)
03804 abort ();
03805 }
03806 *scan_p++ = ' ';
03807 *scan_p = ' ';
03808 break;
03809
03810 case '#':
03811 if (non_whitespace_since_newline)
03812 goto regular;
03813 *scan_p = ' ';
03814 while (scan_p[1] != '\n' || scan_p[0] == '\\')
03815 {
03816 if (!ISSPACE ((const unsigned char)*scan_p))
03817 *scan_p = ' ';
03818 if (++scan_p >= new_clean_text_limit)
03819 abort ();
03820 }
03821 *scan_p++ = ' ';
03822 break;
03823
03824 case '\'':
03825 non_whitespace_since_newline = 1;
03826 while (scan_p[1] != '\'' || scan_p[0] == '\\')
03827 {
03828 if (scan_p[0] == '\\'
03829 && !ISSPACE ((const unsigned char) scan_p[1]))
03830 scan_p[1] = ' ';
03831 if (!ISSPACE ((const unsigned char)*scan_p))
03832 *scan_p = ' ';
03833 if (++scan_p >= new_clean_text_limit)
03834 abort ();
03835 }
03836 *scan_p++ = ' ';
03837 break;
03838
03839 case '"':
03840 non_whitespace_since_newline = 1;
03841 while (scan_p[1] != '"' || scan_p[0] == '\\')
03842 {
03843 if (scan_p[0] == '\\'
03844 && !ISSPACE ((const unsigned char) scan_p[1]))
03845 scan_p[1] = ' ';
03846 if (!ISSPACE ((const unsigned char)*scan_p))
03847 *scan_p = ' ';
03848 if (++scan_p >= new_clean_text_limit)
03849 abort ();
03850 }
03851 if (!ISSPACE ((const unsigned char)*scan_p))
03852 *scan_p = ' ';
03853 scan_p++;
03854 break;
03855
03856 case '\\':
03857 if (scan_p[1] != '\n')
03858 goto regular;
03859 *scan_p = ' ';
03860 break;
03861
03862 case '\n':
03863 non_whitespace_since_newline = 0;
03864 break;
03865
03866 case ' ':
03867 case '\v':
03868 case '\t':
03869 case '\r':
03870 case '\f':
03871 case '\b':
03872 break;
03873
03874 default:
03875 regular:
03876 non_whitespace_since_newline = 1;
03877 break;
03878 }
03879 }
03880 }
03881
03882
03883
03884
03885
03886 static const char *
03887 careful_find_l_paren (p)
03888 const char *p;
03889 {
03890 const char *q;
03891 int paren_depth;
03892
03893 for (paren_depth = 1, q = p-1; paren_depth; check_source (--q >= clean_text_base, 0))
03894 {
03895 switch (*q)
03896 {
03897 case ')':
03898 paren_depth++;
03899 break;
03900 case '(':
03901 paren_depth--;
03902 break;
03903 }
03904 }
03905 return ++q;
03906 }
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925 static void
03926 scan_for_missed_items (file_p)
03927 const file_info *file_p;
03928 {
03929 static const char *scan_p;
03930 const char *limit = clean_text_limit - 3;
03931 static const char *backup_limit;
03932
03933 backup_limit = clean_text_base - 1;
03934
03935 for (scan_p = clean_text_base; scan_p < limit; scan_p++)
03936 {
03937 if (*scan_p == ')')
03938 {
03939 static const char *last_r_paren;
03940 const char *ahead_p;
03941
03942 last_r_paren = scan_p;
03943
03944 for (ahead_p = scan_p + 1; ISSPACE ((const unsigned char)*ahead_p); )
03945 check_source (++ahead_p < limit, limit);
03946
03947 scan_p = ahead_p - 1;
03948
03949 if (ISALPHA ((const unsigned char)*ahead_p) || *ahead_p == '{')
03950 {
03951 const char *last_l_paren;
03952 const int lineno = identify_lineno (ahead_p);
03953
03954 if (setjmp (source_confusion_recovery))
03955 continue;
03956
03957
03958
03959
03960 do
03961 {
03962 last_l_paren = careful_find_l_paren (last_r_paren);
03963 for (last_r_paren = last_l_paren-1;
03964 ISSPACE ((const unsigned char)*last_r_paren); )
03965 check_source (--last_r_paren >= backup_limit, backup_limit);
03966 }
03967 while (*last_r_paren == ')');
03968
03969 if (is_id_char (*last_r_paren))
03970 {
03971 const char *id_limit = last_r_paren + 1;
03972 const char *id_start;
03973 size_t id_length;
03974 const def_dec_info *dd_p;
03975
03976 for (id_start = id_limit-1; is_id_char (*id_start); )
03977 check_source (--id_start >= backup_limit, backup_limit);
03978 id_start++;
03979 backup_limit = id_start;
03980 if ((id_length = (size_t) (id_limit - id_start)) == 0)
03981 goto not_missed;
03982
03983 {
03984 char *func_name = (char *) alloca (id_length + 1);
03985 static const char * const stmt_keywords[]
03986 = { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
03987 const char * const *stmt_keyword;
03988
03989 strncpy (func_name, id_start, id_length);
03990 func_name[id_length] = '\0';
03991
03992
03993
03994
03995 for (stmt_keyword = stmt_keywords; *stmt_keyword; stmt_keyword++)
03996 if (!strcmp (func_name, *stmt_keyword))
03997 goto not_missed;
03998
03999 #if 0
04000 notice ("%s: found definition of `%s' at %s(%d)\n",
04001 pname,
04002 func_name,
04003 shortpath (NULL, file_p->hash_entry->symbol),
04004 identify_lineno (id_start));
04005 #endif
04006
04007
04008
04009 for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
04010 if (dd_p->is_func_def && dd_p->line == lineno)
04011 goto not_missed;
04012
04013
04014
04015
04016 notice ("%s: %d: warning: `%s' excluded by preprocessing\n",
04017 shortpath (NULL, file_p->hash_entry->symbol),
04018 identify_lineno (id_start), func_name);
04019 notice ("%s: function definition not converted\n",
04020 pname);
04021 }
04022 not_missed: ;
04023 }
04024 }
04025 }
04026 }
04027 }
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041 static void
04042 edit_file (hp)
04043 const hash_table_entry *hp;
04044 {
04045 struct stat stat_buf;
04046 const file_info *file_p = hp->fip;
04047 char *new_orig_text_base;
04048 char *new_orig_text_limit;
04049 char *new_clean_text_base;
04050 char *new_clean_text_limit;
04051 size_t orig_size;
04052 size_t repl_size;
04053 int first_definition_in_file;
04054
04055
04056
04057
04058 if (!needs_to_be_converted (file_p))
04059 return;
04060
04061 convert_filename = file_p->hash_entry->symbol;
04062
04063
04064
04065
04066 if (!directory_specified_p (convert_filename)
04067 || file_excluded_p (convert_filename))
04068 {
04069 if (!quiet_flag
04070 #ifdef UNPROTOIZE
04071
04072
04073
04074
04075 && !in_system_include_dir (convert_filename)
04076 #endif
04077 )
04078 notice ("%s: `%s' not converted\n",
04079 pname, shortpath (NULL, convert_filename));
04080 return;
04081 }
04082
04083
04084
04085 if (nochange_flag)
04086 notice ("%s: would convert file `%s'\n",
04087 pname, shortpath (NULL, convert_filename));
04088 else
04089 notice ("%s: converting file `%s'\n",
04090 pname, shortpath (NULL, convert_filename));
04091 fflush (stderr);
04092
04093
04094
04095
04096 if (stat (convert_filename, &stat_buf) == -1)
04097 {
04098 int errno_val = errno;
04099 notice ("%s: can't get status for file `%s': %s\n",
04100 pname, shortpath (NULL, convert_filename),
04101 xstrerror (errno_val));
04102 return;
04103 }
04104 orig_size = stat_buf.st_size;
04105
04106
04107
04108 orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
04109 orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
04110
04111
04112
04113 clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
04114 clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
04115 clean_read_ptr = clean_text_base - 1;
04116
04117
04118
04119
04120
04121
04122 repl_size = orig_size + (orig_size >> 2) + 4096;
04123 repl_text_base = (char *) xmalloc (repl_size + 2);
04124 repl_text_limit = repl_text_base + repl_size - 1;
04125 repl_write_ptr = repl_text_base - 1;
04126
04127 {
04128 int input_file;
04129 int fd_flags;
04130
04131
04132
04133 fd_flags = O_RDONLY;
04134 #ifdef O_BINARY
04135
04136 fd_flags |= O_BINARY;
04137 #endif
04138 if ((input_file = open (convert_filename, fd_flags, 0444)) == -1)
04139 {
04140 int errno_val = errno;
04141 notice ("%s: can't open file `%s' for reading: %s\n",
04142 pname, shortpath (NULL, convert_filename),
04143 xstrerror (errno_val));
04144 return;
04145 }
04146
04147
04148
04149
04150
04151 if (safe_read (input_file, new_orig_text_base, orig_size) !=
04152 (int) orig_size)
04153 {
04154 int errno_val = errno;
04155 close (input_file);
04156 notice ("\n%s: error reading input file `%s': %s\n",
04157 pname, shortpath (NULL, convert_filename),
04158 xstrerror (errno_val));
04159 return;
04160 }
04161
04162 close (input_file);
04163 }
04164
04165 if (orig_size == 0 || orig_text_limit[-1] != '\n')
04166 {
04167 *new_orig_text_limit++ = '\n';
04168 orig_text_limit++;
04169 }
04170
04171
04172
04173 memcpy (new_clean_text_base, orig_text_base,
04174 (size_t) (orig_text_limit - orig_text_base));
04175 do_cleaning (new_clean_text_base, new_clean_text_limit);
04176
04177 #if 0
04178 {
04179 int clean_file;
04180 size_t clean_size = orig_text_limit - orig_text_base;
04181 char *const clean_filename = (char *) alloca (strlen (convert_filename) + 6 + 1);
04182
04183
04184
04185 strcpy (clean_filename, convert_filename);
04186 strcat (clean_filename, ".clean");
04187 if ((clean_file = creat (clean_filename, 0666)) == -1)
04188 {
04189 int errno_val = errno;
04190 notice ("%s: can't create/open clean file `%s': %s\n",
04191 pname, shortpath (NULL, clean_filename),
04192 xstrerror (errno_val));
04193 return;
04194 }
04195
04196
04197
04198 safe_write (clean_file, new_clean_text_base, clean_size, clean_filename);
04199
04200 close (clean_file);
04201 }
04202 #endif
04203
04204
04205
04206
04207
04208
04209 scan_for_missed_items (file_p);
04210
04211
04212
04213 last_known_line_number = 1;
04214 last_known_line_start = clean_text_base;
04215
04216
04217
04218 {
04219 const def_dec_info *def_dec_p;
04220
04221 first_definition_in_file = 1;
04222 def_dec_p = file_p->defs_decs;
04223 for (; def_dec_p; def_dec_p = def_dec_p->next_in_file)
04224 {
04225 const char *clean_text_p = seek_to_line (def_dec_p->line);
04226
04227
04228
04229
04230
04231 #ifndef UNPROTOIZE
04232
04233 if (global_flag && def_dec_p->is_func_def && first_definition_in_file)
04234 {
04235 add_global_decls (def_dec_p->file, clean_text_p);
04236 first_definition_in_file = 0;
04237 }
04238
04239
04240
04241
04242
04243 if (def_dec_p->prototyped
04244 || (!def_dec_p->is_func_def && !def_dec_p->definition))
04245 continue;
04246
04247 #endif
04248
04249 if (def_dec_p->is_func_def)
04250 edit_fn_definition (def_dec_p, clean_text_p);
04251 else
04252 #ifndef UNPROTOIZE
04253 if (def_dec_p->is_implicit)
04254 add_local_decl (def_dec_p, clean_text_p);
04255 else
04256 #endif
04257 edit_fn_declaration (def_dec_p, clean_text_p);
04258 }
04259 }
04260
04261
04262
04263 output_up_to (clean_text_limit - 1);
04264
04265
04266
04267 if (nochange_flag)
04268 {
04269 free (new_orig_text_base);
04270 free (new_clean_text_base);
04271 free (repl_text_base);
04272 return;
04273 }
04274
04275
04276
04277
04278 if (!nosave_flag)
04279 {
04280 char *new_filename
04281 = (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
04282
04283 strcpy (new_filename, convert_filename);
04284 #ifdef __MSDOS__
04285
04286
04287 new_filename[(strlen (convert_filename) - 1] = '\0';
04288 #endif
04289 strcat (new_filename, save_suffix);
04290
04291
04292 if (access (new_filename, F_OK) == 0)
04293 {
04294 if (!quiet_flag)
04295 notice ("%s: warning: file `%s' already saved in `%s'\n",
04296 pname,
04297 shortpath (NULL, convert_filename),
04298 shortpath (NULL, new_filename));
04299 }
04300 else if (rename (convert_filename, new_filename) == -1)
04301 {
04302 int errno_val = errno;
04303 notice ("%s: can't link file `%s' to `%s': %s\n",
04304 pname,
04305 shortpath (NULL, convert_filename),
04306 shortpath (NULL, new_filename),
04307 xstrerror (errno_val));
04308 return;
04309 }
04310 }
04311
04312 if (unlink (convert_filename) == -1)
04313 {
04314 int errno_val = errno;
04315
04316 if (errno_val != ENOENT)
04317 {
04318 notice ("%s: can't delete file `%s': %s\n",
04319 pname, shortpath (NULL, convert_filename),
04320 xstrerror (errno_val));
04321 return;
04322 }
04323 }
04324
04325 {
04326 int output_file;
04327
04328
04329
04330 if ((output_file = creat (convert_filename, 0666)) == -1)
04331 {
04332 int errno_val = errno;
04333 notice ("%s: can't create/open output file `%s': %s\n",
04334 pname, shortpath (NULL, convert_filename),
04335 xstrerror (errno_val));
04336 return;
04337 }
04338 #ifdef O_BINARY
04339
04340 setmode (output_file, O_BINARY);
04341 #endif
04342
04343
04344
04345 {
04346 unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
04347
04348 safe_write (output_file, repl_text_base, out_size, convert_filename);
04349 }
04350
04351 close (output_file);
04352 }
04353
04354
04355
04356 free (new_orig_text_base);
04357 free (new_clean_text_base);
04358 free (repl_text_base);
04359
04360
04361
04362
04363 if (chmod (convert_filename, stat_buf.st_mode) == -1)
04364 {
04365 int errno_val = errno;
04366 notice ("%s: can't change mode of file `%s': %s\n",
04367 pname, shortpath (NULL, convert_filename),
04368 xstrerror (errno_val));
04369 }
04370
04371
04372
04373
04374
04375 }
04376
04377
04378
04379
04380
04381 static void
04382 do_processing ()
04383 {
04384 const char * const *base_pp;
04385 const char * const * const end_pps
04386 = &base_source_filenames[n_base_source_files];
04387
04388 #ifndef UNPROTOIZE
04389 int syscalls_len;
04390 #endif
04391
04392
04393
04394
04395
04396
04397 for (base_pp = base_source_filenames; base_pp < end_pps; base_pp++)
04398 process_aux_info_file (*base_pp, keep_flag, 0);
04399
04400 #ifndef UNPROTOIZE
04401
04402
04403
04404
04405 if (nondefault_syscalls_dir)
04406 {
04407 syscalls_absolute_filename
04408 = (char *) xmalloc (strlen (nondefault_syscalls_dir) + 1
04409 + sizeof (syscalls_filename));
04410 strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
04411 }
04412 else
04413 {
04414 GET_ENVIRONMENT (default_syscalls_dir, "GCC_EXEC_PREFIX");
04415 if (!default_syscalls_dir)
04416 {
04417 default_syscalls_dir = standard_exec_prefix;
04418 }
04419 syscalls_absolute_filename
04420 = (char *) xmalloc (strlen (default_syscalls_dir) + 0
04421 + strlen (target_machine) + 1
04422 + strlen (target_version) + 1
04423 + sizeof (syscalls_filename));
04424 strcpy (syscalls_absolute_filename, default_syscalls_dir);
04425 strcat (syscalls_absolute_filename, target_machine);
04426 strcat (syscalls_absolute_filename, "/");
04427 strcat (syscalls_absolute_filename, target_version);
04428 strcat (syscalls_absolute_filename, "/");
04429 }
04430
04431 syscalls_len = strlen (syscalls_absolute_filename);
04432 if (! IS_DIR_SEPARATOR (*(syscalls_absolute_filename + syscalls_len - 1)))
04433 {
04434 *(syscalls_absolute_filename + syscalls_len++) = DIR_SEPARATOR;
04435 *(syscalls_absolute_filename + syscalls_len) = '\0';
04436 }
04437 strcat (syscalls_absolute_filename, syscalls_filename);
04438
04439
04440
04441
04442 process_aux_info_file (syscalls_absolute_filename, 1, 1);
04443
04444 #endif
04445
04446
04447
04448
04449
04450
04451
04452
04453 visit_each_hash_node (filename_primary, reverse_def_dec_list);
04454
04455 #ifndef UNPROTOIZE
04456
04457
04458
04459
04460
04461
04462
04463
04464 visit_each_hash_node (function_name_primary, connect_defs_and_decs);
04465
04466 #endif
04467
04468
04469
04470 visit_each_hash_node (filename_primary, edit_file);
04471
04472 #ifndef UNPROTOIZE
04473
04474
04475
04476
04477 if (cplusplus_flag && !nochange_flag)
04478 visit_each_hash_node (filename_primary, rename_c_file);
04479
04480 #endif
04481 }
04482
04483 static const struct option longopts[] =
04484 {
04485 {"version", 0, 0, 'V'},
04486 {"file_name", 0, 0, 'p'},
04487 {"quiet", 0, 0, 'q'},
04488 {"silent", 0, 0, 'q'},
04489 {"force", 0, 0, 'f'},
04490 {"keep", 0, 0, 'k'},
04491 {"nosave", 0, 0, 'N'},
04492 {"nochange", 0, 0, 'n'},
04493 {"compiler-options", 1, 0, 'c'},
04494 {"exclude", 1, 0, 'x'},
04495 {"directory", 1, 0, 'd'},
04496 #ifdef UNPROTOIZE
04497 {"indent", 1, 0, 'i'},
04498 #else
04499 {"local", 0, 0, 'l'},
04500 {"global", 0, 0, 'g'},
04501 {"c++", 0, 0, 'C'},
04502 {"syscalls-dir", 1, 0, 'B'},
04503 #endif
04504 {0, 0, 0, 0}
04505 };
04506
04507 extern int main PARAMS ((int, char **const));
04508
04509 int
04510 main (argc, argv)
04511 int argc;
04512 char **const argv;
04513 {
04514 int longind;
04515 int c;
04516 const char *params = "";
04517
04518 pname = strrchr (argv[0], DIR_SEPARATOR);
04519 #ifdef DIR_SEPARATOR_2
04520 {
04521 char *slash;
04522
04523 slash = strrchr (pname ? pname : argv[0], DIR_SEPARATOR_2);
04524 if (slash)
04525 pname = slash;
04526 }
04527 #endif
04528 pname = pname ? pname+1 : argv[0];
04529
04530 #ifdef SIGCHLD
04531
04532
04533 signal (SIGCHLD, SIG_DFL);
04534 #endif
04535
04536 gcc_init_libintl ();
04537
04538 cwd_buffer = getpwd ();
04539 if (!cwd_buffer)
04540 {
04541 notice ("%s: cannot get working directory: %s\n",
04542 pname, xstrerror(errno));
04543 return (FATAL_EXIT_CODE);
04544 }
04545
04546
04547 directory_list = string_list_cons (cwd_buffer, NULL);
04548
04549 while ((c = getopt_long (argc, argv,
04550 #ifdef UNPROTOIZE
04551 "c:d:i:knNp:qvVx:",
04552 #else
04553 "B:c:Cd:gklnNp:qvVx:",
04554 #endif
04555 longopts, &longind)) != EOF)
04556 {
04557 if (c == 0)
04558 c = longopts[longind].val;
04559 switch (c)
04560 {
04561 case 'p':
04562 compiler_file_name = optarg;
04563 break;
04564 case 'd':
04565 directory_list
04566 = string_list_cons (abspath (NULL, optarg), directory_list);
04567 break;
04568 case 'x':
04569 exclude_list = string_list_cons (optarg, exclude_list);
04570 break;
04571
04572 case 'v':
04573 case 'V':
04574 version_flag = 1;
04575 break;
04576 case 'q':
04577 quiet_flag = 1;
04578 break;
04579 #if 0
04580 case 'f':
04581 force_flag = 1;
04582 break;
04583 #endif
04584 case 'n':
04585 nochange_flag = 1;
04586 keep_flag = 1;
04587 break;
04588 case 'N':
04589 nosave_flag = 1;
04590 break;
04591 case 'k':
04592 keep_flag = 1;
04593 break;
04594 case 'c':
04595 params = optarg;
04596 break;
04597 #ifdef UNPROTOIZE
04598 case 'i':
04599 indent_string = optarg;
04600 break;
04601 #else
04602 case 'l':
04603 local_flag = 1;
04604 break;
04605 case 'g':
04606 global_flag = 1;
04607 break;
04608 case 'C':
04609 cplusplus_flag = 1;
04610 break;
04611 case 'B':
04612 nondefault_syscalls_dir = optarg;
04613 break;
04614 #endif
04615 default:
04616 usage ();
04617 }
04618 }
04619
04620
04621 munge_compile_params (params);
04622
04623 n_base_source_files = argc - optind;
04624
04625
04626
04627 base_source_filenames
04628 = (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
04629 n_base_source_files = 0;
04630 for (; optind < argc; optind++)
04631 {
04632 const char *path = abspath (NULL, argv[optind]);
04633 int len = strlen (path);
04634
04635 if (path[len-1] == 'c' && path[len-2] == '.')
04636 base_source_filenames[n_base_source_files++] = path;
04637 else
04638 {
04639 notice ("%s: input file names must have .c suffixes: %s\n",
04640 pname, shortpath (NULL, path));
04641 errors++;
04642 }
04643 }
04644
04645 #ifndef UNPROTOIZE
04646
04647
04648
04649 {
04650 const char *cp;
04651
04652 for (cp = varargs_style_indicator; ISIDNUM (*cp); cp++)
04653 continue;
04654 if (*cp != 0)
04655 varargs_style_indicator = savestring (varargs_style_indicator,
04656 cp - varargs_style_indicator);
04657 }
04658 #endif
04659
04660 if (errors)
04661 usage ();
04662 else
04663 {
04664 if (version_flag)
04665 fprintf (stderr, "%s: %s\n", pname, version_string);
04666 do_processing ();
04667 }
04668
04669 return (errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
04670 }