OSDN Git Service

(required_unistd_h): Delete getgroups from list.
[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 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
61 if [ `echo $1 | wc -w` = 0 ] ; then
62   echo $progname\: usage\: $progname target-dir \[ source-dir \.\.\. \]
63   exit 1
64 fi
65
66 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"
67
68 rel_target_dir=$1
69 # All files in $src_dir_all (normally same as $rel_target_dir) are
70 # processed.
71 src_dir_all=$2
72 # In $src_dir_std (normally same as /usr/include), only the
73 # "standard" ANSI/POSIX files listed in $std_files are processed.
74 src_dir_std=$3
75
76 if [ `expr $rel_target_dir : '\(.\)'` != '/' ] ; then
77   abs_target_dir=$original_dir/$rel_target_dir
78 else
79   abs_target_dir=$rel_target_dir
80 fi
81
82 # Determine whether this system has symbolic links.
83 if ln -s X $rel_target_dir/ShouldNotExist 2>/dev/null; then
84   rm -f $rel_target_dir/ShouldNotExist
85   LINKS=true
86 elif ln -s X /tmp/ShouldNotExist 2>/dev/null; then
87   rm -f /tmp/ShouldNotExist
88   LINKS=true
89 else
90   LINKS=false
91 fi
92
93 if [ \! -d $abs_target_dir ] ; then
94   echo $progname\: creating directory $rel_target_dir
95   mkdir $abs_target_dir
96 fi
97
98 echo $progname\: populating \`$rel_target_dir\'
99
100 include_path=""
101
102 if [ `echo $* | wc -w` != 0 ] ; then
103   for rel_source_dir in $src_dir_all $src_dir_std; do
104     if [ `expr $rel_source_dir : '\(.\)'` != '/' ] ; then
105       abs_source_dir=$original_dir/$rel_source_dir
106     else
107       abs_source_dir=$rel_source_dir
108     fi
109     include_path="$include_path -I$abs_source_dir"
110   done
111 fi
112
113 required_stdlib_h="abort abs atexit atof atoi atol bsearch calloc exit free getenv labs malloc qsort rand realloc srand strtod strtol strtoul system"
114 # "div ldiv", - ignored because these depend on div_t, ldiv_t
115 # ignore these: "mblen mbstowcs mbstowc wcstombs wctomb"
116 # Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions.
117 # Should perhaps also add NULL
118 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 getpgrp getpid getppid getuid isatty link lseek pathconf pause pipe read rmdir setgid setpgid setsid setuid sleep sysconf tcgetpgrp tcsetpgrp ttyname unlink write"
119
120 done_dirs=""
121 echo "" >fixproto.list
122
123 for code in ALL STD ; do
124
125   subdirs="."
126
127   case $code in
128     ALL)
129       rel_source_dir=$src_dir_all
130
131       dirs="."
132       levels=2
133       while $LINKS && test -n "$dirs" -a $levels -gt 0
134       do
135         levels=`expr $levels - 1`
136         newdirs=
137         for d in $dirs ; do
138           # Find all directories under $d, relative to $d, excluding $d itself.
139           # Assume directory names ending in CC or containing ++ are
140           # for C++, so skip those.
141           subdirs="$subdirs "`cd $rel_source_dir/$d; find . -type d -print | \
142                    sed -e '/^\.$/d' -e "s|^\./|${d}/|" -e 's|^\./||' \
143                      -e '/CC$/d' -e '/\+\+/d'`
144           links=
145           links=`cd $rel_source_dir; find $d/. -type l -print | \
146                        sed -e "s|$d/./|$d/|" -e 's|^\./||'`
147           for link in $links --dummy-- ; do
148             test -d $rel_source_dir/$link/. && newdirs="$newdirs $link"
149           done
150         done
151         dirs="$newdirs"
152         subdirs="$subdirs $newdirs"
153       done
154       ;;
155     STD)
156       rel_source_dir=$src_dir_std
157       ;;
158   esac
159
160   if [ `expr $rel_source_dir : '\(.\)'` != '/' ] ; then
161     abs_source_dir=$original_dir/$rel_source_dir
162   else
163     abs_source_dir=$rel_source_dir
164   fi
165
166   if [ \! -d $abs_source_dir ] ; then
167     echo $progname\: warning\: no such directory\: \`$rel_source_dir\'
168     continue
169   fi
170
171   for rel_source_subdir in $subdirs; do
172
173       abs_target_subdir=${abs_target_dir}/${rel_source_subdir}
174       if [ \! -d $abs_target_subdir ] ; then
175         mkdir $abs_target_subdir
176       fi
177       # Append "/"; remove initial "./". Hence "." -> "" and "sys" -> "sys/".
178       rel_source_prefix=`echo $rel_source_subdir | sed -e 's|$|/|' -e 's|^./||'`
179
180       case $code in
181         ALL)
182           # The 'sed' is in case the *.h matches nothing, which yields "*.h"
183           # which would then get re-globbed in the current directory.  Sigh.
184           rel_source_files=`cd ${abs_source_dir}/${rel_source_subdir}; echo *.h | sed -e 's|[*].h|NONE|'`
185           ;;
186
187         STD)
188           files_to_check="$std_files"
189           rel_source_files=""
190
191           # Also process files #included by the $std_files.
192           while [ -n "${files_to_check}" ]
193           do
194             new_files_to_check=""
195             for file in $files_to_check ; do
196               xxfile=`echo $file | sed -e 's|/\([^/\.][^/\.]*\)/\.\./|/|'`
197               # Create the dir where this file will go when fixed.
198               xxdir=`echo ./$file | sed -e 's|/[^/]*$||'`
199               if [ \! -d $abs_target_subdir/$xxdir ] ; then
200                 mkdir $abs_target_subdir/$xxdir
201               fi
202               # Just in case we have edited out a symbolic link
203               if [ -f $src_dir_std/$file -a -f $src_dir_std/$xxfile ] ; then
204                 file=$xxfile
205               fi
206               case " $rel_source_files " in
207                 *" ${file} "*)
208                   # Already seen $file; nothing to do
209                   ;;
210                 *)
211                   if test -f $src_dir_std/$file ; then
212                     rel_dir=`echo $file | sed -n -e 's|^\(.*/\)[^/]*$|\1|p'`
213                     # For #include "foo.h", that might be either "foo.h"
214                     # or "${rel_dir}foo.h (or something bogus).
215                     new_files_to_check="$new_files_to_check "`sed -n \
216                         -e 's@  @ @g' \
217                         -e 's@^ *# *include *<\([^>]*\)>.*$@\1@p' -e \
218                         's@^ *# *include *\"\([^\"]*\)\".*$@\1 '$rel_dir'\1@p'\
219                         <$src_dir_std/$file`
220                     rel_source_files="$rel_source_files $file"
221                   fi
222                   ;;
223               esac
224             done
225             files_to_check="$new_files_to_check"
226           done
227           rel_source_files="$rel_source_files"
228           ;;
229       esac
230
231       for filename in $rel_source_files ; do
232         rel_source_file=${rel_source_prefix}${filename}
233         abs_source_file=$abs_source_dir/$rel_source_file
234         abs_target_file=$abs_target_dir/$rel_source_file
235
236         if test "$filename" = 'NONE' ; then
237           echo "(No *.h files in $abs_source_dir/$rel_source_subdir)"
238         # If target file exists, check if was written while processing one
239         # of the earlier source directories;  if so ignore it.
240         elif test -f $abs_target_file -a -n "$done_dirs" \
241           && grep "$rel_source_file" fixproto.list >/dev/null
242         then true
243         else
244           # echo doing $rel_source_file from $abs_source_dir
245           required_list=
246           extra_check_list=
247           case $rel_source_file in
248             ctype.h)
249               required_list="isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper" ;;
250             dirent.h)
251               required_list="closedir opendir readdir rewinddir" ;;
252             errno.h)
253               extra_check_list="errno" ;;
254             curses.h)
255               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" ;;
256             fcntl.h)
257               required_list="creat fcntl open" ;;
258             grp.h)
259               #Maybe also "getgrent fgetgrent setgrent endgrent" */
260               required_list="getgrgid getgrnam" ;;
261             limit.h)
262               required_list= /* Lots of macros */ ;;
263             locale.h)
264               required_list="localeconv setlocale" ;;
265             math.h)
266               required_list="acos asin atan atan2 ceil cos cosh exp fabs floor fmod frexp ldexp log10 log modf pow sin sinh sqrt tan tanh"
267               extra_check_list="HUGE_VAL" ;;
268             pwd.h)
269               required_list="getpwnam getpwuid" ;;
270             setjmp.h)
271               # Left out siglongjmp sigsetjmp - these depend on sigjmp_buf.
272               required_list="longjmp setjmp" ;;
273             signal.h)
274               # Left out signal() - its prototype is too complex for us!
275               # Also left out "sigaction sigaddset sigdelset sigemptyset
276               # sigfillset sigismember sigpending sigprocmask sigsuspend"
277               # because these need sigset_t or struct sigaction.
278               # Most systems that provide them will also declare them.
279               required_list="kill raise" ;;
280             stdio.h)
281               required_list="clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell fwrite getc getchar gets perror printf putc putchar puts remove rename rewind scanf setbuf setvbuf sprintf sscanf vprintf vsprintf vfprintf tmpfile tmpnam ungetc"
282               if grep '[^_a-zA-Z0-9]_flsbuf' <$abs_source_file >/dev/null; then
283                 required_list="$required_list _flsbuf _filbuf"
284               fi
285               # Should perhaps also handle NULL, EOF, ... ?
286               ;;
287             stdlib.h)
288               required_list="$required_stdlib_h" ;;
289             string.h)
290               required_list="memchr memcmp memcpy memmove memset strcat strchr strcmp strcoll strcpy strcspn strerror strlen strncat strncmp" ;;
291 # Should perhaps also add NULL and size_t
292             sys/stat.h)
293               required_list="chmod fstat mkdir mkfifo stat umask"
294               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" ;;
295             sys/times.h)
296               required_list="times" ;;
297 # "sys/types.h" add types (not in old g++-include)
298             sys/utsname.h)
299               required_list="uname" ;;
300             sys/wait.h)
301               required_list="wait waitpid"
302               extra_check_list="WEXITSTATUS WIFEXITED WIFSIGNALED WIFSTOPPED WSTOPSIG WTERMSIG WNOHANG WNOTRACED" ;;
303             tar.h)
304               required_list=  ;;
305             termios.h)
306               required_list="cfgetispeed cfgetospeed cfsetispeed cfsetospeed tcdrain tcflow tcflush tcgetattr tcsendbreak tcsetattr" ;;
307             time.h)
308               required_list="asctime clock ctime difftime gmtime localtime mktime strftime time tzset" ;;
309             unistd.h)
310               required_list="$required_unistd_h" ;;
311           esac
312           rm -f fixtmp.c fixtmp.i
313           echo "#include <${rel_source_file}>" >fixtmp.c
314           for macro in ${required_list} ${extra_check_list}
315           do
316             echo "#ifdef ${macro}" >>fixtmp.c
317             echo "__DEFINED_MACRO_${macro};" >>fixtmp.c
318             echo "#endif" >>fixtmp.c
319           done
320           if ${CPP} -D__STDC__ -D__cplusplus -D_POSIX_SOURCE $include_path fixtmp.c >fixtmp.i 2>/dev/null
321           then
322            $original_dir/fix-header $rel_source_file $abs_source_file $abs_target_file "$required_list" <fixtmp.i
323           else
324             echo "${progname}: cpp could not parse ${abs_source_file} (ignored)"
325           fi
326           echo "${rel_source_file}" >>fixproto.list
327         fi
328       done
329       rm -f fixtmp.c fixtmp.i
330     done
331     # check for broken assert.h that needs stdio.h
332     if test -f $abs_source_dir/assert.h -a \! -f $abs_target_dir/assert.h \
333       && grep 'stderr' $abs_source_dir/assert.h >/dev/null
334     then
335       if grep 'include.*stdio.h' $abs_source_dir/assert.h >/dev/null
336       then 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     done_dirs="$done_dir $rel_source_dir"
344 done
345
346 # This might be more cleanly moved into the main loop, by adding
347 # a <dummy> source directory at the end.  FIXME!
348 for rel_source_file in unistd.h stdlib.h
349 do
350   if grep "$rel_source_file" fixproto.list >/dev/null
351   then true
352   else
353     echo Adding missing $rel_source_file
354     rel_source_ident=`echo $rel_source_file | tr ./ __`
355     required_list=`eval echo '${required_'${rel_source_ident}'-}'`
356     cat >tmp.h <<EOF
357 #ifndef ${rel_source_ident}
358 #define ${rel_source_ident}
359 #endif
360 EOF
361     $original_dir/fix-header $rel_source_file tmp.h $abs_target_dir/$rel_source_file "$required_list" </dev/null
362     rm tmp.h
363   fi
364 done
365 exit 0