OSDN Git Service

Use ${FIXPROTO_DEFINES}.
[pf3gnuchains/gcc-fork.git] / gcc / fixproto
1 #!/bin/sh
2 #
3 # SYNOPSIS
4 #       fixproto TARGET-DIR SOURCE-DIR-ALL SOURCE-DIR-STD
5 #
6 # COPYRIGHT
7 #       Copyright (C) 1993, 1994 Free Software Foundation, Inc.
8 #       This file is part of GNU CC.
9 #
10 #       GNU CC is free software; you can redistribute it and/or modify
11 #       it under the terms of the GNU General Public License as published by
12 #       the Free Software Foundation; either version 2, or (at your option)
13 #       any later version.
14 #
15 #       GNU CC is distributed in the hope that it will be useful,
16 #       but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 #       GNU General Public License for more details.
19 #
20 #       You should have received a copy of the GNU General Public License
21 #       along with GNU CC; see the file COPYING.  If not, write to
22 #       the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 #
24 # DESCRIPTION
25 #       Adjunct script for GNU CC to populate a directory with ANSI,
26 #       Posix.1, and C++ compatible header files.
27 #
28 #       Each file found under SOURCE-DIR-ALL is analyzed and "fixed."
29 #       Only standard ANSI/POSIX files found under SOURCE-DIR-STD
30 #       are analyzed and "fixed."
31 #       The SOURCE-DIRs are searched in order; a file found
32 #       under multiple SOURCE-DIRs is only handled for the first one.
33 #
34 # STRATEGY
35 #       Each include file is fed through cpp, and the scan-decls program
36 #       parses it, and emits any found function declarations.
37 #       The fix-header program analyzes the scan-decls output,
38 #       together with the original include file, and writes a "fixed"
39 #       include file, if needed.
40 #
41 #       The comment at the beginning of fix-header.c lists specifically
42 #       what kind of changes are made.
43 #
44 # NOTE
45 #       Some file space will be wasted, because the original header
46 #       files are copied.  An earlier version just included the original
47 #       by "reference", using GNU cpp's #include_next mechanism.
48 #       This is currently not done, partly because #include_next is
49 #       fragile (susceptible to version incompatibilties, and depends
50 #       and GCC-specific features), and partly for performance reasons.
51 #
52 # AUTHORS
53 #       Ron Guilmette (rfg@netcom.com) (original idea and code)
54 #       Per Bothner (bothner@cygnus.com) (major re-write)
55
56 progname=$0
57 progname=`basename $progname`
58 original_dir=`pwd`
59 CPP=${CPP-./cpp}
60 DEFINES="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}"
61
62 if [ `echo $1 | wc -w` = 0 ] ; then
63   echo $progname\: usage\: $progname target-dir \[ source-dir \.\.\. \]
64   exit 1
65 fi
66
67 std_files="ctype.h dirent.h errno.h curses.h fcntl.h grp.h locale.h math.h pwd.h setjmp.h signal.h stdio.h stdlib.h string.h sys/stat.h sys/times.h sys/resource.h sys/utsname.h sys/wait.h tar.h termios.h time.h unistd.h"
68
69 rel_target_dir=$1
70 # All files in $src_dir_all (normally same as $rel_target_dir) are
71 # processed.
72 src_dir_all=$2
73 # In $src_dir_std (normally same as /usr/include), only the
74 # "standard" ANSI/POSIX files listed in $std_files are processed.
75 src_dir_std=$3
76
77 if [ `expr $rel_target_dir : '\(.\)'` != '/' ] ; then
78   abs_target_dir=$original_dir/$rel_target_dir
79 else
80   abs_target_dir=$rel_target_dir
81 fi
82
83 # Determine whether this system has symbolic links.
84 if ln -s X $rel_target_dir/ShouldNotExist 2>/dev/null; then
85   rm -f $rel_target_dir/ShouldNotExist
86   LINKS=true
87 elif ln -s X /tmp/ShouldNotExist 2>/dev/null; then
88   rm -f /tmp/ShouldNotExist
89   LINKS=true
90 else
91   LINKS=false
92 fi
93
94 if [ \! -d $abs_target_dir ] ; then
95   echo $progname\: creating directory $rel_target_dir
96   mkdir $abs_target_dir
97 fi
98
99 echo $progname\: populating \`$rel_target_dir\'
100
101 include_path=""
102
103 if [ `echo $* | wc -w` != 0 ] ; then
104   for rel_source_dir in $src_dir_all $src_dir_std; do
105     if [ `expr $rel_source_dir : '\(.\)'` != '/' ] ; then
106       abs_source_dir=$original_dir/$rel_source_dir
107     else
108       abs_source_dir=$rel_source_dir
109     fi
110     include_path="$include_path -I$abs_source_dir"
111   done
112 fi
113
114 required_stdlib_h="abort abs atexit atof atoi atol bsearch calloc exit free getenv labs malloc putenv qsort rand realloc srand strtod strtol strtoul system"
115 # "div ldiv", - ignored because these depend on div_t, ldiv_t
116 # ignore these: "mblen mbstowcs mbstowc wcstombs wctomb"
117 # Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions.
118 # Should perhaps also add NULL
119 required_unistd_h="_exit access alarm chdir chown close ctermid cuserid dup dup2 execl execle execlp execv execve execvp fork fpathconf getcwd getegid geteuid getgid getlogin getopt getpgrp getpid getppid getuid isatty link lseek pathconf pause pipe read rmdir setgid setpgid setsid setuid sleep sysconf tcgetpgrp tcsetpgrp ttyname unlink write"
120
121 done_dirs=""
122 echo "" >fixproto.list
123
124 for code in ALL STD ; do
125
126   subdirs="."
127
128   case $code in
129     ALL)
130       rel_source_dir=$src_dir_all
131
132       dirs="."
133       levels=2
134       while $LINKS && test -n "$dirs" -a $levels -gt 0
135       do
136         levels=`expr $levels - 1`
137         newdirs=
138         for d in $dirs ; do
139           # Find all directories under $d, relative to $d, excluding $d itself.
140           # Assume directory names ending in CC or containing ++ are
141           # for C++, so skip those.
142           subdirs="$subdirs "`cd $rel_source_dir/$d; find . -type d -print | \
143                    sed -e '/^\.$/d' -e "s|^\./|${d}/|" -e 's|^\./||' \
144                      -e '/CC$/d' -e '/\+\+/d'`
145           links=
146           links=`cd $rel_source_dir; find $d/. -type l -print | \
147                        sed -e "s|$d/./|$d/|" -e 's|^\./||'`
148           for link in $links --dummy-- ; do
149             test -d $rel_source_dir/$link/. && newdirs="$newdirs $link"
150           done
151         done
152         dirs="$newdirs"
153         subdirs="$subdirs $newdirs"
154       done
155       ;;
156     STD)
157       rel_source_dir=$src_dir_std
158       ;;
159   esac
160
161   if [ `expr $rel_source_dir : '\(.\)'` != '/' ] ; then
162     abs_source_dir=$original_dir/$rel_source_dir
163   else
164     abs_source_dir=$rel_source_dir
165   fi
166
167   if [ \! -d $abs_source_dir ] ; then
168     echo $progname\: warning\: no such directory\: \`$rel_source_dir\'
169     continue
170   fi
171
172   for rel_source_subdir in $subdirs; do
173
174       abs_target_subdir=${abs_target_dir}/${rel_source_subdir}
175       if [ \! -d $abs_target_subdir ] ; then
176         mkdir $abs_target_subdir
177       fi
178       # Append "/"; remove initial "./". Hence "." -> "" and "sys" -> "sys/".
179       rel_source_prefix=`echo $rel_source_subdir | sed -e 's|$|/|' -e 's|^./||'`
180
181       case $code in
182         ALL)
183           # The 'sed' is in case the *.h matches nothing, which yields "*.h"
184           # which would then get re-globbed in the current directory.  Sigh.
185           rel_source_files=`cd ${abs_source_dir}/${rel_source_subdir}; echo *.h | sed -e 's|[*].h|NONE|'`
186           ;;
187
188         STD)
189           files_to_check="$std_files"
190           rel_source_files=""
191
192           # Also process files #included by the $std_files.
193           while [ -n "${files_to_check}" ]
194           do
195             new_files_to_check=""
196             for file in $files_to_check ; do
197               xxfile=`echo $file | sed -e 's|/\([^/\.][^/\.]*\)/\.\./|/|'`
198               # Create the dir where this file will go when fixed.
199               xxdir=`echo ./$file | sed -e 's|/[^/]*$||'`
200               if [ \! -d $abs_target_subdir/$xxdir ] ; then
201                 mkdir $abs_target_subdir/$xxdir
202               fi
203               # Just in case we have edited out a symbolic link
204               if [ -f $src_dir_std/$file -a -f $src_dir_std/$xxfile ] ; then
205                 file=$xxfile
206               fi
207               case " $rel_source_files " in
208                 *" ${file} "*)
209                   # Already seen $file; nothing to do
210                   ;;
211                 *)
212                   if test -f $src_dir_std/$file ; then
213                     rel_dir=`echo $file | sed -n -e 's|^\(.*/\)[^/]*$|\1|p'`
214                     # For #include "foo.h", that might be either "foo.h"
215                     # or "${rel_dir}foo.h (or something bogus).
216                     new_files_to_check="$new_files_to_check "`sed -n \
217                         -e 's@  @ @g' \
218                         -e 's@^ *# *include *<\([^>]*\)>.*$@\1@p' -e \
219                         's@^ *# *include *\"\([^\"]*\)\".*$@\1 '$rel_dir'\1@p'\
220                         <$src_dir_std/$file`
221                     rel_source_files="$rel_source_files $file"
222                   fi
223                   ;;
224               esac
225             done
226             files_to_check="$new_files_to_check"
227           done
228           rel_source_files="$rel_source_files"
229           ;;
230       esac
231
232       for filename in $rel_source_files ; do
233         rel_source_file=${rel_source_prefix}${filename}
234         abs_source_file=$abs_source_dir/$rel_source_file
235         abs_target_file=$abs_target_dir/$rel_source_file
236
237         if test "$filename" = 'NONE' ; then
238           echo "(No *.h files in $abs_source_dir/$rel_source_subdir)"
239         # If target file exists, check if was written while processing one
240         # of the earlier source directories;  if so ignore it.
241         elif test -f $abs_target_file -a -n "$done_dirs" \
242           && grep "$rel_source_file" fixproto.list >/dev/null
243         then true
244         else
245           # echo doing $rel_source_file from $abs_source_dir
246           required_list=
247           extra_check_list=
248           case $rel_source_file in
249             ctype.h)
250               required_list="isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper" ;;
251             dirent.h)
252               required_list="closedir opendir readdir rewinddir" ;;
253             errno.h)
254               extra_check_list="errno" ;;
255             curses.h)
256               required_list="box delwin endwin getcurx getcury initscr mvcur mvwprintw mvwscanw newwin overlay overwrite scroll subwin touchwin waddstr wclear wclrtobot wclrtoeol waddch wdelch wdeleteln werase wgetch wgetstr winsch winsertln wmove wprintw wrefresh wscanw wstandend wstandout" ;;
257             fcntl.h)
258               required_list="creat fcntl open" ;;
259             grp.h)
260               #Maybe also "getgrent fgetgrent setgrent endgrent" */
261               required_list="getgrgid getgrnam" ;;
262             limit.h)
263               required_list= /* Lots of macros */ ;;
264             locale.h)
265               required_list="localeconv setlocale" ;;
266             math.h)
267               required_list="acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp log10 log modf pow sin sinh sqrt tan tanh"
268               extra_check_list="HUGE_VAL" ;;
269             pwd.h)
270               required_list="getpwnam getpwuid" ;;
271             setjmp.h)
272               # Left out siglongjmp sigsetjmp - these depend on sigjmp_buf.
273               required_list="longjmp setjmp" ;;
274             signal.h)
275               # Left out signal() - its prototype is too complex for us!
276               # Also left out "sigaction sigaddset sigdelset sigemptyset
277               # sigfillset sigismember sigpending sigprocmask sigsuspend"
278               # because these need sigset_t or struct sigaction.
279               # Most systems that provide them will also declare them.
280               required_list="kill raise" ;;
281             stdio.h)
282               required_list="clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell fwrite getc getchar gets pclose perror popen printf putc putchar puts remove rename rewind scanf setbuf setvbuf sprintf sscanf vprintf vsprintf vfprintf tmpfile tmpnam ungetc"
283               if grep '[^_a-zA-Z0-9]_flsbuf' <$abs_source_file >/dev/null; then
284                 required_list="$required_list _flsbuf _filbuf"
285               fi
286               # Should perhaps also handle NULL, EOF, ... ?
287               ;;
288             stdlib.h)
289               required_list="$required_stdlib_h" ;;
290             string.h)
291               required_list="memchr memcmp memcpy memmove memset strcat strchr strcmp strcoll strcpy strcspn strerror strlen strncat strncmp strncpy strpbrk strrchr strspn strstr strtok strxfrm" ;;
292 # Should perhaps also add NULL and size_t
293             sys/stat.h)
294               required_list="chmod fstat mkdir mkfifo stat lstat umask"
295               extra_check_list="S_ISDIR S_ISBLK S_ISCHR S_ISFIFO S_ISREG S_ISLNK S_IFDIR S_IFBLK S_IFCHR S_IFIFO S_IFREG S_IFLNK" ;;
296             sys/times.h)
297               required_list="times" ;;
298 # "sys/types.h" add types (not in old g++-include)
299             sys/utsname.h)
300               required_list="uname" ;;
301             sys/wait.h)
302               required_list="wait waitpid"
303               extra_check_list="WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG WNOHANG WNOTRACED" ;;
304             tar.h)
305               required_list=  ;;
306             termios.h)
307               required_list="cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain tcflow tcflush tcgetattr tcsendbreak tcsetattr" ;;
308             time.h)
309               required_list="asctime clock ctime difftime gmtime localtime mktime strftime time tzset" ;;
310             unistd.h)
311               required_list="$required_unistd_h" ;;
312           esac
313           rm -f fixtmp.c fixtmp.i
314           echo "#include <${rel_source_file}>" >fixtmp.c
315           for macro in ${required_list} ${extra_check_list}
316           do
317             echo "#ifdef ${macro}" >>fixtmp.c
318             echo "__DEFINED_MACRO_${macro};" >>fixtmp.c
319             echo "#endif" >>fixtmp.c
320           done
321           if ${CPP} ${DEFINES} $include_path fixtmp.c >fixtmp.i 2>/dev/null
322           then
323            $original_dir/fix-header $rel_source_file $abs_source_file $abs_target_file "$required_list" <fixtmp.i
324           else
325             echo "${progname}: cpp could not parse ${abs_source_file} (ignored)"
326           fi
327           echo "${rel_source_file}" >>fixproto.list
328         fi
329       done
330       rm -f fixtmp.c fixtmp.i
331     done
332     # check for broken assert.h that needs stdio.h
333     if test -f $abs_source_dir/assert.h -a \! -f $abs_target_dir/assert.h; then
334       if grep 'stderr' $abs_source_dir/assert.h >/dev/null ; then
335         if grep 'include.*stdio.h' $abs_source_dir/assert.h >/dev/null ; then
336           true
337         else
338           echo 'Fixing broken assert.h (needs stdio.h)'
339           cat $abs_source_dir/assert.h >$abs_target_dir/assert.h
340           echo '#include <stdio.h>' >>$abs_target_dir/assert.h
341         fi
342       fi
343       if grep 'exit *(' $abs_source_dir/assert.h >/dev/null || 
344          grep 'abort *(' $abs_source_dir/assert.h >/dev/null ; then
345         if grep 'include.*stdlib.h' $abs_source_dir/assert.h >/dev/null ; then
346           true
347         else
348           echo 'Fixing broken assert.h (needs stdlib.h)'
349           if test ! -f $abs_target_dir/assert.h ; then
350             cat $abs_source_dir/assert.h >$abs_target_dir/assert.h
351           fi
352           echo '#include <stdlib.h>' >>$abs_target_dir/assert.h
353         fi
354       fi
355     fi
356     done_dirs="$done_dir $rel_source_dir"
357 done
358
359 # This might be more cleanly moved into the main loop, by adding
360 # a <dummy> source directory at the end.  FIXME!
361 for rel_source_file in unistd.h stdlib.h
362 do
363   if grep "$rel_source_file" fixproto.list >/dev/null
364   then true
365   else
366     echo Adding missing $rel_source_file
367     rel_source_ident=`echo $rel_source_file | tr ./ __`
368     required_list=`eval echo '${required_'${rel_source_ident}'-}'`
369     cat >tmp.h <<EOF
370 #ifndef ${rel_source_ident}
371 #define ${rel_source_ident}
372 #endif
373 EOF
374     $original_dir/fix-header $rel_source_file tmp.h $abs_target_dir/$rel_source_file "$required_list" </dev/null
375     rm tmp.h
376   fi
377 done
378 exit 0