Merge branch 'maint'
[paraslash.git] / command_util.sh
index ea952e5b1283589d16bff19717ba39b20964648c..f388b2cfb152db7cf34e0b2f84313ba26a209903 100755 (executable)
@@ -1,36 +1,71 @@
-#!/bin/bash
+#!/usr/bin/env bash
 
 
-dump_array_member()
+read_header()
 {
-       echo '{'
-       echo ".name = \"$name_txt\","
-       if test $line_handler -eq 0; then
-               echo ".handler = com_$name_txt,"
-       else
-               echo ".line_handler = com_$name_txt,"
-       fi
-       if test -n "$perms_txt"; then
-               echo ".perms = $perms_txt,"
+       local key value i
+
+       while read key value; do
+               case "$key" in
+               ---)
+                       break
+                       ;;
+               HC:)
+                       header_comment="$value"
+                       ;;
+               CC:)
+                       c_file_comment="$value"
+                       ;;
+               OF:)
+                       output_file="$value"
+                       array_name=${value%command_list}cmds
+                       ;;
+               SF:)
+                       source_files="$value"
+                       ;;
+               AT:)
+                       array_type="$value"
+                       ;;
+               SI:)
+                       for i in $value; do
+                               system_includes="$system_includes
+#include <$i.h>"
+                       done
+                       ;;
+               IN:)
+                       for i in $value; do
+                               includes="$includes
+#include \"$i.h\""
+                       done
+                       includes="$includes
+#include \"$output_file.h\""
+                       ;;
+               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
-       echo ".description = \"$desc_txt\","
-       echo ".synopsis = \"$syn_txt\","
-       echo ".help = "
-       echo "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g'
-       echo '},'
 }
 
-
 read_one_command()
 {
        local line
 
        name_txt=""
        desc_txt=""
-       syn_txt=""
+       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
@@ -40,17 +75,22 @@ 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
-                       ;;
-               S:)
-                       syn_txt="$value"
+               U:)
+                       usage_txt="$value"
                        ;;
                H:)
                        help_txt="${value}"
@@ -66,61 +106,81 @@ ${line# }"
                        ;;
                esac
        done
-       if test -n "$name_txt" -a -n "$desc_txt" -a -n "$syn_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 "$syn_txt" \
+       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
+       #return
        echo "!ERROR!"
        echo "N: $name_txt"
        echo "D: $desc_txt"
-       echo "S: $syn_txt"
+       echo "S: $usage_txt"
        echo "P: $perms_txt"
        echo "H: $help_txt"
+       echo "O: $template_prototype"
 }
 
 dump_man()
 {
-       echo "NAME"
-       printf "\t$name_txt - $desc_txt\n"
-       echo "SYNOPSIS"
-       printf "\t$syn_txt\n"
-       echo "DESCRIPTION"
-       echo "$help_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" | sed -e 's/^  //'
+       echo
        if test -n "$perms_txt"; then
-               echo "PERMISSIONS"
+               echo -n "\\fBpermissions:\\fP "
                if test "$perms_txt" = "0"; then
-                       printf "\t(none)\n"
+                       echo "(none)"
                else
-                       printf "\t$perms_txt\n"
+                       echo "$perms_txt"
                fi
        fi
-
+       echo
 }
 
 
 com_man()
 {
-       local cn="$(grep ^codename Makefile.in)"
-       local ver="$(grep ^AC_INIT configure.ac \
-               | cut -f 2 -d ',')"
-       cn=${cn#*=}
-       ver=${ver# *[}
-       ver=${ver%]}
-       echo "r=paraslash-$ver (cn: $cn)"
-       local n
-       local txtdir=txt
-       local mandir=man/man1
-       local htmldir=html
-       local pfx="$1"
-       mkdir -p $txtdir $mandir $htmldir || exit 1
+       echo "[$section_name]"
+       echo
        while : ; do
                read_one_command
                if test $ret -lt 0; then
@@ -129,17 +189,90 @@ com_man()
                if test $ret -eq 0; then
                        break
                fi
-               n=$pfx-$name_txt
-               echo "pfx: $pfx, name: $n"
-               dump_man > $txtdir/$n.txt
-               txt2man -t "$n" -r "$r"  < $txtdir/$n.txt \
-                       | sed -e 1d > $mandir/$n.1
-               man2html $mandir/$n.1 > $htmldir/$n.html
+               dump_man
        done
 }
 
-com_array()
+dump_proto()
+{
+       local source_file match=""
+
+       echo '/**'
+       echo " * $desc_txt"
+       echo ' *'
+       if [[ "$system_includes" =~ openssl/rc4.h ]]; then
+               echo ' * \param rc4c The rc4 crypt context.'
+       else
+               echo ' * \param fd The file descriptor to send output to.'
+       fi
+       echo ' * \param argc The number of arguments.'
+       echo ' * \param argv The argument vector.'
+       echo ' * '
+       echo " * Usage: $usage_txt"
+       echo ' * '
+       echo "$help_txt" | sed -e 's/^/ * /g'
+       echo ' */'
+       if test -n "$prototype"; then
+               echo "$prototype"
+               echo
+               return
+       fi
+       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
+                       echo "$match"
+                       break
+               fi
+       done
+       echo
+}
+
+dump_array_member()
+{
+       echo '{'
+       echo ".name = \"$name_txt\","
+       echo ".handler = com_$name_txt,"
+       if test -n "$perms_txt"; then
+               echo ".perms = $perms_txt,"
+       fi
+       echo ".description = \"$desc_txt\","
+       echo ".usage = \"$usage_txt\","
+       echo ".help = "
+       printf "%s\n" "$help_txt" | sed -e 's/^/\"/g' -e 's/$/\\n\"/g'
+       echo '},'
+}
+
+
+template_loop()
 {
+       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)
+               $1
+       done
+
+}
+
+com_c_file()
+{
+       echo "/** \file $output_file.c $c_file_comment */"
+       echo "$system_includes"
+       echo "$includes"
+       echo "struct $array_type $array_name[] = {"
        while : ; do
                read_one_command
                if test $ret -lt 0; then
@@ -148,21 +281,20 @@ com_array()
                if test $ret -eq 0; then
                        break
                fi
-               dump_array_member
+               if test $template -eq 0; then
+                       dump_array_member
+                       continue
+               fi
+               template_loop dump_array_member
        done
+       echo '{.name = NULL}};'
 }
 
-dump_proto()
-{
-       if test $line_handler -eq 0; then
-               echo "int com_$name_txt(int, int, char **);"
-       else
-               echo "int com_$name_txt(int, char *);"
-       fi
-}
-
-com_proto()
+com_header()
 {
+       echo "/** \file $output_file.h $header_comment */"
+       echo
+       echo "extern struct $array_type $array_name[];"
        while : ; do
                read_one_command
                if test $ret -lt 0; then
@@ -171,18 +303,23 @@ com_proto()
                if test $ret -eq 0; then
                        break
                fi
-               dump_proto
+               if test $template -eq 0; then
+                       dump_proto
+                       continue
+               fi
+               template_loop dump_proto
        done
 }
 
+read_header
 arg="$1"
 shift
 case "$arg" in
-       "array")
-               com_array
+       "c")
+               com_c_file
                ;;
-       "proto")
-               com_proto
+       "h")
+               com_header
                ;;
        "man")
                com_man $*