1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                 Eclipse Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#          http://www.eclipse.org/org/documents/epl-v10.html           #
11#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20: generate the ksh math builtin table
21: include math.tab
22
23# @(#)math.sh (AT&T Research) 2012-06-13
24
25command=$0
26iffeflags="-n -v"
27iffehdrs="math.h"
28iffelibs="-lm"
29table=/dev/null
30
31eval $1
32shift
33table=$1
34
35: check long double
36
37eval `iffe $iffeflags -c "$cc" - typ long.double 2>&$stderr`
38
39: check ast_standards.h
40
41eval `iffe $iffeflags -F ast_standards.h -c "$cc" - tst use_ast_standards -lm 'note{' 'math.h needs ast_standards.h' '}end' 'link{' '#include <math.h>' '#ifndef isgreater' '#define isgreater(a,b) 0' '#endif' 'int main() { return isgreater(0.0,1.0); }' '}end'`
42case $_use_ast_standards in
431)	iffeflags="$iffeflags -F ast_standards.h" ;;
44esac
45eval `iffe $iffeflags -c "$cc" - tst use_ieeefp -lm 'note{' 'ieeefp.h plays nice' '}end' 'link{' '#include <math.h>' '#include <ieeefp.h>' 'int main() { return 0; }' '}end'`
46case $_use_ieeefp in
471)	iffehdrs="$iffehdrs ieeefp.h" ;;
48esac
49
50: read the table
51
52exec < $table
53ifs=$IFS
54libs=
55names=
56nums=
57while	read type args name aka
58do	case $type in
59	[fix])	names="$names $name"
60		libs="$libs,$name"
61		case $_typ_long_double in
62		1)	libs="$libs,${name}l" ;;
63		esac
64		for a in $aka
65		do	case $a in
66			'{'*)	break
67				;;
68			*=*)	IFS='=|'
69				set $a
70				IFS=$ifs
71				case ",$libs" in
72				*,$1,*)	;;
73				*)	names="$names $1"
74					libs="$libs,$1"
75					case $_typ_long_double in
76					1)	libs="$libs,${1}l" ;;
77					esac
78					;;
79				esac
80				shift
81				while	:
82				do	case $# in
83					0)	break ;;
84					esac
85					case ",$nums" in
86					*,$1,*)	;;
87					*)	nums="$nums,$1" ;;
88					esac
89					shift
90				done
91				;;
92			esac
93		done
94		eval TYPE_$name='$type' ARGS_$name='$args' AKA_$name='$aka'
95		;;
96	esac
97done
98
99: check the math library
100
101eval `iffe $iffeflags -c "$cc" - lib $libs $iffehdrs $iffelibs 2>&$stderr`
102lib=
103for name in $names
104do	eval x='$'_lib_${name}l y='$'_lib_${name}
105	case $x in
106	1)	lib="$lib,${name}l" ;;
107	esac
108	case $y in
109	1)	case $x in
110		'')	lib="$lib,${name}" ;;
111		esac
112		;;
113	esac
114done
115eval `iffe $iffeflags -c "$cc" - dat,npt,mac $lib $iffehdrs $iffelibs 2>&$stderr`
116eval `iffe $iffeflags -c "$cc" - num $nums $iffehdrs $iffelibs 2>&$stderr`
117
118cat <<!
119#pragma prototyped
120
121/* : : generated by $command from $table : : */
122
123typedef Sfdouble_t (*Math_f)(Sfdouble_t,...);
124
125!
126case $_use_ast_standards in
1271)	echo "#include <ast_standards.h>" ;;
128esac
129echo "#include <math.h>"
130case $_hdr_ieeefp in
1311)	echo "#include <ieeefp.h>" ;;
132esac
133echo
134
135: generate the intercept functions and table entries
136
137nl='
138'
139ht='	'
140tab=
141for name in $names
142do	eval x='$'_lib_${name}l y='$'_lib_${name} r='$'TYPE_${name} a='$'ARGS_${name} aka='$'AKA_${name}
143	case $r in
144	i)	L=int R=1 ;;
145	x)	L=Sfdouble_t R=4 ;;
146	*)	L=Sfdouble_t R=0 ;;
147	esac
148	F=local_$name
149	case $x:$y in
150	1:*)	f=${name}l
151		t=Sfdouble_t
152		local=
153		;;
154	*:1)	f=${name}
155		t=double
156		local=$_typ_long_double
157		;;
158	*)	body=
159		for k in $aka
160		do	case $body in
161			?*)	body="$body $k"
162				continue
163				;;
164			esac
165			case $k in
166			'{'*)	body=$k
167				;;
168			*=*)	IFS='=|'
169				set $k
170				IFS=$ifs
171				f=$1
172				shift
173				v=$*
174				eval x='$'_lib_${f}l y='$'_lib_${f}
175				case $x:$y in
176				1:*)	f=${f}l
177					;;
178				*:1)	;;
179				*)	continue
180					;;
181				esac
182				y=
183				while	:
184				do	case $# in
185					0)	break ;;
186					esac
187					eval x='$'_num_$1
188					case $x in
189					1)	case $y in
190						?*)	y="$y || " ;;
191						esac
192						y="${y}q == $1"
193						;;
194					esac
195					shift
196				done
197				case $y in
198				'')	;;
199				*)	r=int R=1
200					echo "static $r $F(Sfdouble_t a1) { $r q = $f(a1); return $y; }"
201					tab="$tab$nl$ht\"\\0${R}${a}${name}\",$ht(Math_f)(uintptr_t)${F},"
202					break
203					;;
204				esac
205				;;
206			esac
207		done
208		case $body in
209		?*)	code="static $L $F("
210			sep=
211			ta=
212			tc=
213			td=
214			for p in 1 2 3 4 5 6 7 8 9
215			do	case $R:$p in
216				4:2)	T=int ;;
217				*)	T=Sfdouble_t ;;
218				esac
219				code="$code${sep}$T a$p"
220				ta="$ta${sep}a$p"
221				tc="$tc${sep}0"
222				td="${td}$T a$p;"
223				case $a in
224				$p)	break ;;
225				esac
226				sep=","
227			done
228			_it_links_=0
229			eval `iffe $iffeflags -c "$cc" - tst it_links_ note{ $F function links }end link{ "static $L $F($ta)$td${body}int main(){return $F($tc)!=0;}" }end sfio.h $iffehdrs $iffelibs 2>&$stderr`
230			case $_it_links_ in
231			1)	code="$code)$body"
232				echo "$code"
233				tab="$tab$nl$ht\"\\0${R}${a}${name}\",$ht(Math_f)(uintptr_t)${F},"
234				;;
235			esac
236			;;
237		esac
238		continue
239		;;
240	esac
241	case $r in
242	i)	r=int ;;
243	*)	r=$t ;;
244	esac
245	eval n='$'_npt_$f m='$'_mac_$f d='$'_dat_$f
246	case $d:$m:$n in
247	1:*:*|*:1:*)
248		;;
249	*:*:1)	code="extern $r $f("
250		sep=
251		for p in 1 2 3 4 5 6 7
252		do	case $p:$f in
253			2:ldexp*)	code="$code${sep}int" ;;
254			*)		code="$code${sep}$t" ;;
255			esac
256			case $a in
257			$p)	break ;;
258			esac
259			sep=","
260		done
261		code="$code);"
262		echo "$code"
263		;;
264	esac
265	case $local:$m:$n:$d in
266	1:*:*:*|*:1:*:*|*:*:1:)
267		args=
268		code="static $L local_$f("
269		sep=
270		for p in 1 2 3 4 5 6 7 8 9
271		do	args="$args${sep}a$p"
272			case $R:$p in
273			4:2)	T=int ;;
274			*)	T=Sfdouble_t ;;
275			esac
276			code="$code${sep}$T a$p"
277			case $a in
278			$p)	break ;;
279			esac
280			sep=","
281		done
282		code="$code){return $f($args);}"
283		echo "$code"
284		f=local_$f
285		;;
286	esac
287	for x in $name $aka
288	do	case $x in
289		'{'*)	break
290			;;
291		*=*)	continue
292			;;
293		esac
294		tab="$tab$nl$ht\"\\0${R}${a}${x}\",$ht(Math_f)(uintptr_t)$f,"
295	done
296done
297tab="$tab$nl$ht\"\",$ht$ht(Math_f)0"
298
299cat <<!
300
301/*
302 * first byte is two-digit octal number.  Last digit is number of args
303 * first digit is 0 if return value is double, 1 for integer
304 */
305const struct mathtab shtab_math[] =
306{$tab
307};
308!
309