fixing stuff
[dyninst.git] / codeCoverage / sparc-sun-solaris2.8 / tests / cc1 / 1protoize.i
1 extern int target_flags;
2 extern int hard_regno_nregs[];
3 extern int hard_regno_mode_ok[64 ];
4 extern int leaf_function;
5 enum reg_class { NO_REGS, GENERAL_REGS, FP_REGS, ALL_REGS, LIM_REG_CLASSES };
6 extern char leaf_reg_remap[];
7 extern char leaf_reg_backmap[];
8 extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
9 extern struct rtx_def *gen_compare_reg ();
10 extern int actual_fsize;
11 extern int apparent_fsize;
12 extern int current_function_calls_alloca;
13 extern int current_function_outgoing_args_size;
14 extern union tree_node *current_function_decl;
15 extern struct rtx_def *legitimize_pic_address ();
16 extern char *singlemove_string ();
17 extern char *output_move_double ();
18 extern char *output_move_quad ();
19 extern char *output_fp_move_double ();
20 extern char *output_fp_move_quad ();
21 extern char *output_block_move ();
22 extern char *output_scc_insn ();
23 extern char *output_cbranch ();
24 extern char *output_return ();
25 extern int flag_pic;
26 typedef unsigned int    size_t;          
27 extern  struct  _iobuf {
28         int     _cnt;
29         char    *_ptr;
30         char    *_base;
31         int     _bufsiz;
32         short   _flag;
33         short   _file;
34 } _iob[3 ];
35 typedef struct _iobuf   FILE;
36 typedef long    fpos_t;
37 extern int      getc( FILE *__stream );
38 extern int      getchar( void );
39 extern int      putc( int __c, FILE *__stream);
40 extern int      putchar( int __c);
41 extern int      feof( FILE *__stream );
42 extern int      ferror( FILE *__stream );
43 extern int      fileno( FILE *__stream );
44 extern int      _filbuf( FILE *p);
45 extern int      _flsbuf( unsigned char x , FILE *p);
46 typedef char *va_list;
47 extern void     clearerr( FILE *__stream); 
48 extern int      fclose( FILE *__stream );
49 extern FILE *   fdopen( int __filedes, char *__type );
50 extern int      fflush( FILE *__stream );
51 extern int      fgetc( FILE *__stream );
52 extern int      fgetpos( FILE *__stream, fpos_t *__pos );
53 extern char *   fgets( char *__s, int __n, FILE *__stream );
54 extern FILE *   fopen( const char *__filename, const char *__type );
55 extern int      fprintf( FILE *__stream, const char *__format, ... );
56 extern int      fputc( int __c, FILE *__stream );
57 extern int      fputs( const char *__s, FILE *__stream );
58 extern size_t   fread( void *__ptr, size_t __size,
59                         size_t __nitems, FILE *__stream ); 
60 extern FILE *   freopen( const char *__filename, const char *__type,
61                         FILE *__stream );
62 extern int      fscanf( FILE *__stream, const char *__format, ... );
63 extern int      fseek( FILE *__stream, long __offset, int __ptrname );
64 extern int      fsetpos( FILE *__stream, const fpos_t *__pos );
65 extern long     ftell( FILE *__stream );
66 extern size_t   fwrite( const void *__ptr, size_t __size,
67                         size_t __nitems, FILE *__stream );
68 extern char *   gets( char *__s );      
69 extern void     perror( const char *__s );
70 extern FILE  *  popen(const char *__command, const char *__type );
71 extern int      printf( const char *__format, ... );    
72 extern int      puts( const char *__s );        
73 extern int      remove( const char *__filename );
74 extern int      rename( const char *__from, const char *__to );
75 extern void     rewind( FILE *__stream );
76 extern int      scanf( const char *__format, ... );     
77 extern void     setbuf( FILE *__stream, char *__buf );
78 extern int      setvbuf( FILE *__stream, char *__buf,
79                         int __type, size_t __size );
80 extern int      sscanf( const char *__s, const char *__format, ... );
81 extern FILE *   tmpfile( void );        
82 extern char *   tmpnam( char *__s );
83 extern int      ungetc( int __c, FILE *__stream );
84 extern int      vfprintf( FILE *__stream, const char *__format, va_list __ap );
85 extern int      vprintf( const char *__format, va_list __ap );
86 extern int      vsprintf( char *__s, const char *__format, va_list __ap);
87 extern char *   tempnam( const char *__dir, const char *__pfx);
88 extern int      putw( int __w, FILE *__stream );
89 extern int      getw(FILE *__stream);
90 extern int      pclose( FILE *__stream );
91 extern int      sprintf( char *__s, const char *__format, ... );
92 extern  unsigned short *_pctype;
93 extern  unsigned short _ctype__[];
94 int     isalnum( int __c );
95 int     isalpha( int __c );
96 int     isascii( int __c );
97 int     iscntrl( int __c );
98 int     isdigit( int __c );
99 int     isgraph( int __c );
100 int     islower( int __c );
101 int     isprint( int __c );
102 int     ispunct( int __c );
103 int     isspace( int __c );
104 int     isupper( int __c );
105 int     isxdigit( int __c );
106 int     toascii( int __c );
107 int     _tolower( int __c );
108 int     _toupper( int __c );
109 int     tolower( int __c );
110 int     toupper( int __c );
111 extern int errno;
112 typedef unsigned char   u_char;
113 typedef unsigned short  u_short;
114 typedef unsigned int    u_int;
115 typedef unsigned int    uint;            
116 typedef unsigned long   u_long;
117 typedef unsigned short  ushort;          
118 typedef volatile char           v_char;
119 typedef volatile short          v_short;
120 typedef volatile long           v_long;
121 typedef volatile unsigned char  vu_char;
122 typedef volatile unsigned short vu_short;
123 typedef volatile unsigned long  vu_long;
124 typedef
125                 char    s_char;
126 typedef struct  _quad { long val[2]; } quad;
127 typedef long    daddr_t;
128 typedef char *  caddr_t;
129 typedef u_long  gno_t;
130 typedef short   cnt_t;                   
131 typedef long    swblk_t;
132 typedef long    paddr_t;                 
133 typedef long    audit_ID_t;
134 typedef short   dev_t;
135 typedef short   gid_t;                   
136 typedef unsigned long   ino_t;
137 typedef unsigned short  mode_t;          
138 typedef short   nlink_t;                 
139 typedef int     off_t;
140 typedef int     pid_t;                   
141 typedef short   uid_t;                   
142 typedef int     time_t;
143 typedef int     clock_t;                         
144 typedef long    key_t;                   
145 typedef long    fd_mask;
146 typedef struct fd_set {
147         fd_mask fds_bits[(((4096         )+(( (sizeof(fd_mask) * 8              )       )-1))/( (sizeof(fd_mask) * 8            )       )) ];
148 } fd_set;
149 struct  stat
150 {
151         dev_t           st_dev;
152         ino_t           st_ino;
153         mode_t          st_mode;
154         nlink_t         st_nlink;
155         uid_t           st_uid;
156         gid_t           st_gid;
157         dev_t           st_rdev;
158         off_t           st_size;
159         time_t          st_atime;
160         int             st_spare1;
161         time_t          st_mtime;
162         int             st_spare2;
163         time_t          st_ctime;
164         int             st_spare3;
165         long            st_blksize;
166         long            st_blocks;
167         unsigned long   st_gennum;
168         long            st_spare4;
169 };
170 extern  mode_t  umask();
171 extern  int
172         chmod(),
173         fstat(),
174         mkdir(),
175         mkfifo(),
176         stat();
177 struct gen_dir {
178                 unsigned long   gd_ino;    
179                 unsigned short  gd_reclen;  
180                 unsigned short  gd_namelen;  
181                 char    gd_name[255  + 1];  
182         };
183 typedef struct _dirdesc {
184         int     dd_fd;
185         long    dd_loc;
186         long    dd_size;
187         long    dd_bbase;
188         long    dd_entno;
189         long    dd_bsize;
190         char *  dd_buf;
191 } DIR;
192 extern  DIR *opendir();
193 extern  int closedir();
194 extern  struct  gen_dir  *readdir();
195 extern  long telldir();
196 extern  void seekdir();
197 typedef int jmp_buf[10 ];
198 typedef int sigjmp_buf[10 ];
199 extern void     longjmp( jmp_buf __env, int __val );
200 extern int      setjmp( jmp_buf __env );
201 extern int      sigsetjmp(sigjmp_buf __env, int __savemask);
202 extern void     siglongjmp(const sigjmp_buf __env, int __val);
203 extern char *optarg;
204 extern int optind;
205 extern int opterr;
206 struct option
207 {
208   const char *name;
209   int has_arg;
210   int *flag;
211   int val;
212 };
213 extern int getopt_loser  ();
214 extern int getopt_long (int argc, char *const *argv, const char *shortopts,
215                         const struct option *longopts, int *longind);
216 extern int getopt_long_only (int argc, char *const *argv,
217                              const char *shortopts,
218                              const struct option *longopts, int *longind);
219 extern int _getopt_internal (int argc, char *const *argv,
220                              const char *shortopts,
221                              const struct option *longopts, int *longind,
222                              int long_only);
223 extern int errno;
224 extern char *sys_errlist[];
225 extern char *version_string;
226 extern char *getpwd ();
227 typedef void * pointer_type;
228 typedef const void * const_pointer_type;
229 extern   void abort ();
230 extern int kill ();
231 extern int creat ();
232 extern void exit ();
233 extern pointer_type malloc ();
234 extern pointer_type realloc ();
235 extern void free ();
236 extern int read ();
237 extern int write ();
238 extern int close ();
239 extern int fflush ();
240 extern int atoi ();
241 extern int puts ();
242 extern int fputs ();
243 extern int fputc ();
244 extern int link ();
245 extern int unlink ();
246 extern int access ();
247 extern int execvp ();
248 extern int setjmp ();
249 extern void longjmp ();
250 extern char *   strcat ();
251 extern int      strcmp ();
252 extern char *   strcpy ();
253 extern int      strncmp ();
254 extern char *   strncpy ();
255 extern char *   rindex ();
256 static const char * const aux_info_suffix = ".X";
257 static const char * const save_suffix = ".save";
258 static const char syscalls_filename[] = "SYSCALLS.c";
259 static const char * const default_syscalls_dir = "/usr/local/lib" ;
260 static char * syscalls_absolute_filename;
261 struct unexpansion_struct {
262   const char *expanded;
263   const char *contracted;
264 };
265 typedef struct unexpansion_struct unexpansion;
266 static const unexpansion unexpansions[] = {
267   { "struct _iobuf", "FILE" },
268   { 0, 0 }
269 };
270 static const int hash_mask = (  (1 << 9)  - 1);
271 struct default_include { const char *fname; int cplusplus; } include_defaults[]
272   = {
273     { "not-needed", 1},
274     { "not-needed", 0},
275     { "/usr/local/include" , 0},
276     { "/usr/include" , 0},
277     { 0, 0}
278     };
279 struct string_list
280 {
281   char *name;
282   struct string_list *next;
283 };
284 struct string_list *directory_list;
285 struct string_list *exclude_list;
286 static const char * const other_var_style = "varargs";
287 static const char *varargs_style_indicator = "va_alist" ;
288 typedef struct hash_table_entry_struct hash_table_entry;
289 typedef struct def_dec_info_struct def_dec_info;
290 typedef struct file_info_struct file_info;
291 typedef struct f_list_chain_item_struct f_list_chain_item;
292 struct hash_table_entry_struct {
293   hash_table_entry *            hash_next;       
294   const char *                  symbol;          
295   union {
296     const def_dec_info *        _ddip;
297     file_info *                 _fip;
298   } _info;
299 };
300 typedef hash_table_entry hash_table[    (1 << 9) ];
301 struct file_info_struct {
302   const hash_table_entry *      hash_entry;  
303   const def_dec_info *          defs_decs;   
304   time_t                        mtime;       
305 };
306 struct f_list_chain_item_struct {
307   const f_list_chain_item *     chain_next;      
308   const char *                  formals_list;    
309 };
310 struct def_dec_info_struct {
311   const def_dec_info *  next_in_file;    
312   file_info *           file;            
313   int                   line;            
314   const char *          ansi_decl;       
315   hash_table_entry *    hash_entry;      
316   unsigned int          is_func_def;     
317   const def_dec_info *  next_for_func;   
318   unsigned int          f_list_count;    
319   char                  prototyped;      
320   const f_list_chain_item * f_list_chain;        
321   const def_dec_info *  definition;      
322   char                  is_static;       
323   char                  is_implicit;     
324   char                  written;         
325 };
326 static const char *pname;
327 static int errors = 0;
328 static const char *compiler_file_name = "gcc";
329 static int version_flag = 0;             
330 static int quiet_flag = 0;               
331 static int nochange_flag = 0;            
332 static int nosave_flag = 0;              
333 static int keep_flag = 0;                
334 static const char ** compile_params = 0;         
335 static int local_flag = 0;               
336 static int global_flag = 0;              
337 static int cplusplus_flag = 0;           
338 static const char* nondefault_syscalls_dir = 0;  
339 static int input_file_name_index = 0;
340 static int aux_info_file_name_index = 0;
341 static int n_base_source_files = 0;
342 static const char **base_source_filenames;
343 static int current_aux_info_lineno;
344 static const char *convert_filename;
345 static const char *invocation_filename;
346 static const char *orig_text_base;
347 static const char *orig_text_limit;
348 static const char *clean_text_base;
349 static const char *clean_text_limit;
350 static const char * clean_read_ptr;
351 static char *repl_text_base;
352 static char *repl_text_limit;
353 static char * repl_write_ptr;
354 static const char *last_known_line_start;
355 static int last_known_line_number;
356 static hash_table filename_primary;
357 static hash_table function_name_primary;
358 static jmp_buf source_confusion_recovery;
359 static char *cwd_buffer;
360 static const char * saved_clean_read_ptr;
361 static char * saved_repl_write_ptr;
362 static const char *shortpath ();
363 pointer_type
364 xmalloc (byte_count)
365      size_t byte_count;
366 {
367   pointer_type rv;
368   rv = malloc (byte_count);
369   if (rv == 0 )
370     {
371       fprintf ((&_iob[2]) , "\n%s: virtual memory exceeded\n", pname);
372       exit (1);
373       return 0;          
374     }
375   else
376     return rv;
377 }
378 pointer_type
379 xrealloc (old_space, byte_count)
380      pointer_type old_space;
381      size_t byte_count;
382 {
383   pointer_type rv;
384   rv = realloc (old_space, byte_count);
385   if (rv == 0 )
386     {
387       fprintf ((&_iob[2]) , "\n%s: virtual memory exceeded\n", pname);
388       exit (1);
389       return 0;          
390     }
391   else
392     return rv;
393 }
394 void
395 xfree (p)
396      const_pointer_type p;
397 {
398   if (p)
399     free ((  pointer_type) p);
400 }
401 static char *
402 savestring (input, size)
403      const char *input;
404      unsigned int size;
405 {
406   char *output = (char *) xmalloc (size + 1);
407   strcpy (output, input);
408   return output;
409 }
410 static char *
411 savestring2 (input1, size1, input2, size2)
412      const char *input1;
413      unsigned int size1;
414      const char *input2;
415      unsigned int size2;
416 {
417   char *output = (char *) xmalloc (size1 + size2 + 1);
418   strcpy (output, input1);
419   strcpy (&output[size1], input2);
420   return output;
421 }
422 void
423 fancy_abort ()
424 {
425   fprintf ((&_iob[2]) , "%s: internal abort\n", pname);
426   exit (1);
427 }
428 static char *
429 dupstr (s)
430      const char *s;
431 {
432   return strcpy ((char *) xmalloc (strlen (s) + 1), s);
433 }
434 static char *
435 dupnstr (s, n)
436      const char *s;
437      size_t n;
438 {
439   char *ret_val = strncpy ((char *) xmalloc (n + 1), s, n);
440   ret_val[n] = '\0';
441   return ret_val;
442 }
443 static const char *
444 substr (s1, s2)
445      const char *s1;
446      const char *const s2;
447 {
448   for (; *s1 ; s1++)
449     {
450       const char *p1;
451       const char *p2;
452       int c;
453       for (p1 = s1, p2 = s2; c = *p2; p1++, p2++)
454         if (*p1 != c)
455           goto outer;
456       return s1;
457 outer:
458       ;
459     }
460   return 0;
461 }
462 void
463 save_pointers ()
464 {
465   saved_clean_read_ptr = clean_read_ptr;
466   saved_repl_write_ptr = repl_write_ptr;
467 }
468 void
469 restore_pointers ()
470 {
471   clean_read_ptr = saved_clean_read_ptr;
472   repl_write_ptr = saved_repl_write_ptr;
473 }
474 static int
475 is_id_char (ch)
476      char ch;
477 {
478   return (((_pctype+1)[ch]&(0001        |0002   |0004   ))  || (ch == '_') || (ch == '$'));
479 }
480 static void
481 usage ()
482 {
483   fprintf ((&_iob[2]) , "%s: usage '%s [ -VqfnkNlgC ] [ -B <diname> ] [ filename ... ]'\n",
484            pname, pname);
485   exit (1);
486 }
487 static int
488 in_system_include_dir (path)
489      const char *path;
490 {
491   struct default_include *p;
492   if (path[0] != '/')
493     abort ();            
494   for (p = include_defaults; p->fname; p++)
495     if (!strncmp (path, p->fname, strlen (p->fname))
496         && path[strlen (p->fname)] == '/')
497       return 1;
498   return 0;
499 }
500 static int
501 is_syscalls_file (fi_p)
502      const file_info *fi_p;
503 {
504   char const *f = fi_p->hash_entry->symbol;
505   size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
506   return sysl <= fl  &&  strcmp (f + fl - sysl, syscalls_filename) == 0;
507 }
508 static int
509 needs_to_be_converted (file_p)
510      const file_info *file_p;
511 {
512   const def_dec_info *ddp;
513   if (is_syscalls_file (file_p))
514     return 0;
515   for (ddp = file_p->defs_decs; ddp; ddp = ddp->next_in_file)
516     if (
517       !ddp->prototyped
518       && (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
519       )
520           return -1;
521   return 0;
522 }
523 static int
524 directory_specified_p (name)
525      const char *name;
526 {
527   struct string_list *p;
528   for (p = directory_list; p; p = p->next)
529     if (!strncmp (name, p->name, strlen (p->name))
530         && name[strlen (p->name)] == '/')
531       {
532         const char *q = name + strlen (p->name) + 1;
533         while (*q)
534           if (*q++ == '/')
535             goto lose;
536         return 1;
537       lose: ;
538       }
539   return 0;
540 }
541 static int
542 file_excluded_p (name)
543      const char *name;
544 {
545   struct string_list *p;
546   int len = strlen (name);
547   for (p = exclude_list; p; p = p->next)
548     if (!strcmp (name + len - strlen (p->name), p->name)
549         && name[len - strlen (p->name) - 1] == '/')
550       return 1;
551   return 0;
552 }
553 static struct string_list *
554 string_list_cons (string, rest)
555      char *string;
556      struct string_list *rest;
557 {
558   struct string_list *temp
559     = (struct string_list *) xmalloc (sizeof (struct string_list));
560   temp->next = rest;
561   temp->name = string;
562   return temp;
563 }
564 static void
565 visit_each_hash_node (hash_tab_p, func)
566      const hash_table_entry *hash_tab_p;
567      void (*func)();
568 {
569   const hash_table_entry *primary;
570   for (primary = hash_tab_p; primary < &hash_tab_p[     (1 << 9) ]; primary++)
571     if (primary->symbol)
572       {
573         hash_table_entry *second;
574         (*func)(primary);
575         for (second = primary->hash_next; second; second = second->hash_next)
576           (*func) (second);
577       }
578 }
579 static hash_table_entry *
580 add_symbol (p, s)
581      hash_table_entry *p;
582      const char *s;
583 {
584   p->hash_next = 0 ;
585   p->symbol = dupstr (s);
586   p->_info._ddip  = 0 ;
587   p->_info._fip  = 0 ;
588   return p;
589 }
590 static hash_table_entry *
591 lookup (hash_tab_p, search_symbol)
592      hash_table_entry *hash_tab_p;
593      const char *search_symbol;
594 {
595   int hash_value = 0;
596   const char *search_symbol_char_p = search_symbol;
597   hash_table_entry *p;
598   while (*search_symbol_char_p)
599     hash_value += *search_symbol_char_p++;
600   hash_value &= hash_mask;
601   p = &hash_tab_p[hash_value];
602   if (! p->symbol)
603       return add_symbol (p, search_symbol);
604   if (!strcmp (p->symbol, search_symbol))
605     return p;
606   while (p->hash_next)
607     {
608       p = p->hash_next;
609       if (!strcmp (p->symbol, search_symbol))
610         return p;
611     }
612   p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
613   p = p->hash_next;
614   return add_symbol (p, search_symbol);
615 }
616 static void
617 free_def_dec (p)
618      def_dec_info *p;
619 {
620   xfree (p->ansi_decl);
621   {
622     const f_list_chain_item * curr;
623     const f_list_chain_item * next;
624     for (curr = p->f_list_chain; curr; curr = next)
625       {
626         next = curr->chain_next;
627         xfree (curr);
628       }
629   }
630   xfree (p);
631 }
632 static char *
633 unexpand_if_needed (aux_info_line)
634      const char *aux_info_line;
635 {
636   static char *line_buf = 0;
637   static int line_buf_size = 0;
638   const unexpansion* unexp_p;
639   int got_unexpanded = 0;
640   const char *s;
641   char *copy_p = line_buf;
642   if (line_buf == 0)
643     {
644       line_buf_size = 1024;
645       line_buf = (char *) xmalloc (line_buf_size);
646     }
647   copy_p = line_buf;
648   for (s = aux_info_line; *s != '\n'; )
649     {
650       for (unexp_p = unexpansions; unexp_p->expanded; unexp_p++)
651         {
652           const char *in_p = unexp_p->expanded;
653           size_t len = strlen (in_p);
654           if (*s == *in_p && !strncmp (s, in_p, len) && !is_id_char (s[len]))
655             {
656               int size = strlen (unexp_p->contracted);
657               got_unexpanded = 1;
658               if (copy_p + size - line_buf >= line_buf_size)
659                 {
660                   int offset = copy_p - line_buf;
661                   line_buf_size *= 2;
662                   line_buf_size += size;
663                   line_buf = (char *) xrealloc (line_buf, line_buf_size);
664                   copy_p = line_buf + offset;
665                 }
666               strcpy (copy_p, unexp_p->contracted);
667               copy_p += size;
668               s += len;
669               goto continue_outer;
670             }
671         }
672       if (copy_p - line_buf == line_buf_size)
673         {
674           int offset = copy_p - line_buf;
675           line_buf_size *= 2;
676           line_buf = (char *) xrealloc (line_buf, line_buf_size);
677           copy_p = line_buf + offset;
678         }
679       *copy_p++ = *s++;
680 continue_outer: ;
681     }
682   if (copy_p + 2 - line_buf >= line_buf_size)
683     {
684       int offset = copy_p - line_buf;
685       line_buf_size *= 2;
686       line_buf = (char *) xrealloc (line_buf, line_buf_size);
687       copy_p = line_buf + offset;
688     }
689   *copy_p++ = '\n';
690   *copy_p++ = '\0';
691   return (got_unexpanded ? dupstr (line_buf) : 0);
692 }
693 static char *
694 abspath (cwd, rel_filename)
695      const char *cwd;
696      const char *rel_filename;
697 {
698   const char *cwd2 = (cwd) ? cwd : cwd_buffer;
699   char *const abs_buffer
700     = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
701   char *endp = abs_buffer;
702   char *outp, *inp;
703   {
704     const char *src_p;
705     if (rel_filename[0] != '/')
706       {
707         src_p = cwd2;
708         while (*endp++ = *src_p++)
709           continue;
710         *(endp-1) = '/';                         
711       }
712     src_p = rel_filename;
713     while (*endp++ = *src_p++)
714       continue;
715   }
716   outp = inp = abs_buffer;
717   *outp++ = *inp++;              
718   for (;;)
719     {
720       if (!inp[0])
721         break;
722       else if (inp[0] == '/' && outp[-1] == '/')
723         {
724           inp++;
725           continue;
726         }
727       else if (inp[0] == '.' && outp[-1] == '/')
728         {
729           if (!inp[1])
730                   break;
731           else if (inp[1] == '/')
732             {
733                     inp += 2;
734                     continue;
735             }
736           else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
737             {
738                     inp += (inp[2] == '/') ? 3 : 2;
739                     outp -= 2;
740                     while (outp >= abs_buffer && *outp != '/')
741                 outp--;
742                     if (outp < abs_buffer)
743                 {
744                   fprintf ((&_iob[2]) , "%s: invalid file name: %s\n",
745                            pname, rel_filename);
746                   exit (1);
747                 }
748                     *++outp = '\0';
749                     continue;
750             }
751         }
752       *outp++ = *inp++;
753     }
754   *outp = '\0';
755   if (outp[-1] == '/')
756     *--outp  = '\0';
757   return dupstr (abs_buffer);
758 }
759 static const char *
760 shortpath (cwd, filename)
761      const char *cwd;
762      const char *filename;
763 {
764   char *rel_buffer;
765   char *rel_buf_p;
766   char *cwd_p = cwd_buffer;
767   char *path_p;
768   int unmatched_slash_count = 0;
769   size_t filename_len = strlen (filename);
770   path_p = abspath (cwd, filename);
771   rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
772   while (*cwd_p && (*cwd_p == *path_p))
773     {
774       cwd_p++;
775       path_p++;
776     }
777   if (!*cwd_p && (!*path_p || *path_p == '/'))   
778     {
779       if (!*path_p)              
780         return ".";
781       else
782         return ++path_p;
783     }
784   else
785     {
786       if (*path_p)
787         {
788           --cwd_p;
789           --path_p;
790           while (*cwd_p != '/')          
791             {
792               --cwd_p;
793               --path_p;
794             }
795           cwd_p++;
796           path_p++;
797           unmatched_slash_count++;
798         }
799       while (*cwd_p)
800         if (*cwd_p++ == '/')
801           unmatched_slash_count++;
802       if (unmatched_slash_count * 3 + strlen (path_p) >= filename_len)
803         return filename;
804       while (unmatched_slash_count--)
805         {
806           if (rel_buffer + filename_len <= rel_buf_p + 3)
807             return filename;
808           *rel_buf_p++ = '.';
809           *rel_buf_p++ = '/';
810         }
811       do
812         {
813           if (rel_buffer + filename_len <= rel_buf_p)
814             return filename;
815         }
816       while (*rel_buf_p++ = *path_p++);
817       --rel_buf_p;
818       if (*(rel_buf_p-1) == '/')
819         *--rel_buf_p = '\0';
820       return rel_buffer;
821     }
822 }
823 static file_info *
824 find_file (filename, do_not_stat)
825      char *filename;
826      int do_not_stat;
827 {
828   hash_table_entry *hash_entry_p;
829   hash_entry_p = lookup (filename_primary, filename);
830   if (hash_entry_p->_info._fip )
831     return hash_entry_p->_info._fip ;
832   else
833     {
834       struct stat stat_buf;
835       file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
836       if (do_not_stat)
837         stat_buf.st_mtime = (time_t) 0;
838       else
839         {
840           if (stat((char *)filename,  &stat_buf)  == -1)
841             {
842               fprintf ((&_iob[2]) , "%s: %s: can't get status: %s\n",
843                        pname, shortpath (0 , filename), sys_errlist[errno]);
844               stat_buf.st_mtime = (time_t) -1;
845             }
846         }
847       hash_entry_p->_info._fip  = file_p;
848       file_p->hash_entry = hash_entry_p;
849       file_p->defs_decs = 0 ;
850       file_p->mtime = stat_buf.st_mtime;
851       return file_p;
852     }
853 }
854 static void
855 aux_info_corrupted ()
856 {
857   fprintf ((&_iob[2]) , "\n%s: fatal error: aux info file corrupted at line %d\n",
858            pname, current_aux_info_lineno);
859   exit (1);
860 }
861 static void
862 check_aux_info (cond)
863      int cond;
864 {
865   if (! cond)
866     aux_info_corrupted ();
867 }
868 static const char *
869 find_corresponding_lparen (p)
870      const char *p;
871 {
872   const char *q;
873   int paren_depth;
874   for (paren_depth = 1, q = p-1; paren_depth; q--)
875     {
876       switch (*q)
877         {
878           case ')':
879             paren_depth++;
880             break;
881           case '(':
882             paren_depth--;
883             break;
884         }
885     }
886   return ++q;
887 }
888 static int
889 referenced_file_is_newer (l, aux_info_mtime)
890      const char *l;
891      time_t aux_info_mtime;
892 {
893   const char *p;
894   file_info *fi_p;
895   char *filename;
896   check_aux_info (l[0] == '/');
897   check_aux_info (l[1] == '*');
898   check_aux_info (l[2] == ' ');
899   {
900     const char *filename_start = p = l + 3;
901     while (*p != ':')
902       p++;
903     filename = (char *) alloca ((size_t) (p - filename_start) + 1);
904     strncpy (filename, filename_start, (size_t) (p - filename_start));
905     filename[p-filename_start] = '\0';
906   }
907   fi_p = find_file (abspath (invocation_filename, filename), 0);
908   return (fi_p->mtime > aux_info_mtime);
909 }
910 static void
911 save_def_or_dec (l, is_syscalls)
912      const char *l;
913      int is_syscalls;
914 {
915   const char *p;
916   const char *semicolon_p;
917   def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
918   def_dec_p->written = 0;
919   check_aux_info (l[0] == '/');
920   check_aux_info (l[1] == '*');
921   check_aux_info (l[2] == ' ');
922   {
923     const char *filename_start = p = l + 3;
924     char *filename;
925     while (*p != ':')
926       p++;
927     filename = (char *) alloca ((size_t) (p - filename_start) + 1);
928     strncpy (filename, filename_start, (size_t) (p - filename_start));
929     filename[p-filename_start] = '\0';
930     def_dec_p->file = find_file (abspath (invocation_filename, filename), is_syscalls);
931   }
932   {
933     const char *line_number_start = ++p;
934     char line_number[10];
935     while (*p != ':')
936       p++;
937     strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
938     line_number[p-line_number_start] = '\0';
939     def_dec_p->line = atoi (line_number);
940   }
941   p++;   
942   check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
943   def_dec_p->prototyped = (*p == 'N');
944   def_dec_p->is_implicit = (*p == 'I');
945   p++;
946   check_aux_info ((*p == 'C') || (*p == 'F'));
947   def_dec_p->is_func_def = ((*p++ == 'F') || is_syscalls);
948   def_dec_p->definition = 0;     
949   check_aux_info (*p++ == ' ');
950   check_aux_info (*p++ == '*');
951   check_aux_info (*p++ == '/');
952   check_aux_info (*p++ == ' ');
953   if (!strncmp (p, "static", 6))
954     def_dec_p->is_static = -1;
955   else if (!strncmp (p, "extern", 6))
956     def_dec_p->is_static = 0;
957   else
958     check_aux_info (0);  
959   {
960     const char *ansi_start = p;
961     p += 6;      
962     while (*++p != ';')
963       continue;
964     semicolon_p = p;
965     def_dec_p->ansi_decl
966       = dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
967   }
968   p--;
969   def_dec_p->f_list_count = 0;
970   def_dec_p->f_list_chain = 0 ;
971   for (;;)
972     {
973       const char *left_paren_p = find_corresponding_lparen (p);
974       {
975         f_list_chain_item *cip =
976           (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
977         cip->formals_list
978           = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
979         cip->chain_next = def_dec_p->f_list_chain;
980         def_dec_p->f_list_chain = cip;
981       }
982       def_dec_p->f_list_count++;
983       p = left_paren_p - 2;
984       if (*p != ')')
985         break;
986       else
987         check_aux_info (*--p == ')');
988     }
989   {
990     const char *past_fn = p + 1;
991     check_aux_info (*past_fn == ' ');
992     while (is_id_char (*p))
993       p--;
994     p++;
995     {
996       char *fn_string = (char *) alloca (past_fn - p + 1);
997       strncpy (fn_string, p, (size_t) (past_fn - p));
998       fn_string[past_fn-p] = '\0';
999       def_dec_p->hash_entry = lookup (function_name_primary, fn_string);
1000     }
1001   }
1002   {
1003     const def_dec_info *other;
1004     for (other = def_dec_p->hash_entry->_info._ddip ; other; other = other->next_for_func)
1005       {
1006         if (def_dec_p->line == other->line && def_dec_p->file == other->file)
1007           {
1008             if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
1009               {
1010                 fprintf ((&_iob[2]) , "%s:%d: declaration of function `%s' takes different forms\n",
1011                          def_dec_p->file->hash_entry->symbol,
1012                          def_dec_p->line,
1013                          def_dec_p->hash_entry->symbol);
1014                 exit (1);
1015               }
1016             free_def_dec (def_dec_p);
1017             return;
1018           }
1019       }
1020   }
1021   def_dec_p->next_for_func = def_dec_p->hash_entry->_info._ddip ;
1022   def_dec_p->hash_entry->_info._ddip  = def_dec_p;
1023   if (!def_dec_p->file->defs_decs)
1024     {
1025       def_dec_p->file->defs_decs = def_dec_p;
1026       def_dec_p->next_in_file = 0 ;
1027     }
1028   else
1029     {
1030       int line = def_dec_p->line;
1031       const def_dec_info *prev = 0 ;
1032       const def_dec_info *curr = def_dec_p->file->defs_decs;
1033       const def_dec_info *next = curr->next_in_file;
1034       while (next && (line < curr->line))
1035         {
1036           prev = curr;
1037           curr = next;
1038           next = next->next_in_file;
1039         }
1040       if (line >= curr->line)
1041         {
1042           def_dec_p->next_in_file = curr;
1043           if (prev)
1044             ((  def_dec_info *) prev)->next_in_file = def_dec_p;
1045           else
1046             def_dec_p->file->defs_decs = def_dec_p;
1047         }
1048       else       
1049         {
1050           ((  def_dec_info *) curr)->next_in_file = def_dec_p;
1051           def_dec_p->next_in_file = next;
1052         }
1053     }
1054 }
1055 static void
1056 munge_compile_params (params_list)
1057      const char *params_list;
1058 {
1059   const char **temp_params
1060     = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
1061   int param_count = 0;
1062   const char *param;
1063   temp_params[param_count++] = compiler_file_name;
1064   for (;;)
1065     {
1066       while (((_pctype+1)[*params_list]&0010    ) )
1067         params_list++;
1068       if (!*params_list)
1069         break;
1070       param = params_list;
1071       while (*params_list && !((_pctype+1)[*params_list]&0010   ) )
1072         params_list++;
1073       if (param[0] != '-')
1074         temp_params[param_count++]
1075           = dupnstr (param, (size_t) (params_list - param));
1076       else
1077         {
1078           switch (param[1])
1079             {
1080               case 'g':
1081               case 'O':
1082               case 'S':
1083               case 'c':
1084                 break;           
1085               case 'o':
1086                 while (((_pctype+1)[*params_list]&0010  ) )
1087                   params_list++;
1088                 while (*params_list && !((_pctype+1)[*params_list]&0010 ) )
1089                   params_list++;
1090                 break;
1091               default:
1092                 temp_params[param_count++]
1093                   = dupnstr (param, (size_t) (params_list - param));
1094             }
1095         }
1096       if (!*params_list)
1097         break;
1098     }
1099   temp_params[param_count++] = "-aux-info";
1100   aux_info_file_name_index = param_count;
1101   temp_params[param_count++] = 0 ;
1102   temp_params[param_count++] = "-S";
1103   temp_params[param_count++] = "-o";
1104   temp_params[param_count++] = "/dev/null";
1105   input_file_name_index = param_count;
1106   temp_params[param_count++] = 0 ;
1107   temp_params[param_count++] = 0 ;
1108   compile_params
1109     = (const char **) xmalloc (sizeof (char *) * (param_count+1));
1110   memcpy (compile_params, temp_params, sizeof (char *) * param_count);
1111 }
1112 static int
1113 gen_aux_info_file (base_filename)
1114      const char *base_filename;
1115 {
1116   int child_pid;
1117   if (!input_file_name_index)
1118     munge_compile_params ("");
1119   compile_params[input_file_name_index] = shortpath (0 , base_filename);
1120   compile_params[aux_info_file_name_index]
1121     = savestring2 (compile_params[input_file_name_index],
1122                    strlen (compile_params[input_file_name_index]),
1123                    ".X",
1124                    2);
1125   if (!quiet_flag)
1126     fprintf ((&_iob[2]) , "%s: compiling `%s'\n",
1127              pname, compile_params[input_file_name_index]);
1128   if (child_pid = vfork  ())
1129     {
1130       if (child_pid == -1)
1131         {
1132           fprintf ((&_iob[2]) , "%s: could not fork process: %s\n",
1133                    pname, sys_errlist[errno]);
1134           return 0;
1135         }
1136       {
1137         int wait_status;
1138         if (wait (&wait_status) == -1)
1139           {
1140             fprintf ((&_iob[2]) , "%s: wait failed: %s\n",
1141                      pname, sys_errlist[errno]);
1142             return 0;
1143           }
1144         if ((wait_status & 0x7F) != 0)
1145           {
1146             fprintf ((&_iob[2]) , "%s: subprocess got fatal signal %d",
1147                      pname, (wait_status & 0x7F));
1148             return 0;
1149           }
1150         if (((wait_status & 0xFF00) >> 8) != 0)
1151           {
1152             fprintf ((&_iob[2]) , "%s: %s exited with status %d\n",
1153                      pname, base_filename, ((wait_status & 0xFF00) >> 8));
1154             return 0;
1155           }
1156         return 1;
1157       }
1158     }
1159   else
1160     {
1161       if (execvp((char *)compile_params[0], (char **) (char *const *) compile_params) )
1162         {
1163           int e = errno, f = ((int)(((&_iob[2]) )->_file)) ;
1164           write (f, pname, strlen (pname));
1165           write (f, ": ", 2);
1166           write (f, compile_params[0], strlen (compile_params[0]));
1167           write (f, ": ", 2);
1168           write (f, sys_errlist[e], strlen (sys_errlist[e]));
1169           write (f, "\n", 1);
1170           _exit (1);
1171         }
1172       return 1;          
1173     }
1174 }
1175 static void
1176 process_aux_info_file (base_source_filename, keep_it, is_syscalls)
1177      const char *base_source_filename;
1178      int keep_it;
1179      int is_syscalls;
1180 {
1181   size_t base_len = strlen (base_source_filename);
1182   char * aux_info_filename
1183     = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
1184   char *aux_info_base;
1185   char *aux_info_limit;
1186   char *aux_info_relocated_name;
1187   const char *aux_info_second_line;
1188   time_t aux_info_mtime;
1189   size_t aux_info_size;
1190   int must_create;
1191   strcpy (aux_info_filename, base_source_filename);
1192   strcat (aux_info_filename, aux_info_suffix);
1193   must_create = 0;
1194 start_over: ;
1195   if (access((char *)aux_info_filename,     4       )  == -1)
1196     {
1197       if (errno ==      2               )
1198         {
1199           if (is_syscalls)
1200             {
1201               fprintf ((&_iob[2]) , "%s: warning: missing SYSCALLS file `%s'\n",
1202                        pname, aux_info_filename);
1203               return;
1204             }
1205           must_create = 1;
1206         }
1207       else
1208         {
1209           fprintf ((&_iob[2]) , "%s: can't read aux info file `%s': %s\n",
1210                    pname, shortpath (0 , aux_info_filename),
1211                    sys_errlist[errno]);
1212           errors++;
1213           return;
1214         }
1215     }
1216   if (must_create)
1217     {
1218       if (!gen_aux_info_file (base_source_filename))
1219         {
1220           errors++;
1221           return;
1222         }
1223       if (access((char *)aux_info_filename,     4       )  == -1)
1224         {
1225           fprintf ((&_iob[2]) , "%s: can't read aux info file `%s': %s\n",
1226                    pname, shortpath (0 , aux_info_filename),
1227                    sys_errlist[errno]);
1228           errors++;
1229           return;
1230         }
1231     }
1232   {
1233     struct stat stat_buf;
1234     if (stat((char *)aux_info_filename,  &stat_buf)  == -1)
1235       {
1236         fprintf ((&_iob[2]) , "%s: can't get status of aux info file `%s': %s\n",
1237                  pname, shortpath (0 , aux_info_filename),
1238                  sys_errlist[errno]);
1239         errors++;
1240         return;
1241       }
1242     if ((aux_info_size = stat_buf.st_size) == 0)
1243       return;
1244     aux_info_mtime = stat_buf.st_mtime;
1245     if (!is_syscalls)
1246       {
1247         if (stat((char *)base_source_filename,  &stat_buf)  == -1)
1248           {
1249             fprintf ((&_iob[2]) , "%s: can't get status of aux info file `%s': %s\n",
1250                      pname, shortpath (0 , base_source_filename),
1251                      sys_errlist[errno]);
1252             errors++;
1253             return;
1254           }
1255         if (stat_buf.st_mtime > aux_info_mtime)
1256           {
1257             must_create = 1;
1258             goto start_over;
1259           }
1260       }
1261   }
1262   {
1263     int aux_info_file;
1264     if ((aux_info_file = open((char *)aux_info_filename,         0 ,  0444 ) ) == -1)
1265       {
1266         fprintf ((&_iob[2]) , "%s: can't open aux info file `%s' for reading: %s\n",
1267                  pname, shortpath (0 , aux_info_filename),
1268                  sys_errlist[errno]);
1269         return;
1270       }
1271     aux_info_base = xmalloc (aux_info_size + 1);
1272     aux_info_limit = aux_info_base + aux_info_size;
1273     *aux_info_limit = '\0';
1274     if (read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
1275       {
1276         fprintf ((&_iob[2]) , "%s: error reading aux info file `%s': %s\n",
1277                  pname, shortpath (0 , aux_info_filename),
1278                  sys_errlist[errno]);
1279         free (aux_info_base);
1280         close (aux_info_file);
1281         return;
1282       }
1283     if (close (aux_info_file))
1284       {
1285         fprintf ((&_iob[2]) , "%s: error closing aux info file `%s': %s\n",
1286                  pname, shortpath (0 , aux_info_filename),
1287                  sys_errlist[errno]);
1288         free (aux_info_base);
1289         close (aux_info_file);
1290         return;
1291       }
1292   }
1293   if (must_create && !keep_it)
1294     if (        unlink((char *)aux_info_filename)  == -1)
1295       fprintf ((&_iob[2]) , "%s: can't delete aux info file `%s': %s\n",
1296                pname, shortpath (0 , aux_info_filename),
1297                sys_errlist[errno]);
1298   {
1299     char *p = aux_info_base;
1300     while (*p != ':')
1301       p++;
1302     p++;
1303     while (*p == ' ')
1304       p++;
1305     invocation_filename = p;     
1306     while (*p != ' ')
1307       p++;
1308     *p++ = '/';
1309     *p++ = '\0';
1310     while (*p++ != '\n')
1311       continue;
1312     aux_info_second_line = p;
1313     aux_info_relocated_name = 0;
1314     if (invocation_filename[0] != '/')
1315       {
1316         char *dir_end;
1317         aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
1318         strcpy (aux_info_relocated_name, base_source_filename);
1319         dir_end = rindex (aux_info_relocated_name, '/');
1320         if (dir_end)
1321           dir_end++;
1322         else
1323           dir_end = aux_info_relocated_name;
1324         strcpy (dir_end, invocation_filename);
1325         invocation_filename = aux_info_relocated_name;
1326       }
1327   }
1328   {
1329     const char *aux_info_p;
1330     if (!is_syscalls)
1331       {
1332         current_aux_info_lineno = 2;
1333         for (aux_info_p = aux_info_second_line; *aux_info_p; )
1334           {
1335             if (referenced_file_is_newer (aux_info_p, aux_info_mtime))
1336               {
1337                 free (aux_info_base);
1338                 xfree (aux_info_relocated_name);
1339                 if (keep_it &&  unlink((char *)aux_info_filename)  == -1)
1340                   {
1341                     fprintf ((&_iob[2]) , "%s: can't delete file `%s': %s\n",
1342                              pname, shortpath (0 , aux_info_filename),
1343                              sys_errlist[errno]);
1344                     return;
1345                   }
1346                 goto start_over;
1347               }
1348             while (*aux_info_p != '\n')
1349               aux_info_p++;
1350             aux_info_p++;
1351             current_aux_info_lineno++;
1352           }
1353       }
1354     current_aux_info_lineno = 2;
1355     for (aux_info_p = aux_info_second_line; *aux_info_p;)
1356       {
1357         char *unexpanded_line = unexpand_if_needed (aux_info_p);
1358         if (unexpanded_line)
1359           {
1360             save_def_or_dec (unexpanded_line, is_syscalls);
1361             free (unexpanded_line);
1362           }
1363         else
1364           save_def_or_dec (aux_info_p, is_syscalls);
1365         while (*aux_info_p != '\n')
1366           aux_info_p++;
1367         aux_info_p++;
1368         current_aux_info_lineno++;
1369       }
1370   }
1371   free (aux_info_base);
1372   xfree (aux_info_relocated_name);
1373 }
1374 static void
1375 rename_c_file (hp)
1376      const hash_table_entry *hp;
1377 {
1378   const char *filename = hp->symbol;
1379   int last_char_index = strlen (filename) - 1;
1380   char *const new_filename = (char *) alloca (strlen (filename) + 1);
1381   if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.')
1382     return;
1383   strcpy (new_filename, filename);
1384   new_filename[last_char_index] = 'C';
1385   if (link((char *)filename, (char *) new_filename)  == -1)
1386     {
1387       fprintf ((&_iob[2]) , "%s: warning: can't link file `%s' to `%s': %s\n",
1388                pname, shortpath (0 , filename),
1389                shortpath (0 , new_filename), sys_errlist[errno]);
1390       errors++;
1391       return;
1392     }
1393   if (  unlink((char *)filename)  == -1)
1394     {
1395       fprintf ((&_iob[2]) , "%s: warning: can't delete file `%s': %s\n",
1396                pname, shortpath (0 , filename), sys_errlist[errno]);
1397       errors++;
1398       return;
1399     }
1400 }
1401 static void
1402 reverse_def_dec_list (hp)
1403      const hash_table_entry *hp;
1404 {
1405   file_info *file_p = hp->_info._fip ;
1406   const def_dec_info *prev = 0 ;
1407   const def_dec_info *current = file_p->defs_decs;
1408   if (!( current = file_p->defs_decs))
1409     return;                      
1410   prev = current;
1411   if (! (current = current->next_in_file))
1412     return;                      
1413   ((  def_dec_info *) prev)->next_in_file = 0 ;
1414   while (current)
1415     {
1416       const def_dec_info *next = current->next_in_file;
1417       ((  def_dec_info *) current)->next_in_file = prev;
1418       prev = current;
1419       current = next;
1420     }
1421   file_p->defs_decs = prev;
1422 }
1423 static const def_dec_info *
1424 find_extern_def (head, user)
1425      const def_dec_info *head;
1426      const def_dec_info *user;
1427 {
1428   const def_dec_info *dd_p;
1429   const def_dec_info *extern_def_p = 0 ;
1430   int conflict_noted = 0;
1431   for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
1432     if (dd_p->is_func_def && !dd_p->is_static && dd_p->file == user->file)
1433       return dd_p;
1434   for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
1435     if (dd_p->is_func_def && !dd_p->is_static)
1436       {
1437         if (!extern_def_p)       
1438           extern_def_p = dd_p;   
1439         else
1440           {
1441             if (is_syscalls_file (dd_p->file))
1442               continue;
1443             if (is_syscalls_file (extern_def_p->file))
1444               {
1445                 extern_def_p = dd_p;
1446                 continue;
1447               }
1448             if (!conflict_noted)         
1449               {
1450                 conflict_noted = 1;
1451                 fprintf ((&_iob[2]) , "%s: conflicting extern definitions of '%s'\n",
1452                          pname, head->hash_entry->symbol);
1453                 if (!quiet_flag)
1454                   {
1455                     fprintf ((&_iob[2]) , "%s: declarations of '%s' will not be converted\n",
1456                              pname, head->hash_entry->symbol);
1457                     fprintf ((&_iob[2]) , "%s: conflict list for '%s' follows:\n",
1458                              pname, head->hash_entry->symbol);
1459                     fprintf ((&_iob[2]) , "%s:     %s(%d): %s\n",
1460                              pname,
1461                              shortpath (0 , extern_def_p->file->hash_entry->symbol),
1462                              extern_def_p->line, extern_def_p->ansi_decl);
1463                   }
1464               }
1465             if (!quiet_flag)
1466               fprintf ((&_iob[2]) , "%s:     %s(%d): %s\n",
1467                        pname,
1468                        shortpath (0 , dd_p->file->hash_entry->symbol),
1469                        dd_p->line, dd_p->ansi_decl);
1470           }
1471       }
1472   if (conflict_noted)
1473     return 0 ;
1474   if (!extern_def_p)
1475     {
1476       for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
1477         if (!dd_p->is_func_def && !dd_p->is_static && dd_p->prototyped)
1478           {
1479             extern_def_p = dd_p;         
1480             if (!quiet_flag)
1481               fprintf ((&_iob[2]) , "%s: warning: using formals list from %s(%d) for function `%s'\n",
1482                        pname,
1483                        shortpath (0 , dd_p->file->hash_entry->symbol),
1484                        dd_p->line, dd_p->hash_entry->symbol);
1485             break;
1486           }
1487       if (!extern_def_p)
1488         {
1489           const char *file = user->file->hash_entry->symbol;
1490           if (!quiet_flag)
1491             if (in_system_include_dir (file))
1492               {
1493                 char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
1494                 char *p;
1495                 strcpy (needed, user->ansi_decl);
1496                 p = (  char *) substr (needed, user->hash_entry->symbol)
1497                     + strlen (user->hash_entry->symbol) + 2;
1498                 *p++ = '?';
1499                 strcpy (p, ");");
1500                 fprintf ((&_iob[2]) , "%s: %d: `%s' used but missing from SYSCALLS\n",
1501                          shortpath (0 , file), user->line,
1502                          needed+7);      
1503               }
1504         }
1505     }
1506   return extern_def_p;
1507 }
1508 static const def_dec_info *
1509 find_static_definition (user)
1510      const def_dec_info *user;
1511 {
1512   const def_dec_info *head = user->hash_entry->_info._ddip ;
1513   const def_dec_info *dd_p;
1514   int num_static_defs = 0;
1515   const def_dec_info *static_def_p = 0 ;
1516   for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
1517     if (dd_p->is_func_def && dd_p->is_static && (dd_p->file == user->file))
1518       {
1519         static_def_p = dd_p;     
1520         num_static_defs++;
1521       }
1522   if (num_static_defs == 0)
1523     {
1524       if (!quiet_flag)
1525         fprintf ((&_iob[2]) , "%s: warning: no static definition for `%s' in file `%s'\n",
1526                  pname, head->hash_entry->symbol,
1527                  shortpath (0 , user->file->hash_entry->symbol));
1528     }
1529   else if (num_static_defs > 1)
1530     {
1531       fprintf ((&_iob[2]) , "%s: multiple static defs of `%s' in file `%s'\n",
1532                pname, head->hash_entry->symbol,
1533                shortpath (0 , user->file->hash_entry->symbol));
1534       return 0 ;
1535     }
1536   return static_def_p;
1537 }
1538 static void
1539 connect_defs_and_decs (hp)
1540      const hash_table_entry *hp;
1541 {
1542   const def_dec_info *dd_p;
1543   const def_dec_info *extern_def_p = 0 ;
1544   int first_extern_reference = 1;
1545   for (dd_p = hp->_info._ddip ; dd_p; dd_p = dd_p->next_for_func)
1546     if (dd_p->prototyped)
1547       ((  def_dec_info *) dd_p)->definition = dd_p;
1548   for (dd_p = hp->_info._ddip ; dd_p; dd_p = dd_p->next_for_func)
1549     if (!dd_p->is_func_def && !dd_p->is_static && !dd_p->definition)
1550       {
1551         if (first_extern_reference)
1552           {
1553             extern_def_p = find_extern_def (hp->_info._ddip , dd_p);
1554             first_extern_reference = 0;
1555           }
1556         ((  def_dec_info *) dd_p)->definition = extern_def_p;
1557       }
1558   for (dd_p = hp->_info._ddip ; dd_p; dd_p = dd_p->next_for_func)
1559     if (!dd_p->is_func_def && dd_p->is_static && !dd_p->definition)
1560       {
1561         const def_dec_info *dd_p2;
1562         const def_dec_info *static_def;
1563       ((  def_dec_info *) dd_p)->definition =
1564         (static_def = find_static_definition (dd_p))
1565           ? static_def
1566           : (const def_dec_info *) -1;
1567       for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
1568         if (!dd_p2->is_func_def && dd_p2->is_static
1569          && !dd_p2->definition && (dd_p2->file == dd_p->file))
1570           ((  def_dec_info *)dd_p2)->definition = dd_p->definition;
1571       }
1572   for (dd_p = hp->_info._ddip ; dd_p; dd_p = dd_p->next_for_func)
1573     if (dd_p->definition == (def_dec_info *) -1)
1574       ((  def_dec_info *) dd_p)->definition = 0 ;
1575 }
1576 static int
1577 identify_lineno (clean_p)
1578      const char *clean_p;
1579 {
1580   int line_num = 1;
1581   const char *scan_p;
1582   for (scan_p = clean_text_base; scan_p <= clean_p; scan_p++)
1583     if (*scan_p == '\n')
1584       line_num++;
1585   return line_num;
1586 }
1587 static void
1588 declare_source_confusing (clean_p)
1589      const char *clean_p;
1590 {
1591   if (!quiet_flag)
1592     {
1593       if (clean_p == 0)
1594         fprintf ((&_iob[2]) , "%s: %d: warning: source too confusing\n",
1595                  shortpath (0 , convert_filename), last_known_line_number);
1596       else
1597         fprintf ((&_iob[2]) , "%s: %d: warning: source too confusing\n",
1598                  shortpath (0 , convert_filename),
1599                  identify_lineno (clean_p));
1600     }
1601   longjmp (source_confusion_recovery, 1);
1602 }
1603 static void
1604 check_source (cond, clean_p)
1605      int cond;
1606      const char *clean_p;
1607 {
1608   if (!cond)
1609     declare_source_confusing (clean_p);
1610 }
1611 static const char *
1612 seek_to_line (n)
1613      int n;
1614 {
1615   if (n < last_known_line_number)
1616     abort ();
1617   while (n > last_known_line_number)
1618     {
1619       while (*last_known_line_start != '\n')
1620         check_source (++last_known_line_start < clean_text_limit, 0);
1621       last_known_line_start++;
1622       last_known_line_number++;
1623     }
1624   return last_known_line_start;
1625 }
1626 static const char *
1627 forward_to_next_token_char (ptr)
1628      const char *ptr;
1629 {
1630   for (++ptr; ((_pctype+1)[*ptr]&0010   ) ; check_source (++ptr < clean_text_limit, 0))
1631     continue;
1632   return ptr;
1633 }
1634 static void
1635 output_bytes (str, len)
1636      const char *str;
1637      size_t len;
1638 {
1639   if ((repl_write_ptr + 1) + len >= repl_text_limit)
1640     {
1641       size_t new_size = (repl_text_limit - repl_text_base) << 1;
1642       char *new_buf = (char *) xrealloc (repl_text_base, new_size);
1643       repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
1644       repl_text_base = new_buf;
1645       repl_text_limit = new_buf + new_size;
1646     }
1647   memcpy (repl_write_ptr + 1, str, len);
1648   repl_write_ptr += len;
1649 }
1650 static void
1651 output_string (str)
1652      const char *str;
1653 {
1654   output_bytes (str, strlen (str));
1655 }
1656 static void
1657 output_up_to (p)
1658      const char *p;
1659 {
1660   size_t copy_length = (size_t) (p - clean_read_ptr);
1661   const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
1662   if (copy_length == 0)
1663     return;
1664   output_bytes (copy_start, copy_length);
1665   clean_read_ptr = p;
1666 }
1667 static int
1668 other_variable_style_function (ansi_header)
1669      const char *ansi_header;
1670 {
1671   const char *p;
1672   int len = strlen (varargs_style_indicator);
1673   for (p = ansi_header; p; )
1674     {
1675       const char *candidate;
1676       if ((candidate = substr (p, varargs_style_indicator)) == 0)
1677         return 0;
1678       else
1679         if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
1680           return 1;
1681         else
1682           p = candidate + 1;
1683     }
1684   return 0;
1685 }
1686 static void
1687 edit_fn_declaration (def_dec_p, clean_text_p)
1688      const def_dec_info *def_dec_p;
1689      const char *volatile clean_text_p;
1690 {
1691   const char *start_formals;
1692   const char *end_formals;
1693   const char *function_to_edit = def_dec_p->hash_entry->symbol;
1694   size_t func_name_len = strlen (function_to_edit);
1695   const char *end_of_fn_name;
1696   const f_list_chain_item *this_f_list_chain_item;
1697   const def_dec_info *definition = def_dec_p->definition;
1698   if (!definition)
1699     return;
1700   if (other_variable_style_function (definition->ansi_decl))
1701     {
1702       if (!quiet_flag)
1703         fprintf ((&_iob[2]) , "%s: %d: warning: varargs function declaration not converted\n",
1704                  shortpath (0 , def_dec_p->file->hash_entry->symbol),
1705                  def_dec_p->line);
1706       return;
1707     }
1708   save_pointers ();
1709   if (setjmp (source_confusion_recovery))
1710     {
1711       restore_pointers ();
1712       fprintf ((&_iob[2]) , "%s: declaration of function `%s' not converted\n",
1713                pname, function_to_edit);
1714       return;
1715     }
1716   while (*clean_text_p != '\n')
1717     check_source (++clean_text_p < clean_text_limit, 0);
1718   clean_text_p--;   
1719   do
1720     {
1721       for (;;)
1722         {
1723           while (!is_id_char (*clean_text_p))
1724             check_source (--clean_text_p > clean_read_ptr, 0);
1725           while (is_id_char (*clean_text_p))
1726             check_source (--clean_text_p > clean_read_ptr, 0);
1727           if (!strncmp (clean_text_p+1, function_to_edit, func_name_len))
1728             {
1729               char ch = *(clean_text_p + 1 + func_name_len);
1730               if (! is_id_char (ch))
1731                 break;                   
1732             }
1733         }
1734       end_of_fn_name = clean_text_p + strlen (def_dec_p->hash_entry->symbol);
1735       start_formals = forward_to_next_token_char (end_of_fn_name);
1736     }
1737   while (*start_formals != '(');
1738   this_f_list_chain_item = definition->f_list_chain;
1739   for (;;)
1740     {
1741       {
1742         int depth;
1743         end_formals = start_formals + 1;
1744         depth = 1;
1745         for (; depth; check_source (++end_formals < clean_text_limit, 0))
1746           {
1747             switch (*end_formals)
1748               {
1749                 case '(':
1750                   depth++;
1751                   break;
1752                 case ')':
1753                   depth--;
1754                   break;
1755               }
1756           }
1757         end_formals--;
1758       }
1759       output_up_to (start_formals);
1760       if (this_f_list_chain_item)
1761         {
1762           output_string (this_f_list_chain_item->formals_list);
1763           this_f_list_chain_item = this_f_list_chain_item->chain_next;
1764         }
1765       else
1766         {
1767           if (!quiet_flag)
1768             fprintf ((&_iob[2]) , "%s: warning: too many parameter lists in declaration of `%s'\n",
1769                      pname, def_dec_p->hash_entry->symbol);
1770           check_source (0, end_formals);   
1771         }
1772       clean_read_ptr = end_formals - 1;
1773       {
1774         const char *another_r_paren = forward_to_next_token_char (end_formals);
1775         if ((*another_r_paren != ')')
1776             || (*(start_formals = forward_to_next_token_char (another_r_paren)) != '('))
1777           {
1778             if (this_f_list_chain_item)
1779               {
1780                 if (!quiet_flag)
1781                   fprintf ((&_iob[2]) , "\n%s: warning: too few parameter lists in declaration of `%s'\n",
1782                            pname, def_dec_p->hash_entry->symbol);
1783                 check_source (0, start_formals);  
1784               }
1785             break;
1786           }
1787       }
1788     }
1789 }
1790 static int
1791 edit_formals_lists (end_formals, f_list_count, def_dec_p)
1792      const char *end_formals;
1793      unsigned int f_list_count;
1794      const def_dec_info *def_dec_p;
1795 {
1796   const char *start_formals;
1797   int depth;
1798   start_formals = end_formals - 1;
1799   depth = 1;
1800   for (; depth; check_source (--start_formals > clean_read_ptr, 0))
1801     {
1802       switch (*start_formals)
1803         {
1804           case '(':
1805             depth--;
1806             break;
1807           case ')':
1808             depth++;
1809             break;
1810         }
1811     }
1812   start_formals++;
1813   f_list_count--;
1814   if (f_list_count)
1815     {
1816       const char *next_end;
1817       next_end = start_formals - 1;
1818       check_source (next_end > clean_read_ptr, 0);
1819       while (((_pctype+1)[*next_end]&0010       ) )
1820         check_source (--next_end > clean_read_ptr, 0);
1821       check_source (*next_end == ')', next_end);
1822       check_source (--next_end > clean_read_ptr, 0);
1823       check_source (*next_end == ')', next_end);
1824       if (edit_formals_lists (next_end, f_list_count, def_dec_p))
1825         return 1;
1826     }
1827   if (f_list_count == 0)
1828     {
1829       const char *expected = def_dec_p->hash_entry->symbol;
1830       const char *func_name_start;
1831       const char *func_name_limit;
1832       size_t func_name_len;
1833       for (func_name_limit = start_formals-1; ((_pctype+1)[*func_name_limit]&0010       ) ; )
1834         check_source (--func_name_limit > clean_read_ptr, 0);
1835       for (func_name_start = func_name_limit++;
1836            is_id_char (*func_name_start);
1837            func_name_start--)
1838         check_source (func_name_start > clean_read_ptr, 0);
1839       func_name_start++;
1840       func_name_len = func_name_limit - func_name_start;
1841       if (func_name_len == 0)
1842         check_source (0, func_name_start);
1843       if (func_name_len != strlen (expected)
1844           || strncmp (func_name_start, expected, func_name_len))
1845         {
1846           fprintf ((&_iob[2]) , "%s: %d: warning: found `%s' but expected `%s'\n",
1847                    shortpath (0 , def_dec_p->file->hash_entry->symbol),
1848                    identify_lineno (func_name_start),
1849                    dupnstr (func_name_start, func_name_len),
1850                    expected);
1851           return 1;
1852         }
1853     }
1854   output_up_to (start_formals);
1855   {
1856     unsigned f_list_depth;
1857     const f_list_chain_item *flci_p = def_dec_p->f_list_chain;
1858     for (f_list_depth = 0; f_list_depth < f_list_count; f_list_depth++)
1859       flci_p = flci_p->chain_next;
1860     output_string (flci_p->formals_list);
1861   }
1862   clean_read_ptr = end_formals - 1;
1863   return 0;
1864 }
1865 static const char *
1866 find_rightmost_formals_list (clean_text_p)
1867      const char *clean_text_p;
1868 {
1869   const char *end_formals;
1870   for (end_formals = clean_text_p; *end_formals != '\n'; end_formals++)
1871     continue;
1872   end_formals--;
1873   while (1)
1874     {
1875       char ch;
1876       const char *l_brace_p;
1877       while (*end_formals != ')')
1878         {
1879           if (((_pctype+1)[*end_formals]&0010   ) )
1880             while (((_pctype+1)[*end_formals]&0010      ) )
1881               check_source (--end_formals > clean_read_ptr, 0);
1882           else
1883             check_source (--end_formals > clean_read_ptr, 0);
1884         }
1885       ch = *(l_brace_p = forward_to_next_token_char (end_formals));
1886       if ((ch == '{') || ((_pctype+1)[ch]&(0001 |0002   )) )
1887         break;
1888       check_source (--end_formals > clean_read_ptr, 0);
1889     }
1890   return end_formals;
1891 }
1892 static void
1893 add_local_decl (def_dec_p, clean_text_p)
1894      const def_dec_info *def_dec_p;
1895      const char *clean_text_p;
1896 {
1897   const char *start_of_block;
1898   const char *function_to_edit = def_dec_p->hash_entry->symbol;
1899   if (!local_flag)
1900     return;
1901   save_pointers ();
1902   if (setjmp (source_confusion_recovery))
1903     {
1904       restore_pointers ();
1905       fprintf ((&_iob[2]) , "%s: local declaration for function `%s' not inserted\n",
1906                pname, function_to_edit);
1907       return;
1908     }
1909   start_of_block = clean_text_p;
1910   while (*start_of_block != '{' && *start_of_block != '\n')
1911     check_source (++start_of_block < clean_text_limit, 0);
1912   if (*start_of_block != '{')
1913     {
1914       if (!quiet_flag)
1915         fprintf ((&_iob[2]) ,
1916           "\n%s: %d: warning: can't add declaration of `%s' into macro call\n",
1917           def_dec_p->file->hash_entry->symbol, def_dec_p->line, 
1918           def_dec_p->hash_entry->symbol);
1919       return;
1920     }
1921   {
1922     const char *ep = forward_to_next_token_char (start_of_block) - 1;
1923     const char *sp;
1924     for (sp = ep; ((_pctype+1)[*sp]&0010        )  && *sp != '\n'; sp--)
1925       continue;
1926     output_up_to (ep);
1927     {
1928       const char *decl = def_dec_p->definition->ansi_decl;
1929       if ((*decl == 'e') && (def_dec_p->file == def_dec_p->definition->file))
1930         decl += 7;
1931       output_string (decl);
1932     }
1933     output_bytes (sp, (size_t) (ep - sp) + 1);
1934   }
1935 }
1936 static void
1937 add_global_decls (file_p, clean_text_p)
1938      const file_info *file_p;
1939      const char *clean_text_p;
1940 {
1941   const def_dec_info *dd_p;
1942   const char *scan_p;
1943   save_pointers ();
1944   if (setjmp (source_confusion_recovery))
1945     {
1946       restore_pointers ();
1947       fprintf ((&_iob[2]) , "%s: global declarations for file `%s' not inserted\n",
1948                pname, shortpath (0 , file_p->hash_entry->symbol));
1949       return;
1950     }
1951   scan_p = find_rightmost_formals_list (clean_text_p);
1952   for (;; --scan_p)
1953     {
1954       if (scan_p < clean_text_base)
1955         break;
1956       check_source (scan_p > clean_read_ptr, 0);
1957       if (*scan_p == ';')
1958         break;
1959     }
1960   scan_p++;
1961   while (((_pctype+1)[*scan_p]&0010     ) )
1962     scan_p++;
1963   scan_p--;
1964   output_up_to (scan_p);
1965   {
1966     int some_decls_added = 0;
1967     for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
1968       if (dd_p->is_implicit && dd_p->definition && !dd_p->definition->written)
1969         {
1970           const char *decl = dd_p->definition->ansi_decl;
1971           if (*decl == 'e' && (dd_p->file == dd_p->definition->file))
1972             decl += 7;
1973           output_string ("\n");
1974           output_string (decl);
1975           some_decls_added = 1;
1976           ((  def_dec_info *) dd_p->definition)->written = 1;
1977         }
1978     if (some_decls_added)
1979       output_string ("\n\n");
1980   }
1981   for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
1982     if (dd_p->definition)
1983       ((  def_dec_info *) dd_p->definition)->written = 0;
1984 }
1985 static void
1986 edit_fn_definition (def_dec_p, clean_text_p)
1987      const def_dec_info *def_dec_p;
1988      const char *clean_text_p;
1989 {
1990   const char *end_formals;
1991   const char *function_to_edit = def_dec_p->hash_entry->symbol;
1992   save_pointers ();
1993   if (setjmp (source_confusion_recovery))
1994     {
1995       restore_pointers ();
1996       fprintf ((&_iob[2]) , "%s: definition of function `%s' not converted\n",
1997                pname, function_to_edit);
1998       return;
1999     }
2000   end_formals = find_rightmost_formals_list (clean_text_p);
2001   if (other_variable_style_function (def_dec_p->ansi_decl))
2002     {
2003       if (!quiet_flag)
2004         fprintf ((&_iob[2]) , "%s: %d: warning: definition of %s not converted\n",
2005                  shortpath (0 , def_dec_p->file->hash_entry->symbol),
2006                  identify_lineno (end_formals), 
2007                  other_var_style);
2008       output_up_to (end_formals);
2009       return;
2010     }
2011   if (edit_formals_lists (end_formals, def_dec_p->f_list_count, def_dec_p))
2012     {
2013       restore_pointers ();
2014       fprintf ((&_iob[2]) , "%s: definition of function `%s' not converted\n",
2015                pname, function_to_edit);
2016       return;
2017     }
2018   output_up_to (end_formals);
2019   {
2020     const char *end_formals_orig;
2021     const char *start_body;
2022     const char *start_body_orig;
2023     const char *scan;
2024     const char *scan_orig;
2025     int have_flotsum = 0;
2026     int have_newlines = 0;
2027     for (start_body = end_formals + 1; *start_body != '{';)
2028       check_source (++start_body < clean_text_limit, 0);
2029     end_formals_orig = orig_text_base + (end_formals - clean_text_base);
2030     start_body_orig = orig_text_base + (start_body - clean_text_base);
2031     scan = end_formals + 1;
2032     scan_orig = end_formals_orig + 1;
2033     for (; scan < start_body; scan++, scan_orig++)
2034       {
2035         if (*scan == *scan_orig)
2036           {
2037             have_newlines |= (*scan_orig == '\n');
2038             if (!((_pctype+1)[*scan_orig]&0010  ) )
2039               *((  char *)scan_orig) = ' ';  
2040           }
2041         else
2042           have_flotsum = 1;
2043       }
2044     if (have_flotsum)
2045       output_bytes (end_formals_orig + 1,
2046                     (size_t) (start_body_orig - end_formals_orig) - 1);
2047     else
2048       if (have_newlines)
2049         output_string ("\n");
2050       else
2051         output_string (" ");
2052     clean_read_ptr = start_body - 1;
2053   }
2054 }
2055 static void
2056 do_cleaning (new_clean_text_base, new_clean_text_limit)
2057      char *new_clean_text_base;
2058      char *new_clean_text_limit;
2059 {
2060   char *scan_p;
2061   int non_whitespace_since_newline = 0;
2062   for (scan_p = new_clean_text_base; scan_p < new_clean_text_limit; scan_p++)
2063     {
2064       switch (*scan_p)
2065         {
2066           case '/':                      
2067             if (scan_p[1] != '*')
2068               goto regular;
2069             non_whitespace_since_newline = 1;
2070             scan_p[0] = ' ';
2071             scan_p[1] = ' ';
2072             scan_p += 2;
2073             while (scan_p[1] != '/' || scan_p[0] != '*')
2074               {
2075                 if (!((_pctype+1)[*scan_p]&0010 ) )
2076                   *scan_p = ' ';
2077                 if (++scan_p >= new_clean_text_limit)
2078                   abort ();
2079               }
2080             *scan_p++ = ' ';
2081             *scan_p = ' ';
2082             break;
2083           case '#':                      
2084             if (non_whitespace_since_newline)
2085               goto regular;
2086             *scan_p = ' ';
2087             while (scan_p[1] != '\n' || scan_p[0] == '\\')
2088               {
2089                 if (!((_pctype+1)[*scan_p]&0010 ) )
2090                   *scan_p = ' ';
2091                 if (++scan_p >= new_clean_text_limit)
2092                   abort ();
2093               }
2094             *scan_p++ = ' ';
2095             break;
2096           case '\'':                     
2097             non_whitespace_since_newline = 1;
2098             while (scan_p[1] != '\'' || scan_p[0] == '\\')
2099               {
2100                 if (scan_p[0] == '\\' && !((_pctype+1)[scan_p[1]]&0010  ) )
2101                   scan_p[1] = ' ';
2102                 if (!((_pctype+1)[*scan_p]&0010 ) )
2103                   *scan_p = ' ';
2104                 if (++scan_p >= new_clean_text_limit)
2105                   abort ();
2106               }
2107             *scan_p++ = ' ';
2108             break;
2109           case '"':                      
2110             non_whitespace_since_newline = 1;
2111             while (scan_p[1] != '"' || scan_p[0] == '\\')
2112               {
2113                 if (scan_p[0] == '\\' && !((_pctype+1)[scan_p[1]]&0010  ) )
2114                   scan_p[1] = ' ';
2115                 if (!((_pctype+1)[*scan_p]&0010 ) )
2116                   *scan_p = ' ';
2117                 if (++scan_p >= new_clean_text_limit)
2118                   abort ();
2119               }
2120             *scan_p++ = ' ';
2121             break;
2122           case '\\':                     
2123             if (scan_p[1] != '\n')
2124               goto regular;
2125             *scan_p = ' ';
2126             break;
2127           case '\n':
2128             non_whitespace_since_newline = 0;    
2129             break;
2130           case ' ':
2131           case '\v':
2132           case '\t':
2133           case '\r':
2134           case '\f':
2135           case '\b':
2136             break;               
2137           default:
2138 regular:
2139             non_whitespace_since_newline = 1;
2140             break;
2141         }
2142     }
2143 }
2144 static const char *
2145 careful_find_l_paren (p)
2146      const char *p;
2147 {
2148   const char *q;
2149   int paren_depth;
2150   for (paren_depth = 1, q = p-1; paren_depth; check_source (--q >= clean_text_base, 0))
2151     {
2152       switch (*q)
2153         {
2154           case ')':
2155             paren_depth++;
2156             break;
2157           case '(':
2158             paren_depth--;
2159             break;
2160         }
2161     }
2162   return ++q;
2163 }
2164 static void
2165 scan_for_missed_items (file_p)
2166      const file_info *file_p;
2167 {
2168   static const char *scan_p;
2169   const char *limit = clean_text_limit - 3;
2170   static const char *backup_limit;
2171   backup_limit = clean_text_base - 1;
2172   for (scan_p = clean_text_base; scan_p < limit; scan_p++)
2173     {
2174       if (*scan_p == ')')
2175         {
2176           static const char *last_r_paren;
2177           const char *ahead_p;
2178           last_r_paren = scan_p;
2179           for (ahead_p = scan_p + 1; ((_pctype+1)[*ahead_p]&0010        ) ; )
2180             check_source (++ahead_p < limit, limit);
2181           scan_p = ahead_p - 1;
2182           if (((_pctype+1)[*ahead_p]&(0001      |0002   ))  || *ahead_p == '{')
2183             {
2184               const char *last_l_paren;
2185               const int lineno = identify_lineno (ahead_p);
2186               if (setjmp (source_confusion_recovery))
2187                 continue;
2188               do
2189                 {
2190                   last_l_paren = careful_find_l_paren (last_r_paren);
2191                   for (last_r_paren = last_l_paren-1; ((_pctype+1)[*last_r_paren]&0010  ) ; )
2192                     check_source (--last_r_paren >= backup_limit, backup_limit);
2193                 }
2194               while (*last_r_paren == ')');
2195               if (is_id_char (*last_r_paren))
2196                 {
2197                   const char *id_limit = last_r_paren + 1;
2198                   const char *id_start;
2199                   size_t id_length;
2200                   const def_dec_info *dd_p;
2201                   for (id_start = id_limit-1; is_id_char (*id_start); )
2202                     check_source (--id_start >= backup_limit, backup_limit);
2203                   id_start++;
2204                   backup_limit = id_start;
2205                   if ((id_length = (size_t) (id_limit - id_start)) == 0)
2206                     goto not_missed;
2207                   {
2208                     char *func_name = (char *) alloca (id_length + 1);
2209                     static const char * const stmt_keywords[]
2210                       = { "if", "while", "for", "switch", "return", 0 };
2211                     const char * const *stmt_keyword;
2212                     strncpy (func_name, id_start, id_length);
2213                     func_name[id_length] = '\0';
2214                     for (stmt_keyword = stmt_keywords; *stmt_keyword; stmt_keyword++)
2215                       if (!strcmp (func_name, *stmt_keyword))
2216                         goto not_missed;
2217                     for (dd_p = file_p->defs_decs; dd_p; dd_p = dd_p->next_in_file)
2218                       if (dd_p->is_func_def && dd_p->line == lineno)
2219                         goto not_missed;
2220                     fprintf ((&_iob[2]) , "%s: %d: warning: `%s' excluded by preprocessing\n",
2221                              shortpath (0 , file_p->hash_entry->symbol),
2222                              identify_lineno (id_start), func_name);
2223                     fprintf ((&_iob[2]) , "%s: function definition not converted\n",
2224                              pname);
2225                   }
2226                 not_missed: ;
2227                 }
2228             }
2229         }
2230     }
2231 }
2232 static void
2233 edit_file (hp)
2234      const hash_table_entry *hp;
2235 {
2236   struct stat stat_buf;
2237   const file_info *file_p = hp->_info._fip ;
2238   char *new_orig_text_base;
2239   char *new_orig_text_limit;
2240   char *new_clean_text_base;
2241   char *new_clean_text_limit;
2242   size_t orig_size;
2243   size_t repl_size;
2244   int first_definition_in_file;
2245   if (!needs_to_be_converted (file_p))
2246     return;
2247   convert_filename = file_p->hash_entry->symbol;
2248   if (!directory_specified_p (convert_filename)
2249       || file_excluded_p (convert_filename))
2250     {
2251       if (!quiet_flag
2252           )
2253         fprintf ((&_iob[2]) , "%s: `%s' not converted\n",
2254                  pname, shortpath (0 , convert_filename));
2255       return;
2256     }
2257   if (nochange_flag)
2258     fprintf ((&_iob[2]) , "%s: would convert file `%s'\n",
2259              pname, shortpath (0 , convert_filename));
2260   else
2261     fprintf ((&_iob[2]) , "%s: converting file `%s'\n",
2262              pname, shortpath (0 , convert_filename));
2263   fflush ((&_iob[2]) );
2264   if (stat((char *)(char *)convert_filename,  &stat_buf)  == -1)
2265     {
2266       fprintf ((&_iob[2]) , "%s: can't get status for file `%s': %s\n",
2267                pname, shortpath (0 , convert_filename), sys_errlist[errno]);
2268       return;
2269     }
2270   orig_size = stat_buf.st_size;
2271   orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
2272   orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
2273   clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
2274   clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
2275   clean_read_ptr = clean_text_base - 1;
2276   repl_size = orig_size + (orig_size >> 2) + 4096;
2277   repl_text_base = (char *) xmalloc (repl_size + 2);
2278   repl_text_limit = repl_text_base + repl_size - 1;
2279   repl_write_ptr = repl_text_base - 1;
2280   {
2281     int input_file;
2282     if ((input_file = open((char *)convert_filename,         0 ,  0444) ) == -1)
2283       {
2284         fprintf ((&_iob[2]) , "%s: can't open file `%s' for reading: %s\n",
2285                  pname, shortpath (0 , convert_filename),
2286                  sys_errlist[errno]);
2287         return;
2288       }
2289     if (read (input_file, new_orig_text_base, orig_size) != orig_size)
2290       {
2291         close (input_file);
2292         fprintf ((&_iob[2]) , "\n%s: error reading input file `%s': %s\n",
2293                  pname, shortpath (0 , convert_filename),
2294                  sys_errlist[errno]);
2295         return;
2296       }
2297     close (input_file);
2298   }
2299   if (orig_size == 0 || orig_text_limit[-1] != '\n')
2300     {
2301       *new_orig_text_limit++ = '\n';
2302       orig_text_limit++;
2303     }
2304   memcpy (new_clean_text_base, orig_text_base,
2305           (size_t) (orig_text_limit - orig_text_base));
2306   do_cleaning (new_clean_text_base, new_clean_text_limit);
2307   scan_for_missed_items (file_p);
2308   last_known_line_number = 1;
2309   last_known_line_start = clean_text_base;
2310   {
2311     const def_dec_info *def_dec_p;
2312     first_definition_in_file = 1;
2313     def_dec_p = file_p->defs_decs;
2314     for (; def_dec_p; def_dec_p = def_dec_p->next_in_file)
2315       {
2316         const char *clean_text_p = seek_to_line (def_dec_p->line);
2317         if (global_flag && def_dec_p->is_func_def && first_definition_in_file)
2318           {
2319             add_global_decls (def_dec_p->file, clean_text_p);
2320             first_definition_in_file = 0;
2321           }
2322         if (def_dec_p->prototyped
2323          || (!def_dec_p->is_func_def && !def_dec_p->definition))
2324           continue;
2325         if (def_dec_p->is_func_def)
2326           edit_fn_definition (def_dec_p, clean_text_p);
2327         else
2328         if (def_dec_p->is_implicit)
2329           add_local_decl (def_dec_p, clean_text_p);
2330         else
2331             edit_fn_declaration (def_dec_p, clean_text_p);
2332       }
2333   }
2334   output_up_to (clean_text_limit - 1);
2335   if (nochange_flag)
2336     {
2337       free (new_orig_text_base);
2338       free (new_clean_text_base);
2339       free (repl_text_base);
2340       return;
2341     }
2342   if (!nosave_flag)
2343     {
2344       char *new_filename =
2345           (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
2346       strcpy (new_filename, convert_filename);
2347       strcat (new_filename, save_suffix);
2348       if (link((char *)convert_filename, (char *) new_filename)  == -1)
2349         {
2350           if (errno ==  17              )
2351             {
2352               if (!quiet_flag)
2353                 fprintf ((&_iob[2]) , "%s: warning: file `%s' already saved in `%s'\n",
2354                          pname,
2355                          shortpath (0 , convert_filename),
2356                          shortpath (0 , new_filename));
2357             }
2358           else
2359             {
2360               fprintf ((&_iob[2]) , "%s: can't link file `%s' to `%s': %s\n",
2361                        pname,
2362                        shortpath (0 , convert_filename),
2363                        shortpath (0 , new_filename),
2364                        sys_errlist[errno]);
2365               return;
2366             }
2367         }
2368     }
2369   if (  unlink((char *)convert_filename)  == -1)
2370     {
2371       fprintf ((&_iob[2]) , "%s: can't delete file `%s': %s\n",
2372                pname, shortpath (0 , convert_filename), sys_errlist[errno]);
2373       return;
2374     }
2375   {
2376     int output_file;
2377     if ((output_file = creat (convert_filename, 0666)) == -1)
2378       {
2379         fprintf ((&_iob[2]) , "%s: can't create/open output file `%s': %s\n",
2380                  pname, shortpath (0 , convert_filename),
2381                  sys_errlist[errno]);
2382         return;
2383       }
2384     {
2385       unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
2386       if (write (output_file, repl_text_base, out_size) != out_size)
2387         fprintf ((&_iob[2]) , "%s: error writing file `%s': %s\n",
2388                  pname, shortpath (0 , convert_filename),
2389                  sys_errlist[errno]);
2390     }
2391     close (output_file);
2392   }
2393   free (new_orig_text_base);
2394   free (new_clean_text_base);
2395   free (repl_text_base);
2396   if (chmod((char *)(char *)convert_filename,  stat_buf.st_mode)  == -1)
2397     fprintf ((&_iob[2]) , "%s: can't change mode of file `%s': %s\n",
2398              pname, shortpath (0 , convert_filename), sys_errlist[errno]);
2399 }
2400 static void
2401 do_processing ()
2402 {
2403   const char * const *base_pp;
2404   const char * const * const end_pps
2405     = &base_source_filenames[n_base_source_files];
2406   int syscalls_len;
2407   for (base_pp = base_source_filenames; base_pp < end_pps; base_pp++)
2408     process_aux_info_file (*base_pp, keep_flag, 0);
2409   if (nondefault_syscalls_dir)
2410     {
2411       syscalls_absolute_filename
2412         = (char *) xmalloc (strlen (nondefault_syscalls_dir)
2413                             + sizeof (syscalls_filename) + 1);
2414       strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
2415     }
2416   else
2417     {
2418       syscalls_absolute_filename
2419         = (char *) xmalloc (strlen (default_syscalls_dir)
2420                             + sizeof (syscalls_filename) + 1);
2421       strcpy (syscalls_absolute_filename, default_syscalls_dir);
2422     }
2423   syscalls_len = strlen (syscalls_absolute_filename);
2424   if (*(syscalls_absolute_filename + syscalls_len - 1) != '/')
2425     {
2426       *(syscalls_absolute_filename + syscalls_len++) = '/';
2427       *(syscalls_absolute_filename + syscalls_len) = '\0';
2428     }
2429   strcat (syscalls_absolute_filename, syscalls_filename);
2430   process_aux_info_file (syscalls_absolute_filename, 1, 1);
2431   visit_each_hash_node (filename_primary, reverse_def_dec_list);
2432   visit_each_hash_node (function_name_primary, connect_defs_and_decs);
2433   visit_each_hash_node (filename_primary, edit_file);
2434   if (cplusplus_flag && !nochange_flag)
2435     visit_each_hash_node (filename_primary, rename_c_file);
2436 }
2437 static struct option longopts[] =
2438 {
2439   {"version", 0, 0, 'V'},
2440   {"file_name", 0, 0, 'p'},
2441   {"quiet", 0, 0, 'q'},
2442   {"silent", 0, 0, 'q'},
2443   {"force", 0, 0, 'f'},
2444   {"keep", 0, 0, 'k'},
2445   {"nosave", 0, 0, 'N'},
2446   {"nochange", 0, 0, 'n'},
2447   {"compiler-options", 1, 0, 'c'},
2448   {"exclude", 1, 0, 'x'},
2449   {"directory", 1, 0, 'd'},
2450   {"local", 0, 0, 'l'},
2451   {"global", 0, 0, 'g'},
2452   {"c++", 0, 0, 'C'},
2453   {"syscalls-dir", 1, 0, 'B'},
2454   {0, 0, 0, 0}
2455 };
2456 int
2457 main (argc, argv)
2458      int argc;
2459      char **const argv;
2460 {
2461   int longind;
2462   int c;
2463   const char *params = "";
2464   pname = rindex (argv[0], '/');
2465   pname = pname ? pname+1 : argv[0];
2466   cwd_buffer = getpwd ();
2467   if (!cwd_buffer)
2468     {
2469       fprintf ((&_iob[2]) , "%s: cannot get working directory: %s\n",
2470                pname, sys_errlist[errno]);
2471       exit (1);
2472     }
2473   directory_list = string_list_cons (cwd_buffer, 0 );
2474   while ((c = getopt_long (argc, argv,
2475                            "B:c:Cd:gklnNp:qvVx:",
2476                            longopts, &longind)) != (-1) )
2477     {
2478       if (c == 0)                
2479         c = longopts[longind].val;
2480       switch (c)
2481         {
2482         case 'p':
2483           compiler_file_name = optarg;
2484           break;
2485         case 'd':
2486           directory_list
2487             = string_list_cons (abspath (0 , optarg), directory_list);
2488           break;
2489         case 'x':
2490           exclude_list = string_list_cons (optarg, exclude_list);
2491           break;
2492         case 'v':
2493         case 'V':
2494           version_flag = 1;
2495           break;
2496         case 'q':
2497           quiet_flag = 1;
2498           break;
2499         case 'n':
2500           nochange_flag = 1;
2501           keep_flag = 1;
2502           break;
2503         case 'N':
2504           nosave_flag = 1;
2505           break;
2506         case 'k':
2507           keep_flag = 1;
2508           break;
2509         case 'c':
2510           params = optarg;
2511           break;
2512         case 'l':
2513           local_flag = 1;
2514           break;
2515         case 'g':
2516           global_flag = 1;
2517           break;
2518         case 'C':
2519           cplusplus_flag = 1;
2520           break;
2521         case 'B':
2522           nondefault_syscalls_dir = optarg;
2523           break;
2524         default:
2525           usage ();
2526         }
2527     }
2528   munge_compile_params (params);
2529   n_base_source_files = argc - optind;
2530   base_source_filenames =
2531     (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
2532   n_base_source_files = 0;
2533   for (; optind < argc; optind++)
2534     {
2535       const char *path = abspath (0 , argv[optind]);
2536       int len = strlen (path);
2537       if (path[len-1] == 'c' && path[len-2] == '.')
2538         base_source_filenames[n_base_source_files++] = path;
2539       else
2540         {
2541           fprintf ((&_iob[2]) , "%s: input file names must have .c suffixes: %s\n",
2542                    pname, shortpath (0 , path));
2543           errors++;
2544         }
2545     }
2546   {
2547     const char *cp;
2548     for (cp = varargs_style_indicator; ((_pctype+1)[*cp]&(0001  |0002   |0004   ))  || *cp == '_'; cp++)
2549       continue;
2550     if (*cp != 0)
2551       varargs_style_indicator = savestring (varargs_style_indicator,
2552                                             cp - varargs_style_indicator);
2553   }
2554   if (errors)
2555     usage ();
2556   else
2557     {
2558       if (version_flag)
2559         fprintf ((&_iob[2]) , "%s: %s\n", pname, version_string);
2560       do_processing ();
2561     }
2562   if (errors)
2563     exit (1);
2564   else
2565     exit (0);
2566   return 1;
2567 }