144d4804dSStefan Eßer#! /bin/sh 244d4804dSStefan Eßer# 344d4804dSStefan Eßer# SPDX-License-Identifier: BSD-2-Clause 444d4804dSStefan Eßer# 5*a970610aSStefan Eßer# Copyright (c) 2018-2024 Gavin D. Howard and contributors. 644d4804dSStefan Eßer# 744d4804dSStefan Eßer# Redistribution and use in source and binary forms, with or without 844d4804dSStefan Eßer# modification, are permitted provided that the following conditions are met: 944d4804dSStefan Eßer# 1044d4804dSStefan Eßer# * Redistributions of source code must retain the above copyright notice, this 1144d4804dSStefan Eßer# list of conditions and the following disclaimer. 1244d4804dSStefan Eßer# 1344d4804dSStefan Eßer# * Redistributions in binary form must reproduce the above copyright notice, 1444d4804dSStefan Eßer# this list of conditions and the following disclaimer in the documentation 1544d4804dSStefan Eßer# and/or other materials provided with the distribution. 1644d4804dSStefan Eßer# 1744d4804dSStefan Eßer# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1844d4804dSStefan Eßer# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1944d4804dSStefan Eßer# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2044d4804dSStefan Eßer# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2144d4804dSStefan Eßer# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2244d4804dSStefan Eßer# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2344d4804dSStefan Eßer# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2444d4804dSStefan Eßer# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2544d4804dSStefan Eßer# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2644d4804dSStefan Eßer# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2744d4804dSStefan Eßer# POSSIBILITY OF SUCH DAMAGE. 2844d4804dSStefan Eßer# 2944d4804dSStefan Eßer 3044d4804dSStefan Eßer# This script is NOT meant to be run! It is meant to be sourced by other 3144d4804dSStefan Eßer# scripts. 3244d4804dSStefan Eßer 3344d4804dSStefan Eßer# Reads and follows a link until it finds a real file. This is here because the 3444d4804dSStefan Eßer# readlink utility is not part of the POSIX standard. Sigh... 3544d4804dSStefan Eßer# @param f The link to find the original file for. 3644d4804dSStefan Eßerreadlink() { 3744d4804dSStefan Eßer 3844d4804dSStefan Eßer _readlink_f="$1" 3944d4804dSStefan Eßer shift 4044d4804dSStefan Eßer 4144d4804dSStefan Eßer _readlink_arrow="-> " 4244d4804dSStefan Eßer _readlink_d=$(dirname "$_readlink_f") 4344d4804dSStefan Eßer 4444d4804dSStefan Eßer _readlink_lsout="" 4544d4804dSStefan Eßer _readlink_link="" 4644d4804dSStefan Eßer 4744d4804dSStefan Eßer _readlink_lsout=$(ls -dl "$_readlink_f") 4844d4804dSStefan Eßer _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}") 4944d4804dSStefan Eßer 5044d4804dSStefan Eßer while [ -z "${_readlink_lsout##*$_readlink_arrow*}" ]; do 5144d4804dSStefan Eßer _readlink_f="$_readlink_d/$_readlink_link" 5244d4804dSStefan Eßer _readlink_d=$(dirname "$_readlink_f") 5344d4804dSStefan Eßer _readlink_lsout=$(ls -dl "$_readlink_f") 5444d4804dSStefan Eßer _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}") 5544d4804dSStefan Eßer done 5644d4804dSStefan Eßer 5744d4804dSStefan Eßer printf '%s' "${_readlink_f##*$_readlink_d/}" 5844d4804dSStefan Eßer} 5944d4804dSStefan Eßer 6044d4804dSStefan Eßer# Quick function for exiting with an error. 6144d4804dSStefan Eßer# @param 1 A message to print. 6244d4804dSStefan Eßer# @param 2 The exit code to use. 6344d4804dSStefan Eßererr_exit() { 6444d4804dSStefan Eßer 6544d4804dSStefan Eßer if [ "$#" -ne 2 ]; then 6644d4804dSStefan Eßer printf 'Invalid number of args to err_exit\n' 6744d4804dSStefan Eßer exit 1 6844d4804dSStefan Eßer fi 6944d4804dSStefan Eßer 7044d4804dSStefan Eßer printf '%s\n' "$1" 7144d4804dSStefan Eßer exit "$2" 7244d4804dSStefan Eßer} 7344d4804dSStefan Eßer 744fca8e0fSStefan Eßer# Function for checking the "d"/"dir" argument of scripts. This function expects 754fca8e0fSStefan Eßer# a usage() function to exist in the caller. 764fca8e0fSStefan Eßer# @param 1 The argument to check. 774fca8e0fSStefan Eßercheck_d_arg() { 784fca8e0fSStefan Eßer 794fca8e0fSStefan Eßer if [ "$#" -ne 1 ]; then 804fca8e0fSStefan Eßer printf 'Invalid number of args to check_d_arg\n' 814fca8e0fSStefan Eßer exit 1 824fca8e0fSStefan Eßer fi 834fca8e0fSStefan Eßer 844fca8e0fSStefan Eßer _check_d_arg_arg="$1" 854fca8e0fSStefan Eßer shift 864fca8e0fSStefan Eßer 874fca8e0fSStefan Eßer if [ "$_check_d_arg_arg" != "bc" ] && [ "$_check_d_arg_arg" != "dc" ]; then 884fca8e0fSStefan Eßer _check_d_arg_msg=$(printf 'Invalid d arg: %s\nMust be either "bc" or "dc".\n\n' \ 894fca8e0fSStefan Eßer "$_check_d_arg_arg") 904fca8e0fSStefan Eßer usage "$_check_d_arg_msg" 914fca8e0fSStefan Eßer fi 924fca8e0fSStefan Eßer} 934fca8e0fSStefan Eßer 944fca8e0fSStefan Eßer# Function for checking the boolean arguments of scripts. This function expects 954fca8e0fSStefan Eßer# a usage() function to exist in the caller. 964fca8e0fSStefan Eßer# @param 1 The argument to check. 974fca8e0fSStefan Eßercheck_bool_arg() { 984fca8e0fSStefan Eßer 994fca8e0fSStefan Eßer if [ "$#" -ne 1 ]; then 1004fca8e0fSStefan Eßer printf 'Invalid number of args to check_bool_arg\n' 1014fca8e0fSStefan Eßer exit 1 1024fca8e0fSStefan Eßer fi 1034fca8e0fSStefan Eßer 1044fca8e0fSStefan Eßer _check_bool_arg_arg="$1" 1054fca8e0fSStefan Eßer shift 1064fca8e0fSStefan Eßer 1074fca8e0fSStefan Eßer if [ "$_check_bool_arg_arg" != "0" ] && [ "$_check_bool_arg_arg" != "1" ]; then 1084fca8e0fSStefan Eßer _check_bool_arg_msg=$(printf 'Invalid bool arg: %s\nMust be either "0" or "1".\n\n' \ 1094fca8e0fSStefan Eßer "$_check_bool_arg_arg") 1104fca8e0fSStefan Eßer usage "$_check_bool_arg_msg" 1114fca8e0fSStefan Eßer fi 1124fca8e0fSStefan Eßer} 1134fca8e0fSStefan Eßer 1144fca8e0fSStefan Eßer# Function for checking the executable arguments of scripts. This function 1154fca8e0fSStefan Eßer# expects a usage() function to exist in the caller. 1164fca8e0fSStefan Eßer# @param 1 The argument to check. 1174fca8e0fSStefan Eßercheck_exec_arg() { 1184fca8e0fSStefan Eßer 1194fca8e0fSStefan Eßer if [ "$#" -ne 1 ]; then 1204fca8e0fSStefan Eßer printf 'Invalid number of args to check_exec_arg\n' 1214fca8e0fSStefan Eßer exit 1 1224fca8e0fSStefan Eßer fi 1234fca8e0fSStefan Eßer 1244fca8e0fSStefan Eßer _check_exec_arg_arg="$1" 1254fca8e0fSStefan Eßer shift 1264fca8e0fSStefan Eßer 1274fca8e0fSStefan Eßer if [ ! -x "$_check_exec_arg_arg" ]; then 1284fca8e0fSStefan Eßer if ! command -v "$_check_exec_arg_arg" >/dev/null 2>&1; then 1294fca8e0fSStefan Eßer _check_exec_arg_msg=$(printf 'Invalid exec arg: %s\nMust be an executable file.\n\n' \ 1304fca8e0fSStefan Eßer "$_check_exec_arg_arg") 1314fca8e0fSStefan Eßer usage "$_check_exec_arg_msg" 1324fca8e0fSStefan Eßer fi 1334fca8e0fSStefan Eßer fi 1344fca8e0fSStefan Eßer} 1354fca8e0fSStefan Eßer 1364fca8e0fSStefan Eßer# Function for checking the file arguments of scripts. This function expects a 1374fca8e0fSStefan Eßer# usage() function to exist in the caller. 1384fca8e0fSStefan Eßer# @param 1 The argument to check. 1394fca8e0fSStefan Eßercheck_file_arg() { 1404fca8e0fSStefan Eßer 1414fca8e0fSStefan Eßer if [ "$#" -ne 1 ]; then 1424fca8e0fSStefan Eßer printf 'Invalid number of args to check_file_arg\n' 1434fca8e0fSStefan Eßer exit 1 1444fca8e0fSStefan Eßer fi 1454fca8e0fSStefan Eßer 1464fca8e0fSStefan Eßer _check_file_arg_arg="$1" 1474fca8e0fSStefan Eßer shift 1484fca8e0fSStefan Eßer 1494fca8e0fSStefan Eßer if [ ! -f "$_check_file_arg_arg" ]; then 1504fca8e0fSStefan Eßer _check_file_arg_msg=$(printf 'Invalid file arg: %s\nMust be a file.\n\n' \ 1514fca8e0fSStefan Eßer "$_check_file_arg_arg") 1524fca8e0fSStefan Eßer usage "$_check_file_arg_msg" 1534fca8e0fSStefan Eßer fi 1544fca8e0fSStefan Eßer} 1554fca8e0fSStefan Eßer 15644d4804dSStefan Eßer# Check the return code on a test and exit with a fail if it's non-zero. 15744d4804dSStefan Eßer# @param d The calculator under test. 15844d4804dSStefan Eßer# @param err The return code. 15944d4804dSStefan Eßer# @param name The name of the test. 16044d4804dSStefan Eßerchecktest_retcode() { 16144d4804dSStefan Eßer 16244d4804dSStefan Eßer _checktest_retcode_d="$1" 16344d4804dSStefan Eßer shift 16444d4804dSStefan Eßer 16544d4804dSStefan Eßer _checktest_retcode_err="$1" 16644d4804dSStefan Eßer shift 16744d4804dSStefan Eßer 16844d4804dSStefan Eßer _checktest_retcode_name="$1" 16944d4804dSStefan Eßer shift 17044d4804dSStefan Eßer 17144d4804dSStefan Eßer if [ "$_checktest_retcode_err" -ne 0 ]; then 17244d4804dSStefan Eßer printf 'FAIL!!!\n' 17344d4804dSStefan Eßer err_exit "$_checktest_retcode_d failed test '$_checktest_retcode_name' with error code $_checktest_retcode_err" 1 17444d4804dSStefan Eßer fi 17544d4804dSStefan Eßer} 17644d4804dSStefan Eßer 17744d4804dSStefan Eßer# Check the result of a test. First, it checks the error code using 17844d4804dSStefan Eßer# checktest_retcode(). Then it checks the output against the expected output 17944d4804dSStefan Eßer# and fails if it doesn't match. 18044d4804dSStefan Eßer# @param d The calculator under test. 18144d4804dSStefan Eßer# @param err The error code. 18244d4804dSStefan Eßer# @param name The name of the test. 18344d4804dSStefan Eßer# @param test_path The path to the test. 18444d4804dSStefan Eßer# @param results_name The path to the file with the expected result. 18544d4804dSStefan Eßerchecktest() { 18644d4804dSStefan Eßer 18744d4804dSStefan Eßer _checktest_d="$1" 18844d4804dSStefan Eßer shift 18944d4804dSStefan Eßer 19044d4804dSStefan Eßer _checktest_err="$1" 19144d4804dSStefan Eßer shift 19244d4804dSStefan Eßer 19344d4804dSStefan Eßer _checktest_name="$1" 19444d4804dSStefan Eßer shift 19544d4804dSStefan Eßer 19644d4804dSStefan Eßer _checktest_test_path="$1" 19744d4804dSStefan Eßer shift 19844d4804dSStefan Eßer 19944d4804dSStefan Eßer _checktest_results_name="$1" 20044d4804dSStefan Eßer shift 20144d4804dSStefan Eßer 20244d4804dSStefan Eßer checktest_retcode "$_checktest_d" "$_checktest_err" "$_checktest_name" 20344d4804dSStefan Eßer 20444d4804dSStefan Eßer _checktest_diff=$(diff "$_checktest_test_path" "$_checktest_results_name") 20544d4804dSStefan Eßer 20644d4804dSStefan Eßer _checktest_err="$?" 20744d4804dSStefan Eßer 20844d4804dSStefan Eßer if [ "$_checktest_err" -ne 0 ]; then 20944d4804dSStefan Eßer printf 'FAIL!!!\n' 21044d4804dSStefan Eßer printf '%s\n' "$_checktest_diff" 21144d4804dSStefan Eßer err_exit "$_checktest_d failed test $_checktest_name" 1 21244d4804dSStefan Eßer fi 21344d4804dSStefan Eßer} 21444d4804dSStefan Eßer 21544d4804dSStefan Eßer# Die. With a message. 21644d4804dSStefan Eßer# @param d The calculator under test. 21744d4804dSStefan Eßer# @param msg The message to print. 21844d4804dSStefan Eßer# @param name The name of the test. 21944d4804dSStefan Eßer# @param err The return code from the test. 22044d4804dSStefan Eßerdie() { 22144d4804dSStefan Eßer 22244d4804dSStefan Eßer _die_d="$1" 22344d4804dSStefan Eßer shift 22444d4804dSStefan Eßer 22544d4804dSStefan Eßer _die_msg="$1" 22644d4804dSStefan Eßer shift 22744d4804dSStefan Eßer 22844d4804dSStefan Eßer _die_name="$1" 22944d4804dSStefan Eßer shift 23044d4804dSStefan Eßer 23144d4804dSStefan Eßer _die_err="$1" 23244d4804dSStefan Eßer shift 23344d4804dSStefan Eßer 23444d4804dSStefan Eßer _die_str=$(printf '\n%s %s on test:\n\n %s\n' "$_die_d" "$_die_msg" "$_die_name") 23544d4804dSStefan Eßer 23644d4804dSStefan Eßer err_exit "$_die_str" "$_die_err" 23744d4804dSStefan Eßer} 23844d4804dSStefan Eßer 23944d4804dSStefan Eßer# Check that a test did not crash and die if it did. 24044d4804dSStefan Eßer# @param d The calculator under test. 24144d4804dSStefan Eßer# @param error The error code. 24244d4804dSStefan Eßer# @param name The name of the test. 24344d4804dSStefan Eßercheckcrash() { 24444d4804dSStefan Eßer 24544d4804dSStefan Eßer _checkcrash_d="$1" 24644d4804dSStefan Eßer shift 24744d4804dSStefan Eßer 24844d4804dSStefan Eßer _checkcrash_error="$1" 24944d4804dSStefan Eßer shift 25044d4804dSStefan Eßer 25144d4804dSStefan Eßer _checkcrash_name="$1" 25244d4804dSStefan Eßer shift 25344d4804dSStefan Eßer 25444d4804dSStefan Eßer 25544d4804dSStefan Eßer if [ "$_checkcrash_error" -gt 127 ]; then 25644d4804dSStefan Eßer die "$_checkcrash_d" "crashed ($_checkcrash_error)" \ 25744d4804dSStefan Eßer "$_checkcrash_name" "$_checkcrash_error" 25844d4804dSStefan Eßer fi 25944d4804dSStefan Eßer} 26044d4804dSStefan Eßer 26144d4804dSStefan Eßer# Check that a test had an error or crash. 26244d4804dSStefan Eßer# @param d The calculator under test. 26344d4804dSStefan Eßer# @param error The error code. 26444d4804dSStefan Eßer# @param name The name of the test. 26544d4804dSStefan Eßer# @param out The file that the test results were output to. 26644d4804dSStefan Eßer# @param exebase The name of the executable. 26744d4804dSStefan Eßercheckerrtest() 26844d4804dSStefan Eßer{ 26944d4804dSStefan Eßer _checkerrtest_d="$1" 27044d4804dSStefan Eßer shift 27144d4804dSStefan Eßer 27244d4804dSStefan Eßer _checkerrtest_error="$1" 27344d4804dSStefan Eßer shift 27444d4804dSStefan Eßer 27544d4804dSStefan Eßer _checkerrtest_name="$1" 27644d4804dSStefan Eßer shift 27744d4804dSStefan Eßer 27844d4804dSStefan Eßer _checkerrtest_out="$1" 27944d4804dSStefan Eßer shift 28044d4804dSStefan Eßer 28144d4804dSStefan Eßer _checkerrtest_exebase="$1" 28244d4804dSStefan Eßer shift 28344d4804dSStefan Eßer 28444d4804dSStefan Eßer checkcrash "$_checkerrtest_d" "$_checkerrtest_error" "$_checkerrtest_name" 28544d4804dSStefan Eßer 28644d4804dSStefan Eßer if [ "$_checkerrtest_error" -eq 0 ]; then 28744d4804dSStefan Eßer die "$_checkerrtest_d" "returned no error" "$_checkerrtest_name" 127 28844d4804dSStefan Eßer fi 28944d4804dSStefan Eßer 29044d4804dSStefan Eßer # This is to check for memory errors with Valgrind, which is told to return 29144d4804dSStefan Eßer # 100 on memory errors. 29244d4804dSStefan Eßer if [ "$_checkerrtest_error" -eq 100 ]; then 29344d4804dSStefan Eßer 29444d4804dSStefan Eßer _checkerrtest_output=$(cat "$_checkerrtest_out") 29544d4804dSStefan Eßer _checkerrtest_fatal_error="Fatal error" 29644d4804dSStefan Eßer 29744d4804dSStefan Eßer if [ "${_checkerrtest_output##*$_checkerrtest_fatal_error*}" ]; then 29844d4804dSStefan Eßer printf "%s\n" "$_checkerrtest_output" 29944d4804dSStefan Eßer die "$_checkerrtest_d" "had memory errors on a non-fatal error" \ 30044d4804dSStefan Eßer "$_checkerrtest_name" "$_checkerrtest_error" 30144d4804dSStefan Eßer fi 30244d4804dSStefan Eßer fi 30344d4804dSStefan Eßer 30444d4804dSStefan Eßer if [ ! -s "$_checkerrtest_out" ]; then 30544d4804dSStefan Eßer die "$_checkerrtest_d" "produced no error message" "$_checkerrtest_name" "$_checkerrtest_error" 30644d4804dSStefan Eßer fi 30744d4804dSStefan Eßer 308d43fa8efSStefan Eßer # To display error messages, uncomment this line. This is useful when 309d43fa8efSStefan Eßer # debugging. 310d43fa8efSStefan Eßer #cat "$_checkerrtest_out" 31144d4804dSStefan Eßer} 31244d4804dSStefan Eßer 31344d4804dSStefan Eßer# Replace a substring in a string with another. This function is the *real* 31444d4804dSStefan Eßer# workhorse behind configure.sh's generation of a Makefile. 31544d4804dSStefan Eßer# 31644d4804dSStefan Eßer# This function uses a sed call that uses exclamation points `!` as delimiters. 31744d4804dSStefan Eßer# As a result, needle can never contain an exclamation point. Oh well. 31844d4804dSStefan Eßer# 31944d4804dSStefan Eßer# @param str The string that will have any of the needle replaced by 32044d4804dSStefan Eßer# replacement. 32144d4804dSStefan Eßer# @param needle The needle to replace in str with replacement. 32244d4804dSStefan Eßer# @param replacement The replacement for needle in str. 32344d4804dSStefan Eßersubstring_replace() { 32444d4804dSStefan Eßer 32544d4804dSStefan Eßer _substring_replace_str="$1" 32644d4804dSStefan Eßer shift 32744d4804dSStefan Eßer 32844d4804dSStefan Eßer _substring_replace_needle="$1" 32944d4804dSStefan Eßer shift 33044d4804dSStefan Eßer 33144d4804dSStefan Eßer _substring_replace_replacement="$1" 33244d4804dSStefan Eßer shift 33344d4804dSStefan Eßer 33444d4804dSStefan Eßer _substring_replace_result=$(printf '%s\n' "$_substring_replace_str" | \ 33544d4804dSStefan Eßer sed -e "s!$_substring_replace_needle!$_substring_replace_replacement!g") 33644d4804dSStefan Eßer 33744d4804dSStefan Eßer printf '%s' "$_substring_replace_result" 33844d4804dSStefan Eßer} 33944d4804dSStefan Eßer 34044d4804dSStefan Eßer# Generates an NLS path based on the locale and executable name. 34144d4804dSStefan Eßer# 34244d4804dSStefan Eßer# This is a monstrosity for a reason. 34344d4804dSStefan Eßer# 34444d4804dSStefan Eßer# @param nlspath The $NLSPATH 34544d4804dSStefan Eßer# @param locale The locale. 34644d4804dSStefan Eßer# @param execname The name of the executable. 34744d4804dSStefan Eßergen_nlspath() { 34844d4804dSStefan Eßer 34944d4804dSStefan Eßer _gen_nlspath_nlspath="$1" 35044d4804dSStefan Eßer shift 35144d4804dSStefan Eßer 35244d4804dSStefan Eßer _gen_nlspath_locale="$1" 35344d4804dSStefan Eßer shift 35444d4804dSStefan Eßer 35544d4804dSStefan Eßer _gen_nlspath_execname="$1" 35644d4804dSStefan Eßer shift 35744d4804dSStefan Eßer 35844d4804dSStefan Eßer # Split the locale into its modifier and other parts. 35944d4804dSStefan Eßer _gen_nlspath_char="@" 36044d4804dSStefan Eßer _gen_nlspath_modifier="${_gen_nlspath_locale#*$_gen_nlspath_char}" 36144d4804dSStefan Eßer _gen_nlspath_tmplocale="${_gen_nlspath_locale%%$_gen_nlspath_char*}" 36244d4804dSStefan Eßer 36344d4804dSStefan Eßer # Split the locale into charset and other parts. 36444d4804dSStefan Eßer _gen_nlspath_char="." 36544d4804dSStefan Eßer _gen_nlspath_charset="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}" 36644d4804dSStefan Eßer _gen_nlspath_tmplocale="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}" 36744d4804dSStefan Eßer 36844d4804dSStefan Eßer # Check for an empty charset. 36944d4804dSStefan Eßer if [ "$_gen_nlspath_charset" = "$_gen_nlspath_tmplocale" ]; then 37044d4804dSStefan Eßer _gen_nlspath_charset="" 37144d4804dSStefan Eßer fi 37244d4804dSStefan Eßer 37344d4804dSStefan Eßer # Split the locale into territory and language. 37444d4804dSStefan Eßer _gen_nlspath_char="_" 37544d4804dSStefan Eßer _gen_nlspath_territory="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}" 37644d4804dSStefan Eßer _gen_nlspath_language="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}" 37744d4804dSStefan Eßer 37844d4804dSStefan Eßer # Check for empty territory and language. 37944d4804dSStefan Eßer if [ "$_gen_nlspath_territory" = "$_gen_nlspath_tmplocale" ]; then 38044d4804dSStefan Eßer _gen_nlspath_territory="" 38144d4804dSStefan Eßer fi 38244d4804dSStefan Eßer 38344d4804dSStefan Eßer if [ "$_gen_nlspath_language" = "$_gen_nlspath_tmplocale" ]; then 38444d4804dSStefan Eßer _gen_nlspath_language="" 38544d4804dSStefan Eßer fi 38644d4804dSStefan Eßer 38744d4804dSStefan Eßer # Prepare to replace the format specifiers. This is done by wrapping the in 38844d4804dSStefan Eßer # pipe characters. It just makes it easier to split them later. 38944d4804dSStefan Eßer _gen_nlspath_needles="%%:%L:%N:%l:%t:%c" 39044d4804dSStefan Eßer 39144d4804dSStefan Eßer _gen_nlspath_needles=$(printf '%s' "$_gen_nlspath_needles" | tr ':' '\n') 39244d4804dSStefan Eßer 39344d4804dSStefan Eßer for _gen_nlspath_i in $_gen_nlspath_needles; do 39444d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "$_gen_nlspath_i" "|$_gen_nlspath_i|") 39544d4804dSStefan Eßer done 39644d4804dSStefan Eßer 39744d4804dSStefan Eßer # Replace all the format specifiers. 39844d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%%" "%") 39944d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%L" "$_gen_nlspath_locale") 40044d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%N" "$_gen_nlspath_execname") 40144d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%l" "$_gen_nlspath_language") 40244d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%t" "$_gen_nlspath_territory") 40344d4804dSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%c" "$_gen_nlspath_charset") 40444d4804dSStefan Eßer 40544d4804dSStefan Eßer # Get rid of pipe characters. 40644d4804dSStefan Eßer _gen_nlspath_nlspath=$(printf '%s' "$_gen_nlspath_nlspath" | tr -d '|') 40744d4804dSStefan Eßer 40844d4804dSStefan Eßer # Return the result. 40944d4804dSStefan Eßer printf '%s' "$_gen_nlspath_nlspath" 41044d4804dSStefan Eßer} 41178bc019dSStefan Eßer 41278bc019dSStefan EßerALL=0 41378bc019dSStefan EßerNOSKIP=1 41478bc019dSStefan EßerSKIP=2 41578bc019dSStefan Eßer 41678bc019dSStefan Eßer# Filters text out of a file according to the build type. 41778bc019dSStefan Eßer# @param in File to filter. 41878bc019dSStefan Eßer# @param out File to write the filtered output to. 41978bc019dSStefan Eßer# @param type Build type. 42078bc019dSStefan Eßerfilter_text() { 42178bc019dSStefan Eßer 42278bc019dSStefan Eßer _filter_text_in="$1" 42378bc019dSStefan Eßer shift 42478bc019dSStefan Eßer 42578bc019dSStefan Eßer _filter_text_out="$1" 42678bc019dSStefan Eßer shift 42778bc019dSStefan Eßer 42878bc019dSStefan Eßer _filter_text_buildtype="$1" 42978bc019dSStefan Eßer shift 43078bc019dSStefan Eßer 43178bc019dSStefan Eßer # Set up some local variables. 43278bc019dSStefan Eßer _filter_text_status="$ALL" 433f6ed05f1SStefan Eßer _filter_text_last_line="" 43478bc019dSStefan Eßer 43578bc019dSStefan Eßer # We need to set IFS, so we store it here for restoration later. 43678bc019dSStefan Eßer _filter_text_ifs="$IFS" 43778bc019dSStefan Eßer 43878bc019dSStefan Eßer # Remove the file- that will be generated. 439f6ed05f1SStefan Eßer rm -rf "$_filter_text_out" 44078bc019dSStefan Eßer 44178bc019dSStefan Eßer # Here is the magic. This loop reads the template line-by-line, and based on 44278bc019dSStefan Eßer # _filter_text_status, either prints it to the markdown manual or not. 44378bc019dSStefan Eßer # 44478bc019dSStefan Eßer # Here is how the template is set up: it is a normal markdown file except 44578bc019dSStefan Eßer # that there are sections surrounded tags that look like this: 44678bc019dSStefan Eßer # 44778bc019dSStefan Eßer # {{ <build_type_list> }} 44878bc019dSStefan Eßer # ... 44978bc019dSStefan Eßer # {{ end }} 45078bc019dSStefan Eßer # 45178bc019dSStefan Eßer # Those tags mean that whatever build types are found in the 45278bc019dSStefan Eßer # <build_type_list> get to keep that section. Otherwise, skip. 45378bc019dSStefan Eßer # 45478bc019dSStefan Eßer # Obviously, the tag itself and its end are not printed to the markdown 45578bc019dSStefan Eßer # manual. 456f6ed05f1SStefan Eßer while IFS= read -r _filter_text_line; do 45778bc019dSStefan Eßer 45878bc019dSStefan Eßer # If we have found an end, reset the status. 459f6ed05f1SStefan Eßer if [ "$_filter_text_line" = "{{ end }}" ]; then 46078bc019dSStefan Eßer 46178bc019dSStefan Eßer # Some error checking. This helps when editing the templates. 46278bc019dSStefan Eßer if [ "$_filter_text_status" -eq "$ALL" ]; then 46378bc019dSStefan Eßer err_exit "{{ end }} tag without corresponding start tag" 2 46478bc019dSStefan Eßer fi 46578bc019dSStefan Eßer 46678bc019dSStefan Eßer _filter_text_status="$ALL" 46778bc019dSStefan Eßer 46878bc019dSStefan Eßer # We have found a tag that allows our build type to use it. 469f6ed05f1SStefan Eßer elif [ "${_filter_text_line#\{\{* $_filter_text_buildtype *\}\}}" != "$_filter_text_line" ]; then 47078bc019dSStefan Eßer 47178bc019dSStefan Eßer # More error checking. We don't want tags nested. 47278bc019dSStefan Eßer if [ "$_filter_text_status" -ne "$ALL" ]; then 47378bc019dSStefan Eßer err_exit "start tag nested in start tag" 3 47478bc019dSStefan Eßer fi 47578bc019dSStefan Eßer 47678bc019dSStefan Eßer _filter_text_status="$NOSKIP" 47778bc019dSStefan Eßer 47878bc019dSStefan Eßer # We have found a tag that is *not* allowed for our build type. 479f6ed05f1SStefan Eßer elif [ "${_filter_text_line#\{\{*\}\}}" != "$_filter_text_line" ]; then 48078bc019dSStefan Eßer 48178bc019dSStefan Eßer if [ "$_filter_text_status" -ne "$ALL" ]; then 48278bc019dSStefan Eßer err_exit "start tag nested in start tag" 3 48378bc019dSStefan Eßer fi 48478bc019dSStefan Eßer 48578bc019dSStefan Eßer _filter_text_status="$SKIP" 48678bc019dSStefan Eßer 48778bc019dSStefan Eßer # This is for normal lines. If we are not skipping, print. 48878bc019dSStefan Eßer else 48978bc019dSStefan Eßer if [ "$_filter_text_status" -ne "$SKIP" ]; then 490f6ed05f1SStefan Eßer if [ "$_filter_text_line" != "$_filter_text_last_line" ]; then 491f6ed05f1SStefan Eßer printf '%s\n' "$_filter_text_line" >> "$_filter_text_out" 492f6ed05f1SStefan Eßer fi 493f6ed05f1SStefan Eßer _filter_text_last_line="$_filter_text_line" 49478bc019dSStefan Eßer fi 49578bc019dSStefan Eßer fi 49678bc019dSStefan Eßer 49778bc019dSStefan Eßer done < "$_filter_text_in" 49878bc019dSStefan Eßer 49978bc019dSStefan Eßer # Reset IFS. 50078bc019dSStefan Eßer IFS="$_filter_text_ifs" 50178bc019dSStefan Eßer} 502