summaryrefslogtreecommitdiff
path: root/gcc/scan-types.sh
blob: 59d786a9fd01cb8a6662a3cd379ad1614e66d783 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#! /bin/sh
# Deduce values of standard ANSI and POSIX types (e.g. size_t, pid_t).
# Emits macros definitions for these, and some other types.
# Intended to be used to massage the sys-protos.h file.
# Expects one arg, which is the GCC source directory.

CC=${CC-"./xgcc -B$1/"}
CPP=${CPP-`echo ${CC} -E -I"$1/"`}
SED=sed

# Generate definitions for the standard types (such as mode_t)
# compatible with those in the standard C header files.
# It works by a dummy program through the C pre-processor, and then
# using sed to search for typedefs in the output.

cat >st-dummy.c <<!EOF!
#include <sys/types.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
#ifdef size_t
typedef size_t Xsize_t;
#elif defined(__SIZE_TYPE__)
typedef __SIZE_TYPE__ Xsize_t;
#endif
#ifdef va_list
typedef va_list XXXva_list;
#endif
!EOF!

if ${CPP} st-dummy.c >TMP ; then true
else
  echo "scan-types: could not invoke ${CPP} on st-dummy.c" 1>&2 ; exit 1
fi
tr '	' ' ' <TMP >st-dummy.out

for TYPE in dev_t clock_t fpos_t gid_t ino_t mode_t nlink_t off_t pid_t size_t ssize_t time_t uid_t va_list int32_t uint_32_t ; do
    IMPORTED=`eval 'echo $'"$TYPE"`
    if [ -n "${IMPORTED}" ] ; then
	eval "$TYPE='$IMPORTED"
    else
	# Search st-dummy.out for a typedef for $TYPE, and write it out
	# to TMP in #define syntax.
	rm -f TMP
	${SED} -n -e "s|.*typedef  *\(.*\) X*$TYPE *;.*|\1|w TMP" <st-dummy.out>/dev/null
	# Now select the first definition.
        if [ -s TMP ]; then
	    # VALUE is now the typedef'd definition of $TYPE.
            eval "VALUE='`${SED} -e 's| *$||' -e '2,$d' <TMP`'"
	    # Unless VALUE contains a blank, look for a typedef for it
	    # in turn (this could be a loop, but that would be over-kill).
	    # Ensure $VALUE is double quoted to protect cases where it
	    # contains an asterisk and would cause filename expansion.
	    # E.g. when va_list is "char *".
	    if echo "$VALUE" | grep " " >/dev/null ; then true
	    else
		rm -f TMP
		${SED} -n -e "s|.*typedef[ 	][ 	]*\(.*[^a-zA-Z0-9_]\)${VALUE}[ 	]*;.*|\1|w TMP" <st-dummy.out>/dev/null
		if [ -s TMP ]; then
		    eval "VALUE='`${SED} -e '2,$d' -e 's|[ 	]*$||' <TMP`'"
		fi
	    fi
	    eval "$TYPE='$VALUE'"
	fi
    fi
done

cat <<!EOF!
#define ${macro_prefix}clock_t ${clock_t-int /* default */}
#define ${macro_prefix}dev_t ${dev_t-int /* default */}
#define ${macro_prefix}fpos_t ${fpos_t-long /* default */}
#define ${macro_prefix}gid_t ${gid_t-int /* default */}
#define ${macro_prefix}ino_t ${ino_t-int /* default */}
#define ${macro_prefix}mode_t ${mode_t-int /* default */}
#define ${macro_prefix}nlink_t ${nlink_t-int /* default */}
#define ${macro_prefix}off_t ${off_t-long /* default */}
#define ${macro_prefix}pid_t ${pid_t-int /* default */}
#define ${macro_prefix}ptrdiff_t __PTRDIFF_TYPE__
#define ${macro_prefix}size_t __SIZE_TYPE__
#define ${macro_prefix}time_t ${time_t-int /* default */}
#define ${macro_prefix}uid_t ${uid_t-int /* default */}
#define ${macro_prefix}wchar_t __WCHAR_TYPE__
#define ${macro_prefix}int32_t ${int32_t-int /* default */}
#define ${macro_prefix}uint32_t ${uint32_t-unsigned int /* default */}
!EOF!

# (wait_arg_t*) should be (int*), according to Posix, but
# BSD traditionally used (union wait*).  Use (void*) to allow either usage.
echo "#define ${macro_prefix}wait_arg_t void"

# ssize_t is the signed version of size_t
if [ -n "${ssize_t}" ] ; then
    echo "#define ${macro_prefix}ssize_t ${ssize_t}"
elif [ -z "${size_t}" ] ; then
    echo "#define ${macro_prefix}ssize_t long"
else
    # Remove "unsigned" from ${size_t} to get ${ssize_t}.
    tmp="`echo ${size_t} | ${SED} -e 's|unsigned||g' -e 's|  | |g'`"
    if [ -z "$tmp" ] ; then
	tmp=int
    else
	# check $tmp doesn't conflict with <unistd.h>
	echo "#include <unistd.h>
	extern $tmp read();" >st-dummy.c
	${CC} -c st-dummy.c >/dev/null 2>&1 || tmp=int
    fi
    echo "#define ${macro_prefix}ssize_t $tmp /* default */"
fi

# va_list can cause problems (e.g. some systems have va_list as a struct).
# Check to see if ${va_list-char*} really is compatible with stdarg.h.
cat >st-dummy.c <<!EOF!
#define X_va_list ${va_list-char* /* default */}
extern long foo(X_va_list ap); /* Check that X_va_list compiles on its own */
#include <stdarg.h>
long foo(X_va_list ap) { return va_arg(ap, long); }
long bar(int i, ...)
{ va_list ap; long j; va_start(ap, i); j = foo(ap); va_end(ap); return j; }
!EOF!
if ${CC} -c st-dummy.c >/dev/null 2>&1 ; then
  # Ok: We have something that works.
  echo "#define ${macro_prefix}va_list ${va_list-char* /* default */}"
else
  # No, it breaks.  Indicate that <stdarg.h> must be included.
  echo "#define ${macro_prefix}NEED_STDARG_H
#define ${macro_prefix}va_list va_list"
fi

# stuff needed for curses.h

# This isn't correct for SVR4 (for example).  However, we only
# use this when adding a missing prototype, so it shouldn't matter.
echo "#define chtype int"
# sys-protos.h uses non-standard names (due to the CHTYPE argument problem).
echo "#define box32 box"
echo "#define initscr32 initscr"
echo "#define w32addch waddch"
echo "#define w32insch winsch"

rm -f st-dummy.c st-dummy.o TMP st-dummy.out