#!/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"