#!/bin/bash THIS_SCRIPT_NAME="$(basename ${BASH_SOURCE[0]})" function pass() { : } function print_log() { printf "[$THIS_SCRIPT_NAME][$(date --iso-8601=ns)] $1\n" } function log_error() { print_log "error: $1" >&2 if [[ $2 =~ ^[0-9]+$ ]] then exit $2 fi } function print_space_indent() { # note: indent_depth has script-wide scope printf "%*s" ${1:-$indent_depth} } function print_tab_indent() { printf "\t" } function indent() { local indent_count=$([[ $1 =~ ^[0-9]+$ ]] && [[ $1 > 0 ]] && echo $1 || echo 1) # note: indent_type has script-wide scope local cmd_print_indent=$([[ $indent_type == s ]] && echo print_space_indent || echo print_tab_indent) $cmd_log "indent_count=[$indent_count]" for ((i=0; i<$indent_count; i++)) do $cmd_print_indent $2 done } # set option defaults before processing options cmd_log=print_log pm_perfix="\$anvil" indent_type=s # number of spaces per indent; only when indent_type is space indent_depth=4 # match subprocesses to skip; skip new, parent, and private subprocesses by default ignore_sub_name_pattern="^(new|parent|_[^[:space:]]+)$" while getopts ":i:no:p:" option do case "$option" in i) if [[ $OPTARG =~ ^[0-9]+$ ]] && [[ $OPTARG > 0 ]] then indent_depth=$OPTARG elif [[ $OPTARG == t ]] then indent_type=t fi ;; n) cmd_log=pass ;; o) pm_perfix="$OPTARG" ;; p) ignore_sub_name_pattern="$OPTARG" ;; :) log_error "option [$OPTARG] missing argument" 1 ;; [?]) log_error "unrecognized option [$OPTARG]" 1 ;; esac done shift $(($OPTIND - 1)) # get positional parameters after processing options pm_path="$1" $cmd_log "pm_path=[$pm_path]" $cmd_log "pm_perfix=[$pm_perfix]" $cmd_log "indent_depth=[$indent_depth]" $cmd_log "ignore_sub_name_pattern=[$ignore_sub_name_pattern]" pm_name="$( \ sed -E -n "s@^[[:space:]]*package[[:space:]]+([^[:space:]]+::)+([^[:space:]]+);.*\$@\2@p" "$pm_path" \ )" $cmd_log "pm_name=[$pm_name]" pm_dispatch_table="my \$pm_${pm_name,,}_dispatch_table = {"; for sub_name in $(sed -E -n "s@^[[:space:]]*sub[[:space:]]+([^[:space:]]+).*\$@\1@p" "$pm_path") do if ! [[ "$sub_name" =~ $ignore_sub_name_pattern ]] then cat << EOF sub ${sub_name} { $(indent)my \$parameters = shift; $(indent)${pm_perfix}->${pm_name}->${sub_name}(\$parameters); } EOF pm_dispatch_table="${pm_dispatch_table}\n$(indent)'${sub_name}' => \&${sub_name}," else $cmd_log "subprocess [$sub_name] skipped" fi done printf "${pm_dispatch_table%,}\n};\n"