1 # ============================================================================ 2 # Copyright (c) 2011-2012 University of Pennsylvania 3 # Copyright (c) 2013-2016 Andreas Schuh 6 # See COPYING file for license information or visit 7 # https://cmake-basis.github.io/download.html#license 8 # ============================================================================ 10 ############################################################################## 12 # @brief Main module of project-independent BASIS utilities. 14 # This module defines the default BASIS utility functions. These default 15 # implementations are not project-specific, i.e., do not make use of particular 16 # project attributes such as the name or version of the project. The utility 17 # functions defined by this module are intended for use in Bash scripts that 18 # are not build as part of a particular BASIS project. Otherwise, the 19 # project-specific implementations should be used instead, i.e., those defined 20 # by the basis.sh module of the project which is automatically added to the 21 # project during the configuration of the build tree. This basis.sh module and 22 # the submodules used by it are generated from template modules which are 23 # customized for the particular project that is being build. 25 # Besides the utility functions which are common to all implementations for 26 # the different programming languages, does this module further provide 27 # fundamental functions for the development in Bash. 29 # @note In Bash, there is no concept of namespaces. Hence, the utility functions 30 # are all defined by the utilities.sh module which is part of the BASIS 31 # installation. By simply setting the constants to the project specific 32 # values, these utility functions are customized for this particular 33 # package. This, however, also means that the BASIS utilities of two 34 # different packages cannot be used within a Bash script at the same 35 # time in general. The order in which the basis.sh modules are sourced 36 # matters. Therefore, in Bash, care must be taken which modules of a 37 # BASIS-based package are being sourced and whether these in turn 38 # source either the utilities.sh module of BASIS or the basis.sh module 39 # which has been configured/customized for this particular package. 40 # If all modules make only use of the utilities.sh module, there are 41 # no conflicts. Thus, Bash should in general only be used for executable 42 # scripts within a project, but not to provide library functions to 43 # other developers. Therefore, consider the use of C++, Python, or Perl, 46 # @ingroup BasisBashUtilities 47 ############################################################################## 49 [
"${_BASIS_UTILITIES_INCLUDED}" ==
'true' ] || {
50 _BASIS_UTILITIES_INCLUDED=
'true' 53 # ============================================================================ 55 # ============================================================================ 57 BASIS_UTILITIES_DIR=
"`cd -P -- "\`
dirname --
"${BASH_SOURCE}"\`
" && pwd`" 58 readonly BASIS_UTILITIES_DIR
60 # ============================================================================ 61 # source other modules 62 # ============================================================================ 64 .
"${BASIS_UTILITIES_DIR}/core.sh" || exit 1 # core utilities, i.e.,
import()
66 import basis.config # constants
68 import basis.shflags # command-line parsing library
70 # ============================================================================
72 # ============================================================================
74 # the following contanst are
set by the
basis.sh module,
if not, because
75 #
this module
is used in a script
which does not belong to a BASIS-based
76 # project, they are initialized to project-independent defaults here
78 ## @brief Project name.
79 [ -n
"${PROJECT}" ] || readonly
PROJECT=
'' 80 ## @brief Project version.
81 [ -n
"${VERSION}" ] || readonly
VERSION=
'' 82 ## @brief Major project version.
84 ## @brief Minor project version.
86 ## @brief Project patch number.
88 ## @brief Project release.
89 [ -n
"${RELEASE}" ] || readonly
RELEASE=
'' 90 ## @brief Default copyright of executables.
91 [ -n
"${COPYRIGHT}" ] || readonly
COPYRIGHT=
'2011-12 University of Pennsylvania, 2013-14 Carnegie Mellon University, 2013-16 Andreas Schuh' 92 ## @brief Default license of executables.
93 [ -n
"${LICENSE}" ] || readonly
LICENSE=
'See https://cmake-basis.github.io/download.html#license or COPYING file.' 94 ## @brief Default contact to use
for help output of executables.
95 [ -n
"${CONTACT}" ] || readonly
CONTACT=
'andreas.schuh.84@gmail.com' 98 # common prefix of target UIDs belonging to
this project
99 [ -n
"${_BASIS_TARGET_UID_PREFIX}" ] || _BASIS_TARGET_UID_PREFIX=
'' 100 # used to make relative paths in executable target information map absolute
101 [ -n
"${_BASIS_EXECUTABLE_TARGETS_BASE}" ] || _BASIS_EXECUTABLE_TARGETS_BASE=
"${BASIS_UTILITIES_DIR}" 103 # declare constants as readonly
114 readonly _BASIS_TARGET_UID_PREFIX
115 readonly _BASIS_EXECUTABLE_TARGETS_BASE
118 ## @addtogroup BasisBashUtilities
122 # ============================================================================
123 # executable information
124 # ============================================================================
126 # ----------------------------------------------------------------------------
127 ## @brief Print contact information.
129 # @param [in] contact Name of contact. Defaults to <tt>${
CONTACT}</tt>.
134 [ -n
"$1" ] && echo -
e "Contact:\n $1" || echo -
e "Contact:\n ${CONTACT}" 137 # ---------------------------------------------------------------------------- 138 ## @brief Print version information including copyright and license notices. 142 # print_version 'foo' '1.0' 143 # print_version 'foo' -v '1.0' 144 # print_version -v 1.0 -p BarStool 'foo' 145 # print_version 'foo' -v '1.2' -c '2012 University of Pennsylvania' \ 146 # -l 'Apache License, Version 2.0' 149 # @param [in] options Function options as documented below. 150 # @param [in] name Name of executable. Should not be set programmatically 151 # to the first argument of the main script, but a string 153 # @param [in] version Version of executable. Defaults to <tt>${RELEASE}</tt> 154 # if defined, otherwise this argument is required. 158 # @tp @b -v, @b --version <version> @endtp 159 # <td>Version of executable. Can be either given as option or second 160 # positional argument after the @p name.</td> 163 # @tp @b -p, @b --project <name> @endtp 164 # <td>Name of project this executable belongs to. 165 # Defaults to <tt>${PROJECT}</tt> if defined. 166 # If 'none', no project information is printed.</td> 169 # @tp @b -c @b --copyright <copyright> @endtp 170 # <td>The copyright notice. Defaults to <tt>${COPYRIGHT}</tt>. 171 # If 'none', no copyright notice is printed.</td> 174 # @tp @b -l @b --license <license> @endtp 175 # <td>Information regarding licensing. Defaults to <tt>${LICENSE}</tt>. 176 # If 'none', no license information is printed.</td> 183 local _basis_pv_name=
'' 184 local _basis_pv_version=
"${RELEASE}" 185 local _basis_pv_project=
"${PROJECT}" 186 local _basis_pv_copyright=
"${COPYRIGHT:-}" 187 local _basis_pv_license=
"${LICENSE:-}" 188 while [ $# -gt 0 ];
do 191 if [ -n
"${_basis_pv_version}" ]; then
192 echo
"print_version(): Version specified twice!" 1>&2
195 if [ $# -gt 1 ]; then
196 _basis_pv_version=
"$2" 198 echo
"print_version(): Option -v, --version is missing an argument!" 1>&2
204 if [ $# -gt 1 ]; then
205 _basis_pv_project=
"$2" 207 echo
"print_version(): Option -p, --project is missing an argument!" 1>&2
213 if [ $# -gt 1 ]; then
214 _basis_pv_copyright=
"$2" 216 echo
"print_version(): Option -c, --copyright is missing an argument!" 1>&2
222 if [ $# -gt 1 ]; then
223 _basis_pv_license=
"$2" 225 echo
"print_version(): Option -l, --license is missing an argument!" 1>&2
231 if [ -z
"${_basis_pv_name}" ]; then
233 elif [ -z
"${_basis_pv_version}" ]; then
236 echo
"print_version(): Too many arguments or invalid option: $1" 1>&2
243 [ -n
"${_basis_pv_name}" ] || { echo
"print_version(): Missing name argument" 1>&2;
return 1; }
244 [ -n
"${_basis_pv_version}" ] || { echo
"print_version(): Missing version argument" 1>&2;
return 1; }
245 echo -n
"${_basis_pv_name}" 246 [ -n
"${_basis_pv_project}" ] && [
"${_basis_pv_project}" !=
'none' ] && {
247 echo -n
" (${_basis_pv_project})" 249 echo
" ${_basis_pv_version}" 250 [ -n
"${_basis_pv_copyright}" ] && [
"${_basis_pv_copyright}" !=
'none' ] && {
251 echo -
e "Copyright (c) ${_basis_pv_copyright}. All rights reserved." 253 [ -n
"${_basis_pv_license}" ] && [
"${_basis_pv_license}" !=
'none' ] && {
254 echo -
e "${_basis_pv_license}" 258 # ---------------------------------------------------------------------------- 259 ## @brief Get UID of build target. 261 # The UID of a build target is its name prepended by a namespace identifier 262 # which should be unique for each project. 264 # This function further initializes the dictionary storing the information 265 # about the executable targets upon the first invocation. Reason to do it 266 # here is that every access to the dictionaries first calls this function 267 # to get the UID of a build target. Moreover, also this function needs to 268 # have the already initialized dictionaries to ensure that an already valid 269 # target identifier is not modified. As Bash does not provide hash tables, 270 # dictionary data structures, the imitation of these is necessary which, 271 # however, results in many eval() calls with noticeable impact on running time. 272 # Therefore, to decrease the time required to source the BASIS utilities, 273 # the required dictionary structure is initialized only upon first use. 275 # @param [out] uid UID of named build target. 276 # @param [in] name Name of build target. 280 # @retval 0 On success. 281 # @retval 1 On failure. 284 [ -n
"$1" ] && [ $# -eq 2 ] ||
return 1
285 local _basis_targetuid_target=
"$2" 286 # initialize module if not done yet - this is only done here because 287 # whenever information is looked up about an executable target, this 288 # function is invoked first 289 if [
"${_BASIS_EXECUTABLETARGETINFO_INITIALIZED}" !=
'true' ]; then
290 _basis_executabletargetinfo_initialize ||
return 1
292 # empty string as input remains unchanged 293 [ -z
"${_basis_targetuid_target}" ] && local
"$1" &&
upvar $1
'' &&
return 0
294 # in case of a leading namespace separator, do not modify target name 295 [
"${_basis_targetuid_target:0:1}" ==
'.' ] && local
"$1" && upvar $1
"${_basis_targetuid_target}" &&
return 0
297 local _basis_targetuid_prefix=
"${_BASIS_TARGET_UID_PREFIX}.DUMMY" 298 # try prepending namespace or parts of it until target is known 299 local _basis_targetuid_path=
'' 300 while [
"${_basis_targetuid_prefix/\.*/}" !=
"${_basis_targetuid_prefix}" ];
do 301 _basis_targetuid_prefix=
"${_basis_targetuid_prefix%\.*}" 302 _basis_executabletargetinfo_get _basis_targetuid_path
"${_basis_targetuid_prefix}.${_basis_targetuid_target}" LOCATION
303 if [ -n
"${_basis_targetuid_path}" ]; then
304 local
"$1" && upvar $1
"${_basis_targetuid_prefix}.${_basis_targetuid_target}" 308 # otherwise, return target name unchanged 309 local
"$1" && upvar $1
"${_basis_targetuid_target}" 312 # ---------------------------------------------------------------------------- 313 ## @brief Determine whether a given build target is known. 315 # @param [in] target Name of build target. 317 # @returns Whether the named target is a known executable target. 320 local _basis_istarget_uid &&
targetuid _basis_istarget_uid
"$1" 321 [ -n
"${_basis_istarget_uid}" ] ||
return 1
322 local _basis_istarget_path && _basis_executabletargetinfo_get _basis_istarget_path
"${_basis_istarget_uid}" LOCATION
323 [ -n
"${_basis_istarget_path}" ]
326 # ---------------------------------------------------------------------------- 327 ## @brief Get absolute path of executable file. 329 # This function determines the absolute file path of an executable. If no 330 # arguments are given, the absolute path of this executable is returned. 331 # If the given argument is a known build target name, the absolute path 332 # of the executable built by this target is returned. Otherwise, the named 333 # command is searched in the system PATH and it's absolute path returned 334 # if found. If the given argument is neither the name of a known build target 335 # nor an executable found on the PATH, an empty string is returned and 336 # the return value is 1. 338 # @param [out] path Absolute path of executable file. 339 # @param [in] target Name/UID of build target. If no argument is given, 340 # the file path of the calling executable is returned. 344 # @retval 0 On success. 345 # @retval 1 On failure. 348 [ -n
"$1" ] && [ $# -eq 1 -o $# -eq 2 ] ||
return 1
349 local _basis_exepath_path=
'' 350 # if no target name given, get path of this executable 352 _basis_exepath_path=
"`realpath "$0
"`" 353 # otherwise, get path of executable built by named target 356 local _basis_exepath_uid &&
targetuid _basis_exepath_uid
"$2" 357 [
"${_basis_exepath_uid:0:1}" ==
'.' ] && _basis_exepath_uid=${_basis_exepath_uid:1}
358 if [ -n
"${_basis_exepath_uid}" ]; then
359 # get path relative to this module 360 _basis_executabletargetinfo_get _basis_exepath_path
"${_basis_exepath_uid}" LOCATION
361 if [ -n
"${_basis_exepath_path}" ]; then
362 # replace IntDir when binary built from C++ with Xcode 363 if [[ ${_basis_exepath_path/\$<CONFIG>} != ${_basis_exepath_path} ]]; then
364 local _basis_exepath_tmp=
'' 365 local _basis_exepath_cfg=
'' 366 for _basis_exepath_cfg in
'Release' 'Debug' 'RelWithDebInfo' 'MinSizeRel';
do 367 _basis_exepath_tmp=${_basis_exepath_path/\$<CONFIG>/$_basis_exepath_cfg}
368 if [ -f
"${_basis_exepath_tmp}" ]; then
369 _basis_exepath_path=
"${_basis_exepath_tmp}" 373 _basis_exepath_path=${_basis_exepath_path/\$<CONFIG>}
376 _basis_exepath_path=`
abspath "${_BASIS_EXECUTABLE_TARGETS_BASE}" "${_basis_exepath_path}"`
377 [ $? -eq 0 ] ||
return 1
379 _basis_exepath_path=`/usr/bin/
which "$2" 2> /dev/null`
382 _basis_exepath_path=`/usr/bin/
which "$2" 2> /dev/null`
386 local
"$1" &&
upvar $1
"${_basis_exepath_path}" 387 [ $? -eq 0 ] && [ -n
"${_basis_exepath_path}" ]
390 # ---------------------------------------------------------------------------- 391 ## @brief Get name of executable file. 393 # @param [out] file Name of executable file or an empty string if not found. 394 # If @p name is not given, the name of this executable is returned. 395 # @param [in] name Name of command or an empty string. 397 # @returns Whether or not the command was found. 399 # @retval 0 On success. 400 # @retval 1 On failure. 403 [ -n
"$1" ] && [ $# -eq 1 -o $# -eq 2 ] ||
return 1
404 local _basis_exename_path &&
exepath _basis_exename_path
"$2" 405 [ $? -eq 0 ] ||
return 1
406 local _basis_exename_name=
"`basename "${_basis_exename_path}
"`" 407 local
"$1" &&
upvar $1
"${_basis_exename_name}" 410 # ---------------------------------------------------------------------------- 411 ## @brief Get directory of executable file. 413 # @param [out] dir Directory of executable file or an empty string if not found. 414 # If @p name is not given, the directory of this executable is returned. 415 # @param [in] name Name of command or an empty string. 417 # @returns Whether or not the command was found. 419 # @retval 0 On success. 420 # @retval 1 On failure. 423 [ -n
"$1" ] && [ $# -eq 1 -o $# -eq 2 ] ||
return 1
424 local _basis_exedir_path &&
exepath _basis_exedir_path
"$2" 425 [ $? -eq 0 ] ||
return 1
426 local _basis_exedir_dir=
"`dirname "${_basis_exedir_path}
"`" 427 local
"$1" &&
upvar $1
"${_basis_exedir_dir}" 430 # ============================================================================ 432 # ============================================================================ 434 # ---------------------------------------------------------------------------- 435 ## @brief Build quoted string from array. 439 # tostring str 'this' "isn't" a 'simple example of "a quoted"' 'string' 443 # @param [out] var Name of result variable for quoted string. 444 # @param [in] elements All remaining arguments are considered to be the 445 # elements of the array to convert. 450 local _basis_tostring_str=
'' 451 local _basis_tostring_element=
'' 452 # GNU bash, version 3.00.15(1)-release (x86_64-redhat-linux-gnu) 453 # turns the array into a single string value if local is used 455 local _basis_tostring_args=(
"$@")
457 _basis_tostring_args=(
"$@")
459 local _basis_tostring_i=1 # first argument
is name of
return variable
460 while [ $_basis_tostring_i -lt ${#_basis_tostring_args[@]} ];
do 461 _basis_tostring_element=
"${_basis_tostring_args[$_basis_tostring_i]}" 462 # escape double quotes 463 _basis_tostring_element=`printf --
"${_basis_tostring_element}" | sed
's/\\"/\\\\"/g'`
464 # surround element by double quotes if necessary 465 match "${_basis_tostring_element}" "[' ]|^$" && _basis_tostring_element=
"\"${_basis_tostring_element}\"" 467 [ -n
"${_basis_tostring_str}" ] && _basis_tostring_str=
"${_basis_tostring_str} " 468 _basis_tostring_str=
"${_basis_tostring_str}${_basis_tostring_element}" 470 let _basis_tostring_i++
472 local
"$1" &&
upvar $1
"${_basis_tostring_str}" 475 # ---------------------------------------------------------------------------- 476 ## @brief Split (quoted) string. 478 # This function can be used to split a (quoted) string into its elements. 482 # str="'this' 'isn\'t' a \"simple example of \\\"a quoted\\\"\" 'string'" 483 # qsplit array "${str}" 484 # echo ${#array[@]} # 5 485 # echo "${array[3]}" # simple example of "a quoted" 488 # @param [out] var Result variable for array. 489 # @param [in] str Quoted string. 494 [ $# -eq 2 ] ||
return 1
495 # GNU bash, version 3.00.15(1)-release (x86_64-redhat-linux-gnu) 496 # turns the array into a single string value if local is used 498 local _basis_qsplit_array=()
500 _basis_qsplit_array=()
502 local _basis_qsplit_str=$2
503 # match arguments from left to right 504 while match "${_basis_qsplit_str}" "[ ]*('([^']|\\\')*[^\\]'|\"([^\"]|\\\")*[^\\]\"|[^ ]+)(.*)";
do 505 # matched element including quotes 506 _basis_qsplit_element=
"${BASH_REMATCH[1]}" 508 if [[ ${_basis_qsplit_element:0:1} ==
'"' && ${_basis_qsplit_element: -1} ==
'"' ]]; then
509 _basis_qsplit_element=
"${_basis_qsplit_element:1}" 510 _basis_qsplit_element=
"${_basis_qsplit_element%\"}" 511 elif [[ ${_basis_qsplit_element:0:1} ==
"'" && ${_basis_qsplit_element: -1} ==
"'" ]]; then
512 _basis_qsplit_element=
"${_basis_qsplit_element:1}" 513 _basis_qsplit_element=
"${_basis_qsplit_element%\'}" 515 # replace quoted quotes within argument by quotes 516 _basis_qsplit_element=`printf --
"${_basis_qsplit_element}" | sed
"s/[\\]'/'/g;s/[\\]\"/\"/g"`
517 # add to resulting array 518 _basis_qsplit_array[${#_basis_qsplit_array[@]}]=
"${_basis_qsplit_element}" 519 # continue with residual command-line 520 _basis_qsplit_str=
"${BASH_REMATCH[4]}" 523 local
"$1" &&
upvar $1
"${_basis_qsplit_array[@]}" 526 # ---------------------------------------------------------------------------- 527 ## @brief Execute command as subprocess. 529 # This function is used to execute a subprocess within a Bash script. 533 # # the next command will exit the current shell if it fails 534 # execute ls /not/existing 535 # # to prevent this, provide the --allow_fail option 536 # execute --allow_fail ls /not/existing 537 # # to make it explicit where the command-line to execute starts, use -- 538 # execute --allow_fail -- ls /not/existing 541 # Note that the output of the command is not redirected by this function. 542 # In order to execute the command quietly, use this function as follows: 544 # execute ls / &> /dev/null 546 # Or to store the command output in a variable including error messages 549 # output=`execute ls / 2>&1` 551 # Note that in this case, the option --allow_fail has no effect as the 552 # calling shell will never be terminated. Only the subshell in which the 553 # command is executed will be terminated. Checking the exit code $? is 554 # in this case required. 556 # @param [in] options Function options as documented below. 557 # @param [in] cmd Executable of command to run or corresponding build 558 # target name. This is assumed to be the first 559 # non-option argument or the argument that follows the 560 # special '--' argument. 561 # @param [in] args All remaining arguments are passed as arguments to 566 # @tp <b>-f, --allow_fail</b> @endtp 567 # <td>Allows the command to fail. By default, if the command 568 # returns a non-zero exit code, the exit() function is 569 # called to terminate the current shell.</td> 572 # @tp <b>-v, --verbose</b> [int] @endtp 573 # <td>Print command-line to stdout before execution. Optionally, as it is 574 # sometimes more convenient to pass in the value of another variable 575 # which controls the verbosity of the parent process itself, a verbosity 576 # value can be specified following the option flag. If this verbosity 577 # less or equal to zero, the command-line of the subprocess is not 578 # printed to stdout, otherwise it is.</td> 581 # @tp <b>-s, --simulate</b> @endtp 582 # <td>If this option is given, the command is not actually 583 # executed, but the command-line printed to stdout only.</td> 587 # @returns Exit code of subprocess. 591 local _basis_execute_allow_fail=
'false' 592 local _basis_execute_simulate=
'false' 593 local _basis_execute_verbose=0
594 local _basis_execute_args=
'' 595 while [ $# -gt 0 ];
do 597 -f|--allow_fail) _basis_execute_allow_fail=
'true'; ;;
598 -s|--simulate) _basis_execute_simulate=
'true'; ;;
600 match "$2" '^-?[0-9]+$' 601 if [ $? -eq 0 ]; then
602 _basis_execute_verbose=$2
605 let _basis_execute_verbose++
613 # command to execute and its arguments 614 local _basis_execute_command=
"$1"; shift
615 [ -n
"${_basis_execute_command}" ] || { echo
"execute_process(): No command specified to execute" 1>&2;
return 1; }
616 # get absolute path of executable 617 local _basis_execute_exec &&
exepath _basis_execute_exec
"${_basis_execute_command}" 618 [ -n
"${_basis_execute_exec}" ] || { echo
"${_basis_execute_command}: Command not found" 1>&2; exit 1; }
619 # some verbose output 620 if [ ${_basis_execute_verbose} -gt 0 ] || [
"${_basis_execute_simulate}" ==
'true' ]; then
622 echo
"\$ ${_basis_execute_exec} ${_basis_execute_args}" 625 [
"${_basis_execute_simulate}" ==
'true' ] ||
"${_basis_execute_exec}" "$@" 626 local _basis_execute_status=$?
627 # if command failed, exit 628 [ ${_basis_execute_status} -eq 0 -o
"${_basis_execute_allow_fail}" ==
'true' ] || {
629 [ -n
"${_basis_execute_args}" ] ||
tostring _basis_execute_args
"$@" 631 echo
"Command ${_basis_execute_exec} ${_basis_execute_args} failed" 1>&2
635 return ${_basis_execute_status}
640 # end of Doxygen group 642 # ============================================================================ 644 # ============================================================================ 646 # ---------------------------------------------------------------------------- 647 # @brief Sanitize string for use in variable name. 649 # @param [out] out Sanitized string. 650 # @param [in] str String to be sanitized. 654 # @retval 0 On success. 655 # @retval 1 On failure. 656 _basis_executabletargetinfo_sanitize()
658 [ $# -eq 2 ] ||
return 1
663 local sane=
"`printf -- "$2
" | tr '[:space:]' '_' | tr -c '[:alnum:]' '_'`" 664 [ -n
"${sane}" ] || {
665 echo
"_basis_executabletargetinfo_sanitize(): Failed to sanitize string '$2'" 1>&2
668 local
"$1" &&
upvar $1
"${sane}" 671 # ---------------------------------------------------------------------------- 672 # @brief Add (key, value) pair to executable target info "hash". 674 # @param [in] key Hash key. 675 # @param [in] name Name of the hash table. 676 # @param [in] value Value associated with the given hash key. 678 # @returns Sets a readonly variable that represents the (key, value) entry. 680 # @sa _basis_executabletargetinfo_get() 681 _basis_executabletargetinfo_add()
683 [ $# -eq 3 ] ||
return 1
685 local key && _basis_executabletargetinfo_sanitize key
"$1" 686 local name && _basis_executabletargetinfo_sanitize name
"$2" 687 [ -n
"${key}" ] && [ -n
"${name}" ] || {
688 if [ -z
"${key}" ] && [ -z
"${name}" ]; then
689 echo
"_basis_executabletargetinfo_add(): Neither lookup table nor key specified" 1>&2
690 elif [ -z
"${key}" ]; then
691 echo
"_basis_executabletargetinfo_add(): No key specified for addition to hash table '${name}'" 1>&2
693 echo
"_basis_executabletargetinfo_add(): No lookup table given for addition of key '${key}'" 1>&2
697 eval
"readonly __BASIS_EXECUTABLETARGETINFO_${name}_${key}='$3'" 698 if [ $? -ne 0 ]; then
699 echo
"Failed to add ${name} of key ${key} to executable target info map!" 1>&2
700 echo
"This may be caused by two CMake build target names being converted to the same key." 1>&2
705 # ---------------------------------------------------------------------------- 706 # @brief Get value from executable target info "hash". 708 # @param [out] value Value corresponding to given @p key 709 # or an empty string if key is unknown. 710 # @param [in] key Hash key. 711 # @param [in] name Name of the hash table. 715 # @retval 0 On success. 716 # @retval 1 On failure. 718 # @sa _basis_executabletargetinfo_add() 719 _basis_executabletargetinfo_get()
721 [ $# -eq 3 ] ||
return 1
723 local key && _basis_executabletargetinfo_sanitize key
"$2" 724 local name && _basis_executabletargetinfo_sanitize name
"$3" 725 [ -n
"${key}" ] && [ -n
"${name}" ] || {
726 if [ -z
"${key}" ] && [ -z
"${name}" ]; then
727 echo
"_basis_executabletargetinfo_get(): Neither lookup table nor key specified" 1>&2
728 elif [ -z
"${key}" ]; then
729 echo
"_basis_executabletargetinfo_get(): No key specified for lookup in hash table '${name}'" 1>&2
731 echo
"_basis_executabletargetinfo_get(): No lookup table given for lookup of key '${key}'" 1>&2
735 eval
"local value=\${__BASIS_EXECUTABLETARGETINFO_${name}_${key}}" 737 local
"$1" &&
upvar $1
"${value}" 740 # initialize table of executable target information upon first use 741 # this function is redefined by the basis.sh module, see targetuid() 742 _basis_executabletargetinfo_initialize()
744 [ $# -eq 0 ] ||
return 1
745 _BASIS_EXECUTABLETARGETINFO_INITIALIZED=
'true' 750 } # _BASIS_UTILITIES_INCLUDED
const unsigned int VERSION_MAJOR
The major version number.
string PROJECT
Project name.
function targetuid(out uid, in name)
Get UID of build target.
function istarget(in target)
Determine whether a given build target is known.
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
def which(command, path=None, verbose=0, exts=None)
function tostring(out var, in elements)
Build quoted string from array.
function upvar(in var, in values)
Assign variable one scope above the caller.
function print_contact(in contact)
Print contact information.
string COPYRIGHT
Default copyright of executables.
string VERSION
Project version.
function exepath(out path, in target)
Get absolute path of executable file.
string RELEASE
Project release.
function qsplit(out var, in str)
Split (quoted) string.
function abspath(in path)
Get absolute path given a relative path.
std::string dirname(const std::string &path)
Get file directory.
function match(in value, in pattern)
This function implements a more portable way to do pattern matching.
function exedir(out dir, in name)
Get directory of executable file.
string LICENSE
Default license of executables.
MultiSwitchArg verbose("v", "verbose", "Increase verbosity of output messages.", false)
const unsigned int VERSION_MINOR
The minor version number.
const unsigned int VERSION_PATCH
The patch number.
function exename(out file, in name)
Get name of executable file.
function print_version(in options, in name, in version)
Print version information including copyright and license notices.
string CONTACT
Default contact to use for help output of executables.
function execute(in options, in cmd, in args)
Execute command as subprocess.