| #! /bin/bash |
| |
| cd `dirname $0` |
| |
| if [ $# -eq 2 ]; |
| then |
| if [ `expr $2 : /` -eq 1 ]; |
| then |
| output_dir=$2 |
| else |
| output_dir=$1/$2 |
| fi |
| else |
| output_dir=../objs |
| fi |
| |
| list_file=data/action_list |
| types_file=data/action_types |
| reps_file=data/action_replacements |
| prefix_file=data/prefixes |
| header_file=data/header_files |
| optional_modules_file=data/modules_optional |
| headers_file=data/headers |
| module_dependencies_file=data/module_dependencies |
| conf_macros_file=data/conf_macros |
| conf_locs_file=data/conf_locs |
| conf_args_file=data/conf_args |
| |
| autogen_notice=text/autogen |
| |
| actions_dir=actions |
| srcs_dir=src |
| include_prefix= |
| file_prefix=ndk_ |
| auto_file_name=config |
| auto_includes_name=includes |
| |
| conf_merge_filename=conf_merge.h |
| conf_cmd_basic_filename=conf_cmd_basic.h |
| conf_cmd_extra_filename=conf_cmd_extra.h |
| |
| |
| spacer=¬ |
| |
| sed_delete_empty_lines='t_NEL;d;:_NEL' |
| |
| |
| function trim_lines { |
| sed -e '/./,$!d' -e :a -e '/^\n*$/{$d;N;ba' -e '}' |
| } |
| |
| |
| function strtoupper { |
| [ $# -eq 1 ] || return 1 |
| local _str _cu _cl _x |
| _cu=(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) |
| _cl=(a b c d e f g h i j k l m n o p q r s t u v w x y z) |
| _str=$1 |
| for ((_x=0;_x<${#_cl[*]};_x++)); do |
| _str=${_str//${_cl[$_x]}/${_cu[$_x]}} |
| done |
| echo $_str |
| } |
| |
| |
| function sed_pad_right { |
| len=$1 |
| spacer=$2 |
| prefix=_PR$3 |
| |
| # returns a SED script that pads out (spaces) to the right to alignment $len |
| # this script should be used inside a call to sed |
| # NOTE : a spacer character $spacer should have already been written into the parsed string |
| |
| echo "t${prefix}a;:${prefix}a;s/^[^$spacer]{$len}/&/;\ |
| t${prefix}b;s/^[^$spacer]*/& /;t${prefix}a;:${prefix}b;s/$spacer/ /" |
| } |
| |
| |
| function sed_pad_left { |
| |
| len=$1 |
| spacer=$2 |
| prefix=_PL$3 |
| |
| # echo "t${prefix}a;:${prefix}a;s/^[^$spacer]{$len}/& /;t${prefix}a" # NOT CORRECT? |
| } |
| |
| |
| function add_notice { |
| |
| echo > $1 |
| cat $autogen_notice | trim_lines >> $1 |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| function add_non_generated_content { |
| |
| file=src/$1.h |
| [ ! -f $file ] && return |
| |
| echo "// Non-generated macros" >> $2 |
| echo >> $2 |
| |
| cat $file | trim_lines >> $2 |
| |
| echo >> $2 |
| echo >> $2 |
| } |
| |
| |
| function add_action_macros { |
| |
| list_file=$actions_dir/$1 |
| |
| [ ! -f $list_file ] && return |
| |
| out=$2 |
| |
| |
| # alignment settings |
| |
| align1=20 |
| align2=35 |
| align3=62 |
| base_shrink=12 |
| define="#define " |
| |
| |
| |
| # base macros |
| |
| echo "// base action macro macros" >> $out |
| echo >> $out |
| |
| cat $list_file | trim_lines | sed -r \ |
| -e "s/^[ ]*([a-zA-Z0-9_]+)([ ]*)\(([a-zA-Z0-9_,]+)\)([ ]*)(.*)/$define%2%_\1_ac(\3,ac)\2\4 {\5;}/" \ |
| -e "s/[ ]{$base_shrink}\{/\{/" \ |
| -e 's/%A%/ac/g' \ |
| >> $out |
| |
| echo >> $out |
| echo >> $out |
| |
| |
| |
| # generated macros |
| |
| echo "// generated action macros" >> $out |
| echo >> $out |
| |
| cat -s $list_file | while read list_line; do |
| |
| [ "x`echo $list_line`" = 'x' ] && continue |
| |
| cat $types_file | while read type_line; do |
| |
| [ "x`echo $type_line`" = 'x' ] && continue |
| |
| #ext=`echo $type_line | grep -E '^[a-zA-Z0-9_]+' | cut -d " " -f1` |
| ext=`echo $type_line | sed -r 's/^([a-zA-Z0-9_]+).*/\1/'` |
| params=`echo $type_line | sed -r 's/^[a-zA-Z0-9_]+[ ]*\((.*)\).*/\1/;ta;d;:a'` |
| act=`echo $type_line | sed -r 's/^[a-zA-Z0-9_]+[ ]*(\(.*\))?(.*)/\2/'` |
| [ "x$params" != "x" ] && params=",$params" |
| |
| echo $list_line | sed -r \ |
| -e "s/^([a-zA-Z0-9_]+)[ ]*\(([a-zA-Z0-9_,]+)\).*/%2%_\1_$ext(\2$params)$spacer%2%_\1_ac$spacer(\2,$act)/" \ |
| -e 's/[ ]*,[ ]*/,/g' \ |
| -e "`sed_pad_right $align2 $spacer 1`" \ |
| -e "`sed_pad_right $align3 $spacer 2`" \ |
| -e "s/.*/$define&/" \ |
| >> $out |
| done |
| echo >> $out |
| done |
| } |
| |
| |
| function replace_prefixes { |
| |
| temp=.temp |
| |
| file=`cat $prefix_file` |
| |
| prefix1= |
| prefix2= |
| |
| for prefix in $file ; do |
| [ "x$prefix2" != "x" ] && echo "Too many prefixes in prefix file $prefix_file" && exit 1 |
| [ "x$prefix1" != "x" ] && prefix2=$prefix && continue |
| prefix1=$prefix |
| done |
| |
| sed -r "s/%1%/$prefix1/g;s/%2%/$prefix2/g" < $1 > $temp |
| |
| mv -f $temp $1 |
| } |
| |
| |
| function replace_other_strings { |
| |
| temp=.temp |
| |
| cat $reps_file | while read line; do |
| |
| rep1= |
| rep2= |
| |
| for rep in $line ; do |
| [ "x$rep2" != "x" ] && echo "Too many replacments in replacements file $reps_file" && exit 1 |
| [ "x$rep1" != "x" ] && rep2=$rep && continue |
| rep1=$rep |
| done |
| |
| sed -r "s/%$rep1%/$rep2/g" < $1 > $temp |
| mv -f $temp $1 |
| done |
| } |
| |
| |
| function generate_header_file { |
| |
| name=$1 |
| out=$output_dir/$file_prefix$name.h |
| |
| add_notice $out |
| add_non_generated_content $name $out |
| add_action_macros $name $out |
| replace_prefixes $out |
| replace_other_strings $out |
| } |
| |
| |
| function add_auto_include { |
| echo "#include <${file_prefix}$2>" >> $1 |
| } |
| |
| |
| function add_include { |
| echo "#include <${include_prefix}${file_prefix}$2>" >> $1 |
| } |
| |
| |
| function generate_non_optional_h_includes { |
| |
| # TODO : split into auto-generated and non-auto-generated ones |
| |
| echo "// non-optional includes" >> $1 |
| echo >> $1 |
| |
| for mod in `cat $headers_file | sort`; do |
| |
| add_auto_include $1 $mod.h |
| done |
| |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| function generate_include_all_includes { |
| |
| echo "// include all optional modules" >> $1 |
| echo >> $1 |
| echo "#ifdef NDK_ALL" >> $1 |
| echo >> $1 |
| |
| modules=`cat $optional_modules_file | sed 's/*//g' | sort` |
| |
| for mod in $modules; do |
| def="NDK_`strtoupper $mod`" |
| echo "#ifndef $def" >> $1 |
| echo "#define $def 1" >> $1 |
| echo "#endif" >> $1 |
| done |
| |
| echo >> $1 |
| echo "#endif" >> $1 |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| function generate_dependent_includes { |
| |
| echo "// module dependencies" >> $1 |
| echo >> $1 |
| |
| cat $module_dependencies_file | while read line; do |
| |
| first=1 |
| |
| for mod in $line; do |
| |
| def="NDK_`strtoupper $mod`" |
| |
| if [ $first = 1 ] ; then |
| |
| echo "#ifdef $def" >> $1 |
| first=0 |
| else |
| echo "#ifndef $def" >> $1 |
| echo "#define $def 1" >> $1 |
| echo "#endif" >> $1 |
| fi |
| done |
| |
| [ $first = 0 ] && echo "#endif" >> $1 |
| done |
| |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| |
| function generate_optional_h_includes { |
| |
| echo "// optional includes" >> $1 |
| echo >> $1 |
| |
| for mod in $modules; do |
| def="NDK_`strtoupper $mod`" |
| echo "#if ($def)" >> $1 |
| add_include $1 $mod.h |
| echo "#endif" >> $1 |
| done |
| |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| |
| |
| |
| function generate_conf_merge_macros_file { |
| |
| file=$conf_merge_filename |
| out_file=${file_prefix}$file |
| out=$output_dir/$out_file |
| |
| add_notice $out |
| |
| echo "// conf-merge-value macros" >> $out |
| echo >> $out |
| |
| cat $srcs_dir/$file | trim_lines >> $out |
| echo >> $out |
| echo >> $out |
| |
| echo "// conf-merge-prop macros" >> $out |
| echo >> $out |
| |
| echo "#define ndk_conf_merge_prop(prop,default)\\" >> $out |
| echo " ndk_conf_merge_value\\" >> $out |
| echo " (conf->prop, prev->prop, default)" >> $out |
| echo >> $out |
| |
| # loads macros, removes empty elements, sorts and translates to merge-prop macros |
| |
| cat $conf_macros_file | sed -r 's/^[A-Z0-9_]+[ ]*[A-Z0-9_]+[ ]*([a-z0-9_]+).*$/\1/;ta;d;:a' \ |
| | sort | sed -r \ |
| 's/(.*)/#define ndk_conf_merge_\1_prop(prop,default,...)\\\ |
| ndk_conf_merge_\1_value\\\ |
| (conf->prop, prev->prop, default,##__VA_ARGS__)\ |
| /' \ |
| >> $out |
| |
| add_auto_include $1 $file |
| } |
| |
| |
| |
| |
| function generate_conf_cmd_basic_file { |
| |
| temp=.rep |
| file=$conf_cmd_basic_filename |
| out_file=${file_prefix}$file |
| out=$output_dir/$out_file |
| |
| align1=35 |
| |
| # initial text |
| |
| add_notice $out |
| |
| |
| # add ndk bitmasks |
| |
| echo "// conf cmd core values/bitmasks" >> $out |
| echo >> $out |
| |
| |
| cat $conf_args_file | sort | trim_lines | sed -r \ |
| -e "s/^([A-Z0-9_]+)/${define}NDK_\1${spacer}NGX_\1/" \ |
| -e $sed_delete_empty_lines \ |
| -e "`sed_pad_right $align1 $spacer`" \ |
| >> $out |
| |
| echo >> $out |
| echo >> $out |
| |
| |
| # add additional bitmasks stored in file |
| |
| echo "// conf cmd bitmasks" >> $out |
| echo >> $out |
| |
| cat $srcs_dir/$conf_cmd_basic_filename | trim_lines >> $out |
| |
| echo >> $out |
| echo >> $out |
| |
| echo "// conf cmd basic macros" >> $out |
| echo >> $out |
| |
| |
| # build replacement string |
| |
| echo -n "s/^([A-Z0-9_]+)$/" > $temp |
| |
| cat $conf_locs_file | sed \ |
| -r -e 's/^([A-Z0-9_]+) *([A-Z0-9_]+).*/#define NDK_\1_CONF_\\1\(name,func,off1,off2,post)\\\\\\\ |
| {ngx_string (name),\\\\\\\ |
| NGX_CONF_\\1|NDK_\1_CONF,\\\\\\\ |
| func, off1, off2, post},\\\ |
| \\/' -e $sed_delete_empty_lines \ |
| >> $temp |
| |
| echo -n "/;$sed_delete_empty_lines" >> $temp |
| |
| |
| # apply the replacement string to the |
| |
| cat $conf_args_file | sort | trim_lines | sed -rf $temp >> $out |
| rm -f $temp |
| |
| add_auto_include $1 $file |
| } |
| |
| |
| |
| function generate_conf_cmd_extra_file { |
| |
| temp=.rep |
| file=$conf_cmd_extra_filename |
| out=$output_dir/${file_prefix}$file |
| |
| align1=35 |
| |
| # initial text |
| |
| add_notice $out |
| |
| echo "// conf command macros" >> $out |
| echo >> $out |
| |
| |
| # build replacement string |
| |
| echo -n 's/^([A-Z0-9_]+)[ ]*([A-Z0-9_]+)[ ]*([a-z0-9_]+).*$/' > $temp |
| |
| cat $conf_locs_file | sed \ |
| -r -e 's/^([A-Z0-9_]+)[ ]*([A-Z0-9_]+)[ ]*([a-zA-Z0-9_]+)/#define NDK_\1_CONF_\\1(name,p,post\)\\\\\\\ |
| NDK_\1_CONF_\\2\\\\\\\ |
| (name,\\\\\\\ |
| ndk_conf_set_\\3_slot,\\\\\\\ |
| NGX_\2_CONF_OFFSET,\\\\\\\ |
| offsetof (ndk_module_\3_conf_t, p),\\\\\\\ |
| post)\\\ |
| \\/' -e $sed_delete_empty_lines \ |
| >> $temp |
| |
| echo -n "/;$sed_delete_empty_lines" >> $temp |
| #echo -n ";`sed_pad_right 60 $spacer`" >> $temp |
| |
| |
| # apply the replacement string to the |
| |
| cat $conf_macros_file | sort | trim_lines | sed -rf $temp -e "`sed_pad_right 60 $spacer`" >> $out |
| rm -f $temp |
| |
| add_auto_include $1 $file |
| } |
| |
| |
| |
| function generate_auto_generated_h_includes { |
| |
| echo "// auto-generated headers" >> $1 |
| echo >> $1 |
| |
| for name in `cat $header_file | sort` ; do |
| |
| generate_header_file $name |
| add_auto_include $1 $name.h |
| done |
| |
| generate_conf_merge_macros_file $1 |
| generate_conf_cmd_basic_file $1 |
| generate_conf_cmd_extra_file $1 |
| |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| |
| function generate_optional_c_includes { |
| |
| echo "// optional includes" >> $1 |
| echo >> $1 |
| |
| modules=`cat $optional_modules_file | sed 's/*//g' | sort` |
| |
| for mod in $modules; do |
| def="NDK_`strtoupper "$mod"`" |
| echo "#if ($def)" >> $1 |
| add_include $1 $mod.c |
| echo "#endif" >> $1 |
| done |
| |
| echo >> $1 |
| echo >> $1 |
| } |
| |
| |
| function generate_commands { |
| |
| echo "// module commands" >> $1 |
| echo >> $1 |
| echo "static ngx_command_t ndk_http_commands[] = {" >> $1 |
| |
| cat $optional_modules_file | sort | while read line; do |
| |
| cmds=`echo "$line" | grep -E '\*'` |
| |
| [ "x$cmds" = "x" ] && continue |
| |
| mod=`echo "$line" | grep -E '^[a-zA-Z0-9_]+' | cut -d " " -f1` |
| up=`strtoupper $mod` |
| def="NDK_$up" |
| defcmd="NDK_${up}_CMDS" |
| |
| echo "#if ($def)" >> $1 |
| echo "#define $defcmd 1" >> $1 |
| add_include $1 $mod.h |
| echo "#undef $defcmd" >> $1 |
| echo "#endif" >> $1 |
| |
| done |
| |
| echo -e " ngx_null_command\n};" >> $1 |
| } |
| |
| |
| function generate_all_h_files { |
| |
| out=$output_dir/${file_prefix}$auto_file_name.h |
| |
| add_notice $out |
| |
| generate_include_all_includes $out |
| generate_dependent_includes $out |
| |
| out=$output_dir/${file_prefix}$auto_includes_name.h |
| |
| generate_optional_h_includes $out |
| generate_non_optional_h_includes $out |
| generate_auto_generated_h_includes $out $list |
| } |
| |
| |
| function generate_all_c_files { |
| |
| out=$output_dir/${file_prefix}$auto_file_name.c |
| |
| add_notice $out |
| generate_optional_c_includes $out |
| generate_commands $out |
| } |
| |
| |
| |
| function generate_all_files { |
| |
| mkdir -p $output_dir |
| rm -f $output_dir/* |
| |
| generate_all_h_files |
| generate_all_c_files |
| } |
| |
| generate_all_files |