2 # ==============================================================================
3 # portsreinstall library script
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 PROGRAM_DEPENDS= # Processes on which the current process depends
11 PROGRAM_NUM_STEPS= # [Used in _program_exec_restartable_loop_operation__routine] Total number of routine steps
12 PROGRAM_STEP_PROGRESS= # [Used in _program_exec_restartable_loop_operation__routine] Current progress as the finished number of routine steps
13 PROGRAM_STEP_COUNTER= # [Used in _program_exec_restartable_loop_operation__routine] Counter string indicating the current progress
14 PROGRAM_STAGETAG= # [Used in _program_exec_restartable_loop_operation__routine] Current stage tag
15 PROGRAM_STEP_COUNTER_LAST_SKIPPED=no # Whether the last iteration was skipped
17 # ============= Check completion of a stage =============
18 program_chk_stage_complete ()
22 [ -e "${DBDIR}/stage.complete/$stagetag" ]
25 # ============= Check completion of a loop in a stage =============
26 program_chk_stage_loop_complete ()
30 program_chk_stage_complete "$stagetag" && return
31 [ -e "${DBDIR}/stage.reinit_loop/$stagetag" ]
34 # ============= Check completion of a loop in a stage =============
35 program_chk_stage_loop_complete ()
39 program_chk_stage_complete "$stagetag" && return
40 [ -e "${DBDIR}/stage.reinit_loop/$stagetag" ]
43 # ============= Register completion of a stage =============
44 program_register_stage_complete ()
48 rm -f "${DBDIR}/stage.reinit_loop/$stagetag"
49 mkdir -p "${DBDIR}/stage.complete"
50 touch "${DBDIR}/stage.complete/$stagetag"
53 # ============= Reset the loop counter of a stage =============
54 program_reset_loop_for_stage ()
58 mkdir -p "${DBDIR}/stage.reinit_loop"
59 touch "${DBDIR}/stage.reinit_loop/$stagetag"
62 # ============= Deregister completion of a stage =============
63 program_deregister_stage_complete ()
67 program_reset_loop_for_stage "$stagetag"
68 rm -f "${DBDIR}/stage.complete/$stagetag"
71 # ============= Register stages on which a stage depends =============
72 program_register_stage_depends ()
74 local stagetag prefix_rpl
77 mkdir -p "${DBDIR}/stage.depends"
78 prefix_rpl=`str_escape_replaceval "${DBDIR}/stage.depends/"`
81 fileedit_add_a_line_if_new "$stagetag" "${DBDIR}/stage.depends/$1"
86 # ============= Reset stages which depend on a stage =============
87 program_reset_depending_stages ()
89 local stagetag prefix_rpl
91 [ -e "${DBDIR}/stage.depends/$stagetag" ] || return 0
92 while read stagetag_dependent
94 program_deregister_stage_complete "$stagetag_dependent"
95 done < ${DBDIR}/stage.depends/$stagetag
98 # ============= Define the default operation for program_exec_and_record_completion =============
99 program_reset_exec_and_record_completion_operation ()
101 _program_exec_and_record_completion__operation ()
103 echo "ERROR: [Internal] _program_exec_and_record_completion__operation is undefined." .&2
108 program_reset_exec_and_record_completion_operation
110 # ============= Execute an operation and record its completion =============
111 program_exec_and_record_completion ()
113 local stagetag PROGRAM_IS_LOOP_TO_BE_INIT
116 if ! program_chk_stage_complete "$stagetag"
118 PROGRAM_STAGETAG=$stagetag
119 program_register_stage_depends "$stagetag" $PROGRAM_DEPENDS
120 _program_exec_and_record_completion__operation "$@"
121 program_reset_depending_stages "$stagetag"
122 program_register_stage_complete "$stagetag"
124 program_reset_exec_and_record_completion_operation
127 # ============= Define the default operation for program_exec_and_record_completion =============
128 program_reset_exec_restartable_loop_operation ()
130 _program_exec_restartable_loop_operation__routine ()
134 echo "ERROR: [Internal] _program_exec_restartable_loop_operation__routine is undefined." .&2
138 program_reset_exec_restartable_loop_operation
140 # ============= Execute a restartable loop operation =============
141 program_exec_restartable_loop_operation ()
143 local inputdb tmp_diff looplist nlines iline item
145 tmp_diff=${TMPDIR}/program_exec_restartable_loop_operation:diff
146 looplist=${DBDIR}/stage.loop_list/$inputdb
147 if fileedit_manipulate_new_lines "$looplist.prev" "$looplist" > $looplist.remain.new
149 if [ -f "$looplist.remain" -a ! -e "${DBDIR}/stage.reinit_loop/$PROGRAM_STAGETAG" ]
151 sort -u "$looplist.remain" "$looplist.remain.new" > $looplist.remain.tmp
152 mv "$looplist.remain.tmp" "$looplist.remain"
154 cat "$looplist" 2> /dev/null > $looplist.tmp || :
155 mv "$looplist.tmp" "$looplist.prev"
157 if [ -f "$looplist.remain" -a ! -e "${DBDIR}/stage.reinit_loop/$PROGRAM_STAGETAG" ]
159 message_restarted_process
161 cat "$looplist" 2> /dev/null > $looplist.remain.tmp || :
162 mv "$looplist.remain.tmp" "$looplist.remain"
163 rm -f "${DBDIR}/stage.reinit_loop/$PROGRAM_STAGETAG"
165 cp "$looplist.remain" "${TMPDIR}/$inputdb.input"
166 PROGRAM_NUM_STEPS=`cat "$looplist" 2> /dev/null | wc -l | tr -d ' '` || :
167 nlines=`wc -l < ${TMPDIR}/$inputdb.input`
168 PROGRAM_STEP_PROGRESS=$(($PROGRAM_NUM_STEPS-$nlines))
170 PROGRAM_STEP_COUNTER_LAST_SKIPPED=no
171 while [ $iline -le $nlines ]
173 item=`sed -n ${iline}p "${TMPDIR}/$inputdb.input"`
175 PROGRAM_STEP_PROGRESS=$(($PROGRAM_STEP_PROGRESS+1))
176 PROGRAM_STEP_COUNTER="[$PROGRAM_STEP_PROGRESS/$PROGRAM_NUM_STEPS $(($PROGRAM_STEP_PROGRESS*100/$PROGRAM_NUM_STEPS))%]"
177 if ! grep -q -Fx "$item" "$looplist.remain" 2> /dev/null
179 [ $iline -gt $nlines ] && PROGRAM_STEP_COUNTER_LAST_SKIPPED=yes
182 _program_exec_restartable_loop_operation__routine "$item"
183 fileedit_rm_a_line "$item" "$looplist.remain"
185 program_reset_exec_restartable_loop_operation