20230322
[shlib.git] / shlib / gplib.shlib
blob50bdca549866ee434d15763df33018bdaaba8b0d
1 #!/bin/bash
2 ############################################################
3 # source: gplib.shlib
4 # author: devenkong(18151155@qq.com)
5 # date: 2021-09-15
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
10 # and modify it.
11 ############################################################
12 # note:
13 # general purpose library. it contain frequently using
14 # functions in other shlib, so that developer should not
15 # include manay libs.
16 # when new feature added, some of them will added into
17 # this file.
18 # the basic function is 'func' and 'dreturn', it provide
19 # function define with named paramter, and return a string
20 # by dreturn.
21 ############################################################
25 # funclist
26 # @ func/dreturn/invoke
27 # @ rptchar/tabn/ntab
28 # @ stdio
29 # @ file-ops
30 # @ misc,is_xxx(var/func/alias is defined),exit_prog()
35 # todo:
36 # @ function paramter is defined with name and type, pointer type is not implemented.
37 # @ release allocated dvar, when dvar soft pkg is works.
38 # @ define return as dreturn, and use shlibopt to enable this feature.
39 # @ set a counter in invoke(), used for invoke info.
43 # this cmd enable alias feature in script. it is disabled in default.
44 shopt -s expand_aliases
47 # global variable re-init if this shlib has been loaded.
48 # invoke this before 'uniqlib'
50 PROG_GVAR_INIT gplib
52 uniqlib gplib
55 ##############################
56 # section: shlib include
57 ##############################
60 ##############################
61 # section: public comment info
62 ##############################
65 ##############################
66 # section: variable define
67 ##############################
69 shlib_gplib_init ()
71 fname=
72 param_type_list=( )
73 param_name_list=( )
75 PROG_ID=$$
78 # paths define
79 # ROOTFS/PROG_NAME/TMP_DIR/LOG_DIR/RUNNING_DIR/ETC_DIR/DATA_DIR/
80 # used for program to access public system dir in different system
81 # enviroument, especially in system of termux app
83 ROOTFS=${ROOTFS:-"`cd $(which ls); cd ..; pwd`"}
84 PROG_NAME=${ROOTFS:-"$(basename $0)"}
85 PROG_PID=$$
86 TMP_DIR=$ROOTFS/tmp/${PROG_NAME}-$$/
87 LOG_DIR=$ROOTFS/var/log/${PROG_NAME}/
88 RUNNING_DIR=$ROOTFS/run/${PROG_NAME}-$$/
89 ETC_DIR=$ROOTFS/etc/${PROG_NAME}/
90 DATA_DIR=$ROOTFS/var/data/${PROG_NAME}/
91 RES_DIR=$ROOTFS/usr/share/${PROG_NAME}/
93 RET_VALUE=
96 shlib_gplib_init
99 # global variable init function invoking.
100 # invoke GVAR_INIT if it is running at first time.
102 #GVAR_INIT gplib
105 ##############################
106 # section: private function
107 ##############################
110 # fsyntax: on_func_return <ret-val>
111 # fdesc: return with string value, and release resource allocated. not
112 # fully implemented.
114 on_func_return_shlib ()
116 local ret
118 # set IFS to null char
119 IFS=$'\x00'
120 read -t 1 ret
122 [[ -z $ret ]] && return 0
124 [[ -z ${ret//[0-9]/} ]] && : echo $ret && return $ret
126 echo $ret
128 return
132 # it can be setted with other functions, and extend different feature.
134 alias on_func_return="on_func_return_shlib"
138 ##############################
139 # section: public function
140 ##############################
142 #####################################################################
143 # [function define]
144 # using [ ] as ( ), makes difference for defination. and () is used
145 # as other feature in sh script, only [ ] can be used as a normal
146 # string char in command line.
147 #####################################################################
150 # fsyntax: func <fun_name> [ <vtype> <vname>, <vname>, ... ]
151 # func abc [ int param1, param2 ]
152 # fdesc: define a function with named paramters.
154 func ()
156 local fname=
157 local param="$@"
158 local tmp=
159 local i
160 local j
162 fname="$1"
163 param=${param#*[}
164 param=${param%]*}
166 OLD_IFS=$IFS
167 IFS=","
168 param=( $param )
169 param_type_list=( )
170 param_name_list=( )
172 IFS=" "
173 for (( i=${#param[@]}-1; i>=0; i-- )); do
174 tmp=( ${param[$i]} )
175 for (( j=${#tmp[@]}-1; j>=0; j-- )); do
176 [[ -z ${tmp[$j]} ]] && continue
178 # ignor var qualifier
179 if [[ -z ${param_name_list[$i]} ]]; then
180 param_name_list[$i]=${tmp[$j]}
181 elif [[ -z ${param_type_list[$idx]} ]]; then
183 else
184 break
186 done
187 done
188 IFS=$OLD_IFS
190 alias {="
191 unalias { ;
192 function $fname () {
193 `for (( i=${#param_name_list[@]}-1;i >= 0; i-- )); do
194 echo -ne \"local \${param_name_list[\$i]}=\\\${$(( i + 1 ))}\";
195 echo -ne \"\n\";
196 done; ` "
200 # fsyntax: dreturn <string>
201 # fdesc: dreturn cmd return from current function with a string stored
202 # in RET_VALUE. and it could invoke resource release functions, to
203 # release resource allocated in function. such as dvar variable.and
204 # this feature have not not implemented currently.
205 # dreturn defined as an alias, so that the default return invoking
206 # could be effective.
208 alias dreturn="{ RET_VALUE=\$(on_func_return) ; return \$?; } <<< "
211 # fsyntax: get_ret_str
212 # fdesc: the wrap of RET_VALUE accessing.
214 get_ret_str ()
216 echo "$RET_VALUE"
220 # fsyntax: invoke [ <paramter1>, ... ]
221 # fdesc: invoke function with paramters. it is used for dvar, to access
222 # functions in dvar. it is not used just now. todo:
223 invoke ()
225 local name=$1
226 shift
227 local cmd="$*"
229 cmd=${cmd#*[}
230 cmd=${cmd%]*}
231 IFS_OLD=$IFS
232 IFS=','
233 cmd=( ${cmd} )
235 $name "${cmd[@]}"
239 # this function group implement an IFS append and restore operation.
240 # it should be implemented in a builtin cmd, and it will cost less cpu.
241 # define pop and restore operation as an alias, it decreas cpu cost.
244 ifspush ()
246 IFS="${1}${IFS}"
249 alias ifspop='IFS="${IFS:1}"'
251 ifset ()
253 OIFS="$IFS"
254 IFS="$1"
257 alias ifsrestore='IFS="${OIFS}"'
260 #####################################################################
261 # [file operation]
262 # use file as c language function.
263 #####################################################################
266 # fsynax: get_file_top_valid_id
267 # fdesc: get free file id on top value. if the function invoked in $(),
268 # $() operation will use a new fd as anonymous pipe fd.
270 get_file_top_valid_id ()
272 local i
274 i=$(ulimit -n)
275 for (( i=$((i-1)); i>0; i-- )); do
276 [[ ! -e /proc/self/fd/$i ]] && echo $i && return
277 done
281 # fsyntax: openfile <fname>
282 # fdesc: create/open a file with fd output.
284 alias openfilefd='{
285 local file=
286 local fd=$(get_file_top_valid_id)
287 echo fd=$fd 2>&1
288 read -r -t 1 file
289 [[ -z $file ]] && return;
290 eval exec $fd<>$file
291 [[ $? == 0 ]] && echo $fd
292 } <<<'
295 # fsyntax: closefile <fd>
296 # fdesc: close a file fd
297 alias closefilefd='{
298 local file=
300 read -r -t 1 file
301 exec $file>&-
302 } <<<'
305 # fsyntax: hfd=$(tmp_file)
306 # fdesc: output temp file name string with the path of temp dir.
308 tmp_file_name ()
310 echo $TMP_DIR/$RANDOM.tmp
314 # TBD: exec {v}>$TMPFILE
315 # it opens a file, and the id store in the variable 'v'.
319 # fsyntax: fname=$(tmp_file)
320 # fdesc: create a temp file, output the file name.
322 tmp_file ()
324 touch $TMP_DIR/$RANDOM.tmp
325 [[ $? == 0 ]] && echo $TMP_DIR/$RANDOM.tmp
329 # fsyntax: hfd=$(tmp_file_fd)
330 # fdesc: create a temp file, output the file id.
332 alias tmp_file_fd='{
333 local file=
334 local fd=$(get_file_top_valid_id)
336 file=$TMP_DIR/$RANDOM.tmp
337 [[ -z $file ]] && return;
338 eval exec $fd<>$file
339 [[ $? == 0 ]] && echo $fd
343 # fsyntax: close_tmp_file <fd>
344 # fdesc: close the temp file by fd, and delete it.
346 close_tmp_file ()
348 if [[ ${!1} != 0 && $(( ${!1} )) == 0 ]]; then
349 local fname="/proc/self/fd/$1"
350 closefile $1
351 [[ -e $fname ]] && rm -rf $fname
352 return 0
353 else
354 [[ -e $1 ]] && rm -rf $1
361 init_prog_dirs ()
367 # fsyntax: delete_tmp_dirs
368 # fdesc: clear temp files. invoked when system booting.
370 delete_tmp_dirs ()
372 [[ -d $TMP_DIR ]] && rm -rf $TMP_DIR
376 # fsyntax: get_file_size <file-name>
377 # fdesc: get size of specified file.
379 get_file_size ()
381 # wc -l $f_logout | cut -d " " -f1
382 size=$(stat $f_logout | grep -e "Size:")
383 size=${size#*Size: }
384 size=${size%% *}
385 # echo size=$size
388 #####################################################################
389 # [stdio]
390 #####################################################################
393 # fsyntax: progexit
394 # fdesc: if exit in 'cat - | while true; do echo xxx; exit; done',
395 # the cmd onlyexit from the sub-process. but this function is used to
396 # exit from the process of current program.
398 progexit ()
400 kill $PROG_ID
404 # it will conflect with the one defined in stdio.shlib.
405 # so comment it.
407 #input ()
409 # OLD_IFS=$IFS
410 # IFS=$'\n'
411 # read -r $@
412 # IFS=$OLD_IFS
416 # fsyntax: info
417 # fdesc: string ouput for program normal information.
419 #info ()
421 # OLD_IFS=$IFS
422 # IFS=$'\n'
423 # read -r $@
424 # IFS=$OLD_IFS
430 # TBD:
431 # bug to be fixed.
436 # fsyntax: rptstr <N> <str>
437 # fdesc: output a string N times.
439 rptstr ()
441 printf "%*s" "$1" "$2"
445 # fsync: tabn <N>
446 # fdesc: output N tabs. tabn output tab as blanks.
448 TAB_CNT=4
449 #alias tabn='eval printf "%*s" \$(( $(cat -) * $TAB_CNT)) " ") <<< '
450 alias tabn='{ hgf_idx=$(( $(cat -) * $TAB_CNT)); for ((;hgf_idx>0;hgf_idx--)); do echo -n " "; done; } <<< '
451 alias ntab='printf "%*s" $(cat -) "\t") <<< '
454 #####################################################################
455 # [misc]
456 # other misc functions.
457 #####################################################################
460 # is_xxx
461 # it is frequently used in program, to judge weather the object is defined.
465 # fsynax: is_digital <vname>
466 # fdesc: check if the var content is digital number.
467 is_digital ()
469 local tmp
471 # todo: string started with array, some times give this err hint:
472 # ": 1testsuitetestingshlog: value too great for base (error token is "1testsuitetestingshlog")"
473 # tmp=$($(( ${!1//[[:punct:]]/} )) 2>/dev/null)
474 # if [[ ${!1} != 0 && -n $tmp && "$tmp" == "0" ]]; then
475 if [[ "${!1}" =~ [^0-9] ]]; then
476 echo false && return 0
477 else
478 echo true
483 # fsyntax: is_var_defined <vname>
484 # fdesc: check if the var is defined.
485 is_var_defined ()
487 [[ -z "${!1}" ]] && echo false && return 0
488 echo true
492 # fsyntax: is_func_defined <vname>
493 # fdesc: check if the func is defined.
494 is_func_defined ()
496 [[ "$(declare -F $1)" == "$1" ]] && echo true && return 0
497 echo false
499 return 1
503 # fsyntax: is_alias_defined <aname>
504 # fdesc: check if the alias cmd is defined.
506 is_alias_defined ()
508 [[ -n "$(alias $1)" ]] && echo true && return 0
509 echo false
510 return 1
514 # fsyntax: exist_invoke <vname>
515 # fdesc: check if the func/alias is defined.
516 exist_invoke ()
518 if [[ "$(declare -F $1)" != "$1" ]]; then
519 if [[ -n "$(alias $1)" ]]; then
520 # cmd not exist.
521 return 1
525 # invoke
526 "$@"
530 # fsyntax: dbgout_disp <cmd>
531 # fdesc: display command output string in a row.
533 dbgout_disp ()
535 blank=" "" ";
536 width=$(stty size| cut -d " " -f2);
537 half=$(($width/2-2));
539 { "$@"; } |
540 while read line ; do
541 len=${#line};
542 if [ $len -le $width ]; then
543 if [ $len -le $(($half+2+2)) ]; then
544 echo -ne "\r$line";
545 else
546 echo -ne "\r$line" | cut -b -$half -z;
547 echo -n " -- "
548 echo -ne "$line" | cut -b $(($half+2+2))- -z;
550 echo -n "${blank:0:$(($width - $len))}";
551 else
552 echo -ne "\r$line" | cut -b -$half -z;
553 echo -n " -- "
554 echo -ne "$line" | tail -c -$half -z;
556 echo -ne "\r";
557 done;
559 echo;
562 return
564 # use { } < <(cmd) structure, the code in {} can be executed as a non sub-process.
567 ######################
568 # section: file tail
569 ######################