4 # fixproto TARGET-DIR SOURCE-DIR-ALL SOURCE-DIR-STD
7 # Copyright (C) 1993, 1994, 1997, 1998, 2002, 2003
8 # Free Software Foundation, Inc.
9 # This file is part of GCC.
11 # GCC is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2, or (at your option)
16 # GCC is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with GCC; see the file COPYING. If not, write to
23 # the Free Software Foundation, 59 Temple Place - Suite 330,
24 # Boston, MA 02111-1307, USA.
27 # Adjunct script for GCC to populate a directory with ANSI,
28 # Posix.1, and C++ compatible header files.
30 # Each file found under SOURCE-DIR-ALL is analyzed and "fixed."
31 # Only standard ANSI/POSIX files found under SOURCE-DIR-STD
32 # are analyzed and "fixed."
33 # The SOURCE-DIRs are searched in order; a file found
34 # under multiple SOURCE-DIRs is only handled for the first one.
37 # Each include file is fed through cpp, and the scan-decls program
38 # parses it, and emits any found function declarations.
39 # The fix-header program analyzes the scan-decls output,
40 # together with the original include file, and writes a "fixed"
41 # include file, if needed.
43 # The comment at the beginning of fix-header.c lists specifically
44 # what kind of changes are made.
47 # Some file space will be wasted, because the original header
48 # files are copied. An earlier version just included the original
49 # by "reference", using GNU cpp's #include_next mechanism.
50 # This is currently not done, partly because #include_next is
51 # fragile (susceptible to version incompatibilities, and depends
52 # and GCC-specific features), and partly for performance reasons.
55 # Ron Guilmette (rfg@netcom.com) (original idea and code)
56 # Per Bothner (bothner@cygnus.com) (major re-write)
58 dirname=`echo "$0" | sed 's,^[^/]*$,.,;s,//*[^/]*$,,'`
59 progname
=`echo "$0" | sed 's,.*/,,'`
60 original_dir
=`${PWDCMD-pwd}`
61 FIX_HEADER
=${FIX_HEADER-$original_dir/fix-header}
62 DEFINES
="-D__STDC__=0 -D__cplusplus ${FIXPROTO_DEFINES}"
64 if mkdir
-p .
2> /dev
/null
; then
65 # Great, mkdir accepts -p
66 mkinstalldirs
="mkdir -p"
68 # We expect mkinstalldirs to be passed in the environment.
69 # If it is not, assume it is in the directory that contains this script.
70 mkinstalldirs
=${mkinstalldirs-"/bin/sh $dirname/mkinstalldirs"}
71 if $mkinstalldirs .
2> /dev
/null
; then
74 # But, in case of failure, fallback to plain mkdir, and hope it works
79 if [ `echo $1 | wc -w` = 0 ] ; then
80 echo $progname\
: usage\
: $progname target-dir \
[ source-dir \.\.\. \
]
84 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"
87 # All files in $src_dir_all (normally same as $rel_target_dir) are
90 # In $src_dir_std (normally same as /usr/include), only the
91 # "standard" ANSI/POSIX files listed in $std_files are processed.
94 case $rel_target_dir in
96 abs_target_dir
=$rel_target_dir
99 abs_target_dir
=$original_dir/$rel_target_dir
103 # Determine whether this system has symbolic links.
104 if ln -s X
$rel_target_dir/ShouldNotExist
2>/dev
/null
; then
105 rm -f $rel_target_dir/ShouldNotExist
107 elif ln -s X
/tmp
/ShouldNotExist
2>/dev
/null
; then
108 rm -f /tmp
/ShouldNotExist
114 if [ \
! -d $abs_target_dir ] ; then
115 echo $progname\
: creating directory
$rel_target_dir
116 $mkinstalldirs $abs_target_dir
119 echo $progname\
: populating \
`$rel_target_dir\'
123 if [ `echo $
* |
wc -w` != 0 ] ; then
124 for rel_source_dir in $src_dir_all $src_dir_std; do
125 case $rel_source_dir in
126 /* | [A-Za-z]:[\\/]*)
127 abs_source_dir=$rel_source_dir
130 abs_source_dir=$original_dir/$rel_source_dir
133 include_path="$include_path -I$abs_source_dir"
139 echo "" >fixproto.list
141 for code in ALL STD ; do
147 rel_source_dir=$src_dir_all
151 while $LINKS && test -n "$dirs" -a $levels -gt 0
153 levels=`expr $levels - 1`
156 # Find all directories under $d, relative to $d, excluding $d itself.
157 # Assume directory names ending in CC or containing ++ are
158 # for C++, so skip those.
159 subdirs="$subdirs "`cd $rel_source_dir/$d; find .
-type d
-print | \
160 sed -e '/^\.$/d' -e "s|^\./|${d}/|" -e 's|^\./||' \
161 -e '/CC$/d' -e '/[+][+]/d'`
163 links=`cd $rel_source_dir; find $d/.
-type l
-print | \
164 sed -e "s|$d/./|$d/|" -e 's|^\./||'`
165 for link in $links --dummy-- ; do
166 test -d $rel_source_dir/$link/. && newdirs="$newdirs $link"
170 subdirs="$subdirs $newdirs"
174 rel_source_dir=$src_dir_std
178 case $rel_source_dir in
179 /* | [A-Za-z]:[\\/]*)
180 abs_source_dir=$rel_source_dir
183 abs_source_dir=$original_dir/$rel_source_dir
187 if [ \! -d $abs_source_dir ] ; then
188 echo $progname\: warning\: no such directory\: \`$rel_source_dir\'
192 for rel_source_subdir
in $subdirs; do
194 abs_target_subdir
=${abs_target_dir}/${rel_source_subdir}
195 if [ \
! -d $abs_target_subdir ] ; then
196 if $mkinstalldirs $abs_target_subdir ; then
197 subdirs_made
="$abs_target_subdir $subdirs_made"
200 # Append "/"; remove initial "./". Hence "." -> "" and "sys" -> "sys/".
201 rel_source_prefix
=`echo $rel_source_subdir | sed -e 's|$|/|' -e 's|^./||'`
205 # The 'sed' is in case the *.h matches nothing, which yields "*.h"
206 # which would then get re-globbed in the current directory. Sigh.
207 rel_source_files
=`cd ${abs_source_dir}/${rel_source_subdir}; echo *.h | sed -e 's|[*].h|NONE|'`
211 files_to_check
="$std_files"
214 # Also process files #included by the $std_files.
215 while [ -n "${files_to_check}" ]
217 new_files_to_check
=""
218 for file in $files_to_check ; do
219 xxfile
=`echo $file | sed -e 's|/\([^/\.][^/\.]*\)/\.\./|/|'`
220 # Create the dir where this file will go when fixed.
221 xxdir
=`echo ./$file | sed -e 's|/[^/]*$||'`
222 if [ \
! -d $abs_target_subdir/$xxdir ] ; then
223 if $mkinstalldirs $abs_target_subdir/$xxdir ; then
224 subdirs_made
="$abs_target_subdir/$xxdir $subdirs_made"
227 # Just in case we have edited out a symbolic link
228 if [ -f $src_dir_std/$file -a -f $src_dir_std/$xxfile ] ; then
231 case " $rel_source_files " in
233 # Already seen $file; nothing to do
236 if test -f $src_dir_std/$file ; then
237 rel_dir
=`echo $file | sed -n -e 's|^\(.*/\)[^/]*$|\1|p'`
238 # For #include "foo.h", that might be either "foo.h"
239 # or "${rel_dir}foo.h (or something bogus).
240 new_files_to_check
="$new_files_to_check "`sed -n \
242 -e 's@^ *# *include *<\([^>]*\)>.*$@\1@p' -e \
243 's@^ *# *include *\"\([^\"]*\)\".*$@\1 '$rel_dir'\1@p'\
245 rel_source_files
="$rel_source_files $file"
250 files_to_check
="$new_files_to_check"
252 rel_source_files
="$rel_source_files"
256 for filename
in $rel_source_files ; do
257 rel_source_file
=${rel_source_prefix}${filename}
258 abs_source_file
=$abs_source_dir/$rel_source_file
259 abs_target_file
=$abs_target_dir/$rel_source_file
261 if test "$filename" = 'NONE' ; then
262 echo "(No *.h files in $abs_source_dir/$rel_source_subdir)"
263 # If target file exists, check if was written while processing one
264 # of the earlier source directories; if so ignore it.
265 elif test -f $abs_target_file -a -n "$done_dirs" \
266 && grep "$rel_source_file" fixproto.list
>/dev
/null
269 $FIX_HEADER $rel_source_file $abs_source_file $abs_target_file ${DEFINES} $include_path
270 if test $?
!= 0 ; then exit 1 ; fi
271 echo "${rel_source_file}" >>fixproto.list
275 done_dirs
="$done_dir $rel_source_dir"
278 # This might be more cleanly moved into the main loop, by adding
279 # a <dummy> source directory at the end. FIXME!
281 # All the headers we create define size_t and NULL.
282 for rel_source_file
in unistd.h stdlib.h string.h
time.h
; do
283 if grep "$rel_source_file" fixproto.list
>/dev
/null
; then
284 : # It exists, we don't need to make it
286 echo Adding missing
$rel_source_file
287 rel_source_ident
=`echo $rel_source_file | tr ./ __`
289 /* Fake ${rel_source_file}, created by GCC.
290 The functions declared in this file do not necessarily exist in
292 #ifndef __${rel_source_ident}
293 #define __${rel_source_ident}
296 #define __need_size_t
299 # Insert special stuff for particular files here.
300 case ${rel_source_file} in
302 # If time.h doesn't exist, find out if sys/time.h does.
303 if test -f $src_dir_std/sys
/time.h \
304 ||
grep "sys/time.h" fixproto.list
>/dev
/null
; then
305 # It does; include it and hope it has the needed declarations.
306 # Some versions require sys/types.h.
309 #include <sys/types.h>
310 #include <sys/time.h>
313 # It doesn't. Make up plausible definitions for time_t, clock_t.
314 # Forward-declare struct tm. Hope nobody tries to use it. (Odds
319 typedef long clock_t;
326 #endif /* __${rel_source_ident} */
328 ${FIX_HEADER} $rel_source_file tmp.h
$abs_target_dir/$rel_source_file ${DEFINES} $include_path
329 if test $?
!= 0 ; then exit 1 ; fi
330 if test -f $abs_target_dir/$rel_source_file ; then
333 mv tmp.h
$abs_target_dir/$rel_source_file
338 # Remove any directories that we made that are still empty.
339 rmdir $subdirs_made 2>/dev
/null