command_util: Remove code for generating .c files.
[paraslash.git] / command_util.sh
index 4a9a03cc77f9637e20fc797d99f655ca3ce90a30..1530aee7333ea03a1b2748d85d60ce68c2eae2dd 100755 (executable)
@@ -1,25 +1,4 @@
-#!/bin/bash
-
-
-dump_array_member()
-{
-       echo '{'
-       echo ".name = \"$name_txt\","
-       if test $line_handler -eq 0; then
-               echo ".handler = com_$name_txt,"
-       else
-               echo ".handler = NULL,"
-               echo ".line_handler = com_$name_txt,"
-       fi
-       if test -n "$perms_txt"; then
-               echo ".perms = $perms_txt,"
-       fi
-       echo ".description = \"$desc_txt\","
-       echo ".usage = \"$usage_txt\","
-       echo ".help = "
-       echo "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g'
-       echo '},'
-}
+#!/usr/bin/env bash
 
 read_header()
 {
@@ -30,39 +9,19 @@ read_header()
                ---)
                        break
                        ;;
-               HC:)
-                       header_comment="$value"
-                       ;;
-               CC:)
-                       c_file_comment="$value"
-                       ;;
-               OF:)
-                       output_file="$value"
-                       array_name=${value%command_list}cmds
+               BN:)
+                       base_name="$value"
                        ;;
                SF:)
-                       source_file="$value"
-                       ;;
-               AT:)
-                       array_type="$value"
-                       ;;
-               IN:)
-                       for i in $value; do
-                               includes="$includes
-#include \"$i.h\""
-                       done
-                       includes="$includes
-#include \"$output_file.h\""
+                       source_files="$value"
                        ;;
                SN:)
                        section_name="$value"
+                       ;;
+               TM:)
+                       template_members="$value"
                esac
        done
-       if test -z "$header_comment" -o -z "$c_file_comment" \
-                       -o -z "$output_file"; then
-               echo "header error" 1&>2
-               exit 1
-       fi
 }
 
 read_one_command()
@@ -74,7 +33,9 @@ read_one_command()
        usage_txt=""
        help_txt=""
        perms_txt=""
-       line_handler=0
+       template=0
+       template_name=""
+       template_prototype=""
        mkdir -p man/man1
        while read key value; do
                case "$key" in
@@ -84,15 +45,20 @@ read_one_command()
                N:)
                        name_txt="$value"
                        ;;
+               T:)
+                       template_name="$value"
+                       template=1
+                       ;;
+               O:)
+                       template_prototype="$value"
+                       template=1
+                       ;;
                P:)
                        perms_txt="$value"
                        ;;
                D:)
                        desc_txt="$value"
                        ;;
-               L:)
-                       line_handler=1
-                       ;;
                U:)
                        usage_txt="$value"
                        ;;
@@ -110,10 +76,20 @@ ${line# }"
                        ;;
                esac
        done
-       if test -n "$name_txt" -a -n "$desc_txt" -a -n "$usage_txt" \
-                       -a -n "$help_txt"; then
-               ret=1
-               return
+       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
@@ -121,23 +97,43 @@ ${line# }"
                return
        fi
        ret=-1
-       return
+       #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()
 {
-       echo ".SS \"$name_txt\""
-       echo "$desc_txt"
-       echo
-       echo "\\fBusage: \\fP$usage_txt"
+       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"
+       echo "$help_txt" | sed -e 's/^  //'
        echo
        if test -n "$perms_txt"; then
                echo -n "\\fBpermissions:\\fP "
@@ -167,11 +163,87 @@ com_man()
        done
 }
 
-com_c_file()
+make_proto()
 {
-       echo "/** \file $output_file.c $c_file_comment */"
-       echo "$includes"
-       echo "struct $array_type $array_name[] = {"
+       local source_file match="" CR='
+'
+       if test -n "$prototype"; then
+               result="$prototype$CR"
+               return
+       fi
+       result=
+       for source_file in $source_files; do
+               match=$(grep "^\(__noreturn \)*int com_$name_txt(" $source_file | head -n 1 | sed -e 's/$/;/1')
+               if test -n "$match"; then
+                       result="$result$match$CR"
+                       break
+               fi
+       done
+}
+
+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
+               local sed_cmd="sed -e s/@member@/$member/g"
+               #echo "sed_cmd: $sed_cmd"
+               name_txt=$(echo "$t_name" | $sed_cmd)
+               #name_txt="$tname"
+               perms_txt=$(echo "$t_perms" | $sed_cmd)
+               desc_txt=$(echo "$t_desc" | $sed_cmd)
+               usage_txt=$(echo "$t_usage" | $sed_cmd)
+               help_txt=$(printf "%s\n" "$t_help" | $sed_cmd)
+               prototype=$(echo "$template_prototype" | $sed_cmd)
+               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 CR='
+'
+
        while : ; do
                read_one_command
                if test $ret -lt 0; then
@@ -180,37 +252,26 @@ com_c_file()
                if test $ret -eq 0; then
                        break
                fi
-               dump_array_member
+               if test $template -eq 0; then
+                       make_proto
+                       printf "%s" "$result"
+                       make_array_member
+                       array_members="$array_members$result"
+                       continue
+               fi
+               template_loop make_proto
+               printf "%s" "$result"
+               template_loop make_array_member
+               array_members="$array_members$result"
        done
-       echo '{.name = NULL}};'
+       array_members="$array_members{.name = NULL} \\$CR"
+       echo "#define DEFINE_$(tr 'a-z' 'A-Z' <<< "$base_name")_CMD_ARRAY $array_members"
 }
 
-dump_proto()
+com_completion()
 {
-       echo '/**'
-       echo " * $desc_txt"
-       echo ' *'
-       echo ' * \param fd the file descriptor to send output to'
-       if test $line_handler -eq 0; then
-               echo ' * \param argc the number of arguments'
-               echo ' * \param argv the argument vector'
-       else
-               echo ' * \param cmdline the full command line'
-       fi
-       echo ' * '
-       echo " * usage: $usage_txt"
-       echo ' * '
-       echo "$help_txt" | sed -e 's/^/ * /g'
-       echo ' */'
-       grep "^\(__noreturn \)*int com_$name_txt(" $source_file | sed -e 's/$/;/1'
-       echo
-}
 
-com_header()
-{
-       echo "/** \file $output_file.h $header_comment */"
-       echo
-       echo "extern struct $array_type $array_name[];"
+       echo "#define $1 \\"
        while : ; do
                read_one_command
                if test $ret -lt 0; then
@@ -219,21 +280,28 @@ com_header()
                if test $ret -eq 0; then
                        break
                fi
-               dump_proto
+               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
-       "c")
-               com_c_file
-               ;;
        "h")
                com_header
                ;;
        "man")
                com_man $*
                ;;
+       "compl")
+               com_completion $*
+               ;;
 esac