OSDN Git Service

Fixed a bug of error end when no obsolete package is installed.
[portsreinstall/current.git] / lib / libcommand_do.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - "do"/"redo" command operation -
5 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Operation of redo command before the database reconstruction =============
10 command_do_do__command_all_exec_command_specific_preconfiguration ()
11 {
12         program_deregister_stage_complete FORGET::PREPARATION_INSPECT_MASTER
13         program_deregister_stage_complete ALL_COMPLETE
14 }
15
16 # ============= Operation of redo command before the database reconstruction =============
17 command_do_redo__command_all_exec_command_specific_preconfiguration ()
18 {
19         program_deregister_stage_complete REDO_INIT
20         if [ $opt_reset_targets = yes ]
21         then
22                 program_deregister_stage_complete DETERMINE_SPECIFIED_TARGETS
23                 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
24                 rm -rf "${DBDIR}/targets"
25         fi
26         command_do_do__command_all_exec_command_specific_preconfiguration
27 }
28
29 # ============= Meta process for redo =============
30 command_do_meta_process_for_redo ()
31 {
32         local PROGRAM_DEPENDS
33         PROGRAM_DEPENDS=''
34         _program_exec_and_record_completion__operation ()
35         {
36                 rm -f "${DBDIR}/new_success_in_current_run"
37                 [ "x$COMMAND_MODE" = xredo ] || return 0
38                 message_echo "[REDO mode]"
39                 message_echo
40         }
41         program_exec_and_record_completion REDO_INIT
42 }
43
44 # ============= Determine specified targets =============
45 command_do_determine_specified_targets ()
46 {
47         local PROGRAM_DEPENDS
48         PROGRAM_DEPENDS=''
49         _program_exec_and_record_completion__operation ()
50         {
51                 local tag level dbsuffix
52                 message_section_title "Determining specified targets"
53                 cat "${DBDIR}/stage.loop_list/target_itself.specified" \
54                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
55                         "${DBDIR}/stage.loop_list/target_requirements.specified" \
56                         "${DBDIR}/need.list" \
57                         "${DBDIR}/targets_specified_so_far" 2> /dev/null \
58                         | sort -u > ${DBDIR}/targets_specified_so_far.tmp
59                 mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
60                 rm -f "${DBDIR}/stage.loop_list/target_itself.specified" \
61                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
62                         "${DBDIR}/stage.loop_list/target_requirements.specified"
63                 if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
64                 then
65                         options_select_new_ports_if_duplicated O \
66                                 "${DBDIR}/stage.loop_list/target_itself.specified" "$opt_target_itself"
67                         options_select_new_ports_if_duplicated t \
68                                 "${DBDIR}/stage.loop_list/target_dependents.specified" "$opt_target_dependents"
69                         options_select_new_ports_if_duplicated T \
70                                 "${DBDIR}/stage.loop_list/target_requirements.specified" "$opt_target_requirements"
71                         if [ `cat "${DBDIR}/stage.loop_list/target_itself.specified" \
72                                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
73                                 "${DBDIR}/stage.loop_list/target_requirements.specified" | wc -l` -eq 0 ]
74                         then
75                                 message_echo "ERROR: No matching port for target globs." >&2
76                                 message_echo >&2
77                                 exit 1
78                         fi
79                         cat "${DBDIR}/stage.loop_list/target_itself.specified" \
80                                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
81                                 "${DBDIR}/stage.loop_list/target_requirements.specified" \
82                                 | sort -u > ${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset
83                         cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset" "${DBDIR}/need.list" 2> /dev/null \
84                                 | sort -u > ${DBDIR}/need.list.tmp
85                         mv "${DBDIR}/need.list.tmp" "${DBDIR}/need.list"
86                         sort -u "${DBDIR}/need.list" "${DBDIR}/targets_specified_so_far" \
87                                 > ${DBDIR}/targets_specified_so_far.tmp
88                         mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
89                         for tag in all run build none
90                         do
91                                 for level in direct full
92                                 do
93                                         dbsuffix=$tag.$level
94                                         {
95                                                 cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset"
96                                                 cat "${DBDIR}/stage.loop_list/target_dependents.specified" | while read origin
97                                                 do
98                                                         nodedir=${DBDIR}/requires/$origin
99                                                         cat "$nodedir/dependents.$dbsuffix" 2> /dev/null
100                                                 done
101                                                 cat "${DBDIR}/stage.loop_list/target_requirements.specified" | while read origin
102                                                 do
103                                                         nodedir=${DBDIR}/requires/$origin
104                                                         cat "$nodedir/requirements.$dbsuffix" 2> /dev/null
105                                                 done
106                                         } | sort -u | while read origin
107                                         do
108                                                 fileedit_rm_a_line "$origin" "${DBDIR}/success.$dbsuffix.list"
109                                                 fileedit_rm_a_line "$origin" "${DBDIR}/todo_after_requirements_succeed.$dbsuffix.list"
110                                                 rm -f "${DBDIR}/requires/$origin/succeeded_once"
111                                         done
112                                 done
113                         done
114                 fi
115                 message_echo
116         }
117         program_exec_and_record_completion DETERMINE_SPECIFIED_TARGETS
118 }
119
120 # ============= Show specified targets =============
121 command_do_show_specified_targets ()
122 {
123         if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" -a $opt_batch_mode = no ]
124         then
125                 message_echo "INFO: (Re/de-)installation will be carried out only for the targets:"
126                 echo
127                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_itself.specified` -gt 0 ]
128                 then
129                         message_echo "[Targets only]"
130                         echo "----------------------------------------"
131                         cat "${DBDIR}/stage.loop_list/target_itself.specified"
132                         echo "----------------------------------------"
133                         echo
134                 fi
135                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_dependents.specified` -gt 0 ]
136                 then
137                         message_echo "[Targets with their `options_get_dependency_msgterm` dependents]"
138                         echo "----------------------------------------"
139                         cat "${DBDIR}/stage.loop_list/target_dependents.specified"
140                         echo "----------------------------------------"
141                         echo
142                 fi
143                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_requirements.specified` -gt 0 ]
144                 then
145                         message_echo "[Targets with their `options_get_dependency_msgterm` requirements]"
146                         echo "----------------------------------------"
147                         cat "${DBDIR}/stage.loop_list/target_requirements.specified"
148                         echo "----------------------------------------"
149                         echo
150                 fi
151         fi
152 }
153
154 # ============= Determine all target ports =============
155 command_do_determine_all_target_ports ()
156 {
157         local PROGRAM_DEPENDS
158         PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS COLLECT_ALL_INSTALLED_PACKAGES'
159         _program_exec_and_record_completion__operation ()
160         {
161                 message_section_title "Determining all target ports"
162                 {
163                         if [ $opt_only_target_scope = no ]
164                         then
165                                 cat "${DBDIR}/installed_ports" 2> /dev/null || :
166                         fi
167                         cat "${DBDIR}/stage.loop_list/target_itself.specified" || :
168                         cat "${DBDIR}/stage.loop_list/target_dependents.specified" || :
169                         cat "${DBDIR}/stage.loop_list/target_requirements.specified" || :
170                         cat "${DBDIR}/targets_specified_so_far" || :
171                 }  2> /dev/null | sort -u > "${DBDIR}/stage.loop_list/ports_to_inspect"
172                 while read origin
173                 do
174                         [ -d "${PORTSDIR}/$origin" ] || echo "$origin"
175                 done < ${DBDIR}/stage.loop_list/ports_to_inspect > ${DBDIR}/obsoletes_to_escape_for_inspection
176                 message_echo
177         }
178         program_exec_and_record_completion DETERMINE_ALL_TARGET_PORTS
179 }
180
181 # ============= Prepare for inspecting all dependencies =============
182 command_do_prepare_for_inspect_all_dependencies ()
183 {
184         local PROGRAM_DEPENDS
185         PROGRAM_DEPENDS='PARSE_CONF  DETERMINE_ALL_TARGET_PORTS'
186         _program_exec_and_record_completion__operation ()
187         {
188                 message_section_title "Preparing for inspection of all dependencies"
189                 database_build_escape "${DBDIR}/escaped_obsoletes" < ${DBDIR}/obsoletes_to_escape_for_inspection
190                 cp /dev/null "${DBDIR}/done_required_ports_to_inspect"
191                 message_echo
192         }
193         program_exec_and_record_completion PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
194 }
195
196 # ============= Check ports of which the port options are changed and reset their databases =============
197 # Return status 0 for no need to update of inspected ports and 1 for needed to do it
198 command_do_reset_changed_portdb ()
199 {
200         local tmp_ls
201         program_chk_stage_complete INSPECT_DEPENDENTS || return
202         pkgsys_exists_saved_port_oprions_timestamps || return
203         message_section_title "Inspecting changes of port options"
204         tmp_ls=${TMPDIR}/command_do_reset_changed_portdb
205         rm -f "$tmp_ls.updated"
206         if [ ! -d "${PORT_DBDIR}" ]
207         then
208                 message_echo "WARNING: ${PORT_DBDIR} is missing. All port options are recognized as default."
209         fi
210         pkgsys_get_saved_port_oprions_timestamps_all > $tmp_ls.db
211         pkgsys_get_current_port_oprions_timestamp > $tmp_ls.log
212         pkgsys_get_changed_port_oprions "$tmp_ls.db" "$tmp_ls.log" > $tmp_ls.diff
213         if ! [ `wc -l < $tmp_ls.diff` -gt 0 ]
214         then
215                 message_echo
216                 return
217         fi
218         message_echo "INFO: There are some changes. Inspecting the detail..."
219         cp /dev/null "$tmp_ls.uninspected.dbfile"
220         cp /dev/null "$tmp_ls.uninspected.origin"
221         cp /dev/null "$tmp_ls.nonexistent.db"
222         pkgsys_conv_portoptiondbs_to_globs < $tmp_ls.diff > $tmp_ls.glob
223         str_escape_replaceval_filter < $tmp_ls.diff > $tmp_ls.diff.rpl
224         paste "$tmp_ls.diff" "$tmp_ls.diff.rpl" "$tmp_ls.glob" | while read -r dbfile dbfile_rpl glob
225         do
226                 pkgsys_eval_ports_glob "$glob" > $tmp_ls.origins
227                 if [ `wc -l < $tmp_ls.origins` -gt 0 ]
228                 then
229                         sed -E "s/^/$dbfile_rpl /" < $tmp_ls.origins
230                 else
231                         echo $dbfile >> $tmp_ls.nonexistent.db
232                 fi
233         done | while read dbfile origin
234         do
235                 if [ -d "${DBDIR}/requires/$origin" ]
236                 then
237                         message_echo "Change detected on $origin: Resetting"
238                         database_build_patch_reconf "$origin"
239                         program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
240                         program_deregister_stage_complete ALL_COMPLETE
241                         touch "$tmp_ls.updated"
242                 else
243                         echo "$dbfile" >> $tmp_ls.uninspected.dbfile
244                         echo "$origin" >> $tmp_ls.uninspected.origin
245                 fi
246         done
247         message_echo "INFO: Recording for not inspected ports..."
248         pkgsys_conv_portorigin_to_port_oprion_timestamp_logname < $tmp_ls.uninspected.origin > $tmp_ls.uninspected.logname
249         str_escape_regexp_filter < $tmp_ls.uninspected.dbfile | sed 's/^/^/;s/$/[[:space:]]/' > $tmp_ls.uninspected.dbfile_ptn
250         paste "$tmp_ls.uninspected.dbfile_ptn" "$tmp_ls.uninspected.logname" | while read -r dbfile_ptn logname
251         do
252                 grep -E "$dbfile_ptn" < $tmp_ls.log > ${DBDIR}/ls_dbdir/$logname.log 2> /dev/null || :
253         done
254         str_escape_regexp_filter < $tmp_ls.nonexistent.db | sed 's/^/^/;s/$/[[:space:]]/' > $tmp_ls.nonexistent.db_ptn
255         grep -E -f "$tmp_ls.nonexistent.db_ptn" < $tmp_ls.log | pkgsys_register_list_nonexistent_portopriondb
256         message_echo
257         [ ! -e "$tmp_ls.updated" ]
258 }
259
260 # ============= Inspection of all dependencies =============
261 command_do_inspection_of_all_dependencies ()
262 {
263         local PROGRAM_DEPENDS
264         PROGRAM_DEPENDS='PREPARE_FOR_INSPECT_ALL_DEPENDENCIES'
265         _program_exec_restartable_loop_operation__routine ()
266         {
267                 local origin
268                 origin=$1
269                 database_build_inspect_dependencies "$origin"
270         }
271         _program_exec_and_record_completion__operation ()
272         {
273                 local DEPTH_INDEX 
274                 message_section_title "Inspecting dependencies of the all installed packages"
275                 [ $opt_only_target_scope = no -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] && \
276                         message_echo "INFO: Ports which seem irrelevant to the targets are also inspected in order to get complete information."
277                 DEPTH_INDEX='--'
278                 program_exec_restartable_loop_operation ports_to_inspect
279                 database_build_post_inspect_dependencies
280                 database_maintain_clear_prevset
281                 message_echo
282         }
283         program_exec_and_record_completion INSPECT_ALL_DEPENDENCIES
284 }
285
286 # ============= Convert dependency-lists to actual ones =============
287 command_do_convert_dependency_lists_to_actual_ones ()
288 {
289         local PROGRAM_DEPENDS
290         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES'
291         _program_exec_restartable_loop_operation__routine ()
292         {
293                 local origin table dbtag level tag target
294                 origin=$1
295                 for table in dependents requirements
296                 do
297                         for dbtag in requires obsolete
298                         do
299                                 for level in direct full
300                                 do
301                                         for tag in all run build
302                                         do
303                                                 target=${DBDIR}/$dbtag/$origin/${table}.${tag}.${level}
304                                                 if [ -e "$target.src" ]
305                                                 then
306                                                         sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" "$target.src" \
307                                                                 | grep -v '^$' | sort -u > $target.tmp
308                                                         [ -e "$target" ] && ! diff -q "$target.tmp" "$target" > /dev/null \
309                                                                 && echo "$origin" >> ${DBDIR}/update_dependencies
310                                                         mv "$target.tmp" "$target"
311                                                 else
312                                                         [ -e "$target" ] && echo "$origin" >> ${DBDIR}/update_dependencies
313                                                         rm -f "$target"
314                                                 fi
315                                         done
316                                 done
317                         done
318                 done
319         }
320         _program_exec_and_record_completion__operation ()
321         {
322                 message_section_title "Conversion of dependency-lists to actual ones"
323                 program_exec_restartable_loop_operation convert_dependency_lists
324                 sort -u "${DBDIR}/update_dependencies" > ${DBDIR}/update_dependencies.tmp
325                 mv "${DBDIR}/update_dependencies.tmp" "${DBDIR}/update_dependencies"
326                 for tag in all run build
327                 do
328                         ( cd "${DBDIR}/requires" && \
329                                 find . -depth 3 -type f -name requirements.${tag}.full -or -name requirements.${tag}.full.orig ) \
330                                 | sort -u \
331                                 | sed 's|^./||;s|/[^/]*$||' \
332                                 | grep -v -Fx -f "${DBDIR}/update_dependencies" \
333                                 > ${TMPDIR}/convert_requirements_list:full_complete.grep_pattern || :
334                         ( cd "${DBDIR}/requires" && \
335                                 find . -depth 3 -type f -name requirements.${tag}.direct -or -name requirements.${tag}.direct.orig ) \
336                                 | sort -u \
337                                 | sed 's|^./||;s|/[^/]*$||' \
338                                 | grep -v -Fx -f "${TMPDIR}/convert_requirements_list:full_complete.grep_pattern" \
339                                 > ${DBDIR}/stage.loop_list/complete_recursive_${tag}time_reqlists || :
340                 done
341                 for inspected_level_tmp in direct node
342                 do
343                         cat "${DBDIR}/ports.inspected.${inspected_level_tmp}.list" || :
344                 done 2> /dev/null | sort -u > ${DBDIR}/stage.loop_list/trim_dependency_lists_rm_uninspected_ports
345                 find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/stage.loop_list/inspect_dependent
346                 [ -e "${DBDIR}/dependents_files" ] && \
347                         mv "${DBDIR}/dependents_files" "${DBDIR}/dependents_files.prev"
348                 rm -f "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" "${DBDIR}/dependents_files.tmp"
349                 message_echo
350         }
351         program_exec_and_record_completion CONVERT_REQUIREMENTS_LIST
352 }
353
354 # ============= Completion of recursive requirement lists =============
355 command_do_completion_of_recursive_requirement_lists ()
356 {
357         local PROGRAM_DEPENDS _REQUIREMENT_LISTS_tag
358         for _REQUIREMENT_LISTS_tag in all run build
359         do
360                 PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
361                 _program_exec_restartable_loop_operation__routine ()
362                 {
363                         local tag dbpath origin suffix
364                         tag=${_REQUIREMENT_LISTS_tag}
365                         dbpath=$1
366                         origin=`str_dirpath_to_origin "$dbpath"`
367                         for suffix in '' .orig
368                         do
369                                 database_build_get_complete_recursive_dependency "$tag" "$origin" "$suffix" > /dev/null
370                         done
371                 }
372                 _program_exec_and_record_completion__operation ()
373                 {
374                         local tag
375                         tag=${_REQUIREMENT_LISTS_tag}
376                         message_section_title "Completion of ${tag}-time requirement lists"
377                         program_exec_restartable_loop_operation complete_recursive_${tag}time_reqlists
378                         message_echo
379                 }
380                 program_exec_and_record_completion RECURSIVE_REQUIREMENT_LISTS:${_REQUIREMENT_LISTS_tag}
381         done
382 }
383
384 # ============= Trim dependency lists by removing uninspected ports =============
385 command_do_trim_dependency_lists_by_removing_uninspected_ports ()
386 {
387         local PROGRAM_DEPENDS
388         if [ $opt_only_target_scope = yes ]
389         then
390                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST'
391                 _program_exec_restartable_loop_operation__routine ()
392                 {
393                         local dbpath tag level srcdb
394                         dbpath=$1
395                         for tag in all run build
396                         do
397                                 for level in direct full
398                                 do
399                                         srcdb=requirements.${tag}.${level}
400                                         [ -e "$dbpath/$srcdb" ] || continue
401                                         grep -Fx -f "${DBDIR}/inspected_ports" "$dbpath/$srcdb" > $dbpath/$srcdb.tmp || :
402                                         mv "$dbpath/$srcdb.tmp" "$dbpath/$srcdb"
403                                 done
404                         done
405                 }
406                 _program_exec_and_record_completion__operation ()
407                 {
408                         message_section_title "Trimming dependency lists by removing uninspected ports"
409                         program_exec_restartable_loop_operation trim_dependency_lists_rm_uninspected_ports
410                         message_echo
411                 }
412                 program_exec_and_record_completion TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS
413         fi
414 }
415
416 # ============= Inspection of dependents =============
417 command_do_inspection_of_dependents ()
418 {
419         local PROGRAM_DEPENDS
420         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS'
421         _program_exec_restartable_loop_operation__routine ()
422         {
423                 local dbpath origin tag level suffix srcdb dstdb
424                 dbpath=$1
425                 origin=`str_dirpath_to_origin "$dbpath"`
426                 for tag in all run build
427                 do
428                         for suffix in '' .orig
429                         do
430                                 for level in direct full
431                                 do
432                                         srcdb=requirements.${tag}.${level}${suffix}
433                                         [ -e "$dbpath/$srcdb" ] || continue
434                                         dstdb=dependents.${tag}.${level}${suffix}
435                                         while read origin_requirement
436                                         do
437                                                 dstpath=${DBDIR}/requires/$origin_requirement
438                                                 echo "$dstpath/$dstdb" >> ${DBDIR}/dependents_files.tmp
439                                                 [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue
440                                                 mkdir -p "$dstpath"
441                                                 echo "$origin" >> $dstpath/$dstdb.raw
442                                                 echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp
443                                         done < $dbpath/$srcdb
444                                 done
445                                 srcdb=ignored_requirements.${tag}${suffix}
446                                 [ -e "$dbpath/$srcdb" ] || continue
447                                 dstdb=ignored_dependents.${tag}${suffix}
448                                 while read origin_requirement
449                                 do
450                                         dstpath=${DBDIR}/requires/$origin_requirement
451                                         echo "$dstpath/$dstdb" >> ${DBDIR}/ignored_dependents_files.tmp
452                                         [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue
453                                         mkdir -p "$dstpath"
454                                         echo "$origin" >> $dstpath/$dstdb.raw
455                                         echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_ignored_dependents_lists_unique.tmp
456                                 done < $dbpath/$srcdb
457                         done
458                 done
459         }
460         _program_exec_and_record_completion__operation ()
461         {
462                 local dbrequires_valesc
463                 message_section_title "Inspection of dependents"
464                 dbrequires_valesc=`str_escape_replaceval "${DBDIR}/requires/"`
465                 program_exec_restartable_loop_operation inspect_dependent
466                 for dbtype in dependents ignored_dependents
467                 do
468                         sort -u "${DBDIR}/stage.loop_list/make_${dbtype}_lists_unique.tmp" 2> /dev/null \
469                                 > ${DBDIR}/stage.loop_list/make_${dbtype}_lists_unique || :
470                         sort -u "${DBDIR}/${dbtype}_files.tmp" 2> /dev/null > ${DBDIR}/${dbtype}_files || :
471                         [ -e "${DBDIR}/make_${dbtype}_lists_unique.prev" ] && \
472                                 fileedit_manipulate_old_lines "${DBDIR}/${dbtype}_files.prev" "${DBDIR}/${dbtype}_files" \
473                                 | xargs rm -f
474                 done
475                 message_echo
476         }
477         program_exec_and_record_completion INSPECT_DEPENDENTS
478 }
479
480 # ============= Restore escaped obsolete packages for inspection =============
481 command_do_restore_escaped_obsoletes ()
482 {
483         local PROGRAM_DEPENDS
484         PROGRAM_DEPENDS='INSPECT_DEPENDENTS'
485         _program_exec_and_record_completion__operation ()
486         {
487                 message_section_title "Restoring escaped obsolete packages for inspection"
488                 cat "${DBDIR}/escaped_obsoletes" 2> /dev/null | database_build_restore
489                 rm -f "${DBDIR}/escaped_obsoletes"
490                 message_echo
491         }
492         program_exec_and_record_completion RESTORE_ESCAPED_OBSOLETE_PACKAGES_FOR_INSPECTION
493 }
494
495 # ============= Remove duplicated lines in dependents lists =============
496 command_do_remove_duplicated_lines_in_dependents_lists ()
497 {
498         local PROGRAM_DEPENDS
499         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS'
500         _program_exec_restartable_loop_operation__routine ()
501         {
502                 local dbpath tag level dstdb
503                 dstdb=$1
504                 cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp
505                 mv "$dstdb.tmp" "$dstdb"
506                 rm -f "$dstdb.raw"
507         }
508         _program_exec_and_record_completion__operation ()
509         {
510                 local dbrequires_valesc
511                 message_section_title "Removing duplicated items in dependents lists"
512                 program_exec_restartable_loop_operation make_dependents_lists_unique
513                 message_echo
514         }
515         program_exec_and_record_completion MAKE_DEPENDENTS_LISTS_UNIQUE
516 }
517
518 # ============= Remove duplicated lines in ignored dependents lists =============
519 command_do_remove_duplicated_lines_in_ignored_dependents_lists ()
520 {
521         local PROGRAM_DEPENDS
522         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS'
523         _program_exec_restartable_loop_operation__routine ()
524         {
525                 local dbpath tag level dstdb
526                 dstdb=$1
527                 cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp
528                 mv "$dstdb.tmp" "$dstdb"
529                 rm -f "$dstdb.raw"
530         }
531         _program_exec_and_record_completion__operation ()
532         {
533                 local dbrequires_valesc
534                 message_section_title "Removing duplicated items in ignored dependents lists"
535                 program_exec_restartable_loop_operation make_ignored_dependents_lists_unique
536                 message_echo
537         }
538         program_exec_and_record_completion MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE
539 }
540
541 # ============= Preparation of target attribute information =============
542 command_do_preparation_of_target_attribute_information ()
543 {
544         local PROGRAM_DEPENDS _TARGET_ATTR_INFO_table
545         for _TARGET_ATTR_INFO_table in requirements dependents itself
546         do
547                 [ `cat "${DBDIR}/stage.loop_list/target_${_TARGET_ATTR_INFO_table}.replaced.specified" 2> /dev/null \
548                         | wc -l` -gt 0 ] || continue
549                 PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS CONVERT_REQUIREMENTS_LIST'
550                 _program_exec_restartable_loop_operation__routine ()
551                 {
552                         local origin dbtargets_valesc table
553                         origin=$1
554                         dbtargets_valesc=`str_escape_replaceval "${DBDIR}/targets/"`
555                         table=${_TARGET_ATTR_INFO_table}
556                         for database in requires initial
557                         do
558                                 dbpath=${DBDIR}/$database/$origin
559                                 dstpath=${DBDIR}/targets/$origin
560                                 mkdir -p "$dstpath"
561                                 touch "$dstpath/target_itself"
562                                 echo "$origin" >> ${DBDIR}/all_targets.lst
563                                 [ $table = itself ] && continue
564                                 for tag in all run build
565                                 do
566                                         for level in direct full
567                                         do
568                                                 srcdb=${table}.${tag}.${level}
569                                                 dstdb=target_${database}_${table}.${tag}.${level}
570                                                 [ -e "$dbpath/$srcdb" ] || continue
571                                                 cat "$dbpath/$srcdb" >> ${DBDIR}/all_targets.lst
572                                                 sed -E "s/^/$dbtargets_valesc/; s|$|/$dstdb|" "$dbpath/$srcdb" \
573                                                         | fileedit_add_a_line_to_files_if_new "$origin"
574                                         done
575                                 done
576                         done
577                 }
578                 _program_exec_and_record_completion__operation ()
579                 {
580                         local table
581                         table=${_TARGET_ATTR_INFO_table}
582                         message_section_title "Preparation of target attribute information for dependency [$table]"
583                         program_exec_restartable_loop_operation target_$table.replaced.specified
584                         message_echo
585                 }
586                 program_exec_and_record_completion TARGET_ATTR_INFO:${_TARGET_ATTR_INFO_table}
587         done
588 }
589
590 # ============= Post-process after the preparation of target attribute information =============
591 command_do_post_process_after_the_preparation_of_target_attribute_information ()
592 {
593         local PROGRAM_DEPENDS
594         PROGRAM_DEPENDS='MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents'
595         _program_exec_and_record_completion__operation ()
596         {
597                 message_section_title "Post-process after the preparation of target attribute information"
598                 sort -u "${DBDIR}/all_targets.lst" 2> /dev/null \
599                         | grep -Fx -f "${DBDIR}/inspected_ports" \
600                         | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" 2> /dev/null \
601                         > ${DBDIR}/all_targets.lst.tmp || :
602                 mv "${DBDIR}/all_targets.lst.tmp" "${DBDIR}/all_targets.lst"
603                 find "${DBDIR}/targets" -depth 2 -type d > ${DBDIR}/stage.loop_list/build_complement_to_new_dependents_for_targets 2> /dev/null || :
604                 {
605                         cat "${DBDIR}/all_targets.lst" "${DBDIR}/need.with_replaced.list" 2> /dev/null || :
606                         find "${DBDIR}/moved_from" -depth 3 -type f -name installed_version \
607                                 | sed -E 's|.*/([^/]+/[^/]+)/[^/]*$|\1|'
608                 } | sort -u > ${DBDIR}/stage.loop_list/inspect_necessity
609                 cp /dev/null "${DBDIR}/stage.loop_list/parse_target_attr_info"
610                 find -E "${DBDIR}/requires" -depth 3 -type f -regex '.*/necessary_port\.(direct|full)$' -delete
611                 message_echo
612         }
613         program_exec_and_record_completion TARGET_ATTR_INFO_POSTPROCESS
614 }
615
616 # ============= Build of data on complement to new dependents for target attribute information =============
617 command_do_build_of_data_on_complement_to_new_dependents_for_target_attribute_information ()
618 {
619         local PROGRAM_DEPENDS
620         PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents CONVERT_REQUIREMENTS_LIST'
621         _program_exec_restartable_loop_operation__routine ()
622         {
623                 local dbpath origin
624                 dbpath=$1
625                 origin=`str_dirpath_to_origin "$dbpath"`
626                 database_build_complement_to_new_dependents_for_targets "$origin"
627         }
628         _program_exec_and_record_completion__operation ()
629         {
630                 message_section_title "Build of data on complement to new dependents for target attribute information"
631                 program_exec_restartable_loop_operation build_complement_to_new_dependents_for_targets
632                 sort -u "${DBDIR}/stage.loop_list/parse_target_attr_info" > ${DBDIR}/stage.loop_list/parse_target_attr_info.tmp
633                 mv "${DBDIR}/stage.loop_list/parse_target_attr_info.tmp" "${DBDIR}/stage.loop_list/parse_target_attr_info"
634                 message_echo
635         }
636         program_exec_and_record_completion COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO
637 }
638
639 # ============= Parse target attribute information =============
640 command_do_parse_target_attribute_information ()
641 {
642         local PROGRAM_DEPENDS
643         PROGRAM_DEPENDS='COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO'
644         _program_exec_restartable_loop_operation__routine ()
645         {
646                 local dbpath origin
647                 dbpath=$1
648                 origin=`str_dirpath_to_origin "$dbpath"`
649                 database_build_target_attributes "$origin"
650         }
651         _program_exec_and_record_completion__operation ()
652         {
653                 message_section_title "Parsing target attribute information"
654                 program_exec_restartable_loop_operation parse_target_attr_info
655                 message_echo
656         }
657         program_exec_and_record_completion PARSE_TARGET_ATTR_INFO
658 }
659
660 # ============= Inspection of necessity =============
661 command_do_inspection_of_necessity ()
662 {
663         local PROGRAM_DEPENDS
664         PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS RECURSIVE_REQUIREMENT_LISTS:run RECURSIVE_REQUIREMENT_LISTS:build INSPECT_ALL_DEPENDENCIES'
665         _program_exec_restartable_loop_operation__routine ()
666         {
667                 local origin
668                 origin=$1
669                 for level in direct full
670                 do
671                         database_build_inspect_necessity_for_only_new_upgrade "$origin" "$level"
672                 done
673         }
674         _program_exec_and_record_completion__operation ()
675         {
676                 message_section_title "Inspection of necessity"
677                 program_exec_restartable_loop_operation inspect_necessity
678                 for level in direct full
679                 do
680                         find "${DBDIR}/requires" -depth 3 -type f -name "necessary_port.${level}" \
681                                 > ${DBDIR}/stage.loop_list/necessary_ports.${level}
682                 done
683                 message_echo
684         }
685         program_exec_and_record_completion INSPECT_NECESSITY
686 }
687
688 # ============= Inspection of necessary upgrades =============
689 command_do_inspection_of_necessary_upgrades ()
690 {
691         local PROGRAM_DEPENDS _NECESSARY_UPDATES_level
692         for _NECESSARY_UPDATES_level in direct full
693         do
694                 PROGRAM_DEPENDS='INSPECT_NECESSITY INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE'
695                 _program_exec_restartable_loop_operation__routine ()
696                 {
697                         local markerpath level dbpath origin tag
698                         markerpath=$1
699                         level=${_NECESSARY_UPDATES_level}
700                         dbpath=`dirname "$markerpath"`
701                         origin=`str_dirpath_to_origin "$dbpath"`
702                         database_query_does_a_port_need_update "$origin" || return 0
703                         for tag in all run build none
704                         do
705                                 touch "$dbpath/necessary_upgrade.$tag.${level}"
706                                 [ -e "$dbpath/dependents.$tag.${level}" -o "$dbpath/ignored_dependents.$tag" ] || continue
707                                 cat "$dbpath/dependents.$tag.${level}" "$dbpath/ignored_dependents.$tag" 2> /dev/null | \
708                                         while read origin_dependent
709                                         do
710                                                 touch "${DBDIR}/requires/$origin_dependent/necessary_upgrade.$tag.${level}"
711                                         done
712                         done
713                 }
714                 _program_exec_and_record_completion__operation ()
715                 {
716                         local level
717                         level=${_NECESSARY_UPDATES_level}
718                         message_section_title "Inspection of necessary upgrades at the $level level"
719                         program_exec_restartable_loop_operation necessary_ports.${level}
720                         message_echo
721                 }
722                 program_exec_and_record_completion NECESSARY_UPDATES:${_NECESSARY_UPDATES_level}
723         done
724 }
725
726 # ============= Preparation for inspection of new leaf ports =============
727 command_do_preparation_for_inspection_of_new_leaf_ports ()
728 {
729         local PROGRAM_DEPENDS
730         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
731         then
732                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE PARSE_CONF'
733                 _program_exec_and_record_completion__operation ()
734                 {
735                         message_section_title "Preparation for inspection of new leaf ports"
736                         find "${DBDIR}/requires" -depth 3 -type f -name dependents.all.full -or -name ignored_dependents.all \
737                                 | sed -E 's|.*/([^/]+/[^/]+)/[^/]+$|\1|' \
738                                 | sort -u > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports
739                         sort -u "${DBDIR}/inspected_ports" > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports
740                         fileedit_manipulate_new_lines \
741                                 "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports" \
742                                 "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports" \
743                                 | grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null \
744                                 > ${DBDIR}/stage.loop_list/leaf_ports_primary_candidates || :
745                         cp /dev/null "${DBDIR}/leaf_ports.filter"
746                         cp /dev/null "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
747                         message_echo
748                 }
749                 program_exec_and_record_completion PREPARE_INSPECT_LEAF_PORTS
750         fi
751 }
752
753 # ============= Inspection of new primary leaf ports =============
754 command_do_inspection_of_new_primary_leaf_ports ()
755 {
756         local PROGRAM_DEPENDS
757         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
758         then
759                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE PREPARE_INSPECT_LEAF_PORTS PARSE_CONF'
760                 _program_exec_restartable_loop_operation__routine ()
761                 {
762                         local origin origin_ini dbpath origin_req
763                         origin=$1
764                         pkgsys_is_pkgtool "$origin" && return
765                         dbpath=${DBDIR}/requires/$origin
766                         grep -q -Fx "$origin" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
767                         if ! grep -q -Fx "$origin" "${DBDIR}/noneed.list" 2> /dev/null
768                         then
769                                 if [ -e "$dbpath/initial_orig" ]
770                                 then
771                                         origin_ini=`cat "$dbpath/initial_orig"`
772                                         [ -e "${DBDIR}/initial/$origin_ini/installed_version" \
773                                                 -a `cat "${DBDIR}/initial/$origin_ini/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
774                                                 && return
775                                 fi
776                                 [ -e "${DBDIR}/initial/$origin/installed_version" \
777                                         -a `cat "${DBDIR}/initial/$origin/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
778                                         && return
779                         fi
780                         if [ -e "$dbpath/requirements.all.full" -o -e "$dbpath/ignored_requirements.all" ]
781                         then
782                                 cat "$dbpath/requirements.all.full" "$dbpath/ignored_requirements.all" 2> /dev/null | \
783                                         grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null| \
784                                         fileedit_add_lines_if_new "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
785                         fi
786                         fileedit_add_a_line_if_new "$origin" "${DBDIR}/leaf_ports.filter"
787                 }
788                 _program_exec_and_record_completion__operation ()
789                 {
790                         local num_leaves num_leaves_prev
791                         message_section_title "Inspection of new primary leaf ports"
792                         program_exec_restartable_loop_operation leaf_ports_primary_candidates
793                         wc -l < ${DBDIR}/leaf_ports.filter | tr -d ' ' > ${DBDIR}/num_leaves
794                         cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
795                         message_echo "  `cat "${DBDIR}/num_leaves"` primary leaf port(s) is/are found."
796                         message_echo
797                 }
798                 program_exec_and_record_completion INSPECT_PRIMARY_LEAF_PORTS
799         fi
800 }
801
802 # ============= Inspection of requirements of new leaf ports =============
803 command_do_inspection_of_requirements_of_new_leaf_ports ()
804 {
805         local PROGRAM_DEPENDS
806         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
807         then
808                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE INSPECT_PRIMARY_LEAF_PORTS PARSE_CONF'
809                 _program_exec_and_record_completion__operation ()
810                 {
811                         local num_leaves num_leaves_prev num_inspect num_leaves_new
812                         message_section_title "Inspection of requirements of new leaf ports"
813                         message_echo "INFO: The inspection proceeds by iterative method."
814                         while :
815                         do
816                                 _program_exec_restartable_loop_operation__routine ()
817                                 {
818                                         local origin dbpath
819                                         origin=$1
820                                         pkgsys_is_pkgtool "$origin" && return
821                                         dbpath=${DBDIR}/requires/$origin
822                                         grep -q -Fx "$origin" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
823                                         cat "$dbpath/dependents.all.full" "$dbpath/ignored_dependents.all"  2> /dev/null \
824                                                 | grep -Fxq -v -f "${DBDIR}/leaf_ports.filter" 2> /dev/null && return
825                                         cat "$dbpath/requirements.all.full" "$dbpath/ignored_requirements.all" 2> /dev/null \
826                                                 >> ${DBDIR}/leaf_ports_secondary_candidates.new_requirements || :
827                                         fileedit_add_a_line_if_new "$origin" "${DBDIR}/leaf_ports.filter"
828                                 }
829                                 program_exec_restartable_loop_operation leaf_ports_secondary_candidates
830                                 num_leaves_prev=`cat "${DBDIR}/num_leaves"`
831                                 num_leaves=`wc -l < ${DBDIR}/leaf_ports.filter | tr -d ' '`
832                                 num_leaves_new=`echo $(($num_leaves-$num_leaves_prev)) | tr -d ' '`
833                                 if [ $num_leaves_new -eq 0 ]
834                                 then
835                                         message_echo "  No more leaf port is found."
836                                         message_echo "  $num_leaves leaf port(s) is/are found in total."
837                                         break
838                                 fi
839                                 {
840                                         grep -Fx -v -f "${DBDIR}/leaf_ports.filter" \
841                                                 "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
842                                         cat "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" || :
843                                 } 2> /dev/null | grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null | sort -u \
844                                         > ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp || :
845                                 program_reset_loop_for_stage INSPECT_REQUIREMENTS_OF_LEAF_PORTS
846                                 mv "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp" \
847                                         "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
848                                 cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
849                                 echo "$num_leaves" > ${DBDIR}/num_leaves
850                                 num_inspect=`wc -l < ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates | tr -d ' '`
851                                 message_echo "  $num_leaves_new leaf port(s) is/are newly found; continue for $num_inspect candidate(s)."
852                         done
853                         grep -Fx -f "${DBDIR}/leaf_ports.filter" "${DBDIR}/inspected_ports" 2> /dev/null | sort -u > ${DBDIR}/leaf_ports || :
854                         message_echo
855                 }
856                 program_exec_and_record_completion INSPECT_REQUIREMENTS_OF_LEAF_PORTS
857         fi
858 }
859
860 # ============= Order the ports considering dependencies =============
861 command_do_order_the_ports_considering_dependencies ()
862 {
863         local PROGRAM_DEPENDS
864         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
865         _program_exec_and_record_completion__operation ()
866         {
867                 message_section_title "Ordering dependencies"
868                 if ! database_build_order_ports_considering_dependencies
869                 then
870                         message_echo "ERROR: Unsatisfied dependencies are remained:" >&2
871                         message_cat "${DBDIR}/unsatisfied.list"
872                         message_echo "*** Aborted by ${APPNAME}"
873                         message_echo "The ports tree seems broken. You might have caught an incomplete version."
874                         message_echo "You are encouraged to update the ports tree by portsnap(8)."
875                         message_echo "Then execute"
876                         message_echo " ${APPNAME} clean"
877                         message_echo "before restart."
878                         temp_terminate_process () { :; }
879                         exit 1
880                 fi
881                 message_echo
882         }
883         program_exec_and_record_completion ORDER_ALL_DEPENDENCIES
884 }
885
886 # ============= Selection of removing leaf ports =============
887 command_do_selection_of_removing_leaf_ports ()
888 {
889         local PROGRAM_DEPENDS
890         PROGRAM_DEPENDS='INSPECT_REQUIREMENTS_OF_LEAF_PORTS'
891         _program_exec_and_record_completion__operation ()
892         {
893                 message_section_title "Selection of removing leaf ports"
894                 deinstall_select_leaf_ports_to_delete
895                 message_echo
896         }
897         program_exec_and_record_completion SELECT_LEAF_PORTS
898 }
899
900 # ============= Selection of removing obsolete ports =============
901 command_do_selection_of_removing_obsolete_ports ()
902 {
903         local PROGRAM_DEPENDS
904         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES PARSE_CONF'
905         _program_exec_and_record_completion__operation ()
906         {
907                 message_section_title "Selection of removing obsolete ports"
908                 deinstall_select_obsolete_ports_to_delete
909                 message_echo
910         }
911         program_exec_and_record_completion SELECT_OBSOLETE_PORTS
912 }
913
914 # ============= Collection of leaf ports to delete =============
915 command_do_collection_of_leaf_ports_to_delete ()
916 {
917         local PROGRAM_DEPENDS
918         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
919         then
920                 PROGRAM_DEPENDS='SELECT_LEAF_PORTS'
921                 _program_exec_and_record_completion__operation ()
922                 {
923                         local src src_unselected reqptn_file src_with_initial_origins
924                         message_section_title "Collecting leaf ports to delete"
925                         src=${DBDIR}/leaf_ports
926                         src_unselected=${DBDIR}/leaf_ports_to_delete.unselected
927                         src_with_initial_origins=${DBDIR}/leaf_ports.with_ini
928                         reqptn_file=${DBDIR}/leaf_ports.requirements_of_unselected
929                         cat "$src_unselected" 2> /dev/null | while read origin
930                         do
931                                 cat "${DBDIR}/requires/$origin/requirements.all.full" "${DBDIR}/requires/$origin/ignored_requirements.all" || :
932                         done 2> /dev/null | sort -u > $reqptn_file
933                         database_query_add_initial_origins < $src > $src_with_initial_origins
934                         message_echo
935                 }
936                 program_exec_and_record_completion COLLECT_LEAF_PORTS_TO_DELETE
937         fi
938 }
939
940 # ============= Collection of obsolete ports to delete =============
941 command_do_collection_of_obsolete_ports_to_delete ()
942 {
943         local PROGRAM_DEPENDS
944         PROGRAM_DEPENDS='SELECT_OBSOLETE_PORTS'
945         _program_exec_and_record_completion__operation ()
946         {
947                 local src src_selected src_unselected dst_selected reqptn_file
948                 message_section_title "Collecting obsolete ports to delete"
949                 src=${DBDIR}/obsolete_ports.can_be_deleted
950                 src_selected=${DBDIR}/obsolete_ports_to_delete.selected
951                 src_unselected=${DBDIR}/obsolete_ports_to_delete.unselected
952                 dst_selected=${DBDIR}/obsolete_ports_to_delete
953                 reqptn_file=${DBDIR}/obsolete_ports.requirements_of_unselected
954                 cat "$src_unselected" 2> /dev/null | while read origin
955                 do
956                         cat "${DBDIR}/initial/$origin/requirements.run.full" || :
957                         cat "${DBDIR}/obsolete/$origin/requirements.run.full" || :
958                 done | sort -u > $reqptn_file
959                 grep -v -Fx -f "$reqptn_file" "$src_selected" > $dst_selected 2> /dev/null || :
960                 message_echo
961         }
962         program_exec_and_record_completion COLLECT_OBSOLETE_PORTS_TO_DELETE
963 }
964
965 # ============= Set up the list of ports to reinstall =============
966 command_do_set_up_the_list_of_ports_to_reinstall ()
967 {
968         local PROGRAM_DEPENDS
969         PROGRAM_DEPENDS='ORDER_ALL_DEPENDENCIES'
970         _program_exec_and_record_completion__operation ()
971         {
972                 message_section_title "Setting up the list of ports to reinstall"
973                 cp -p "${DBDIR}/reinst_order.list" "${DBDIR}/stage.loop_list/reinst_todo"
974                 message_echo
975         }
976         program_exec_and_record_completion SETUP_REINST_TODO
977 }
978
979 # ============= Composition of a list for deinstallation of obsolete and leaf packages =============
980 command_do_composition_of_a_list_for_deinstallation_of_obsolete_and_leaf_packages ()
981 {
982         local PROGRAM_DEPENDS
983         PROGRAM_DEPENDS='COLLECT_LEAF_PORTS_TO_DELETE COLLECT_OBSOLETE_PORTS_TO_DELETE'
984         _program_exec_and_record_completion__operation ()
985         {
986                 local reqptn_leaf reqptn_obs leaf_selected leaf_selected_src obs_selected obs_selected_src grepptn preserved
987                 message_section_title "Composing a list for deinstallation of obsolete and leaf packages"
988                 reqptn_leaf=${DBDIR}/leaf_ports.requirements_of_unselected
989                 reqptn_obs=${DBDIR}/obsolete_ports.requirements_of_unselected
990                 leaf_selected_src=${DBDIR}/leaf_ports_to_delete.selected
991                 leaf_selected=${DBDIR}/leaf_ports_to_delete
992                 obs_selected_src=${DBDIR}/obsolete_ports_to_delete.selected
993                 obs_selected=${DBDIR}/obsolete_ports_to_delete
994                 grepptn=${DBDIR}/ports_to_delete.grep_pattern
995                 grepptn_col1=${DBDIR}/ports_to_delete.grep_pattern_col1
996                 preserved=${TMPDIR}/LIST_DEINST_PKGS::preserved
997                 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
998                 then
999                         cat "$reqptn_leaf" "$reqptn_obs" 2> /dev/null | sort -u > $grepptn
1000                         grep -v -Fx -f "$grepptn" "$leaf_selected_src" 2> /dev/null \
1001                                 | database_query_add_initial_origins > $leaf_selected || :
1002                         cat "$obs_selected" "$leaf_selected" 2> /dev/null || :
1003                 else
1004                         rm -f "$leaf_selected"
1005                         cat "$obs_selected" 2> /dev/null
1006                 fi | sort -u > ${DBDIR}/stage.loop_list/ports_to_delete
1007                 str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \
1008                         | sed 's/^/^/;s/$/[[:space:]]/' > $grepptn_col1
1009                 cat "${DBDIR}/leaf_ports.with_ini" "${DBDIR}/obsolete_ports" 2> /dev/null \
1010                         | grep -Fx -v -f "${DBDIR}/stage.loop_list/ports_to_delete" > ${DBDIR}/stage.loop_list/ports_to_restore 2> /dev/null || :
1011                 if [ $opt_batch_mode = no ]
1012                 then
1013                         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] && \
1014                                 grep -v -Fx -f "${DBDIR}/stage.loop_list/ports_to_delete" "$leaf_selected_src" > $preserved 2> /dev/null
1015                         then
1016                                 message_echo "INFO: Following leaf ports are preserved because required by other preserved leaf/obsolete ports."
1017                                 message_echo "----------------"
1018                                 while read origin
1019                                 do
1020                                         pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null` || :
1021                                         if [ -n "$pkgtag" ]
1022                                         then
1023                                                 echo "$origin" "($pkgtag)"
1024                                         else
1025                                                 echo "$origin"
1026                                         fi
1027                                 done < $preserved
1028                                 message_echo "----------------"
1029                         fi
1030                         if grep -v -Fx -f "${DBDIR}/stage.loop_list/ports_to_delete" "$obs_selected_src" > $preserved 2> /dev/null
1031                         then
1032                                 message_echo "INFO: Following obsolete ports are preserved because required by other obsolete ports."
1033                                 message_echo "----------------"
1034                                 while read origin
1035                                 do
1036                                         pkgtag=`cat "${DBDIR}/initial/$origin/installed_version" 2> /dev/null` || :
1037                                         if [ -n "$pkgtag" ]
1038                                         then
1039                                                 echo "$origin" "($pkgtag)"
1040                                         else
1041                                                 echo "$origin"
1042                                         fi
1043                                 done < $preserved
1044                                 message_echo "----------------"
1045                         fi
1046                 fi
1047                 message_echo
1048         }
1049         program_exec_and_record_completion LIST_DEINST_PKGS
1050 }
1051
1052 # ============= Collect entire distfiles list =============
1053 command_do_collect_entire_distfiles_list ()
1054 {
1055         local PROGRAM_DEPENDS
1056         if [ $opt_inspect_entire_distinfo = yes ]
1057         then
1058                 PROGRAM_DEPENDS=''
1059                 _program_exec_and_record_completion__operation ()
1060                 {
1061                         message_section_title "Collecting entire distfiles list"
1062                         find "${PORTSDIR}" -depth 3 -name distinfo -exec cat {} \; \
1063                                 | grep '^SHA256 ' | sed -E 's/^SHA256 \(([^)]*)\).*/\1/' \
1064                                 | sort -u > ${DBDIR}/distfiles.entire.tmp
1065                         mv "${DBDIR}/distfiles.entire.tmp" "${DBDIR}/distfiles.entire"
1066                         message_echo
1067                 }
1068                 program_exec_and_record_completion COLLECT_ALL_DISTFILES_LIST
1069         fi
1070 }
1071
1072 # ============= Inspection of all required distfiles =============
1073 command_do_inspection_of_all_required_distfiles ()
1074 {
1075         local PROGRAM_DEPENDS
1076         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES COLLECT_ALL_DISTFILES_LIST'
1077         _program_exec_and_record_completion__operation ()
1078         {
1079                 message_section_title "Summarizing distfiles list"
1080                 {
1081                         cat "${DBDIR}/distfiles.entire" || :
1082                         cat "${DBDIR}/distfiles.inspected" || :
1083                 } 2> /dev/null | sort -u | str_escape_regexp_filter \
1084                         | sed 's|^|^\\.\\/|; s|$|$|' > ${DBDIR}/distfiles.grep.pattern || :
1085                 message_echo
1086         }
1087         program_exec_and_record_completion DISTFILES_LIST
1088 }
1089
1090 # ============= Clean up of reinstallation status for preparation =============
1091 command_do_clean_up_of_reinstallation_status_for_preparation ()
1092 {
1093         local PROGRAM_DEPENDS
1094         PROGRAM_DEPENDS='REDO_INIT INSPECT_ALL_DEPENDENCIES'
1095         _program_exec_and_record_completion__operation ()
1096         {
1097                 message_section_title "Cleaning up of reinstallation status for preparation"
1098                 rm -rf "${DBDIR}/status.ports"
1099                 message_echo
1100         }
1101         program_exec_and_record_completion CLEANUP_REINST_STATUS
1102 }
1103
1104 # ============= Completion of building the temporary database =============
1105 command_do_completion_of_building_the_temporary_database ()
1106 {
1107         local PROGRAM_DEPENDS
1108         PROGRAM_DEPENDS='REDO_INIT SETUP_REINST_TODO CLEANUP_REINST_STATUS PARSE_CONF INSPECT_ALL_DEPENDENCIES RESTORE_ESCAPED_OBSOLETE_PACKAGES_FOR_INSPECTION NECESSARY_UPDATES:direct NECESSARY_UPDATES:full PARSE_TARGET_ATTR_INFO MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE COLLECT_LEAF_PORTS_TO_DELETE'
1109         _program_exec_and_record_completion__operation ()
1110         {
1111                 message_section_title "The temporary database is completely built up"
1112                 message_echo
1113         }
1114         program_exec_and_record_completion PREPARATION
1115 }
1116
1117 # ============= End of do/redo prepare  =============
1118 command_do_end_at_prepare_complete ()
1119 {
1120         local tmp_msg
1121         tmp_msg=${TMPDIR}/command_do_end_at_prepare_complete:msg
1122         cat > "$tmp_msg" << eof
1123 Done (skipped reinstallation) at `message_timestamp`
1124
1125  You can restart this process from the aborted/terminated point by executing without options or arguments as:
1126   ${APPNAME}
1127 eof
1128         message_cat "$tmp_msg"
1129         temp_terminate_process () { :; }
1130 }
1131
1132 # ============= Reinstallation of remained ports =============
1133 command_do_reinstallation_of_remained_ports ()
1134 {
1135         local PROGRAM_DEPENDS
1136         PROGRAM_DEPENDS='PREPARATION'
1137         _program_exec_restartable_loop_operation__routine ()
1138         {
1139                 reinstall_exec "$@"
1140                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1141         }
1142         _program_exec_and_record_completion__operation ()
1143         {
1144                 local _MSG_CURRENT_STAGE_general
1145                 _MSG_CURRENT_STAGE_general="reinstallation"
1146                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1147                 message_section_title "Reinstallation"
1148                 program_exec_restartable_loop_operation reinst_todo
1149                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1150                 reinstall_restore_conflicts
1151                 temp_set_msg_current_stage
1152                 message_echo
1153         }
1154         program_exec_and_record_completion REINSTALLATION
1155 }
1156
1157 # ============= Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again  =============
1158 command_do_restore_needed_obsolete_and_leaf_packages ()
1159 {
1160         local PROGRAM_DEPENDS
1161         PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1162         _program_exec_restartable_loop_operation__routine ()
1163         {
1164                 deinstall_restore "$@"
1165         }
1166         _program_exec_and_record_completion__operation ()
1167         {
1168                 local _MSG_CURRENT_STAGE_general
1169                 _MSG_CURRENT_STAGE_general="restoration of unselected obsolete/leaf packages"
1170                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1171                 message_section_title "Restoration of unselected obsolete/leaf packages"
1172                 program_exec_restartable_loop_operation ports_to_restore
1173                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1174                 temp_set_msg_current_stage
1175                 message_echo
1176         }
1177         program_exec_and_record_completion RESTORE_ONCE_DEINST_PKGS
1178 }
1179
1180 # ============= Deinstallation of unused obsolete and leaf packages =============
1181 command_do_deinstallation_of_unused_obsolete_and_leaf_packages ()
1182 {
1183         local PROGRAM_DEPENDS
1184         PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1185         _program_exec_restartable_loop_operation__routine ()
1186         {
1187                 deinstall_exec "$@"
1188         }
1189         _program_exec_and_record_completion__operation ()
1190         {
1191                 local _MSG_CURRENT_STAGE_general
1192                 _MSG_CURRENT_STAGE_general="deinstallation of obsolete/leaf packages"
1193                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1194                 message_section_title "Deinstallation of unused obsolete/leaf packages"
1195                 program_exec_restartable_loop_operation ports_to_delete
1196                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1197                 temp_set_msg_current_stage
1198                 message_echo
1199         }
1200         program_exec_and_record_completion DEINST_UNUSED_PKGS
1201 }
1202
1203 # ============= Clean up obsolete or unused distfiles =============
1204 command_do_clean_up_obsolete_or_unused_distfiles ()
1205 {
1206         local PROGRAM_DEPENDS
1207         if [ $opt_only_target_scope = no -a $opt_keep_distfiles = no ]
1208         then
1209                 PROGRAM_DEPENDS='REINSTALLATION DISTFILES_LIST'
1210                 _program_exec_and_record_completion__operation ()
1211                 {
1212                         local tmp_distfiles_exists
1213                         message_section_title "Cleaning up obsolete or unused distfiles"
1214                         tmp_distfiles_exists=${TMPDIR}/CLEANUP_OBSLETE_DISTFILES::distfiles_exists
1215                         [ $opt_dry_run = yes ] && message_echo "INFO: The operations are not actually carried out."
1216                         ( set -e; cd "${DISTDIR}" && find . -type f ) \
1217                                 | sed 's|^\./||' | sort -u > $tmp_distfiles_exists
1218                         fileedit_manipulate_old_lines "$tmp_distfiles_exists" "${DBDIR}/distfiles.entire" \
1219                                 | while read distfile
1220                         do
1221                                 if [ $opt_batch_mode = no ]
1222                                 then
1223                                         echo "  $distfile"
1224                                 fi
1225                                 [ $opt_dry_run = yes ] && continue
1226                                 rm -f "${DISTDIR}/$distfile"
1227                         done
1228                         message_echo
1229                 }
1230                 program_exec_and_record_completion CLEANUP_OBSLETE_DISTFILES
1231         fi
1232 }
1233
1234 # ============= Rebuild of package database =============
1235 command_do_rebuild_of_package_database ()
1236 {
1237         local PROGRAM_DEPENDS
1238         PROGRAM_DEPENDS='REINSTALLATION RESTORE_ONCE_DEINST_PKGS DEINST_UNUSED_PKGS'
1239         _program_exec_and_record_completion__operation ()
1240         {
1241                 which -s pkgdb || return 0
1242                 message_section_title "Rebuilding package database for portupgrade"
1243                 if grep -q @ "${DBDIR}/stage.loop_list/reinst_todo"
1244                 then
1245                         message_echo "INFO: Skipped because of lacking flavor support."
1246                 else
1247                         pkgdb -fu
1248                 fi
1249                 message_echo
1250         }
1251         program_exec_and_record_completion REBUILD_PKGDB
1252 }
1253
1254 # =============Operation of redo command irrespective of option settings =============
1255 command_do_redo__command_all_exec_irrespective_of_saved_options ()
1256 {
1257         [ $opt_reload_conf = yes ] || return 0
1258         program_deregister_stage_complete SAVE_PREV_CONF
1259         program_deregister_stage_complete ALL_COMPLETE
1260         rm -f "${DBDIR}"/complete
1261 }
1262
1263 # ============= Preparation of the temporary database =============
1264 command_do_prepare ()
1265 {
1266         # Meta process for redo
1267         command_do_meta_process_for_redo
1268         
1269         # Determine specified targets
1270         command_do_determine_specified_targets
1271         
1272         # Show specified targets
1273         command_do_show_specified_targets
1274         
1275         # Determine all target ports
1276         command_do_determine_all_target_ports
1277         
1278         # Loop considering cases that port options are changed after inspection
1279         while true
1280         do
1281                 # Prepare for inspecting all dependencies
1282                 command_do_prepare_for_inspect_all_dependencies
1283                 
1284                 # Inspection of all dependencies
1285                 command_do_inspection_of_all_dependencies
1286                 
1287                 # Convert dependency-lists to actual ones
1288                 command_do_convert_dependency_lists_to_actual_ones
1289                 
1290                 # Completion of recursive requirement lists
1291                 command_do_completion_of_recursive_requirement_lists
1292                 
1293                 # Trim dependency lists by removing uninspected ports
1294                 command_do_trim_dependency_lists_by_removing_uninspected_ports
1295                 
1296                 # Inspection of dependents
1297                 command_do_inspection_of_dependents
1298                 
1299                 # End the loop when no change is made on port options after the inspection
1300                 command_do_reset_changed_portdb && break
1301         done
1302         
1303         # Restore escaped obsolete packages for inspection
1304         command_do_restore_escaped_obsoletes
1305         
1306         # Remove duplicated lines in dependents lists
1307         command_do_remove_duplicated_lines_in_dependents_lists
1308         
1309         # Remove duplicated lines in ignored dependents lists
1310         command_do_remove_duplicated_lines_in_ignored_dependents_lists
1311         
1312         # Preparation of target attribute information
1313         command_do_preparation_of_target_attribute_information
1314         
1315         # Post-process after the preparation of target attribute information
1316         command_do_post_process_after_the_preparation_of_target_attribute_information
1317         
1318         # Build of data on complement to new dependents for target attribute information
1319         command_do_build_of_data_on_complement_to_new_dependents_for_target_attribute_information
1320         
1321         # Parse target attribute information
1322         command_do_parse_target_attribute_information
1323         
1324         # Inspection of necessity
1325         command_do_inspection_of_necessity
1326         
1327         # Inspection of necessary upgrades
1328         command_do_inspection_of_necessary_upgrades
1329         
1330         # Preparation for inspection of new leaf ports
1331         command_do_preparation_for_inspection_of_new_leaf_ports
1332         
1333         # Inspection of new primary leaf ports
1334         command_do_inspection_of_new_primary_leaf_ports
1335         
1336         # Inspection of requirements of new leaf ports
1337         command_do_inspection_of_requirements_of_new_leaf_ports
1338         
1339         # Order the ports considering dependencies
1340         command_do_order_the_ports_considering_dependencies
1341         
1342         # Selection of removing leaf ports
1343         command_do_selection_of_removing_leaf_ports
1344         
1345         # Selection of removing obsolete ports
1346         command_do_selection_of_removing_obsolete_ports
1347         
1348         # Collection of leaf ports to delete
1349         command_do_collection_of_leaf_ports_to_delete
1350         
1351         # Collection of obsolete ports to delete
1352         command_do_collection_of_obsolete_ports_to_delete
1353         
1354         # Set up the list of ports to reinstall
1355         command_do_set_up_the_list_of_ports_to_reinstall
1356         
1357         # Composition of a list for deinstallation of obsolete and leaf packages
1358         command_do_composition_of_a_list_for_deinstallation_of_obsolete_and_leaf_packages
1359         
1360         # Collect entire distfiles list
1361         command_do_collect_entire_distfiles_list
1362         
1363         # Inspection of all required distfiles
1364         command_do_inspection_of_all_required_distfiles
1365         
1366         # Clean up of reinstallation status for preparation
1367         command_do_clean_up_of_reinstallation_status_for_preparation
1368         
1369         # Completion of building the temporary database
1370         command_do_completion_of_building_the_temporary_database
1371 }
1372
1373 # ============= Reset the progress of reinstallation for retrial =============
1374 command_do_reset_for_reinst_retrial ()
1375 {
1376         program_deregister_stage_complete REINSTALLATION
1377         program_deregister_stage_complete RESTORE_ONCE_DEINST_PKGS
1378         program_deregister_stage_complete DEINST_UNUSED_PKGS
1379         rm -rf "${DBDIR}/status.ports" "${DBDIR}/new_success_in_current_run"
1380 }
1381
1382 # ============= Main operation of do/redo =============
1383 command_do_main ()
1384 {
1385         local ntrial
1386         # Reset termination messages
1387         temp_reset_termination_messages_common
1388         
1389         ntrial=0
1390         while true
1391         do
1392                 if [ $ntrial -gt 0 ]
1393                 then
1394                         message_echo "########## RETRIAL ($ntrial) OF (RE)INSTALLATION ##########"
1395                         message_echo
1396                 fi
1397                 
1398                 if [ $opt_fetch_only = yes ]
1399                 then
1400                         # Reinstallation of remained ports
1401                         command_do_reinstallation_of_remained_ports
1402                         
1403                         message_echo "Completed the fetch only mode."
1404                         exit
1405                 elif [ $opt_delete_then_reinstall = no ]
1406                 then
1407                         # Reinstallation of remained ports
1408                         command_do_reinstallation_of_remained_ports
1409                         
1410                         # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again 
1411                         command_do_restore_needed_obsolete_and_leaf_packages
1412                         
1413                         # Deinstallation of unused obsolete and leaf packages
1414                         command_do_deinstallation_of_unused_obsolete_and_leaf_packages
1415                 else
1416                         # Deinstallation of unused obsolete and leaf packages
1417                         command_do_deinstallation_of_unused_obsolete_and_leaf_packages
1418                         
1419                         # Reinstallation of remained ports
1420                         command_do_reinstallation_of_remained_ports
1421                         # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again 
1422                         
1423                         command_do_restore_needed_obsolete_and_leaf_packages
1424                 fi
1425                 
1426                 # Clean up obsolete or unused distfiles
1427                 command_do_clean_up_obsolete_or_unused_distfiles
1428                 
1429                 # Rebuild of package database
1430                 command_do_rebuild_of_package_database
1431                 
1432                 # Retry if incomplete
1433                 command_do_is_everything_resolved && break
1434                 database_query_is_any_progress || break
1435                 command_do_reset_for_reinst_retrial
1436                 ntrial=$(($ntrial+1))
1437         done
1438         :
1439 }
1440
1441 # ============= Check whether everything is resolved =============
1442 command_do_is_everything_resolved ()
1443 {
1444         local subject
1445         for subject in failure redo conflict
1446         do
1447                 database_query_show_single_list_exec "$subject" \
1448                         `options_get_dependency_type` `options_get_dependency_level` > /dev/null 2> /dev/null && return 1
1449         done
1450         :
1451 }
1452
1453 # ============= Notice of failures =============
1454 command_do_failure_notice ()
1455 {
1456         local exists_unresolved_ports
1457         exists_unresolved_ports=
1458         message_summary_dependents_of_failed_reinstallation failure || exists_unresolved_ports=y
1459         message_summary_dependents_of_failed_reinstallation redo || exists_unresolved_ports=y
1460         message_summary_dependents_of_failed_reinstallation conflict || exists_unresolved_ports=y
1461         [ "x$exists_unresolved_ports" = xy ] || return 0
1462         message_summary_advice_on_manual_solution
1463         return 1
1464 }
1465
1466 # ============= Ending process =============
1467 command_do_ending_process ()
1468 {
1469         local PROGRAM_DEPENDS
1470         temp_terminate_process () { :; }
1471         if command_do_failure_notice
1472         then
1473                 if [ $opt_no_opening_message = yes ]
1474                 then
1475                         message_echo "Done as ${APPNAME}"
1476                 else
1477                         message_section_title "COMPLETELY DONE"
1478                 fi
1479                 if [ $opt_fetch_only = no -a $opt_dry_run = no ]
1480                 then
1481                         PROGRAM_DEPENDS='REBUILD_PKGDB CLEANUP_OBSLETE_DISTFILES '
1482                         _program_exec_and_record_completion__operation ()
1483                         {
1484                         }
1485                         program_exec_and_record_completion ALL_COMPLETE
1486                         [ $opt_no_opening_message = yes ] || message_echo "- E N D -"
1487                 else
1488                         message_echo "INFO: Redo for the real (re)installation."
1489                 fi
1490         else
1491                 message_warn_no_achieved_progress
1492                 message_section_title "Done with some unresolved problems"
1493                 message_echo "- To be continued -"
1494         fi
1495 }