2 ############################################################
4 # author: CottonCandyOwner(CottonCandyOwner@126.com)
6 ############################################################
7 # Copyright (C) 2022- Free Software Foundation, Inc.
8 # This configure script is free software; the Free Software
9 # Foundation gives unlimited permission to copy, distribute
11 ############################################################
13 # generate dir & file in srcpkg by a .catalog file.
14 # it's also used for testing script skeletone dir generating.
15 # it uses .tmpl file to generate initial code, and also
16 # could sync code to .catalog file.
17 ############################################################
26 # another way to use this program:
28 # source codegen --load
29 # DEF_INPUT_CATALOG="testing/testing.catalog"
31 # then, add arg desc string proc, same as itself.
33 # opt_desc_str_dispatch codegen_desc_str
35 # now, the new program which sourced this code has
36 # same feature as codegen in codegen_desc_str. we can
37 # type 'xxx --help' to get helper info in program.
54 ##############################
55 # section: public comment info
56 ##############################
60 ##############################
61 # section: variable define
62 ##############################
66 # this comment is used for version id auto update.
73 readonly CGEN_VER_DATE
=20230501
76 readonly CGEN_PROG
=`basename $0`
78 readonly CGEN_PROG_VERSION
="v${CGEN_V1}.${CGEN_V2}\${CGEN_V3:+\".$CGEN_V3\"}\${CGEN_VEXT:+\"$CGEN_VEXT\"}\${CGEN_VER_DATE:+\"-$CGEN_VER_DATE\"}"
79 CGEN_PROG_VERSION_STR
="`eval echo $CGEN_PROG_VERSION`
80 Copyright (C) 2023- Free Software Foundation, Inc.
81 This configure script is free software; the Free Software
82 Foundation gives unlimited permission to copy, distribute
85 Writen by CottenCandyOwner(CottenCandyOwner@126.com).
88 CGEN_PROG_BANNER
="$CGEN_PROG $CGEN_PROG_VERSION_STR"
89 CGEN_PROG_SYNTAX
='Usage: $CGEN_PROG -[${p_shortparam//\|/}]'
90 CGEN_PROG_DESC
=" this program is an automatical code generating utility.
93 CGEN_PROG_OTHER_DESC
="
96 @ code generating and synchronizing:
98 s[y]nchronize code to output dir.
102 list catalog structure in testdir.
105 save catalog node info into .catalog file.
108 CGEN_USAGE_FMT
='$CGEN_PROG_BANNER
112 $CGEN_PROG_OTHER_DESC'
115 # do not delete this comment, it is used for var define code intert.
117 # args-var-define-begin
118 # args-var-define-end
122 # desc-str for codegen
123 # @ every paramter desc-str-line start with 'param'.
124 # @ every colum start with '|', and seperated by blanks.
125 # @ '|blank' means a blank line dispalyed in helper.
126 # @ follow with a '' quoated string is the option category string.
127 # @ comment '#' in desc-str is also supported, and can be used to
128 # disable some option have not been implemented.
129 # @ desc-str can be in multiple var. and some of them maybe re-used
130 # for other program by 'source xxx --loadshlib'.
132 codegen_desc_hdr_str
="
133 |prog $0 'this program uses design draft file orgnized by catalog with tab/blank indent, to generate dir & file in src/lib/doc/testing dirs of srcpkg. it also generate testing dir framework in testing dir of srcpkg.'
143 # @ PARAMETER DEFINE.
144 # this desc str would be referenced in scripttest, consider about opt name space.
145 # =, param name for opt.
146 # %, var name if this opt is enabled.
147 # &, proc func if opt trigged.
149 # this coppy of code display on editor with 125 char.
151 |blank 'Design File Auto Gen Paramters:'
152 |param |-l |--list |--- |= |%<list> |&<on_list> |'list items and dirs under srcpkg dir.'
153 |param |- |--idrange |--- |= |%<idrange> |& |'list items in range of catalog id.'
154 |param |-S |--save |--- |=<save_file> |%<save_file> |&<on_save> |'generate catalog from srcpkg dir. if'
155 |'the catalog file is exist, just'
156 |'display desc info only. append -f'
157 |'option to recover an original '
159 |param |-y |--sync |--- |=[finput] |%<finput> |&<on_sync> |'generate dirs/files by specified'
160 |'/default .catalog file.'
161 |param |-M |--matching |--- |=<matching> |%<matching> |&<on_matching> |'string matching test, and generate '
162 |'chksum. this chksum used in catalog'
163 |'file as an uniq-id for deep catalog,'
164 |'or large number of items define.'
166 |param |-l |--list |--- |= |%<list> |&<on_list> |'list items and dirs under srcpkg dir.'
168 |blank 'Other Paramters:'
169 |param |-f |--force |--- |= |%<oprforce> |& |'force operation option. it\'s a general option combine with other options.'
170 |param |-i |--input |--- |=[finput] |%<finput> |& |'specify input file. leave it blank for stdin.'
171 |param |-d |--dir |--- |=<root_dir> |%<root_dir> |& |'default root dir for file generating. '
172 |'if not specified, use default value'
173 |'in script(doc/designdoc/'
174 |'module-design.catalog, ...).'
177 codegen_other_desc_str
="
179 |blank 'Version & Helper & Debug:'
180 |param |-V |--version |--- |= |%<version> |&<on_version> |'output version info of this program.'
181 |param |-h |-- |--- |= |%<hinfo> |&<on_hinfo> |'simplly helper doc only for options.'
182 |param |- |--help |--- |= |%<help> |&<on_help> |'this helper doc.'
186 #|param |-O |--output-dir |--- |=<output_dir> |%<output_dir> |& |'temp dir for testing.'
192 # applicational variables for code gen.
211 # TBD: build/skeletone.catalog or doc/designdoc/design.catalog
213 DEF_INPUT_CATALOG
="doc/designdoc/module-design.catalog"
215 DEF_INPUT_CATALOG_ARR
=(
216 doc
/designdoc
/module-design.catalog
217 doc
/module-design.catalog
218 build
/module-design.catalog
219 doc
/designdoc
/testing.catalog
221 testing
/testing.catalog
223 DEF_INPUT_CATALOG_LIST
="doc/designdoc/module-design.catalog"
227 ##############################
228 # section: private function
229 ##############################
232 ############################################################################
234 ############################################################################
253 for file in $FILE_EXT_LIST; do
260 # catanode analyzing for comparation.
262 OnAnyalyzeCataNodeProc
()
264 ITEM_CHKSUM
="$(echo "$NTYPE $NNAME $NDESC" | cksum)"
266 if [[ ${NODE_TYPE} != 'cont' ]]; then
267 NODE_TBL
[$ITEM_CHKSUM]="$(declare -p NCATAID NTYPE NNAME NDESC NODE_TYPE NFULLCATAID CONT_TYPE ITEM_TYPE SRC_TYPE CATACNT)"
268 NODE_TBL
[$ITEM_CHKSUM]="$(NODE_TBL[$ITEM_CHKSUM]//declare/declare -g)"
269 NODE_TBL_EXIST
[$ITEM_CHKSUM]="1"
271 if [[ ${NODE_TYPE} == 'item' ]]; then
272 ITEM_CHKSUM_ID
="$ITEM_CHKSUM"
273 save_curr_ctx
"$ITEM_CHKSUM"
276 eval CONT_NODE_TBL_
${ITEM_CHKSUM_ID}[$ITEM_CHKSUM]="\"$(declare -p NCATAID NTYPE NNAME NDESC NODE_TYPE NFULLCATAID CONT_TYPE ITEM_TYPE SRC_TYPE CATACNT)\""
277 eval CONT_NODE_TBL_
${ITEM_CHKSUM_ID}[$ITEM_CHKSUM]="\"\$(CONT_NODE_TBL_${ITEM_CHKSUM_ID}[$ITEM_CHKSUM]//declare/declare -g)\""
282 # catanode comparing.
284 OnCompareCataNodeProc
()
286 ITEM_CHKSUM
="$(echo "$NTYPE $NNAME $NDESC" | cksum)"
288 if [[ ${NODE_TYPE} != 'cont' ]]; then
289 if [[ -n ${NODE_TBL[$ITEM_CHKSUM]} ]]; then
290 # unset NODE_TBL[$ITEM_CHKSUM]
291 # del_bak_ctx "$ITEM_CHKSUM"
292 unset NODE_TBL_EXIST
[$ITEM_CHKSUM]
294 NEW_NODE_TBL
="$(declare -p NCATAID NTYPE NNAME NDESC NODE_TYPE NFULLCATAID CONT_TYPE ITEM_TYPE SRC_TYPE CATACNT)"
295 NEW_NODE_TBL
[$ITEM_CHKSUM]="$(NEW_NODE_TBL[$ITEM_CHKSUM]//declare/declare -g)"
298 if [[ ${NODE_TYPE} == 'item' ]]; then
299 ITEM_CHKSUM_ID
="$ITEM_CHKSUM"
304 vname
="CONT_NODE_TBL_${ITEM_CHKSUM_ID}[$ITEM_CHKSUM]"
305 if [[ -n ${!vname} ]]; then
309 eval $vname="\"$(declare -p NCATAID NTYPE NNAME NDESC NODE_TYPE NFULLCATAID CONT_TYPE ITEM_TYPE SRC_TYPE CATACNT)\""
310 eval $vname="$(!vname//declare/declare -g)"
315 deleted_node_tbl_foreach
()
320 # ergodic deleted list, and get the ITEM_CHKSUM_ID from main design file.
323 cnt
="${#NODE_TBL[@]}"
324 for ITEM_CHKSUM
in ${!NODE_TBL[@]}; do
326 eval ${NODE_TBL[$ITEM_CHKSUM]}
328 # get foreach file in current node.
330 # TBD: output operation.
334 new_file_node_tbl_foreach
()
340 cnt
="${#NODE_TBL[@]}"
341 for ITEM_CHKSUM
in ${!NODE_TBL_EXIST[@]}; do
342 # restore NODE contex
349 new_cont_node_tbl_foreach
()
356 local item_node_list
=
359 cnt
="${#NODE_TBL[@]}"
360 item_node_list
="${!NEW_CONT_NODE_TBL_} ${!CONT_NODE_TBL_}"
361 item_node_list
="${item_node_list//NEW_CONT_NODE_TBL_/}"
362 item_node_list
="${item_node_list//CONT_NODE_TBL_/}"
363 item_node_list
="$(echo "$item_node_list" | uniq)"
364 for itemid
in ${item_node_list}; do
365 var
="NEW_CONT_NODE_TBL_${itemid}[@]"
366 for ITEM_CHKSUM
in ${!var}; do
367 # restore NODE contex
368 var
="NEW_CONT_NODE_TBL_${itemid}[$ITEM_CHKSUM]"
374 for cont
in $ITEM_CONT_TYPE_LIST; do
375 vname
="CONT_${cont^^}_LIST"
376 eval "NEW_$vname=\"${!vname}\""
381 var
="CONT_NODE_TBL_${itemid}[@]"
382 for ITEM_CHKSUM
in ${!var}; do
383 # restore NODE contex
384 var
="${itemid}[$ITEM_CHKSUM]"
390 for cont
in $ITEM_CONT_TYPE_LIST; do
391 vname
="CONT_${cont^^}_LIST"
392 eval "DEL_$vname=\"${!vname}\""
396 # TBD: item file re-gen
400 catalog_content_cmp
()
404 tmp
=${tmp:-"${DEF_INPUT_CATALOG}"}
405 [[ ! -e ${tmp} ]] && return
407 [[ ! -e $SRCPKG_DIR/build
/${DEF_INPUT_CATALOG} ]] && return
409 vonCataNodeProc
=OnAnyalyzeCataNodeProc
410 catalog_each_line
"$SRCPKG_DIR/build/${DEF_INPUT_CATALOG}"
412 vonCataNodeProc
=OnCompareCataNodeProc
413 catalog_each_line
"$tmp"
415 # TBD: chk if NEW_* info is modified or new.
417 deleted_node_tbl_foreach
418 new_file_node_tbl_foreach
419 new_cont_node_tbl_foreach
424 save_file_list
/tmp
/codegen.dir.txt
429 # * this feature is hard to be implemented in this code.
433 # foreach deleted node, compare NNAME NDESC in new catalog file.
438 ############################################################################
440 ############################################################################
442 onDirSubjectDirEntering
()
447 eval tmp
="\"\${LAYEDDIR_${DIR_TYPE^^}[@]}\""
448 cata_dbgout
"@@@@@ onDirSubjectDirEntering($1, $2, $(echo "$tmp" | tr -s ' ' '/'))\n"
449 declare -p OUTPUT_DIR
450 mkdir
-p "$OUTPUT_DIR"
453 # fyntax: onItemSubjectDirEntering <item-node-type> <item-node-name> <item-node-layerddir>
454 # fdesc: get other info by 'ITEM_XXX' and other vars.
455 onItemSubjectDirEntering
()
457 cata_dbgout
"=====> onItemSubjectDirEntering($1, $2, $3)\n"
464 cata_dbgout
"=====> onItemEntering($1, $2, $3)\n"
466 ITEM_CHKSUM
="$(echo "$NTYPE $NNAME $NDESC" | cksum)"
467 ITEM_CHKSUM
="${ITEM_CHKSUM:0:6}"
468 save_curr_ctx
"$ITEM_CHKSUM"
469 #declare -A -g ITEM_CTX[$ITEM_CHKSUM]="$(declare -p NFULLCATAID ${!LAYEDDIR_*})"
470 # echo $ITEM_CHKSUM ${CONTEX_BAK[$ITEM_CHKSUM]} >&2
473 # fyntax onItemExiting <item-node-type> <item-node-name>
474 # fdesc: get other info by 'ITEM_XXX' and other vars.
480 cata_dbgout
"=======================================\n"
481 cata_dbgout
"onItemExiting($1, $2, $3)\n"
483 [[ -z $ITEM_CONT_TYPE_LIST ]] && return
485 # echo CONTENT LIST INFO:
486 for cont
in $ITEM_CONT_TYPE_LIST; do
487 vname
="CONT_${cont^^}_LIST"
488 # echo "$vname=\"${!vname}\""
492 # declare -p FILE_EXT_LIST DIR_TYPE_LIST
497 ITEM_CONT_TYPE_LIST
=""
502 cata_dbgout
"== onItemFileProc() $STR\n"
508 cata_dbgout
"== onDirFileProc() $STR\n"
516 cata_dbgout
"onContProc($1, $2, $3)\n"
519 vname
="CONT_${1^^}_LIST"
520 declare -g ${vname}+="$2"$
'\n'
521 declare -g ${vname}+="$3"$
'\n'
523 if [[ ! "$ITEM_CONT_TYPE_LIST" =~
$1 ]]; then
524 ITEM_CONT_TYPE_LIST
+="$1"$
'\n'
530 THISDOC
="${THISDOC:0:-1}"
531 [[ -z "${THISDOC//[[:space:]]/}" ]] && return
533 echo THISDOC
="\"$THISDOC\""
541 # at the end of file output, record file list in output dir
542 tmp
="$(envar_get catalog::testdir::SUBJECTDIR)/* "
543 tmp
+="$(envar_get catalog::docdir::SUBJECTDIR)/* "
544 tmp
+="$(envar_get catalog::designdir::SUBJECTDIR)/* "
545 tmp
+="$(envar_get catalog::exdir::SUBJECTDIR)/* "
546 tmp
+="$(envar_get catalog::incdir::SUBJECTDIR)/* "
547 tmp
+="$(envar_get catalog::srcdir::SUBJECTDIR)/* "
548 tmp
+="$(envar_get catalog::libdir::SUBJECTDIR)/* "
549 tmp
+="$(envar_get catalog::bindir::SUBJECTDIR)/* "
550 tmp
+="$(envar_get catalog::shlibdir::SUBJECTDIR)/* "
552 mkdir
"$(dirname $1)"
554 find $tmp > "$1" 2>/dev
/null
557 load_catanode_param
()
559 include param
/param.shlib
561 # init node parameter.
562 declare -g G_NODE_STR_FMT
="$(envar_get catalog::catanode::STR_FMT)"
563 declare -g G_NODE_PAIRCHARS
="$(envar_get catalog::catanode::PAIRCHARS)"
565 declare -p G_NODE_STR_FMT G_NODE_PAIRCHARS
567 # envar_create catalog::catanode::STR_FMT='<@{NCATAID}>@{ALIGN}[@{NTYPE}]@{ALIGN}@{NNAME}@{ALIGN}[@{NDESC}]'
568 G_OUTPUT_DIR_FMT
="$(envar_get catalog::dirnode::OUTPUT_DIR_FMT)"
569 declare -p G_OUTPUT_DIR_FMT
574 vonItemEntering
=onItemEntering
575 vonItemSubjectDirEntering
=onItemSubjectDirEntering
576 vonItemExiting
=onItemExiting
577 vonItemFileProc
=onItemFileProc
579 vonDirSubjectDirEntering
=onDirSubjectDirEntering
580 vonDirFileProc
=onDirFileProc
582 vonContProc
=onContProc
591 # first using file in opt param.
592 [[ -n "$finput" && ! -e $finput ]] && errflag
=1
593 [[ -z "$finput" ]] && errflag
=1 && echo "input file '$finput' is not exist" >&2
594 [[ "$finput" == enable ]] && errflag
=1
596 # second using file in $DEF_INPUT_CATALOG
597 if [[ "$errflag" == 1 ]]; then
598 [[ -e "$DEF_INPUT_CATALOG" ]] && finput
=$DEF_INPUT_CATALOG && errflag
=0
599 echo "input file '$DEF_INPUT_CATALOG'. (errflag=$errflag)" >&2
602 # third using file in DEF_INPUT_CATALOG_ARR[@]
603 if [[ "$errflag" == 1 ]]; then
604 for finput
in $DEF_INPUT_CATALOG_ARR; do
605 echo "finput=$finput" >&2
606 [[ -e $finput ]] && break
609 [[ ! -e $finput ]] && echo "input .catalog file '$finput' is not exist." >&2 && exit
613 finput
="/tmp/`basename $finput`"
616 mkdir
-p $SRCPKG_DIR/build
/
617 cp $finput $SRCPKG_DIR/build
/$
(basename $finput).bak
619 # always uses backup file.
620 echo $SRCPKG_DIR/build
/$
(basename $finput).bak
625 catalog_2_dirfiles
()
629 echo catalog_2_dirfiles
$finput
634 TEST_DIR_STR_FMT
="$(envar_get catalog::testdir::STR_FMT)"
636 # load param. invoke external param load func.
638 [[ -n $vonParamLoad ]] && $vonParamLoad
640 # get valid input file name
641 [[ "$1" != enable ]] && finput
="$1"
642 finput
="$(init_input_file "$finput")"
643 [[ ! -e $finput ]] &&
644 echo "[error] input/default .catalog file $1 does not exist." >&2 &&
645 echo -ne "[error] default .catalog file: \n${DEF_INPUT_CATALOG_ARR[@]}\n" >&2 &&
648 echo "input file: $finput"
650 # analyze catalog file.
651 vonCataNodeProc
=onDefaultCataNodeProc
652 catalog_each_line
"$finput"
654 # save outputed dir structure.
655 save_file_list
"$SRCPKG_DIR/build/codegen.dir.txt"
658 onItemNodeCataNodeDisplay
()
664 strfmt @CATANODE_STR_FMT
665 echo "$TPREFIX$CATANODE_STR"
666 # echo -ne "$TPREFIX[item] ${2} ${tmp4} \"${3}\"\n" # >&2
669 onDirNodeCataNodeDisplay
()
675 # declare -p NCATAID NTYPE NNAME NDESC
676 strfmt @CATANODE_STR_FMT
677 echo "$TPREFIX$CATANODE_STR"
678 # echo -ne "$TPREFIX[${1}] ${2} ${4} \"${3}\"\n" # >&2
683 ############################################################################
685 ############################################################################
691 include param
/param.shlib
696 TEST_DIR_STR_FMT
="$(envar_get catalog::testdir::STR_FMT)"
697 CATANODE_STR_FMT
="$(envar_get catalog::catanode::STR_FMT)"
698 vonItemNode
=onItemNodeCataNodeDisplay
699 vonDirNode
=onDirNodeCataNodeDisplay
701 if [[ $oprforce == "enable" ]]; then
702 list_full_content testing
/
704 list_full_content testing
/ |
more
714 info
"generate catalog from testing dir!\n"
716 [[ -z $1 ]] && return
725 # 描述文件中第一个有效行的空格数或tab数为缩进字符串的单位,用于计算目录层数。
730 info
"generate testing dir framework from catalog!\n"
734 # 比较已有的testcase目录与func_list,对差异部分进行更新。
736 ## catalog_content_cmp $path
737 ## output_dir_cmp $path
738 ## catalog_2_dir $path
741 catalog_2_dirfiles
$1
750 include param
/catanode.shlib
752 echo "'$@' matching='$matching'"
756 #NCATAID_REGEX="([[:xdigit:]-]*)"
758 NNAME_REGEX
="([[:alnum:]_]*)"
759 #NDESC_REGEX="([[:alnum:]_-+[:blank:]]*)"
760 NDESC_REGEX
="([^\.\"]*)"
761 NODE_TYPE_REGEX
="([[:alnum:]_]*)"
763 STR_FMT
="$(envar_get catalog::catanode::STR_FMT)"
764 PAIRCHARS
="$(envar_get catalog::catanode::PAIRCHARS)"
766 ITEM_CHKSUM
="$(echo "$NTYPE $NNAME $NDESC" | cksum)"
767 ITEM_CHKSUM
="${ITEM_CHKSUM:0:6}"
768 declare -p NCATAID_REGEX STR_FMT NCATAID NTYPE NNAME NDESC ITEM_CHKSUM
787 echo -ne "Options:\n"
789 echo -ne "\nuse '$PROG --help' for more details.\n"
797 [[ -z $term_width ]] && term_width
=80
799 helper
="$(opt_helper)"
800 eval CGEN_PROG_SYNTAX
="\"$CGEN_PROG_SYNTAX\""
801 eval echo -ne "\"$CGEN_USAGE_FMT\""
806 ############################################################################
808 ############################################################################
816 [[ "$@" =~
'--load' ]] && return
821 # prog_opt_dispatch "$@"
822 opt_desc_str_dispatch codegen_desc_hdr_str
823 opt_desc_str_dispatch codegen_desc_str
824 opt_desc_str_dispatch codegen_other_desc_str
827 init_dbglogout
2 testing
20000
828 # set_output_prefix info ""
832 # running action list function for options after init.
833 # the paramter for init will be effact, then execute the
839 ##############################
840 # section: public function
841 ##############################
845 # fdesc: the wrap of main(), and it append init code of some feature.
849 if [[ "$@" =~
"--debug" ]]; then
850 declare -g DBGOUTD_OUTPUT
=1
852 # does not need to shift args if the --debug option is not the
853 # first option. it will be ignore in process.
857 if [[ $1 != "--loadshlib" ]]; then
867 ##############################
869 ##############################
877 # copy code from term.shlib in shlib, do not use whole lib.
879 readonly CNORMAL
="\033[0m" # restore to normal mode
880 readonly FCGREEN
="\033[32m" # font green
881 readonly FCMAGENTA
="\033[35m" # font magenta
882 readonly FCRED
="\033[31m" # font red
883 readonly FCCYAN
="\033[36m" # font cyan
884 readonly CREV
="\033[7m" # reverse