]> Kevux Git Server - fll/commitdiff
Update: Improve example bootstrap script, exiting properly on error.
authorKevin Day <Kevin@kevux.org>
Mon, 28 Apr 2025 22:14:33 +0000 (17:14 -0500)
committerKevin Day <Kevin@kevux.org>
Mon, 28 Apr 2025 22:14:33 +0000 (17:14 -0500)
The `bootstrap-example.sh` has been used as a demonstratable example that can be used to build this project.
This script has become incredibly convenient but I had not made it as resilient as it could be.

This changes the script to properly exit with a non-zero return code on error.
This should allow for adding this script to a series of bash commands along with the conditional operators like `&&` and `||`.

build/scripts/bootstrap-example.sh

index fdbe0109bbf4f4c954efe594b960021e5d0bcd71..588ae4c13d6ca596ae1538e6b03159df3ecfb6f3 100644 (file)
 #   SHELL_ENGINE="zsh" zsh ./bootstrap-example.sh
 #
 
-if [[ ${SHELL_ENGINE} == "zsh" ]] ; then
-  emulate ksh
-fi
-
-path_original="${PWD}/"
-path_work="${path_original}fll/"
-
-verbose=
-verbose_common=
-color=
-shared=
-static=
-version=0.7.1
-mode_compiler_param="-m"
-mode_compiler_value="gcc"
-mode_part=
-mode_parameter=
-mode_path=
-mode_value=
-mode_thread_param="-m"
-mode_thread_value="thread"
-build_mode=
-build_mode_extra_param_1=
-build_mode_extra_value_1=
-build_mode_extra_param_2=
-build_mode_extra_value_2=
-shell_command=bash
-exclude_programs=
-fake_programs="fss_read fss_write iki_read iki_write status_code"
-grab_next=
-skip=
-
-if [[ ${SHELL_ENGINE} == "zsh" ]] ; then
-  shell_command=zsh
-fi
-
-let i=2
-j=
-p=
-
-while [[ ${i} -le $# ]] ; do
+main() {
+  if [[ ${SHELL_ENGINE} == "zsh" ]] ; then
+    emulate ksh
+  fi
+
+  local path_original="${PWD}/"
+  local path_work="${path_original}fll/"
+
+  local verbose=
+  local verbose_common=
+  local color=
+  local shared=
+  local static=
+  local version=0.7.1
+  local mode_compiler_param="-m"
+  local mode_compiler_value="gcc"
+  local mode_part=
+  local mode_parameter=
+  local mode_path=
+  local mode_value=
+  local mode_thread_param="-m"
+  local mode_thread_value="thread"
+  local build_mode=
+  local build_mode_extra_param_1=
+  local build_mode_extra_value_1=
+  local build_mode_extra_param_2=
+  local build_mode_extra_value_2=
+  local shell_command=bash
+  local exclude_programs=
+  local fake_programs="fss_read fss_write iki_read iki_write status_code"
+  local grab_next=
+  local skip=
 
   if [[ ${SHELL_ENGINE} == "zsh" ]] ; then
-    p=${(P)i}
-  else
-    p=${!i}
+    shell_command=zsh
   fi
 
-  if [[ ${grab_next} == "exclude_program" ]] ; then
-    exclude_programs="${exclude_programs}${p} "
-    grab_next=
-  elif [[ ${p} == "+d" ]] ; then
-    color="+d"
-  elif [[ ${p} == "+l" ]] ; then
-    color="+l"
-  elif [[ ${p} == "+n" ]] ; then
-    color="+n"
-  elif [[ ${p} == "+Q" ]] ; then
-    verbose="+Q"
-    verbose_common=
-  elif [[ ${p} == "+E" ]] ; then
-    verbose="+E"
-    verbose_common=
-  elif [[ ${p} == "+N" ]] ; then
-    verbose="+N"
-    verbose_common=
-  elif [[ ${p} == "+V" ]] ; then
-    verbose="+V"
-    verbose_common="-v"
-  elif [[ ${p} == "+D" ]] ; then
-    verbose="+D"
-    verbose_common="-v"
-  elif [[ ${p} == "-X" ]] ; then
-    grab_next="exclude_program"
-  elif [[ ${p} == "--enable-static" ]] ; then
-    static="--enable-static"
-  elif [[ ${p} == "--disable-static" ]] ; then
-    static="--disable-static"
-  elif [[ ${p} == "--enable-shared" ]] ; then
-    shared="--enable-shared"
-  elif [[ ${p} == "--disable-shared" ]] ; then
-    shared="--disable-shared"
-  elif [[ ${p} == "clang" ]] ; then
-    mode_compiler_value="clang"
-  elif [[ ${p} == "-w" || ${p} == "--work" ]] ; then
-    let i++
+  let i=2
+  j=
+  p=
+
+  while [[ ${i} -le $# ]] ; do
 
-    if [[ ${i} -le $# ]] ; then
-      path_work=${p}
+    if [[ ${SHELL_ENGINE} == "zsh" ]] ; then
+      p=${(P)i}
+    else
+      p=${!i}
     fi
-  fi
 
-  let i++
-done
+    if [[ ${grab_next} == "exclude_program" ]] ; then
+      exclude_programs="${exclude_programs}${p} "
+      grab_next=
+    elif [[ ${p} == "+d" ]] ; then
+      color="+d"
+    elif [[ ${p} == "+l" ]] ; then
+      color="+l"
+    elif [[ ${p} == "+n" ]] ; then
+      color="+n"
+    elif [[ ${p} == "+Q" ]] ; then
+      verbose="+Q"
+      verbose_common=
+    elif [[ ${p} == "+E" ]] ; then
+      verbose="+E"
+      verbose_common=
+    elif [[ ${p} == "+N" ]] ; then
+      verbose="+N"
+      verbose_common=
+    elif [[ ${p} == "+V" ]] ; then
+      verbose="+V"
+      verbose_common="-v"
+    elif [[ ${p} == "+D" ]] ; then
+      verbose="+D"
+      verbose_common="-v"
+    elif [[ ${p} == "-X" ]] ; then
+      grab_next="exclude_program"
+    elif [[ ${p} == "--enable-static" ]] ; then
+      static="--enable-static"
+    elif [[ ${p} == "--disable-static" ]] ; then
+      static="--disable-static"
+    elif [[ ${p} == "--enable-shared" ]] ; then
+      shared="--enable-shared"
+    elif [[ ${p} == "--disable-shared" ]] ; then
+      shared="--disable-shared"
+    elif [[ ${p} == "clang" ]] ; then
+      mode_compiler_value="clang"
+    elif [[ ${p} == "-w" || ${p} == "--work" ]] ; then
+      let i++
+
+      if [[ ${i} -le $# ]] ; then
+        path_work=${p}
+      fi
+    fi
+
+    let i++
+  done
+
+  boostrap_process ${*}
 
-if [[ ! -d ${path_work} ]] ; then
-  mkdir ${verbose_common} -p ${path_work}
-fi
+  let result=${?}
 
-if [[ ${1} == "individual" ]] ; then
-  ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -i
+  # Regardless of what happens always return to the starting directory.
+  cd ${path_original}
 
-  if [[ ${?} -eq 0 ]] ; then
-    for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do
+  return ${result}
+}
 
-      echo && echo "Processing ${i}." &&
+boostrap_process() {
+  if [[ ! -d ${path_work} ]] ; then
+    mkdir ${verbose_common} -p ${path_work}
 
-      cd package/individual/${i}-${version}/ &&
+    if [[ ${?} -ne 0 ]] ; then return 1 ; fi
+  fi
 
-      ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+  if [[ ${1} == "individual" ]] ; then
+    ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -i
 
-      ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m individual -m individual_thread ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+    if [[ ${?} -eq 0 ]] ; then
+      for i in f_type f_status f_memory f_type_array f_string f_utf f_abstruse f_account f_capability f_color f_compare f_console f_control_group f_conversion f_directory f_environment f_execute f_file f_fss f_iki f_limit f_network f_parse f_path f_pipe f_print f_random f_rip f_serialize f_signal f_socket f_status_string f_thread f_time fl_control_group fl_conversion fl_directory fl_environment fl_execute fl_fss fl_iki fl_path fl_print fl_status_string fl_utf_file fll_control_group fll_error fll_execute fll_file fll_fss fll_fss_status_string fll_iki fll_print fll_program ; do
 
-      ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
+        echo && echo "Processing ${i}." &&
 
-      cd ${path_original} || break
-    done
+        cd package/individual/${i}-${version}/ &&
+
+        ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+
+        ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m individual -m individual_thread ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+
+        ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
+
+        cd ${path_original}
+
+        if [[ ${?} -ne 0 ]] ; then return 1 ; fi
+      done
+    fi
   fi
-fi
 
-if [[ ${1} == "level" ]] ; then
-  ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -l &&
+  if [[ ${1} == "level" ]] ; then
+    ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -l &&
+
+    cd package/level/fll-level_0-${version}/ &&
 
-  cd package/level/fll-level_0-${version}/ &&
+    ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-  ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+    ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
 
-  ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+    ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
 
-  ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
+    cd ${path_original} &&
 
-  cd ${path_original} &&
+    cd package/level/fll-level_1-${version}/ &&
 
-  cd package/level/fll-level_1-${version}/ &&
+    ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-  ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+    ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
 
-  ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+    ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
 
-  ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} &&
+    cd ${path_original} &&
 
-  cd ${path_original} &&
+    cd package/level/fll-level_2-${version}/ &&
 
-  cd package/level/fll-level_2-${version}/ &&
+    ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-  ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+    ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
 
-  ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m level ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+    ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
 
-  ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
-fi
+    if [[ ${?} -ne 0 ]] ; then return 1 ; fi
+  fi
 
-if [[ ${1} == "monolithic" ]] ; then
-  ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -m &&
+  if [[ ${1} == "monolithic" ]] ; then
+    ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -m &&
 
-  cd package/monolithic/fll-${version}/ &&
+    cd package/monolithic/fll-${version}/ &&
 
-  ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+    ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-  ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m monolithic ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
+    ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m monolithic ${mode_thread_param} ${mode_thread_value} ${mode_compiler_param} ${mode_compiler_value} &&
 
-  ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
-fi
+    ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
 
-# The following in an example on building individual projects.
-for mode_part in byte_dump example fake firewall utf8 ; do
-  if [[ ${1} == "${mode_part}-individual" || ${1} == "${mode_part}-level" || ${1} == "${mode_part}-monolithic" || ${1} == "${mode_part}-stand_alone" ]] ; then
-    break;
+    if [[ ${?} -ne 0 ]] ; then return 1 ; fi
   fi
 
-  mode_part=
-done
+  # The following are examples on building individual projects.
+  for mode_part in byte_dump example fake firewall utf8 ; do
+    if [[ ${1} == "${mode_part}-individual" || ${1} == "${mode_part}-level" || ${1} == "${mode_part}-monolithic" || ${1} == "${mode_part}-stand_alone" ]] ; then
+      break;
+    fi
+
+    mode_part=
+  done
 
-if [[ ${mode_part} != "" ]] ; then
-  mode_parameter="-p"
-  mode_path="program"
-  mode_value=
-  build_mode_extra_param_1=
-  build_mode_extra_value_1=
-  build_mode_extra_param_2=
-  build_mode_extra_value_2=
+  if [[ ${mode_part} != "" ]] ; then
+    mode_parameter="-p"
+    mode_path="program"
+    mode_value=
+    build_mode_extra_param_1=
+    build_mode_extra_value_1=
+    build_mode_extra_param_2=
+    build_mode_extra_value_2=
 
-  if [[ ${1} == "${mode_part}-individual" ]] ; then
-    build_mode="individual"
+    if [[ ${1} == "${mode_part}-individual" ]] ; then
+      build_mode="individual"
 
-    if [[ ${mode_thread_param} != "" ]] ; then
-      build_mode_extra_param_1="-m"
-      build_mode_extra_value_1="individual_thread"
+      if [[ ${mode_thread_param} != "" ]] ; then
+        build_mode_extra_param_1="-m"
+        build_mode_extra_value_1="individual_thread"
+      fi
+
+      build_mode_extra_param_2=${mode_thread_param}
+      build_mode_extra_value_2=${mode_thread_value}
+    elif [[ ${1} == "${mode_part}-level" ]] ; then
+      build_mode="level"
+      build_mode_extra_param_1=${mode_thread_param}
+      build_mode_extra_value_1=${mode_thread_value}
+    elif [[ ${1} == "${mode_part}-monolithic" ]] ; then
+      build_mode="monolithic"
+      build_mode_extra_param_1=${mode_thread_param}
+      build_mode_extra_value_1=${mode_thread_value}
+    elif [[ ${1} == "${mode_part}-stand_alone" ]] ; then
+      build_mode="stand_alone"
+      mode_path="stand_alone"
+      mode_parameter="-S"
+      mode_value="${mode_part}"
+      build_mode_extra_param_1=${mode_thread_param}
+      build_mode_extra_value_1=${mode_thread_value}
     fi
 
-    build_mode_extra_param_2=${mode_thread_param}
-    build_mode_extra_value_2=${mode_thread_value}
-  elif [[ ${1} == "${mode_part}-level" ]] ; then
-    build_mode="level"
-    build_mode_extra_param_1=${mode_thread_param}
-    build_mode_extra_value_1=${mode_thread_value}
-  elif [[ ${1} == "${mode_part}-monolithic" ]] ; then
-    build_mode="monolithic"
-    build_mode_extra_param_1=${mode_thread_param}
-    build_mode_extra_value_1=${mode_thread_value}
-  elif [[ ${1} == "${mode_part}-stand_alone" ]] ; then
-    build_mode="stand_alone"
-    mode_path="stand_alone"
-    mode_parameter="-S"
-    mode_value="${mode_part}"
-    build_mode_extra_param_1=${mode_thread_param}
-    build_mode_extra_value_1=${mode_thread_value}
-  fi
+    ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild ${mode_parameter} ${mode_value} &&
 
-  ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild ${mode_parameter} ${mode_value} &&
+    cd package/${mode_path}/${mode_part}-${version}/ &&
 
-  cd package/${mode_path}/${mode_part}-${version}/ &&
+    ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-  ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+    ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
 
-  ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
+    ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
 
-  ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
+    if [[ ${?} -ne 0 ]] ; then return 1 ; fi
 
-# The following in an example on building all FLL program projects using the project bootstrapped from above.
-elif [[ ${1} == "programs-individual" || ${1} == "programs-level" || ${1} == "programs-monolithic" ]] ; then
-  build_mode_extra_param_1=
-  build_mode_extra_value_1=
-  build_mode_extra_param_2=
-  build_mode_extra_value_2=
+  # The following in an example on building all FLL program projects using the project bootstrapped from above.
+  elif [[ ${1} == "programs-individual" || ${1} == "programs-level" || ${1} == "programs-monolithic" ]] ; then
+    build_mode_extra_param_1=
+    build_mode_extra_value_1=
+    build_mode_extra_param_2=
+    build_mode_extra_value_2=
 
-  if [[ ${1} == "programs-individual" ]] ; then
-    build_mode="individual"
+    if [[ ${1} == "programs-individual" ]] ; then
+      build_mode="individual"
 
-    if [[ ${mode_thread_param} != "" ]] ; then
-      build_mode_extra_param_1="-m"
-      build_mode_extra_value_1="individual_thread"
-    fi
+      if [[ ${mode_thread_param} != "" ]] ; then
+        build_mode_extra_param_1="-m"
+        build_mode_extra_value_1="individual_thread"
+      fi
 
-    build_mode_extra_param_2=${mode_thread_param}
-    build_mode_extra_value_2=${mode_thread_value}
-  elif [[ ${1} == "programs-level" ]] ; then
-    build_mode="level"
-    build_mode_extra_param_1=${mode_thread_param}
-    build_mode_extra_value_1=${mode_thread_value}
-  elif [[ ${1} == "programs-monolithic" ]] ; then
-    build_mode="monolithic"
-    build_mode_extra_param_1=${mode_thread_param}
-    build_mode_extra_value_1=${mode_thread_value}
-  fi
+      build_mode_extra_param_2=${mode_thread_param}
+      build_mode_extra_value_2=${mode_thread_value}
+    elif [[ ${1} == "programs-level" ]] ; then
+      build_mode="level"
+      build_mode_extra_param_1=${mode_thread_param}
+      build_mode_extra_value_1=${mode_thread_value}
+    elif [[ ${1} == "programs-monolithic" ]] ; then
+      build_mode="monolithic"
+      build_mode_extra_param_1=${mode_thread_param}
+      build_mode_extra_value_1=${mode_thread_value}
+    fi
 
-  ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -p &&
+    ${shell_command} build/scripts/package.sh ${verbose} ${color} rebuild -p &&
 
-  cd package/program
+    cd package/program
 
-  if [[ ${?} -eq 0 ]] ; then
+    if [[ ${?} -eq 0 ]] ; then
 
-    for i in * ; do
+      for i in * ; do
 
-      skip=
+        skip=
 
-      for j in ${exclude_programs} ; do
-        if [[ ${i} == "${j}-${version}" ]] ; then
-          skip="true"
+        for j in ${exclude_programs} ; do
+          if [[ ${i} == "${j}-${version}" ]] ; then
+            skip="true"
 
-          break
-        fi
-      done
+            break
+          fi
+        done
 
-      if [[ $skip != "" ]] ; then
-        echo "Skipping program: '${i}'."
-        echo
+        if [[ $skip != "" ]] ; then
+          echo "Skipping program: '${i}'."
+          echo
 
-        continue
-      fi
+          continue
+        fi
 
-      cd ${path_original}package/program/${i} &&
+        cd ${path_original}package/program/${i} &&
 
-      ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
+        ${shell_command} ./bootstrap.sh clean ${verbose} ${color} &&
 
-      ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
+        ${shell_command} ./bootstrap.sh build ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
 
-      ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} ||
+        ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
 
-      break
+        if [[ ${?} -ne 0 ]] ; then return 1 ; fi
 
-      if [[ $(type -p fake) != "" && ${fake_programs} != "" ]] ; then
-        for j in ${fake_programs} ; do
-          if [[ ${i} == "${j}-${version}" ]] ; then
-            cd ${path_original}package/program/${i} &&
+        if [[ $(type -p fake) != "" && ${fake_programs} != "" ]] ; then
+          for j in ${fake_programs} ; do
+            if [[ ${i} == "${j}-${version}" ]] ; then
+              cd ${path_original}package/program/${i} &&
 
-            fake clean make ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
+              fake clean make ${verbose} ${color} ${shared} ${static} -w ${path_work} -m ${build_mode} ${build_mode_extra_param_1} ${build_mode_extra_value_1} ${build_mode_extra_param_2} ${build_mode_extra_value_2} ${mode_compiler_param} ${mode_compiler_value} &&
 
-            ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work} ||
+              ${shell_command} ./install.sh ${verbose} ${color} ${shared} ${static} -w ${path_work}
 
-            skip="break"
-          fi
-        done
+              if [[ ${?} -ne 0 ]] ; then return 1 ; fi
+            fi
+          done
+        fi
+      done
+    else
+      echo
+      echo "ERROR: failed to change directory to 'package/program'."
+      echo
 
-       if [[ $skip == "break" ]] ; then break ; fi
-     fi
-    done
-  else
+      if [[ ${?} -ne 0 ]] ; then return 1 ; fi
+    fi
+  elif [[ ${1} != "individual" && ${1} != "level" && ${1} != "monolithic" ]] ; then
     echo
-    echo "ERROR: failed to change directory to 'package/program'."
+    echo "ERROR: '${1}' is not a supported build mode."
     echo
+
+    if [[ ${?} -ne 0 ]] ; then return 1 ; fi
   fi
-elif [[ ${1} != "individual" && ${1} != "level" && ${1} != "monolithic" ]] ; then
-  echo
-  echo "ERROR: '${1}' is not a supported build mode."
-  echo
-fi
-
-# Regardless of what happens always return to the starting directory.
-cd ${path_original}
+
+  return 0
+}
+
+main ${*}