1test -n "$1" -a -n "$2" -a -n "$3" 2set -ef 3 4SED=sed 5if test -x /usr/xpg4/bin/sed; then 6 SED=/usr/xpg4/bin/sed 7fi 8if test -z ${PYTHON}; then 9 PYTHON=`/usr/bin/env python` 10fi 11if test -z ${PYTHON}; then 12 echo "Python not found" 13 exit 1 14fi 15 16get_fields () 17{ 18 local level=1 aggr=0 name= fields= 19 for token in $2 20 do 21 case "$token" in 22 struct|union) 23 test $level != 1 || aggr=1 fields= name= 24 ;; 25 "{") 26 level=$(expr $level + 1) 27 ;; 28 "}") 29 level=$(expr $level - 1) 30 if [ $level = 1 -a $name = $1 ] 31 then 32 echo "$fields }" 33 return 0 34 fi 35 ;; 36 [a-zA-Z_]*) 37 test $aggr = 0 -o -n "$name" || name="$token" 38 ;; 39 esac 40 test $aggr = 0 || fields="$fields $token" 41 done 42} 43 44get_typedefs () 45{ 46 local level=1 state= 47 for token in $1 48 do 49 case "$token" in 50 typedef) 51 test $level != 1 || state=1 52 ;; 53 COMPAT_HANDLE\(*\)) 54 test $level != 1 -o "$state" != 1 || state=2 55 ;; 56 [\{\[]) 57 level=$(expr $level + 1) 58 ;; 59 [\}\]]) 60 level=$(expr $level - 1) 61 ;; 62 ";") 63 test $level != 1 || state= 64 ;; 65 [a-zA-Z_]*) 66 test $level != 1 -o "$state" != 2 || echo "$token" 67 ;; 68 esac 69 done 70} 71 72build_enums () 73{ 74 local level=1 kind= fields= members= named= id= token 75 for token in $2 76 do 77 case "$token" in 78 struct|union) 79 test $level != 2 || fields=" " 80 kind="$token;$kind" 81 ;; 82 "{") 83 level=$(expr $level + 1) 84 ;; 85 "}") 86 level=$(expr $level - 1) 87 if [ $level = 1 ] 88 then 89 if [ "${kind%%;*}" = union ] 90 then 91 echo 92 echo "enum XLAT_$1 {" 93 for m in $members 94 do 95 echo " XLAT_${1}_$m," 96 done 97 echo "};" 98 fi 99 return 0 100 elif [ $level = 2 ] 101 then 102 named='?' 103 fi 104 ;; 105 [a-zA-Z]*) 106 id=$token 107 if [ -n "$named" -a -n "${kind#*;}" ] 108 then 109 build_enums ${1}_$token "$fields" 110 named='!' 111 fi 112 ;; 113 ",") 114 test $level != 2 || members="$members $id" 115 ;; 116 ";") 117 test $level != 2 || members="$members $id" 118 test -z "$named" || kind=${kind#*;} 119 named= 120 ;; 121 esac 122 test -z "$fields" || fields="$fields $token" 123 done 124} 125 126handle_field () 127{ 128 if [ -z "$5" ] 129 then 130 echo " \\" 131 if [ -z "$4" ] 132 then 133 printf %s "$1(_d_)->$3 = (_s_)->$3;" 134 else 135 printf %s "$1XLAT_${2}_HNDL_$(echo $3 | $SED 's,\.,_,g')(_d_, _s_);" 136 fi 137 elif [ -z "$(echo "$5" | $SED 's,[^{}],,g')" ] 138 then 139 local tag=$(echo "$5" | ${PYTHON} -c ' 140import re,sys 141for line in sys.stdin.readlines(): 142 print re.subn(r"\s*(struct|union)\s+(compat_)?(\w+)\s.*", r"\3", line)[0].rstrip() 143') 144 echo " \\" 145 printf %s "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);" 146 else 147 local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token 148 for token in $5 149 do 150 case "$token" in 151 struct|union) 152 test $level != 2 || fields=" " 153 if [ $level = 1 ] 154 then 155 kind=$token 156 if [ $kind = union ] 157 then 158 echo " \\" 159 printf %s "${1}switch ($(echo $3 | $SED 's,\.,_,g')) {" 160 fi 161 fi 162 ;; 163 "{") 164 level=$(expr $level + 1) id= 165 ;; 166 "}") 167 level=$(expr $level - 1) id= 168 if [ $level = 1 -a $kind = union ] 169 then 170 echo " \\" 171 printf %s "$1}" 172 fi 173 ;; 174 "[") 175 if [ $level != 2 -o $arrlvl != 1 ] 176 then 177 : 178 elif [ -z "$array" ] 179 then 180 array=" " 181 else 182 array="$array;" 183 fi 184 arrlvl=$(expr $arrlvl + 1) 185 ;; 186 "]") 187 arrlvl=$(expr $arrlvl - 1) 188 ;; 189 COMPAT_HANDLE\(*\)) 190 if [ $level = 2 -a -z "$id" ] 191 then 192 type=${token#COMPAT_HANDLE?} 193 type=${type%?} 194 type=${type#compat_} 195 fi 196 ;; 197 compat_domain_handle_t) 198 if [ $level = 2 -a -z "$id" ] 199 then 200 array_type=$token 201 fi 202 ;; 203 [a-zA-Z]*) 204 if [ -z "$id" -a -z "$type" -a -z "$array_type" ] 205 then 206 for id in $typedefs 207 do 208 test $id != "$token" || type=$id 209 done 210 if [ -z "$type" ] 211 then 212 id=$token 213 else 214 id= 215 fi 216 else 217 id=$token 218 fi 219 ;; 220 [\,\;]) 221 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] 222 then 223 if [ $kind = union ] 224 then 225 echo " \\" 226 printf %s "${1}case XLAT_${2}_$(echo $3.$id | $SED 's,\.,_,g'):" 227 handle_field "$1 " $2 $3.$id "$type" "$fields" 228 elif [ -z "$array" -a -z "$array_type" ] 229 then 230 handle_field "$1" $2 $3.$id "$type" "$fields" 231 elif [ -z "$array" ] 232 then 233 copy_array " " $3.$id 234 else 235 handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields" 236 fi 237 test "$token" != ";" || fields= id= type= 238 array= 239 if [ $kind = union ] 240 then 241 echo " \\" 242 printf %s "$1 break;" 243 fi 244 fi 245 ;; 246 *) 247 if [ -n "$array" ] 248 then 249 array="$array $token" 250 fi 251 ;; 252 esac 253 test -z "$fields" || fields="$fields $token" 254 done 255 fi 256} 257 258copy_array () 259{ 260 echo " \\" 261 echo "${1}if ((_d_)->$2 != (_s_)->$2) \\" 262 printf %s "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));" 263} 264 265handle_array () 266{ 267 local i="i$(echo $4 | $SED 's,[^;], ,g' | wc -w | $SED 's,[[:space:]]*,,g')" 268 echo " \\" 269 echo "$1{ \\" 270 echo "$1 unsigned int $i; \\" 271 printf %s "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {" 272 if [ "$4" = "${4#*;}" ] 273 then 274 handle_field "$1 " $2 $3[$i] "$5" "$6" 275 else 276 handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6" 277 fi 278 echo " \\" 279 echo "$1 } \\" 280 printf %s "$1}" 281} 282 283build_body () 284{ 285 echo 286 printf %s "#define XLAT_$1(_d_, _s_) do {" 287 local level=1 fields= id= array= arrlvl=1 array_type= type= token 288 for token in $2 289 do 290 case "$token" in 291 struct|union) 292 test $level != 2 || fields=" " 293 ;; 294 "{") 295 level=$(expr $level + 1) id= 296 ;; 297 "}") 298 level=$(expr $level - 1) id= 299 ;; 300 "[") 301 if [ $level != 2 -o $arrlvl != 1 ] 302 then 303 : 304 elif [ -z "$array" ] 305 then 306 array=" " 307 else 308 array="$array;" 309 fi 310 arrlvl=$(expr $arrlvl + 1) 311 ;; 312 "]") 313 arrlvl=$(expr $arrlvl - 1) 314 ;; 315 COMPAT_HANDLE\(*\)) 316 if [ $level = 2 -a -z "$id" ] 317 then 318 type=${token#COMPAT_HANDLE?} 319 type=${type%?} 320 type=${type#compat_} 321 fi 322 ;; 323 compat_domain_handle_t) 324 if [ $level = 2 -a -z "$id" ] 325 then 326 array_type=$token 327 fi 328 ;; 329 [a-zA-Z_]*) 330 if [ -n "$array" ] 331 then 332 array="$array $token" 333 elif [ -z "$id" -a -z "$type" -a -z "$array_type" ] 334 then 335 for id in $typedefs 336 do 337 test $id != "$token" || type=$id 338 done 339 if [ -z "$type" ] 340 then 341 id=$token 342 else 343 id= 344 fi 345 else 346 id=$token 347 fi 348 ;; 349 [\,\;]) 350 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] 351 then 352 if [ -z "$array" -a -z "$array_type" ] 353 then 354 handle_field " " $1 $id "$type" "$fields" 355 elif [ -z "$array" ] 356 then 357 copy_array " " $id 358 else 359 handle_array " " $1 $id "${array#*;}" "$type" "$fields" 360 fi 361 test "$token" != ";" || fields= id= type= 362 array= 363 fi 364 ;; 365 *) 366 if [ -n "$array" ] 367 then 368 array="$array $token" 369 fi 370 ;; 371 esac 372 test -z "$fields" || fields="$fields $token" 373 done 374 echo " \\" 375 echo "} while (0)" 376} 377 378check_field () 379{ 380 if [ -z "$(echo "$4" | $SED 's,[^{}],,g')" ] 381 then 382 echo "; \\" 383 local n=$(echo $3 | $SED 's,[^.], ,g' | wc -w | $SED 's,[[:space:]]*,,g') 384 if [ -n "$4" ] 385 then 386 for n in $4 387 do 388 case $n in 389 struct|union) 390 ;; 391 [a-zA-Z_]*) 392 printf %s " CHECK_${n#xen_}" 393 break 394 ;; 395 *) 396 echo "Malformed compound declaration: '$n'" >&2 397 exit 1 398 ;; 399 esac 400 done 401 elif [ $n = 0 ] 402 then 403 printf %s " CHECK_FIELD_($1, $2, $3)" 404 else 405 printf %s " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | $SED 's!\.!, !g'))" 406 fi 407 else 408 local level=1 fields= id= token 409 for token in $4 410 do 411 case "$token" in 412 struct|union) 413 test $level != 2 || fields=" " 414 ;; 415 "{") 416 level=$(expr $level + 1) id= 417 ;; 418 "}") 419 level=$(expr $level - 1) id= 420 ;; 421 [a-zA-Z]*) 422 id=$token 423 ;; 424 [\,\;]) 425 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] 426 then 427 check_field $1 $2 $3.$id "$fields" 428 test "$token" != ";" || fields= id= 429 fi 430 ;; 431 esac 432 test -z "$fields" || fields="$fields $token" 433 done 434 fi 435} 436 437build_check () 438{ 439 echo 440 echo "#define CHECK_$1 \\" 441 local level=1 fields= kind= id= arrlvl=1 token 442 for token in $2 443 do 444 case "$token" in 445 struct|union) 446 if [ $level = 1 ] 447 then 448 kind=$token 449 printf %s " CHECK_SIZE_($kind, $1)" 450 elif [ $level = 2 ] 451 then 452 fields=" " 453 fi 454 ;; 455 "{") 456 level=$(expr $level + 1) id= 457 ;; 458 "}") 459 level=$(expr $level - 1) id= 460 ;; 461 "[") 462 arrlvl=$(expr $arrlvl + 1) 463 ;; 464 "]") 465 arrlvl=$(expr $arrlvl - 1) 466 ;; 467 [a-zA-Z_]*) 468 test $level != 2 -o $arrlvl != 1 || id=$token 469 ;; 470 [\,\;]) 471 if [ $level = 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] 472 then 473 check_field $kind $1 $id "$fields" 474 test "$token" != ";" || fields= id= 475 fi 476 ;; 477 esac 478 test -z "$fields" || fields="$fields $token" 479 done 480 echo "" 481} 482 483list="$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)" 484fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$list")" 485if [ -z "$fields" ] 486then 487 echo "Fields of '$2' not found in '$3'" >&2 488 exit 1 489fi 490name=${2#compat_} 491name=${name#xen} 492case "$1" in 493"!") 494 typedefs="$(get_typedefs "$list")" 495 build_enums $name "$fields" 496 build_body $name "$fields" 497 ;; 498"?") 499 build_check $name "$fields" 500 ;; 501*) 502 echo "Invalid translation indicator: '$1'" >&2 503 exit 1 504 ;; 505esac 506