OSDN Git Service

* invoke.texi: Use @gol at ends of lines inside @gccoptlist.
[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, 1997, 1998 Free Software Foundation, Inc.
8 #       This file is part of GCC.
9 #
10 #       GCC 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 #       GCC 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 GCC; see the file COPYING.  If not, write to
22 #       the Free Software Foundation, 59 Temple Place - Suite 330,
23 #       Boston, MA 02111-1307, USA.
24 #
25 # DESCRIPTION
26 #       Adjunct script for GCC to populate a directory with ANSI,
27 #       Posix.1, and C++ compatible header files.
28 #
29 #       Each file found under SOURCE-DIR-ALL is analyzed and "fixed."
30 #       Only standard ANSI/POSIX files found under SOURCE-DIR-STD
31 #       are analyzed and "fixed."
32 #       The SOURCE-DIRs are searched in order; a file found
33 #       under multiple SOURCE-DIRs is only handled for the first one.
34 #
35 # STRATEGY
36 #       Each include file is fed through cpp, and the scan-decls program
37 #       parses it, and emits any found function declarations.
38 #       The fix-header program analyzes the scan-decls output,
39 #       together with the original include file, and writes a "fixed"
40 #       include file, if needed.
41 #
42 #       The comment at the beginning of fix-header.c lists specifically
43 #       what kind of changes are made.
44 #
45 # NOTE
46 #       Some file space will be wasted, because the original header
47 #       files are copied.  An earlier version just included the original
48 #       by "reference", using GNU cpp's #include_next mechanism.
49 #       This is currently not done, partly because #include_next is
50 #       fragile (susceptible to version incompatibilities, and depends
51 #       and GCC-specific features), and partly for performance reasons.
52 #
53 # AUTHORS
54 #       Ron Guilmette (rfg@netcom.com) (original idea and code)
55 #       Per Bothner (bothner@cygnus.com) (major re-write)
56
57 dirname=`echo "$0" | sed 's,^[^/]*$,.,;s,//*[^/]*$,,'`
58 progname=`echo "$0" | sed 's,.*/,,'`
59 original_dir=`pwd`
60 FIX_HEADER=${FIX_HEADER-$original_dir/fix-header}
61 DEFINES="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}"
62
63 if mkdir -p . 2> /dev/null; then
64   # Great, mkdir accepts -p
65   mkinstalldirs="mkdir -p"
66 else
67   # We expect mkinstalldirs to be passed in the environment.
68   # If it is not, assume it is in the directory that contains this script.
69   mkinstalldirs=${mkinstalldirs-"/bin/sh $dirname/mkinstalldirs"}
70   if $mkinstalldirs . 2> /dev/null; then
71     :
72   else
73     # But, in case of failure, fallback to plain mkdir, and hope it works
74     mkinstalldirs=mkdir
75   fi
76 fi
77
78 if [ `echo $1 | wc -w` = 0 ] ; then
79   echo $progname\: usage\: $progname target-dir \[ source-dir \.\.\. \]
80   exit 1
81 fi
82
83 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/socket.h sys/stat.h sys/times.h sys/resource.h sys/utsname.h sys/wait.h tar.h termios.h time.h unistd.h utime.h"
84
85 rel_target_dir=$1
86 # All files in $src_dir_all (normally same as $rel_target_dir) are
87 # processed.
88 src_dir_all=$2
89 # In $src_dir_std (normally same as /usr/include), only the
90 # "standard" ANSI/POSIX files listed in $std_files are processed.
91 src_dir_std=$3
92
93 case $rel_target_dir in
94   /* | [A-Za-z]:[\\/]*)
95      abs_target_dir=$rel_target_dir
96      ;;
97   *)
98      abs_target_dir=$original_dir/$rel_target_dir
99      ;;
100 esac
101
102 # Determine whether this system has symbolic links.
103 if ln -s X $rel_target_dir/ShouldNotExist 2>/dev/null; then
104   rm -f $rel_target_dir/ShouldNotExist
105   LINKS=true
106 elif ln -s X /tmp/ShouldNotExist 2>/dev/null; then
107   rm -f /tmp/ShouldNotExist
108   LINKS=true
109 else
110   LINKS=false
111 fi
112
113 if [ \! -d $abs_target_dir ] ; then
114   echo $progname\: creating directory $rel_target_dir
115   $mkinstalldirs $abs_target_dir
116 fi
117
118 echo $progname\: populating \`$rel_target_dir\'
119
120 include_path=""
121
122 if [ `echo $* | wc -w` != 0 ] ; then
123   for rel_source_dir in $src_dir_all $src_dir_std; do
124      case $rel_source_dir in
125        /* | [A-Za-z]:[\\/]*)
126          abs_source_dir=$rel_source_dir
127          ;;
128        *)
129          abs_source_dir=$original_dir/$rel_source_dir
130          ;;
131      esac
132     include_path="$include_path -I$abs_source_dir"
133   done
134 fi
135
136 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"
137 # "div ldiv", - ignored because these depend on div_t, ldiv_t
138 # ignore these: "mblen mbstowcs mbstowc wcstombs wctomb"
139 # Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions.
140 # Should perhaps also add NULL
141 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"
142
143 done_dirs=""
144 subdirs_made=""
145 echo "" >fixproto.list
146
147 for code in ALL STD ; do
148
149   subdirs="."
150
151   case $code in
152     ALL)
153       rel_source_dir=$src_dir_all
154
155       dirs="."
156       levels=2
157       while $LINKS && test -n "$dirs" -a $levels -gt 0
158       do
159         levels=`expr $levels - 1`
160         newdirs=
161         for d in $dirs ; do
162           # Find all directories under $d, relative to $d, excluding $d itself.
163           # Assume directory names ending in CC or containing ++ are
164           # for C++, so skip those.
165           subdirs="$subdirs "`cd $rel_source_dir/$d; find . -type d -print | \
166                    sed -e '/^\.$/d' -e "s|^\./|${d}/|" -e 's|^\./||' \
167                      -e '/CC$/d' -e '/[+][+]/d'`
168           links=
169           links=`cd $rel_source_dir; find $d/. -type l -print | \
170                        sed -e "s|$d/./|$d/|" -e 's|^\./||'`
171           for link in $links --dummy-- ; do
172             test -d $rel_source_dir/$link/. && newdirs="$newdirs $link"
173           done
174         done
175         dirs="$newdirs"
176         subdirs="$subdirs $newdirs"
177       done
178       ;;
179     STD)
180       rel_source_dir=$src_dir_std
181       ;;
182   esac
183
184   case $rel_source_dir in
185     /* | [A-Za-z]:[\\/]*)
186        abs_source_dir=$rel_source_dir
187        ;;
188     *)
189        abs_source_dir=$original_dir/$rel_source_dir
190        ;;
191   esac
192
193   if [ \! -d $abs_source_dir ] ; then
194     echo $progname\: warning\: no such directory\: \`$rel_source_dir\'
195     continue
196   fi
197
198   for rel_source_subdir in $subdirs; do
199
200       abs_target_subdir=${abs_target_dir}/${rel_source_subdir}
201       if [ \! -d $abs_target_subdir ] ; then
202         if $mkinstalldirs $abs_target_subdir ; then
203           subdirs_made="$abs_target_subdir $subdirs_made"
204         fi
205       fi
206       # Append "/"; remove initial "./". Hence "." -> "" and "sys" -> "sys/".
207       rel_source_prefix=`echo $rel_source_subdir | sed -e 's|$|/|' -e 's|^./||'`
208
209       case $code in
210         ALL)
211           # The 'sed' is in case the *.h matches nothing, which yields "*.h"
212           # which would then get re-globbed in the current directory.  Sigh.
213           rel_source_files=`cd ${abs_source_dir}/${rel_source_subdir}; echo *.h | sed -e 's|[*].h|NONE|'`
214           ;;
215
216         STD)
217           files_to_check="$std_files"
218           rel_source_files=""
219
220           # Also process files #included by the $std_files.
221           while [ -n "${files_to_check}" ]
222           do
223             new_files_to_check=""
224             for file in $files_to_check ; do
225               xxfile=`echo $file | sed -e 's|/\([^/\.][^/\.]*\)/\.\./|/|'`
226               # Create the dir where this file will go when fixed.
227               xxdir=`echo ./$file | sed -e 's|/[^/]*$||'`
228               if [ \! -d $abs_target_subdir/$xxdir ] ; then
229                 if $mkinstalldirs $abs_target_subdir/$xxdir ; then
230                   subdirs_made="$abs_target_subdir/$xxdir $subdirs_made"
231                 fi
232               fi
233               # Just in case we have edited out a symbolic link
234               if [ -f $src_dir_std/$file -a -f $src_dir_std/$xxfile ] ; then
235                 file=$xxfile
236               fi
237               case " $rel_source_files " in
238                 *" ${file} "*)
239                   # Already seen $file; nothing to do
240                   ;;
241                 *)
242                   if test -f $src_dir_std/$file ; then
243                     rel_dir=`echo $file | sed -n -e 's|^\(.*/\)[^/]*$|\1|p'`
244                     # For #include "foo.h", that might be either "foo.h"
245                     # or "${rel_dir}foo.h (or something bogus).
246                     new_files_to_check="$new_files_to_check "`sed -n \
247                         -e 's@  @ @g' \
248                         -e 's@^ *# *include *<\([^>]*\)>.*$@\1@p' -e \
249                         's@^ *# *include *\"\([^\"]*\)\".*$@\1 '$rel_dir'\1@p'\
250                         <$src_dir_std/$file`
251                     rel_source_files="$rel_source_files $file"
252                   fi
253                   ;;
254               esac
255             done
256             files_to_check="$new_files_to_check"
257           done
258           rel_source_files="$rel_source_files"
259           ;;
260       esac
261
262       for filename in $rel_source_files ; do
263         rel_source_file=${rel_source_prefix}${filename}
264         abs_source_file=$abs_source_dir/$rel_source_file
265         abs_target_file=$abs_target_dir/$rel_source_file
266
267         if test "$filename" = 'NONE' ; then
268           echo "(No *.h files in $abs_source_dir/$rel_source_subdir)"
269         # If target file exists, check if was written while processing one
270         # of the earlier source directories;  if so ignore it.
271         elif test -f $abs_target_file -a -n "$done_dirs" \
272           && grep "$rel_source_file" fixproto.list >/dev/null
273         then true
274         else
275           $FIX_HEADER $rel_source_file $abs_source_file $abs_target_file ${DEFINES} $include_path
276           if test $? != 0 ; then exit 1 ; fi
277           echo "${rel_source_file}" >>fixproto.list
278         fi
279       done
280     done
281     done_dirs="$done_dir $rel_source_dir"
282 done
283
284 # This might be more cleanly moved into the main loop, by adding
285 # a <dummy> source directory at the end.  FIXME!
286 for rel_source_file in unistd.h stdlib.h
287 do
288   if grep "$rel_source_file" fixproto.list >/dev/null
289   then true
290   else
291     echo Adding missing $rel_source_file
292     rel_source_ident=`echo $rel_source_file | tr ./ __`
293     required_list=`eval echo '${required_'${rel_source_ident}'-}'`
294     cat >tmp.h <<EOF
295 #ifndef __${rel_source_ident}
296 #define __${rel_source_ident}
297 EOF
298     if test $rel_source_file = stdlib.h
299     then
300       # Make sure it contains a definition of size_t.
301       cat >>tmp.h <<EOF
302
303 #define __need_size_t
304 #include <stddef.h>
305 EOF
306     fi
307     cat >>tmp.h <<EOF
308
309 #endif /* __${rel_source_ident} */
310 EOF
311     ${FIX_HEADER} $rel_source_file tmp.h $abs_target_dir/$rel_source_file ${DEFINES} $include_path
312     if test $? != 0 ; then exit 1 ; fi
313     if test -f $abs_target_dir/$rel_source_file
314     then
315       rm tmp.h
316     else
317       mv tmp.h $abs_target_dir/$rel_source_file
318     fi
319   fi
320 done
321
322 # Remove any directories that we made that are still empty.
323 rmdir $subdirs_made 2>/dev/null
324
325 exit 0