first version.
[build-srcpkg.git] / example / build-config.abc / tools / build-srcpkg / shlib / incfile.shlib
blob4b5ab213ceff6a406c69f1016c8c0b95217eb5e4
3 # if source file direct nestly, the sub file source path is not correct.
4 # use this alias cmd to fix this problem.
5 # it stores $PWD, entering dir of include file.
9 # return if has been sourced before.
10 # this code is disabled, it should be putted in application program.
12 #alias include >/dev/null 2>&1
13 #[[ $? == 0 ]] && alias inc="include" return
15         
16 # TBD: write value in tmp, it should be generated by _EVL
17 #       SRCPKG_DIR_FULL=$PWD
20 shopt -s expand_aliases
21 alias include="diffinc "
24 inc_info ()
26         echo "$1" | grep -E "inc_info" >/dev/null 2>&1
27         test "$?" != 0 && return
28         
29         echo -ne "$@" # "\n"
32 inc_lvl=0
34 inc_indent_info ()
36         local cnt=$inc_lvl
38         echo "$1" | grep -E "inc_info" >/dev/null 2>&1
39         test "$?" != 0 && return
41         # for debugging.
42         while [[ $cnt -gt 0 ]]; do
43                 inc_info "  "
44                 : $((cnt--))
45         done
46         echo -ne "inc ($1)\n"
49 inc_dbgout ()
51         echo "$1" | grep -E "inc_dbgout" >/dev/null 2>&1
52         test "$?" != 0 && return
53         echo -ne "$@" # "\n"
56 #alias inc="diffinc "
57 #incfile ()
58 inc ()
60         local pwd=$PWD
61         local vname=
63         [[ -z "$1" || ! -f "$1" ]] && return
64         
65         inc_indent_info
66         
67         # uniq load
68         vname="`basename $1`"
69         vname=`echo "$vname" | tr [[:punct:]] '_' | tr '[[:lower:]]' '[[:upper:]]'`
70         eval test \"\$$vname\" = 1 && return
71         eval $vname=1
72         
73 #       echo inc $1
74         : $((inc_lvl++))
76         cd $(dirname $1)
77         source $(basename $1)
78         cd $pwd
79         
80         : $((inc_lvl--))
83 # get func list in current process.
84 get_func_list ()
86         local data=
88         while read data; do
89                 data="${data##* }"
90                 echo -ne "${data}\n"
91         done < <(declare -F)
94 # get var list in current process.
95 get_var_list ()
97         local data=
98         
99         while read data; do
100                 data="${data%%=*}"
101                 data="${data##* }"
102                 echo "${data}"
103         done < <(declare -p | grep -e "declare" | sed -e "s/^.*-f.*$//g")
106 # get alias list in current process.
107 get_alias_list ()
109         local data=
110         
111         while read data; do
112                 echo "${data}"
113         done < <(alias | grep -e "^alias")
117 # syntax: var_list_diff <outputvarname> = <listvarname1> - <listvarname2>
118 # desc: it diff two variable data, and get the new appended info.
120 listvar_diff ()
122     local vout=$1
123     local vin1="$3"
124     local vin2="$5"
125     local data=
126     
127     if test -n "$1" && test -n "$3" && test -n "$5" && test "$2" = '=' && test "$4" = '-' ; then
128         declare -g $1=
129         declare "$3=$(echo "${!3}" | tr ' ' $'\n')";
130         declare "$5=$(echo "${!5}" | tr ' ' $'\n')";
131 #        echo "${!5}"
132 #        echo "${!3}"
133         while read data; do
134             data=${data#< }
135             # save to array.
136             declare -g $1+="${data}"$'\n'
137         done < <(echo "${!5}" | diff --from-file=<(echo "${!3}") - | grep -e "<";)
138                 declare -g $1+="${!1%$'\n'}"
139     fi
142 diffinc ()
144         local vname=${1##*/}
145         vname=${vname%.*}
146         vname=${vname//[^[:alnum:]_]/_}
147         
148         #
149         # declare var before source, or it will be append to varlist_xxx.
150         #
151         declare funclist1_$vname=""
152         declare funclist2_$vname=""
153         declare varlist1_$vname=""
154         declare varlist2_$vname=""
155         declare aliaslist1_$vname=""
156         declare aliaslist2_$vname=""
157         
158         #
159         # getting func/var/alias list before
160         #
161         eval funclist1_$vname=\"\$\(get_func_list\)\"
162         eval varlist1_$vname=\"\$\(get_var_list\)\"
163         eval aliaslist1_$vname=\"\$\(get_alias_list\)\"
164         
165         #
166         # file source.
167         #
168 #       echo include $1
169         incfile $1
170         
171         #
172         # getting func/var/alias list after
173         #
174         eval funclist2_$vname=\"\$\(get_func_list\)\"
175         eval varlist2_$vname=\"\$\(get_var_list\)\"
176         eval aliaslist2_$vname=\"\$\(get_alias_list\)\"
177         
178         #
179         # diff list between before and after.
180         #
181         listvar_diff funclist_$vname = funclist2_$vname - funclist1_$vname
182         listvar_diff varlist_$vname = varlist2_$vname - varlist1_$vname
183         listvar_diff aliaslist_$vname = aliaslist2_$vname - aliaslist1_$vname
184         
185 #       eval echo funclist_$vname=\${funclist_$vname} > 3.txt
186 #       eval echo varlist_$vname=\${varlist_$vname} >> 3.txt
187 #       eval echo aliaslist_$vname=\${aliaslist_$vname} >> 3.txt
191 # fsyntax: loadimi <imi-file-name>
193 loadimi ()
195         local data=
196         local bak=
197         local vlist=
198         local flag=""
199         local tmp=
200         local i=
201         local pwd=$PWD
202         local file=$(basename $1)
203         local cnt=$inc_lvl
205         test -z "$1" || test ! -f "$1" && return
207         # for debugging.
208         while test "$cnt" -gt 0 ; do
209                 inc_info "  "
210                 : $((cnt--))
211         done
212         inc_info "loadimi ($@)\n"
214         : $((inc_lvl++))
215         
216         # it's normal if file is not exist.
217         test ! -e "${1}" && 
218                 inc_dbgout "parameter file($1) is not exist.\n" && 
219                 unset $name && 
220                 return 0
221         
222         test "`echo "$1" | grep -o -P '([^\.]*)' | tail -n 1`" != "imi" && 
223                 err "specified file $1 is not .imi file.\n" && 
224                 unset $name && 
225                 return 1
226         
227         cd $(dirname $1)
229         if test -e "$file" ; then
230                 # it need -r param to receive '\'.
231                 while read -r data; do
232                         : $(( i++ ))
233                         [[ "${data}" =~ $'\r' ]] && data=$(echo ${data:0:-1})
234                         # filter comment, and skip blank line.
235                         [[ -z ${data//[[:space:]]/} ]] && continue
236                         if [[ ${data} =~ '#' ]]; then
237                                 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
238                                 data="${data//[[:space:]]*[#].*/}"
239                         fi
240                         
241                         [[ "${data}" =~ ^inc\  || "${data}" =~ ^loadimi\  || "${data}" =~ ^loadlist\  ]] && eval $data && continue;
242             
243                         if [[ "${data}" =~ '=(' ]]; then
244                                 flag="array"
245                                 tmp="${data}"$'\n'
246 #                               [[ ! "${data}" =~ ')' ]] && continue
247                         fi
248                         
249                         if [[ "${flag}" == 'array' ]]; then
250                                 if [[ ! "${data}" =~ '=(' ]]; then
251                                         if [[ "${data}" =~ ')' ]]; then
252                                                 tmp+="${data%%\)*})"$'\n'
253                                                 data="$tmp"
254                                         else
255                                                 tmp+="${data}"$'\n'
256                                         fi
257                                 fi
258                                 
259                                 if [[ "${data}" =~ ')' ]]; then
260                                         flag=""
261                                 else
262                                         continue
263                                 fi
264                         fi
265                         
266                         # ignore [xxx] section setting, use it as an ini file.
267                         [[ ${data} =~ ^[[:space:]]*\[ ]] && continue
268                         
269                         inc_dbgout "data=\"${data}\"\n"
270                         
271                         if [[ ${data} =~ _EVL ]]; then
272                                 # define _EVL
273                                 eval declare -g "${data}"
275                                 # define without _EVL
276                                 data="${data/_EVL=/=}"
277                                 #
278                                 # it can works with "" or '' in config file.
279                                 # multi-line paramter putted in a single line,
280                                 # and assign to the specified variable.
281                                 #
282                                 data="${data//\"/\\\"}"
283 #                               data="${data//\'/\\\'}"
284 #                               inc_dbgout "=== ${data}\n"
285                                 # \$\'\\\"\"\\\n\\\"\"\'
286                                 eval "$(eval echo \"${data}\")"
287                         else
288                                 # append newline after every one.
289 #                               inc_dbgout "=== ${data}\n"
290                                 eval "${data}"
291                                 #$'"\n"'
292                         fi
293                         
294                         [[ ! "$data" =~ '=' ]] && echo -e "\033[1m\033[31m[error][$file:line$i]\033[0m: '$data' not a valid assign statement." && exit -1
295                         
296                         # backup var name.
297                         tmp="$data"
298                         local dqcnt=0
299                         local qcnt=0
300                         local charcnt=0
301                         while [[ "${tmp}" =~ '=' ]]; do
302                                 bak="${tmp%=*}"
303                                 bak2="${tmp##*=}"
304                                 [[ ${bak: -1,1} == '+' ]] && bak="${bak:0:-1}"
305                                 tmp="$bak"
307 #                               [[ "$abc" =~ (\=.*\=.*)*(\=.*) && $(($(expr length ${abc//[^=]/})%2)) == 1 ]] && echo bbb ${BASH_REMATCH[@]}
308 #                               [[ "${tmp##*=}" =~ '"'{1,3,2} ]] && tmp="$bak" && continue
310                                 #
311                                 # matching quote
312                                 #
313                                 charcnt="${bak2//[^\']/}"
314                                 qcnt=$((${#charcnt} + qcnt))
315                                 charcnt="${bak2//[^\"]/}"
316                                 dqcnt=$((${#charcnt} + dqcnt))
317                                 [[ "${bak2}" =~ (\'.*\'.*)*(\'.*) && $((qcnt%2)) == 1 ]] && continue
318                                 [[ "${bak2}" =~ (\".*\".*)*(\".*) && $((dqcnt%2)) == 1 ]] && continue
320                                 [[ "${tmp}" =~ '#' ]] && continue;
321                                 [[ "${tmp: -1:1}" == ':' ]] && continue;
322                                 break
323                         done
324                         data="$tmp"
325                         
326                         # generate var in auto by _EVL suffix.
327                         if [[ "${data}" =~ _EVL$ ]]; then
328                                 eval "${data}=${!data}"
329                         fi
331                         vlist+="${data}"$'\n'
332 #                       inc_dbgout "vlist+=\"${data}$'\n'\""
333                 done < "$file"
335                 # get var name, and delete redundent "\n".
336                 # it need -r param to receive '\'.
337                 while read -r data; do
338                         [[ -z $data ]] && continue
340                         while [[ "${!data: -1:1}" == $'\n' ]]; do
341                                 eval "$data=\"\${!data:0:-1}\""
342                         done
343                 done <<< "$vlist"
344         else
345                 :
346                 err "list file '$1' is not exist.\n"
347         fi
348         
349         cd $pwd
350         
351         : $((inc_lvl--))
355 # fsyntax: loadlist <list-file-name>
356 # fdesc: load .list file. if not exist, load .lst file.
358 loadlist ()
360         local tmp=
361         local data=
362         local bak=
363         local bak2=
364         local i=0
365         local name=
366         local pwd=$PWD
367         local file=$(basename $1)
368         local cnt=$inc_lvl
370         [[ -z "$1" || ! -f "$1" ]] && return
372         # for debugging.
373         while [[ $cnt -gt 0 ]]; do
374                 inc_info "  "
375                 : $((cnt--))
376         done
377         inc_info -ne "loadlist ($1)\n"
379         : $((inc_lvl++))
380         
381         #
382         # skip nestly loaded file.
383         #
384         name=${1//[^[:alnum:]_]/_}
385         if [[ -v ${name} && ${!name} == Y ]]; then
386 #               echo "file $name loaded nestly."
387 #               exit
388                 return
389         fi
390         declare -g "$name=Y"
392         [[ ${1##*\.} != "lst" && ${1##*\.} != "list" ]] && err "specified file '$1' is not .list or .lst file.\n" && unset $name && return 1
394         cd $(dirname $1)
396         if [[ -e "$file" ]]; then
397                 # it need -r param to receive '\'.
398                 while read -r data; do
399                         : $(( i++ ))
400                         # filter comment, and skip blank line.
401                         [[ -z ${data//[[:space:]|]/} ]] && continue
402                         if [[ ${data} =~ '#' ]]; then
403                                 [[ ${data} =~ ^[[:space:]]*[#] ]] && continue
404                                 data="${data%%*([[:space:]])[#]*}"
405                                 [[ -z "${data}" ]] && continue
406                         fi
407                         
408                         [[ "${data}" =~ '^inc ' || "${data}" =~ '^loadimi ' || "${data}" =~ '^loadlist ' ]] && eval $data && continue;
409             
410                         #
411                         # append '\' for '\"'
412                         #
413                         data="${data//\\\"/\\\\\\\"}"
414                         
415                         # append newline after every one.
416                         inc_dbgout "list: ${data}\n"
417 #                       eval "${data}"$'"\n"'
418                         eval declare -g "${data}"
419                         [[ $? != 0 ]] && err "[$file:line$i]: '$data' failed.\n" && exit -1
421                         # get var name.
422                         tmp="$data"
423                         local dqcnt=0
424                         local qcnt=0
425                         local charcnt=0
426                         while [[ "${tmp}" =~ '=' ]]; do
427                                 bak="${tmp%=*}"
428                                 bak2="${tmp##*=}"
429                                 [[ ${bak: -1,1} == '+' ]] && bak="${bak:0:-1}"
430                                 tmp="$bak"
432 #                               [[ "$abc" =~ (\=.*\=.*)*(\=.*) && $(($(expr length ${abc//[^=]/})%2)) == 1 ]] && echo bbb ${BASH_REMATCH[@]}
433 #                               [[ "${tmp##*=}" =~ '"'{1,3,2} ]] && tmp="$bak" && continue
435                                 #
436                                 # matching quote
437                                 #
438                                 charcnt="${bak2//[^\']/}"
439                                 qcnt=$((${#charcnt} + qcnt))
440                                 charcnt="${bak2//[^\"]/}"
441                                 dqcnt=$((${#charcnt} + dqcnt))
442                                 [[ "${bak2}" =~ (\'.*\'.*)*(\'.*) && $((qcnt%2)) == 1 ]] && continue
443                                 [[ "${bak2}" =~ (\".*\".*)*(\".*) && $((dqcnt%2)) == 1 ]] && continue
445                                 [[ "${tmp}" =~ '#' ]] && continue;
446                                 [[ "${tmp: -1:1}" == ':' ]] && continue;
447                                 break
448                         done
449                         data="$tmp"
451                         bak="$data"
453                         # get var name, and delete redundent "\n".
454                         bak="${bak%=*}"
455                         [[ ${bak: -1:1} == '+' ]] && bak="${bak:0:-1}"
457                         while [[ "${!bak: -1:1}" == $'\n' ]]; do
458                                 eval "$bak=\"\${!bak:0:-1}\""
459                         done
461                         #
462                         # CFLAGS_DEF_LIST_Y+=" -DMACHTYPE=\"$MACHTYPE\" "
463                         # disable '\"' to '\\\"'.
464                         #
465 #                       declare -g "$bak=${!bak//\\\"/\\\\\\\"}"
467                         # append blank to the end of string in auto.
468                         [[ "${!bak: -1:1}" != ' ' || "${!bak: -1:1}" != $'\n' ]] && declare -g $bak+=$'\n'
469                 done < $file
470         else
471                 :
472 #               err "list file is not exist.\n"
473         fi
475         #
476         # it can be loaded next time un-nestly.
477         #
478         unset $name
480         cd $pwd
481         
482         : $((inc_lvl--))