2 # ==============================================================================
3 # portsreinstall library script
4 # - Interface of libraries for command line options -
5 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Variables =============
10 OPTIONS_ERRNO=0 # 0: no error, 1: configuration error, 2: internal error
13 # ============= Database of options which are given at each run and not saved =============
14 # [Syntax of option databases]
15 # short_name, long_name, variable, defult_vaule, set_value
16 # Columns are delimited by tab characters.
23 # ============= Database of options which are saved and renewable at each run =============
24 options_db_saved_and_renewable ()
30 # ============= Database of options which are saved and renewable only at the initial runs of redo command (on target specification) =============
31 options_db_saved_and_renewable_in_redo_on_target ()
37 # ============= Database of options which are saved and renewable only at the initial runs of redo command (on configuration files) =============
38 options_db_saved_and_renewable_in_redo_on_conf ()
44 # ============= Database of options which are saved and not renewable until the temporary database is cleaned =============
45 options_db_saved_and_non_renewable ()
51 # ============= Regularize the option value =============
56 # ============= Database of all options to be saved =============
59 options_db_saved_and_renewable
60 options_db_saved_and_renewable_in_redo_on_target
61 options_db_saved_and_renewable_in_redo_on_conf
62 options_db_saved_and_non_renewable
65 # ============= Database of all options =============
72 # ============= Database for selected option sets =============
81 options_db_saved_and_renewable
83 renewable_in_redo_on_target )
84 options_db_saved_and_renewable_in_redo_on_target
86 renewable_in_redo_on_conf )
87 options_db_saved_and_renewable_in_redo_on_conf
90 options_db_saved_and_non_renewable
102 message_echo "ERROR: Invalid argument [$1] for options_inverse_parse" >&2
112 # ============= Convert from a short option name to the corresponding variable name =============
113 options_convert_shortname_to_varname ()
117 options_db_all | grep -m 1 "^${shortname}[[:space:]]" | cut -f 3 | sort -u
120 # ============= Dump all command line arguments and options =============
123 echo -n "`echo "$0" | sed -E 's/(.)/\\\\\\1/g'`"
126 echo -n " `echo "$1" | sed -E 's/(.)/\\\\\\1/g'`"
131 # ============= Get default option settings =============
134 options_db_all | cut -f 3,4 | sort -u | sed -E 's/[[:space:]]/=/'
137 # ============= Initialize option settings with the default values =============
138 options_set_default ()
140 options_default > ${TMPDIR}/default_optvals.sh
141 . "${TMPDIR}/default_optvals.sh"
144 # ============= Get the argument for getopts =============
145 options_getopts_arg ()
147 options_db_all | cut -f 1,5 | grep -v '^[[:space:]]' | sort -u \
148 | sed -E 's/[[:space:]]:$/:/;s/[[:space:]].*$//' | tr -d '\n'
151 # ============= Get option settings =============
152 options_getopts_only_short ()
154 local OPTERR getopts_option option command OPTARG nshifts val
156 getopts_option=`options_getopts_arg`
157 while getopts $getopts_option option > /dev/null
159 val=`str_escape_replaceval "$OPTARG"`
160 command=`options_db_all | grep -m 1 "^${option}[[:space:]]" \
161 | cut -f 3,5 | sed -E 's/[[:space:]]/=/;s/:$/'$val'/' || :`
162 [ -n "$command" ] || return 1
163 echo -n "$command;OPTIND=$OPTIND;"
167 # ============= Get option settings =============
170 local OPTIND option command nshifts val erropt
177 eval `( set -e; options_getopts_only_short "$@")`
179 nshifts=$(($nshifts+$OPTIND-1))
180 [ "x$1" = "x--" ] && break
181 expr "x$1" : '^x-.*' > /dev/null || break
182 [ $# -eq 0 ] && break
184 option=`expr "x$1" : '^x--\([a-zA-Z0-9][a-zA-Z0-9-]*\).*'` || break
185 command=`options_db_all | cut -f 2,3,5 | grep -m 1 "^${option}[[:space:]]" \
186 | cut -f 2,3 | sed -E 's/[[:space:]]/=/' || :`
187 [ -n "$command" ] || break
188 if expr "$command" : '^[^=]*=:$' > /dev/null
190 expr "x$1" : '^x--[a-zA-Z0-9][a-zA-Z0-9-]*=.*' > /dev/null || break
191 val=`expr "x$1" : '^x--[a-zA-Z0-9][a-zA-Z0-9-]*=\(.*\)'` || :
192 eval `expr "$command" : '^\([^=]*=\).*'`\$val
194 [ "x$1" = "x--$option" ] || break
197 nshifts=$(($nshifts+1))
203 || { message_echo "ERROR: Illeagal option [$erropt]" >&2; OPTIONS_ERRNO=1; return 1; }
204 OPTIONS_SHIFT=$nshifts
208 # ============= Filter option value definitions to pick up selected groups =============
211 grep `options_db "$@" | cut -f 3 | sed 's/^/-e ^/;s/$/=/'`
214 # ============= Compose an option set in a command line form from the current settings =============
215 options_inverse_parse ()
217 options_db "$@" | while read short_name long_name variable defult_vaule set_value
220 eval val_def=$defult_vaule
221 eval val_set=$set_value
222 if [ "x$set_value" = x: ]
224 [ "x$val" = "x$val_def" ] \
225 || misc_get_all_vardefs | grep -m 1 "^$variable=" \
226 | sed "s/^[^=]*=/-$short_name /"
227 elif [ "x$val" = "x$val_set" ]
229 echo -n "-$short_name"
232 done | tr '\n' ' ' | sed 's/ *$//'
235 # ============= Filter option value definitions to pick up non-default ones =============
236 options_filter_configured ()
239 tmpptn=${TMPDIR}/options_filter_configured:ptn
240 options_db "$@" | while read short_name long_name variable defult_vaule set_value
243 eval val_def=$defult_vaule
244 [ "x$val" = "x$val_def" ] || echo "^$variable="
249 # ============= Check inclusion of invalid options intending to be renewed =============
250 options_chk_invalid_optvals_renewal ()
252 local dbgroup comment_condition invalid_options num_invalid_options term_opts delimiter
255 misc_get_all_vardefs | options_filter_configured "$dbgroup" \
256 > ${TMPDIR}/options_renewed_optvals:invalid_options_defs
257 invalid_options=`options_inverse_parse "$dbgroup" < ${TMPDIR}/options_renewed_optvals:invalid_options_defs`
258 num_invalid_options=`wc -l < ${TMPDIR}/options_renewed_optvals:invalid_options_defs`
259 if [ $num_invalid_options -ne 0 ]
261 term_opts="Option $invalid_options is"
262 [ $num_invalid_options -gt 1 ] && term_opts="Options $invalid_options are"
264 [ -n "$comment_condition" ] && delimiter=' '
265 message_echo "ERROR: $term_opts invalid in restarted runs${delimiter}${comment_condition}." >&2
270 # ============= Get renewed option value definitions as well as checking their validity =============
271 options_renewed_optvals ()
273 local flag_shortname dbgroup flag_varname flag
276 flag_varname=`options_convert_shortname_to_varname "$flag_shortname"`
277 eval "flag=\$$flag_varname"
278 if [ "x$flag" = xyes ]
280 misc_get_all_vardefs | options_filter "$dbgroup"
282 options_chk_invalid_optvals_renewal "$dbgroup" "without -$flag_shortname"
286 # ============= Select new target ports specified by globs if duplicated for each glob pattern =============
287 options_select_new_ports_if_duplicated ()
289 local option dstfile optargs tmp_target_ports tmp_existing_ports tmp_new_ports itemlist globs_list nlines iline title desc
294 tmp_target_ports=${TMPDIR}/options_select_new_ports_if_duplicated:target_ports
295 tmp_existing_ports=${TMPDIR}/options_select_new_ports_if_duplicated:existing_ports
296 tmp_new_ports=${TMPDIR}/options_select_new_ports_if_duplicated:new_ports
297 globs_list=${TMPDIR}/options_select_new_ports_if_duplicated::globs_list
298 itemlist=${TMPDIR}/options_select_new_ports_if_duplicated::itemlist
299 cp /dev/null "$dstfile.tmp"
300 echo "$optargs" | sed -E 's/[ :]+/\
301 /g' | grep -v '^$' | sort -u > $globs_list
302 nlines=`wc -l < $globs_list`
304 while [ $iline -le $nlines ]
306 glob=`sed -n ${iline}p "$globs_list"`
308 rm -f "$tmp_target_ports"
309 pkgsys_register_evaluated_globs add "$tmp_target_ports" "$glob"
310 if [ `cat "$tmp_target_ports" 2> /dev/null | wc -l` -eq 0 ]
312 message_echo "WARNING: No matching port for target glob [$glob]." >&2
315 cp /dev/null "$tmp_existing_ports"
316 cp /dev/null "$tmp_new_ports"
319 if pkgsys_exists_or_existed_from_orig "$origin" \
320 || cat "${DBDIR}/installed_ports" "${DBDIR}/targets_specified_so_far" 2> /dev/null \
321 | grep -q -Fx "$origin"
323 echo "$origin" >> $tmp_existing_ports
325 echo "$origin" >> $tmp_new_ports
327 done < $tmp_target_ports
328 cat "$tmp_existing_ports" >> $dstfile.tmp
329 if [ $opt_allow_new_targets = yes ]
331 if [ `wc -l < $tmp_new_ports` -gt 1 ]
333 title="Uninspected ports matching a glob pattern [$glob] for -$option option"
334 desc='Checked ones are newly installed.'
337 echo "$origin '' off"
338 printf '%s\t""\t%s\n' "$origin" '' "$val"
339 done < $tmp_new_ports > $itemlist
340 misc_dialog_checklist "$title" "$desc" "$dstfile.tmp" "$itemlist"
342 cat "$tmp_new_ports" >> $dstfile.tmp
345 [ `wc -l < $tmp_new_ports` -eq 0 ] || \
346 message_echo "WARNING: Ignored not-yet-installed ports for target glob [$glob]." >&2
347 if [ `wc -l < $tmp_existing_ports` -eq 0 ]
349 message_echo "WARNING: No available matching port for target glob [$glob]." >&2
353 mv "$dstfile.tmp" "$dstfile"
356 # ============= Get the database type of dependency algorithm for the current option setting =============
357 options_get_dependency_type ()
359 case $opt_include_buildtime_dependencies+$opt_include_runtime_dependencies in
375 # ============= Parse the database type tag of dependency algorithm and reflect it to option values =============
376 options_parse_dependency_type ()
382 opt_include_buildtime_dependencies=yes
383 opt_include_runtime_dependencies=yes
386 opt_include_buildtime_dependencies=no
387 opt_include_runtime_dependencies=yes
390 opt_include_buildtime_dependencies=yes
391 opt_include_runtime_dependencies=no
394 opt_include_buildtime_dependencies=no
395 opt_include_runtime_dependencies=no
400 # ============= Get the database level of dependency algorithm for the current option setting =============
401 options_get_dependency_level ()
403 case $opt_only_target_scope in
413 # ============= Parse the database level tag of dependency algorithm and reflect it to option values =============
414 options_parse_dependency_level ()
420 opt_only_target_scope=yes
423 opt_only_target_scope=no
428 # ============= Get the message term of dependency algorithm for the current option setting =============
429 options_get_dependency_msgterm ()
432 scope=`options_get_dependency_level`
433 case $opt_include_buildtime_dependencies+$opt_include_runtime_dependencies in
435 echo "$scope run- and build-time"
438 echo "$scope run-time"
441 echo "$scope build-time"
449 # ============= Get effective option value about importing pkgtools.conf(5) =============
450 options_get_effective_opt_load_pkgtoolsconf ()
452 local effective_opt_load_pkgtoolsconf
453 if [ $opt_load_pkgtoolsconf = undef ]
455 if [ -e "$PKGTOOLSCONF" ] && which -s portupgrade
457 effective_opt_load_pkgtoolsconf=default
459 effective_opt_load_pkgtoolsconf=no
461 elif ! which -s portupgrade
463 message_echo "WARNING: pkgtools.conf is ignored because portupgrade is not installed." >&2
464 effective_opt_load_pkgtoolsconf=no
466 echo "$effective_opt_load_pkgtoolsconf"
469 # ============= Show the setting of an option group =============
470 options_show_group_setting ()
472 local opt_control group_reset group_remain reset_opts result_opts str_opt_control str_rstoption notice_reset notice_result
476 reset_opts=`options_inverse_parse $group_reset`
477 result_opts=`options_inverse_parse $group_remain`
478 if [ $is_batch_mode = yes ]
480 printf '%s\t%s\t%s\n' "$opt_control" "$reset_opts" "$result_opts"
482 str_opt_control=`echo "$opt_control" | sed -E 's/(.)/-\1 /g;s/ *$//'`
483 str_rstoption=Option`[ \`echo -n "$opt_control" | wc -c\` -ge 2 ] && echo s` || :
484 notice_reset=`[ -z "$reset_opts" ] && echo ' (nothing)'` || :
485 notice_result=`[ -z "$result_opts" ] && echo ' (default)'` || :
486 echo "$str_rstoption [$str_opt_control] will reset [$reset_opts]$notice_reset so that the settings become [$result_opts]$notice_result."
490 # ============= Show the all options =============
494 is_batch_mode=$opt_batch_mode
496 [ -e "${DBDIR}/saved_options.sh" ] && . "${DBDIR}/saved_options.sh"
497 savedopts=`options_inverse_parse`
498 if [ $is_batch_mode = yes ]
500 printf '\t%s\n' "$savedopts"
502 echo "The saved setting is [$savedopts]."
504 options_show_group_setting M \
505 'renewable_anytime' 'non_renewable renewable_in_redo_on_target renewable_in_redo_on_conf'
506 options_show_group_setting N \
507 'renewable_in_redo_on_target' 'non_renewable renewable_anytime renewable_in_redo_on_conf'
508 options_show_group_setting L \
509 'renewable_in_redo_on_conf' 'non_renewable renewable_anytime renewable_in_redo_on_target'
510 options_show_group_setting MN \
511 'renewable_anytime renewable_in_redo_on_target' 'non_renewable renewable_in_redo_on_conf'
512 options_show_group_setting ML \
513 'renewable_anytime renewable_in_redo_on_conf' 'non_renewable renewable_in_redo_on_target'
514 options_show_group_setting NL \
515 'renewable_in_redo_on_target renewable_in_redo_on_conf' 'non_renewable renewable_anytime'
516 options_show_group_setting MNL \
517 'renewable_anytime renewable_in_redo_on_target renewable_in_redo_on_conf' 'non_renewable'