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