11f958cfaSStefan Eßer#! /bin/sh 21f958cfaSStefan Eßer# 33960d892SStefan Eßer# SPDX-License-Identifier: BSD-2-Clause 41f958cfaSStefan Eßer# 5682da5a0SStefan Eßer# Copyright (c) 2018-2025 Gavin D. Howard and contributors. 61f958cfaSStefan Eßer# 71f958cfaSStefan Eßer# Redistribution and use in source and binary forms, with or without 81f958cfaSStefan Eßer# modification, are permitted provided that the following conditions are met: 91f958cfaSStefan Eßer# 101f958cfaSStefan Eßer# * Redistributions of source code must retain the above copyright notice, this 111f958cfaSStefan Eßer# list of conditions and the following disclaimer. 121f958cfaSStefan Eßer# 131f958cfaSStefan Eßer# * Redistributions in binary form must reproduce the above copyright notice, 141f958cfaSStefan Eßer# this list of conditions and the following disclaimer in the documentation 151f958cfaSStefan Eßer# and/or other materials provided with the distribution. 161f958cfaSStefan Eßer# 171f958cfaSStefan Eßer# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 181f958cfaSStefan Eßer# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191f958cfaSStefan Eßer# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201f958cfaSStefan Eßer# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 211f958cfaSStefan Eßer# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 221f958cfaSStefan Eßer# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 231f958cfaSStefan Eßer# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 241f958cfaSStefan Eßer# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 251f958cfaSStefan Eßer# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 261f958cfaSStefan Eßer# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 271f958cfaSStefan Eßer# POSSIBILITY OF SUCH DAMAGE. 281f958cfaSStefan Eßer# 291f958cfaSStefan Eßer 302f57ecaeSStefan Eßer# This script is NOT meant to be run! It is meant to be sourced by other 312f57ecaeSStefan Eßer# scripts. 322f57ecaeSStefan Eßer 332f57ecaeSStefan Eßer# Reads and follows a link until it finds a real file. This is here because the 342f57ecaeSStefan Eßer# readlink utility is not part of the POSIX standard. Sigh... 352f57ecaeSStefan Eßer# @param f The link to find the original file for. 361f958cfaSStefan Eßerreadlink() { 371f958cfaSStefan Eßer 381f958cfaSStefan Eßer _readlink_f="$1" 391f958cfaSStefan Eßer shift 401f958cfaSStefan Eßer 411f958cfaSStefan Eßer _readlink_arrow="-> " 421f958cfaSStefan Eßer _readlink_d=$(dirname "$_readlink_f") 431f958cfaSStefan Eßer 441f958cfaSStefan Eßer _readlink_lsout="" 451f958cfaSStefan Eßer _readlink_link="" 461f958cfaSStefan Eßer 471f958cfaSStefan Eßer _readlink_lsout=$(ls -dl "$_readlink_f") 481f958cfaSStefan Eßer _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}") 491f958cfaSStefan Eßer 501f958cfaSStefan Eßer while [ -z "${_readlink_lsout##*$_readlink_arrow*}" ]; do 511f958cfaSStefan Eßer _readlink_f="$_readlink_d/$_readlink_link" 521f958cfaSStefan Eßer _readlink_d=$(dirname "$_readlink_f") 531f958cfaSStefan Eßer _readlink_lsout=$(ls -dl "$_readlink_f") 541f958cfaSStefan Eßer _readlink_link=$(printf '%s' "${_readlink_lsout#*$_readlink_arrow}") 551f958cfaSStefan Eßer done 561f958cfaSStefan Eßer 571f958cfaSStefan Eßer printf '%s' "${_readlink_f##*$_readlink_d/}" 581f958cfaSStefan Eßer} 591f958cfaSStefan Eßer 602f57ecaeSStefan Eßer# Quick function for exiting with an error. 612f57ecaeSStefan Eßer# @param 1 A message to print. 622f57ecaeSStefan Eßer# @param 2 The exit code to use. 631f958cfaSStefan Eßererr_exit() { 641f958cfaSStefan Eßer 651f958cfaSStefan Eßer if [ "$#" -ne 2 ]; then 661f958cfaSStefan Eßer printf 'Invalid number of args to err_exit\n' 671f958cfaSStefan Eßer exit 1 681f958cfaSStefan Eßer fi 691f958cfaSStefan Eßer 701f958cfaSStefan Eßer printf '%s\n' "$1" 711f958cfaSStefan Eßer exit "$2" 721f958cfaSStefan Eßer} 731f958cfaSStefan Eßer 74aaf1213cSStefan Eßer# Function for checking the "d"/"dir" argument of scripts. This function expects 75aaf1213cSStefan Eßer# a usage() function to exist in the caller. 76aaf1213cSStefan Eßer# @param 1 The argument to check. 77aaf1213cSStefan Eßercheck_d_arg() { 78aaf1213cSStefan Eßer 79aaf1213cSStefan Eßer if [ "$#" -ne 1 ]; then 80aaf1213cSStefan Eßer printf 'Invalid number of args to check_d_arg\n' 81aaf1213cSStefan Eßer exit 1 82aaf1213cSStefan Eßer fi 83aaf1213cSStefan Eßer 84aaf1213cSStefan Eßer _check_d_arg_arg="$1" 85aaf1213cSStefan Eßer shift 86aaf1213cSStefan Eßer 87aaf1213cSStefan Eßer if [ "$_check_d_arg_arg" != "bc" ] && [ "$_check_d_arg_arg" != "dc" ]; then 88aaf1213cSStefan Eßer _check_d_arg_msg=$(printf 'Invalid d arg: %s\nMust be either "bc" or "dc".\n\n' \ 89aaf1213cSStefan Eßer "$_check_d_arg_arg") 90aaf1213cSStefan Eßer usage "$_check_d_arg_msg" 91aaf1213cSStefan Eßer fi 92aaf1213cSStefan Eßer} 93aaf1213cSStefan Eßer 94aaf1213cSStefan Eßer# Function for checking the boolean arguments of scripts. This function expects 95aaf1213cSStefan Eßer# a usage() function to exist in the caller. 96aaf1213cSStefan Eßer# @param 1 The argument to check. 97aaf1213cSStefan Eßercheck_bool_arg() { 98aaf1213cSStefan Eßer 99aaf1213cSStefan Eßer if [ "$#" -ne 1 ]; then 100aaf1213cSStefan Eßer printf 'Invalid number of args to check_bool_arg\n' 101aaf1213cSStefan Eßer exit 1 102aaf1213cSStefan Eßer fi 103aaf1213cSStefan Eßer 104aaf1213cSStefan Eßer _check_bool_arg_arg="$1" 105aaf1213cSStefan Eßer shift 106aaf1213cSStefan Eßer 107aaf1213cSStefan Eßer if [ "$_check_bool_arg_arg" != "0" ] && [ "$_check_bool_arg_arg" != "1" ]; then 108aaf1213cSStefan Eßer _check_bool_arg_msg=$(printf 'Invalid bool arg: %s\nMust be either "0" or "1".\n\n' \ 109aaf1213cSStefan Eßer "$_check_bool_arg_arg") 110aaf1213cSStefan Eßer usage "$_check_bool_arg_msg" 111aaf1213cSStefan Eßer fi 112aaf1213cSStefan Eßer} 113aaf1213cSStefan Eßer 114aaf1213cSStefan Eßer# Function for checking the executable arguments of scripts. This function 115aaf1213cSStefan Eßer# expects a usage() function to exist in the caller. 116aaf1213cSStefan Eßer# @param 1 The argument to check. 117aaf1213cSStefan Eßercheck_exec_arg() { 118aaf1213cSStefan Eßer 119aaf1213cSStefan Eßer if [ "$#" -ne 1 ]; then 120aaf1213cSStefan Eßer printf 'Invalid number of args to check_exec_arg\n' 121aaf1213cSStefan Eßer exit 1 122aaf1213cSStefan Eßer fi 123aaf1213cSStefan Eßer 124aaf1213cSStefan Eßer _check_exec_arg_arg="$1" 125aaf1213cSStefan Eßer shift 126aaf1213cSStefan Eßer 127aaf1213cSStefan Eßer if [ ! -x "$_check_exec_arg_arg" ]; then 128aaf1213cSStefan Eßer if ! command -v "$_check_exec_arg_arg" >/dev/null 2>&1; then 129aaf1213cSStefan Eßer _check_exec_arg_msg=$(printf 'Invalid exec arg: %s\nMust be an executable file.\n\n' \ 130aaf1213cSStefan Eßer "$_check_exec_arg_arg") 131aaf1213cSStefan Eßer usage "$_check_exec_arg_msg" 132aaf1213cSStefan Eßer fi 133aaf1213cSStefan Eßer fi 134aaf1213cSStefan Eßer} 135aaf1213cSStefan Eßer 136aaf1213cSStefan Eßer# Function for checking the file arguments of scripts. This function expects a 137aaf1213cSStefan Eßer# usage() function to exist in the caller. 138aaf1213cSStefan Eßer# @param 1 The argument to check. 139aaf1213cSStefan Eßercheck_file_arg() { 140aaf1213cSStefan Eßer 141aaf1213cSStefan Eßer if [ "$#" -ne 1 ]; then 142aaf1213cSStefan Eßer printf 'Invalid number of args to check_file_arg\n' 143aaf1213cSStefan Eßer exit 1 144aaf1213cSStefan Eßer fi 145aaf1213cSStefan Eßer 146aaf1213cSStefan Eßer _check_file_arg_arg="$1" 147aaf1213cSStefan Eßer shift 148aaf1213cSStefan Eßer 149aaf1213cSStefan Eßer if [ ! -f "$_check_file_arg_arg" ]; then 150aaf1213cSStefan Eßer _check_file_arg_msg=$(printf 'Invalid file arg: %s\nMust be a file.\n\n' \ 151aaf1213cSStefan Eßer "$_check_file_arg_arg") 152aaf1213cSStefan Eßer usage "$_check_file_arg_msg" 153aaf1213cSStefan Eßer fi 154aaf1213cSStefan Eßer} 155aaf1213cSStefan Eßer 1562f57ecaeSStefan Eßer# Check the return code on a test and exit with a fail if it's non-zero. 1572f57ecaeSStefan Eßer# @param d The calculator under test. 1582f57ecaeSStefan Eßer# @param err The return code. 1592f57ecaeSStefan Eßer# @param name The name of the test. 16047a52dc4SStefan Eßerchecktest_retcode() { 16147a52dc4SStefan Eßer 16247a52dc4SStefan Eßer _checktest_retcode_d="$1" 16347a52dc4SStefan Eßer shift 16447a52dc4SStefan Eßer 16547a52dc4SStefan Eßer _checktest_retcode_err="$1" 16647a52dc4SStefan Eßer shift 16747a52dc4SStefan Eßer 16847a52dc4SStefan Eßer _checktest_retcode_name="$1" 16947a52dc4SStefan Eßer shift 17047a52dc4SStefan Eßer 17147a52dc4SStefan Eßer if [ "$_checktest_retcode_err" -ne 0 ]; then 17247a52dc4SStefan Eßer printf 'FAIL!!!\n' 17347a52dc4SStefan Eßer err_exit "$_checktest_retcode_d failed test '$_checktest_retcode_name' with error code $_checktest_retcode_err" 1 17447a52dc4SStefan Eßer fi 17547a52dc4SStefan Eßer} 17647a52dc4SStefan Eßer 1772f57ecaeSStefan Eßer# Check the result of a test. First, it checks the error code using 1782f57ecaeSStefan Eßer# checktest_retcode(). Then it checks the output against the expected output 1792f57ecaeSStefan Eßer# and fails if it doesn't match. 1802f57ecaeSStefan Eßer# @param d The calculator under test. 1812f57ecaeSStefan Eßer# @param err The error code. 1822f57ecaeSStefan Eßer# @param name The name of the test. 1832f57ecaeSStefan Eßer# @param test_path The path to the test. 1842f57ecaeSStefan Eßer# @param results_name The path to the file with the expected result. 18547a52dc4SStefan Eßerchecktest() { 18647a52dc4SStefan Eßer 18747a52dc4SStefan Eßer _checktest_d="$1" 18847a52dc4SStefan Eßer shift 18947a52dc4SStefan Eßer 19047a52dc4SStefan Eßer _checktest_err="$1" 19147a52dc4SStefan Eßer shift 19247a52dc4SStefan Eßer 19347a52dc4SStefan Eßer _checktest_name="$1" 19447a52dc4SStefan Eßer shift 19547a52dc4SStefan Eßer 19647a52dc4SStefan Eßer _checktest_test_path="$1" 19747a52dc4SStefan Eßer shift 19847a52dc4SStefan Eßer 19947a52dc4SStefan Eßer _checktest_results_name="$1" 20047a52dc4SStefan Eßer shift 20147a52dc4SStefan Eßer 20247a52dc4SStefan Eßer checktest_retcode "$_checktest_d" "$_checktest_err" "$_checktest_name" 20347a52dc4SStefan Eßer 20447a52dc4SStefan Eßer _checktest_diff=$(diff "$_checktest_test_path" "$_checktest_results_name") 20547a52dc4SStefan Eßer 20647a52dc4SStefan Eßer _checktest_err="$?" 20747a52dc4SStefan Eßer 20847a52dc4SStefan Eßer if [ "$_checktest_err" -ne 0 ]; then 20947a52dc4SStefan Eßer printf 'FAIL!!!\n' 21047a52dc4SStefan Eßer printf '%s\n' "$_checktest_diff" 21147a52dc4SStefan Eßer err_exit "$_checktest_d failed test $_checktest_name" 1 21247a52dc4SStefan Eßer fi 21347a52dc4SStefan Eßer} 21447a52dc4SStefan Eßer 2152f57ecaeSStefan Eßer# Die. With a message. 2162f57ecaeSStefan Eßer# @param d The calculator under test. 2172f57ecaeSStefan Eßer# @param msg The message to print. 2182f57ecaeSStefan Eßer# @param name The name of the test. 2192f57ecaeSStefan Eßer# @param err The return code from the test. 2201f958cfaSStefan Eßerdie() { 2211f958cfaSStefan Eßer 2221f958cfaSStefan Eßer _die_d="$1" 2231f958cfaSStefan Eßer shift 2241f958cfaSStefan Eßer 2251f958cfaSStefan Eßer _die_msg="$1" 2261f958cfaSStefan Eßer shift 2271f958cfaSStefan Eßer 2281f958cfaSStefan Eßer _die_name="$1" 2291f958cfaSStefan Eßer shift 2301f958cfaSStefan Eßer 2311f958cfaSStefan Eßer _die_err="$1" 2321f958cfaSStefan Eßer shift 2331f958cfaSStefan Eßer 2341f958cfaSStefan Eßer _die_str=$(printf '\n%s %s on test:\n\n %s\n' "$_die_d" "$_die_msg" "$_die_name") 2351f958cfaSStefan Eßer 2361f958cfaSStefan Eßer err_exit "$_die_str" "$_die_err" 2371f958cfaSStefan Eßer} 2381f958cfaSStefan Eßer 2392f57ecaeSStefan Eßer# Check that a test did not crash and die if it did. 2402f57ecaeSStefan Eßer# @param d The calculator under test. 2412f57ecaeSStefan Eßer# @param error The error code. 2422f57ecaeSStefan Eßer# @param name The name of the test. 2431f958cfaSStefan Eßercheckcrash() { 2441f958cfaSStefan Eßer 2451f958cfaSStefan Eßer _checkcrash_d="$1" 2461f958cfaSStefan Eßer shift 2471f958cfaSStefan Eßer 2481f958cfaSStefan Eßer _checkcrash_error="$1" 2491f958cfaSStefan Eßer shift 2501f958cfaSStefan Eßer 2511f958cfaSStefan Eßer _checkcrash_name="$1" 2521f958cfaSStefan Eßer shift 2531f958cfaSStefan Eßer 2542f57ecaeSStefan Eßer 2551f958cfaSStefan Eßer if [ "$_checkcrash_error" -gt 127 ]; then 2561f958cfaSStefan Eßer die "$_checkcrash_d" "crashed ($_checkcrash_error)" \ 2571f958cfaSStefan Eßer "$_checkcrash_name" "$_checkcrash_error" 2581f958cfaSStefan Eßer fi 2591f958cfaSStefan Eßer} 2601f958cfaSStefan Eßer 2612f57ecaeSStefan Eßer# Check that a test had an error or crash. 2622f57ecaeSStefan Eßer# @param d The calculator under test. 2632f57ecaeSStefan Eßer# @param error The error code. 2642f57ecaeSStefan Eßer# @param name The name of the test. 2652f57ecaeSStefan Eßer# @param out The file that the test results were output to. 2662f57ecaeSStefan Eßer# @param exebase The name of the executable. 26747a52dc4SStefan Eßercheckerrtest() 2681f958cfaSStefan Eßer{ 26947a52dc4SStefan Eßer _checkerrtest_d="$1" 2701f958cfaSStefan Eßer shift 2711f958cfaSStefan Eßer 27247a52dc4SStefan Eßer _checkerrtest_error="$1" 2731f958cfaSStefan Eßer shift 2741f958cfaSStefan Eßer 27547a52dc4SStefan Eßer _checkerrtest_name="$1" 2761f958cfaSStefan Eßer shift 2771f958cfaSStefan Eßer 27847a52dc4SStefan Eßer _checkerrtest_out="$1" 2791f958cfaSStefan Eßer shift 2801f958cfaSStefan Eßer 28147a52dc4SStefan Eßer _checkerrtest_exebase="$1" 2821f958cfaSStefan Eßer shift 2831f958cfaSStefan Eßer 28447a52dc4SStefan Eßer checkcrash "$_checkerrtest_d" "$_checkerrtest_error" "$_checkerrtest_name" 2851f958cfaSStefan Eßer 28647a52dc4SStefan Eßer if [ "$_checkerrtest_error" -eq 0 ]; then 28747a52dc4SStefan Eßer die "$_checkerrtest_d" "returned no error" "$_checkerrtest_name" 127 2881f958cfaSStefan Eßer fi 2891f958cfaSStefan Eßer 2902f57ecaeSStefan Eßer # This is to check for memory errors with Valgrind, which is told to return 2912f57ecaeSStefan Eßer # 100 on memory errors. 29247a52dc4SStefan Eßer if [ "$_checkerrtest_error" -eq 100 ]; then 2931f958cfaSStefan Eßer 29447a52dc4SStefan Eßer _checkerrtest_output=$(cat "$_checkerrtest_out") 29547a52dc4SStefan Eßer _checkerrtest_fatal_error="Fatal error" 2961f958cfaSStefan Eßer 29747a52dc4SStefan Eßer if [ "${_checkerrtest_output##*$_checkerrtest_fatal_error*}" ]; then 29847a52dc4SStefan Eßer printf "%s\n" "$_checkerrtest_output" 29947a52dc4SStefan Eßer die "$_checkerrtest_d" "had memory errors on a non-fatal error" \ 30047a52dc4SStefan Eßer "$_checkerrtest_name" "$_checkerrtest_error" 3011f958cfaSStefan Eßer fi 3021f958cfaSStefan Eßer fi 3031f958cfaSStefan Eßer 30447a52dc4SStefan Eßer if [ ! -s "$_checkerrtest_out" ]; then 30547a52dc4SStefan Eßer die "$_checkerrtest_d" "produced no error message" "$_checkerrtest_name" "$_checkerrtest_error" 3061f958cfaSStefan Eßer fi 3071f958cfaSStefan Eßer 3085d58a515SStefan Eßer # To display error messages, uncomment this line. This is useful when 3095d58a515SStefan Eßer # debugging. 3105d58a515SStefan Eßer #cat "$_checkerrtest_out" 3111f958cfaSStefan Eßer} 3121f958cfaSStefan Eßer 3132f57ecaeSStefan Eßer# Replace a substring in a string with another. This function is the *real* 3142f57ecaeSStefan Eßer# workhorse behind configure.sh's generation of a Makefile. 3152f57ecaeSStefan Eßer# 3162f57ecaeSStefan Eßer# This function uses a sed call that uses exclamation points `!` as delimiters. 3172f57ecaeSStefan Eßer# As a result, needle can never contain an exclamation point. Oh well. 3182f57ecaeSStefan Eßer# 3192f57ecaeSStefan Eßer# @param str The string that will have any of the needle replaced by 3202f57ecaeSStefan Eßer# replacement. 3212f57ecaeSStefan Eßer# @param needle The needle to replace in str with replacement. 3222f57ecaeSStefan Eßer# @param replacement The replacement for needle in str. 3231f958cfaSStefan Eßersubstring_replace() { 3241f958cfaSStefan Eßer 3251f958cfaSStefan Eßer _substring_replace_str="$1" 3261f958cfaSStefan Eßer shift 3271f958cfaSStefan Eßer 3281f958cfaSStefan Eßer _substring_replace_needle="$1" 3291f958cfaSStefan Eßer shift 3301f958cfaSStefan Eßer 3311f958cfaSStefan Eßer _substring_replace_replacement="$1" 3321f958cfaSStefan Eßer shift 3331f958cfaSStefan Eßer 3341f958cfaSStefan Eßer _substring_replace_result=$(printf '%s\n' "$_substring_replace_str" | \ 3351f958cfaSStefan Eßer sed -e "s!$_substring_replace_needle!$_substring_replace_replacement!g") 3361f958cfaSStefan Eßer 3371f958cfaSStefan Eßer printf '%s' "$_substring_replace_result" 3381f958cfaSStefan Eßer} 3391f958cfaSStefan Eßer 3402f57ecaeSStefan Eßer# Generates an NLS path based on the locale and executable name. 3412f57ecaeSStefan Eßer# 3422f57ecaeSStefan Eßer# This is a monstrosity for a reason. 3432f57ecaeSStefan Eßer# 3442f57ecaeSStefan Eßer# @param nlspath The $NLSPATH 3452f57ecaeSStefan Eßer# @param locale The locale. 3462f57ecaeSStefan Eßer# @param execname The name of the executable. 3471f958cfaSStefan Eßergen_nlspath() { 3481f958cfaSStefan Eßer 3491f958cfaSStefan Eßer _gen_nlspath_nlspath="$1" 3501f958cfaSStefan Eßer shift 3511f958cfaSStefan Eßer 3521f958cfaSStefan Eßer _gen_nlspath_locale="$1" 3531f958cfaSStefan Eßer shift 3541f958cfaSStefan Eßer 3551f958cfaSStefan Eßer _gen_nlspath_execname="$1" 3561f958cfaSStefan Eßer shift 3571f958cfaSStefan Eßer 3582f57ecaeSStefan Eßer # Split the locale into its modifier and other parts. 3591f958cfaSStefan Eßer _gen_nlspath_char="@" 3601f958cfaSStefan Eßer _gen_nlspath_modifier="${_gen_nlspath_locale#*$_gen_nlspath_char}" 3611f958cfaSStefan Eßer _gen_nlspath_tmplocale="${_gen_nlspath_locale%%$_gen_nlspath_char*}" 3621f958cfaSStefan Eßer 3632f57ecaeSStefan Eßer # Split the locale into charset and other parts. 3641f958cfaSStefan Eßer _gen_nlspath_char="." 3651f958cfaSStefan Eßer _gen_nlspath_charset="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}" 3661f958cfaSStefan Eßer _gen_nlspath_tmplocale="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}" 3671f958cfaSStefan Eßer 3682f57ecaeSStefan Eßer # Check for an empty charset. 3691f958cfaSStefan Eßer if [ "$_gen_nlspath_charset" = "$_gen_nlspath_tmplocale" ]; then 3701f958cfaSStefan Eßer _gen_nlspath_charset="" 3711f958cfaSStefan Eßer fi 3721f958cfaSStefan Eßer 3732f57ecaeSStefan Eßer # Split the locale into territory and language. 3741f958cfaSStefan Eßer _gen_nlspath_char="_" 3751f958cfaSStefan Eßer _gen_nlspath_territory="${_gen_nlspath_tmplocale#*$_gen_nlspath_char}" 3761f958cfaSStefan Eßer _gen_nlspath_language="${_gen_nlspath_tmplocale%%$_gen_nlspath_char*}" 3771f958cfaSStefan Eßer 3782f57ecaeSStefan Eßer # Check for empty territory and language. 3791f958cfaSStefan Eßer if [ "$_gen_nlspath_territory" = "$_gen_nlspath_tmplocale" ]; then 3801f958cfaSStefan Eßer _gen_nlspath_territory="" 3811f958cfaSStefan Eßer fi 3821f958cfaSStefan Eßer 3831f958cfaSStefan Eßer if [ "$_gen_nlspath_language" = "$_gen_nlspath_tmplocale" ]; then 3841f958cfaSStefan Eßer _gen_nlspath_language="" 3851f958cfaSStefan Eßer fi 3861f958cfaSStefan Eßer 3872f57ecaeSStefan Eßer # Prepare to replace the format specifiers. This is done by wrapping the in 3882f57ecaeSStefan Eßer # pipe characters. It just makes it easier to split them later. 3891f958cfaSStefan Eßer _gen_nlspath_needles="%%:%L:%N:%l:%t:%c" 3901f958cfaSStefan Eßer 3911f958cfaSStefan Eßer _gen_nlspath_needles=$(printf '%s' "$_gen_nlspath_needles" | tr ':' '\n') 3921f958cfaSStefan Eßer 3931f958cfaSStefan Eßer for _gen_nlspath_i in $_gen_nlspath_needles; do 3941f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "$_gen_nlspath_i" "|$_gen_nlspath_i|") 3951f958cfaSStefan Eßer done 3961f958cfaSStefan Eßer 3972f57ecaeSStefan Eßer # Replace all the format specifiers. 3981f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%%" "%") 3991f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%L" "$_gen_nlspath_locale") 4001f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%N" "$_gen_nlspath_execname") 4011f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%l" "$_gen_nlspath_language") 4021f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%t" "$_gen_nlspath_territory") 4031f958cfaSStefan Eßer _gen_nlspath_nlspath=$(substring_replace "$_gen_nlspath_nlspath" "%c" "$_gen_nlspath_charset") 4041f958cfaSStefan Eßer 4052f57ecaeSStefan Eßer # Get rid of pipe characters. 4061f958cfaSStefan Eßer _gen_nlspath_nlspath=$(printf '%s' "$_gen_nlspath_nlspath" | tr -d '|') 4071f958cfaSStefan Eßer 4082f57ecaeSStefan Eßer # Return the result. 4091f958cfaSStefan Eßer printf '%s' "$_gen_nlspath_nlspath" 4101f958cfaSStefan Eßer} 4115bdd6265SStefan Eßer 4125bdd6265SStefan EßerALL=0 4135bdd6265SStefan EßerNOSKIP=1 4145bdd6265SStefan EßerSKIP=2 4155bdd6265SStefan Eßer 4165bdd6265SStefan Eßer# Filters text out of a file according to the build type. 4175bdd6265SStefan Eßer# @param in File to filter. 4185bdd6265SStefan Eßer# @param out File to write the filtered output to. 4195bdd6265SStefan Eßer# @param type Build type. 4205bdd6265SStefan Eßerfilter_text() { 4215bdd6265SStefan Eßer 4225bdd6265SStefan Eßer _filter_text_in="$1" 4235bdd6265SStefan Eßer shift 4245bdd6265SStefan Eßer 4255bdd6265SStefan Eßer _filter_text_out="$1" 4265bdd6265SStefan Eßer shift 4275bdd6265SStefan Eßer 4285bdd6265SStefan Eßer _filter_text_buildtype="$1" 4295bdd6265SStefan Eßer shift 4305bdd6265SStefan Eßer 4315bdd6265SStefan Eßer # Set up some local variables. 4325bdd6265SStefan Eßer _filter_text_status="$ALL" 4331576f667SStefan Eßer _filter_text_last_line="" 4345bdd6265SStefan Eßer 4355bdd6265SStefan Eßer # We need to set IFS, so we store it here for restoration later. 4365bdd6265SStefan Eßer _filter_text_ifs="$IFS" 4375bdd6265SStefan Eßer 4385bdd6265SStefan Eßer # Remove the file- that will be generated. 4391576f667SStefan Eßer rm -rf "$_filter_text_out" 4405bdd6265SStefan Eßer 4415bdd6265SStefan Eßer # Here is the magic. This loop reads the template line-by-line, and based on 4425bdd6265SStefan Eßer # _filter_text_status, either prints it to the markdown manual or not. 4435bdd6265SStefan Eßer # 4445bdd6265SStefan Eßer # Here is how the template is set up: it is a normal markdown file except 4455bdd6265SStefan Eßer # that there are sections surrounded tags that look like this: 4465bdd6265SStefan Eßer # 4475bdd6265SStefan Eßer # {{ <build_type_list> }} 4485bdd6265SStefan Eßer # ... 4495bdd6265SStefan Eßer # {{ end }} 4505bdd6265SStefan Eßer # 4515bdd6265SStefan Eßer # Those tags mean that whatever build types are found in the 4525bdd6265SStefan Eßer # <build_type_list> get to keep that section. Otherwise, skip. 4535bdd6265SStefan Eßer # 4545bdd6265SStefan Eßer # Obviously, the tag itself and its end are not printed to the markdown 4555bdd6265SStefan Eßer # manual. 4561576f667SStefan Eßer while IFS= read -r _filter_text_line; do 4575bdd6265SStefan Eßer 4585bdd6265SStefan Eßer # If we have found an end, reset the status. 4591576f667SStefan Eßer if [ "$_filter_text_line" = "{{ end }}" ]; then 4605bdd6265SStefan Eßer 4615bdd6265SStefan Eßer # Some error checking. This helps when editing the templates. 4625bdd6265SStefan Eßer if [ "$_filter_text_status" -eq "$ALL" ]; then 4635bdd6265SStefan Eßer err_exit "{{ end }} tag without corresponding start tag" 2 4645bdd6265SStefan Eßer fi 4655bdd6265SStefan Eßer 4665bdd6265SStefan Eßer _filter_text_status="$ALL" 4675bdd6265SStefan Eßer 4685bdd6265SStefan Eßer # We have found a tag that allows our build type to use it. 4691576f667SStefan Eßer elif [ "${_filter_text_line#\{\{* $_filter_text_buildtype *\}\}}" != "$_filter_text_line" ]; then 4705bdd6265SStefan Eßer 4715bdd6265SStefan Eßer # More error checking. We don't want tags nested. 4725bdd6265SStefan Eßer if [ "$_filter_text_status" -ne "$ALL" ]; then 4735bdd6265SStefan Eßer err_exit "start tag nested in start tag" 3 4745bdd6265SStefan Eßer fi 4755bdd6265SStefan Eßer 4765bdd6265SStefan Eßer _filter_text_status="$NOSKIP" 4775bdd6265SStefan Eßer 4785bdd6265SStefan Eßer # We have found a tag that is *not* allowed for our build type. 4791576f667SStefan Eßer elif [ "${_filter_text_line#\{\{*\}\}}" != "$_filter_text_line" ]; then 4805bdd6265SStefan Eßer 4815bdd6265SStefan Eßer if [ "$_filter_text_status" -ne "$ALL" ]; then 4825bdd6265SStefan Eßer err_exit "start tag nested in start tag" 3 4835bdd6265SStefan Eßer fi 4845bdd6265SStefan Eßer 4855bdd6265SStefan Eßer _filter_text_status="$SKIP" 4865bdd6265SStefan Eßer 4875bdd6265SStefan Eßer # This is for normal lines. If we are not skipping, print. 4885bdd6265SStefan Eßer else 4895bdd6265SStefan Eßer if [ "$_filter_text_status" -ne "$SKIP" ]; then 4901576f667SStefan Eßer if [ "$_filter_text_line" != "$_filter_text_last_line" ]; then 4911576f667SStefan Eßer printf '%s\n' "$_filter_text_line" >> "$_filter_text_out" 4921576f667SStefan Eßer fi 4931576f667SStefan Eßer _filter_text_last_line="$_filter_text_line" 4945bdd6265SStefan Eßer fi 4955bdd6265SStefan Eßer fi 4965bdd6265SStefan Eßer 4975bdd6265SStefan Eßer done < "$_filter_text_in" 4985bdd6265SStefan Eßer 4995bdd6265SStefan Eßer # Reset IFS. 5005bdd6265SStefan Eßer IFS="$_filter_text_ifs" 5015bdd6265SStefan Eßer} 502