#!/usr/bin/env bash read_header() { local key value i while read key value; do case "$key" in ---) break ;; BN:) base_name="$value" ;; SF:) source_files="$value" ;; SN:) section_name="$value" ;; TM:) template_members="$value" esac done } read_one_command() { local line name_txt="" desc_txt="" usage_txt="" help_txt="" perms_txt="" template=0 template_name="" template_prototype="" while read key value; do case "$key" in ---) break ;; N:) name_txt="$value" ;; T:) template_name="$value" template=1 ;; O:) template_prototype="$value" template=1 ;; P:) perms_txt="$value" ;; D:) desc_txt="$value" ;; U:) usage_txt="$value" ;; H:) help_txt="${value}" while read line; do if test "$line" = "---"; then break; fi line=${line#H:} help_txt="$help_txt ${line# }" done break ;; esac done if test $template -eq 0; then if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \ -a -n "$help_txt"; then ret=1 return fi else if test -n "$template_name" -a -n "$template_prototype" \ -a -n "$name_txt " -a -n "$template_members" \ -a -n "$desc_txt" -a -n "$usage_txt" \ -a -n "$help_txt"; then ret=1 return fi fi if test -z "$name_txt" -a -z "$desc_txt" -a -z "$usage_txt" \ -a -z "$help_txt"; then ret=0 return fi ret=-1 #return echo "!ERROR!" echo "N: $name_txt" echo "D: $desc_txt" echo "S: $usage_txt" echo "P: $perms_txt" echo "H: $help_txt" echo "O: $template_prototype" } dump_man() { if test $template -eq 0; then echo ".SS \"$name_txt\"" echo "$desc_txt" echo echo "\\fBUsage: \\fP$usage_txt" else for member in $template_members; do local sed_cmd="sed -e s/@member@/$member/g" local t_name_txt=$(echo $name_txt | $sed_cmd) echo ".SS \"$t_name_txt\"" done echo "$desc_txt" | sed -e "s/@member@/{$(echo $template_members | sed -e 's/ / | /g')}/g" echo echo "\\fBUsage: \\fP" echo echo ".nf" for member in $template_members; do local sed_cmd="sed -e s/@member@/$member/g" local t_usage_txt=$(echo $usage_txt | $sed_cmd) printf "\t$t_usage_txt\n" done echo ".fi" fi echo echo "$help_txt" | sed -e 's/^ //' echo if test -n "$perms_txt"; then echo -n "\\fBpermissions:\\fP " if test "$perms_txt" = "0"; then echo "(none)" else echo "$perms_txt" fi fi echo } com_man() { echo "[$section_name]" echo while : ; do read_one_command if test $ret -lt 0; then exit 1 fi if test $ret -eq 0; then break fi dump_man done } cmd_handler_name() { result="com_$name_txt," } make_array_member() { local TAB=' ' CR=' ' local tmp result="{.name = \"$name_txt\", .handler = com_$name_txt, " if test -n "$perms_txt"; then result="$result .perms = $perms_txt," fi result="$result.description = \"$desc_txt\", .usage = \"$usage_txt\", \\$CR .help = " tmp="$(printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g' \ -e "s/$TAB/\\\t/g" -e's/$/\\/g')" result="$result$tmp$CR}, \\$CR" } make_completion() { local CR=' ' result=" {.name = \"$name_txt\", .completer = ${name_txt}_completer}, \\$CR" } template_loop() { local loop_result= local t_name="$name_txt" local t_perms="$perms_txt" local t_desc="$desc_txt" local t_usage="$usage_txt" local t_help="$help_txt" local t_source_files="$source_files" local member for member in $template_members; do name_txt="${t_name//@member@/$member}" perms_txt="${t_perms//@member@/$member}" desc_txt="${t_desc//@member@/$member}" usage_txt="${t_usage//@member@/$member}" help_txt="${t_help//@member@/$member}" prototype="${template_prototype//@member@/$member}" result= $1 loop_result="$loop_result$result" done result="$loop_result" # reset global variables name_txt="$t_name" perms_txt="$t_perms" desc_txt="$t_desc" usage_txt="$t_usage" help_txt="$t_help" source_files="$t_source_files" } com_header() { local array_members handlers= CR=' ' while : ; do read_one_command if test $ret -lt 0; then exit 1 fi if test $ret -eq 0; then break fi if test $template -eq 0; then cmd_handler_name handlers+="$result" make_array_member array_members="$array_members$result" continue fi template_loop cmd_handler_name handlers+="$result" template_loop make_array_member array_members="$array_members$result" done array_members="$array_members{.name = NULL} \\$CR" echo "#define DEFINE_${base_name^^}_CMD_ARRAY $array_members" echo "#define ${base_name^^}_COMMAND_HANDLERS ${handlers%,}" } com_completion() { echo "#define $1 \\" while : ; do read_one_command if test $ret -lt 0; then exit 1 fi if test $ret -eq 0; then break fi if test $template -eq 0; then make_completion printf "%s" "$result" continue fi template_loop make_completion printf "%s" "$result" done echo } read_header arg="$1" shift case "$arg" in "h") com_header ;; "man") com_man $* ;; "compl") com_completion $* ;; esac