160 lines
2.8 KiB
Bash
160 lines
2.8 KiB
Bash
#!/bin/bash
|
|
nl='
|
|
'
|
|
safeIFS=' '
|
|
safeIFS=" $safeIFS$nl"
|
|
IFS=$safeIFS
|
|
allu=QWERTYUIOPASDFGHJKLZXCVBNM
|
|
alll=qwertyuiopasdfghjklzxcvbnm
|
|
alln=0123456789
|
|
|
|
test_n() {
|
|
test x"$1" = x"" || return 0
|
|
return 1
|
|
}
|
|
|
|
test_z() {
|
|
test x"$1" = x""
|
|
}
|
|
|
|
genopt_die() {
|
|
if test_z "$1"; then
|
|
echo >&2 "E: invalid input in '$srcfile': '$line'"
|
|
else
|
|
echo >&2 "E: $*"
|
|
echo >&2 "N: in '$srcfile': '$line'"
|
|
fi
|
|
rm -f "$bn.gen"
|
|
exit 1
|
|
}
|
|
|
|
genopt_soptc() {
|
|
optc=`echo "$line" | sed 's/^[<>]\(.\).*$/\1/'`
|
|
test x"$optc" = x'|' && return
|
|
optclo=`echo "$optc" | tr $allu $alll`
|
|
if test x"$optc" = x"$optclo"; then
|
|
islo=1
|
|
else
|
|
islo=0
|
|
fi
|
|
sym=`echo "$line" | sed 's/^[<>]/|/'`
|
|
o_str=$o_str$nl"<$optclo$islo$sym"
|
|
}
|
|
|
|
genopt_scond() {
|
|
case x$cond in
|
|
x)
|
|
cond=
|
|
;;
|
|
x*' '*)
|
|
cond=`echo "$cond" | sed 's/^ //'`
|
|
cond="#if $cond"
|
|
;;
|
|
x'!'*)
|
|
cond=`echo "$cond" | sed 's/^!//'`
|
|
cond="#ifndef $cond"
|
|
;;
|
|
x*)
|
|
cond="#ifdef $cond"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
do_genopt() {
|
|
srcfile=$1
|
|
test -f "$srcfile" || genopt_die Source file \$srcfile not set.
|
|
bn=`basename "$srcfile" | sed 's/.opt$//'`
|
|
o_hdr='/* +++ GENERATED FILE +++ DO NOT EDIT +++ */'
|
|
o_gen=
|
|
o_str=
|
|
o_sym=
|
|
ddefs=
|
|
state=0
|
|
exec <"$srcfile"
|
|
IFS=
|
|
while IFS= read line; do
|
|
IFS=$safeIFS
|
|
case $state:$line in
|
|
2:'|'*)
|
|
# end of input
|
|
o_sym=`echo "$line" | sed 's/^.//'`
|
|
o_gen=$o_gen$nl"#undef F0"
|
|
o_gen=$o_gen$nl"#undef FN"
|
|
o_gen=$o_gen$ddefs
|
|
state=3
|
|
;;
|
|
1:@@)
|
|
# start of data block
|
|
o_gen=$o_gen$nl"#endif"
|
|
o_gen=$o_gen$nl"#ifndef F0"
|
|
o_gen=$o_gen$nl"#define F0 FN"
|
|
o_gen=$o_gen$nl"#endif"
|
|
state=2
|
|
;;
|
|
*:@@*)
|
|
genopt_die ;;
|
|
0:/\*-|0:\ \**|0:)
|
|
o_hdr=$o_hdr$nl$line
|
|
;;
|
|
0:@*|1:@*)
|
|
# start of a definition block
|
|
sym=`echo "$line" | sed 's/^@//'`
|
|
if test $state = 0; then
|
|
o_gen=$o_gen$nl"#if defined($sym)"
|
|
else
|
|
o_gen=$o_gen$nl"#elif defined($sym)"
|
|
fi
|
|
ddefs="$ddefs$nl#undef $sym"
|
|
state=1
|
|
;;
|
|
0:*|3:*)
|
|
genopt_die ;;
|
|
1:*)
|
|
# definition line
|
|
o_gen=$o_gen$nl$line
|
|
;;
|
|
2:'<'*'|'*)
|
|
genopt_soptc
|
|
;;
|
|
2:'>'*'|'*)
|
|
genopt_soptc
|
|
cond=`echo "$line" | sed 's/^[^|]*|//'`
|
|
genopt_scond
|
|
case $optc in
|
|
'|') optc=0 ;;
|
|
*) optc=\'$optc\' ;;
|
|
esac
|
|
IFS= read line || genopt_die Unexpected EOF
|
|
IFS=$safeIFS
|
|
test_z "$cond" || o_gen=$o_gen$nl"$cond"
|
|
o_gen=$o_gen$nl"$line, $optc)"
|
|
test_z "$cond" || o_gen=$o_gen$nl"#endif"
|
|
;;
|
|
esac
|
|
done
|
|
case $state:$o_sym in
|
|
3:) genopt_die Expected optc sym at EOF ;;
|
|
3:*) ;;
|
|
*) genopt_die Missing EOF marker ;;
|
|
esac
|
|
echo "$o_str" | sort | while IFS='|' read x opts cond; do
|
|
IFS=$safeIFS
|
|
test_n "$x" || continue
|
|
genopt_scond
|
|
test_z "$cond" || echo "$cond"
|
|
echo "\"$opts\""
|
|
test_z "$cond" || echo "#endif"
|
|
done | {
|
|
echo "$o_hdr"
|
|
echo "#ifndef $o_sym$o_gen"
|
|
echo "#else"
|
|
cat
|
|
echo "#undef $o_sym"
|
|
echo "#endif"
|
|
} >"$bn.gen"
|
|
IFS=$safeIFS
|
|
return 0
|
|
}
|
|
|
|
do_genopt "$1"
|