| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- #!/usr/bin/env bash
- # 通用脚本工具函数(供 run_local_* 使用)
- ryanjson_init_utf8_locale() {
- # Force UTF-8 locale for script-generated files/logs when available.
- local localeValue=""
- if command -v locale >/dev/null 2>&1; then
- if locale -a 2>/dev/null | grep -qx "C.UTF-8"; then
- localeValue="C.UTF-8"
- elif locale -a 2>/dev/null | grep -qx "en_US.UTF-8"; then
- localeValue="en_US.UTF-8"
- fi
- fi
- if [[ -n "${localeValue}" ]]; then
- export LC_ALL="${localeValue}"
- export LANG="${localeValue}"
- fi
- }
- ryanjson_init_utf8_locale
- ryanjson_init_utf8_log() {
- # Initialize a UTF-8 log file (no BOM).
- local path="$1"
- mkdir -p "$(dirname "${path}")"
- : > "${path}"
- }
- ryanjson_abs_dir() {
- # 返回文件/目录的绝对路径(仅取目录部分)
- local inputPath="$1"
- (cd "$(dirname "${inputPath}")" && pwd)
- }
- ryanjson_repo_root_from_source() {
- # 从脚本路径向上回溯,拿到仓库根目录
- local sourcePath="$1"
- local levelsUp="${2:-0}"
- local currentDir=""
- currentDir="$(ryanjson_abs_dir "${sourcePath}")"
- while (( levelsUp > 0 )); do
- currentDir="$(cd "${currentDir}/.." && pwd)"
- levelsUp=$((levelsUp - 1))
- done
- printf '%s\n' "${currentDir}"
- }
- ryanjson_print_banner_begin() {
- # 统一 banner 输出(开始)
- local title="$1"
- echo "===================================================="
- echo "${title}"
- }
- ryanjson_print_banner_kv() {
- # 统一 banner 输出(KV)
- local key="$1"
- local value="$2"
- echo " - ${key}=${value}"
- }
- ryanjson_print_banner_kv_optional() {
- # 仅在值非空时输出 banner KV
- local key="$1"
- local value="$2"
- if [[ -n "${value}" ]]; then
- ryanjson_print_banner_kv "${key}" "${value}"
- fi
- }
- ryanjson_print_banner_end() {
- # 统一 banner 输出(结束)
- echo "===================================================="
- }
- ryanjson_log_phase() {
- # 阶段提示
- echo "[阶段] $*"
- }
- ryanjson_log_info() {
- # 普通信息
- echo "[信息] $*"
- }
- ryanjson_log_warn() {
- # 警告提示
- echo "[警告] $*"
- }
- ryanjson_log_error() {
- # 错误提示
- echo "[错误] $*"
- }
- ryanjson_log_done() {
- # 完成提示
- echo "[完成] $*"
- }
- ryanjson_is_nonneg_int() {
- # 非负整数判断
- [[ "$1" =~ ^[0-9]+$ ]]
- }
- ryanjson_is_positive_int() {
- # 正整数判断
- [[ "$1" =~ ^[0-9]+$ ]] && (( $1 > 0 ))
- }
- ryanjson_is_01() {
- # 0/1 开关判断
- [[ "$1" == "0" || "$1" == "1" ]]
- }
- ryanjson_require_01() {
- # 校验 0/1 开关
- local name="$1"
- local value="$2"
- if ! ryanjson_is_01 "${value}"; then
- ryanjson_log_error "${name} 仅支持 0/1,当前值:${value}"
- return 1
- fi
- }
- ryanjson_require_pos_int() {
- # 校验正整数(可选附加单位)
- local name="$1"
- local value="$2"
- local unit="${3:-}"
- if ! ryanjson_is_positive_int "${value}"; then
- if [[ -n "${unit}" ]]; then
- ryanjson_log_error "${name} 仅支持正整数(${unit}),当前值:${value}"
- else
- ryanjson_log_error "${name} 仅支持正整数,当前值:${value}"
- fi
- return 1
- fi
- }
- ryanjson_require_nonneg_int() {
- # 校验非负整数
- local name="$1"
- local value="$2"
- if ! ryanjson_is_nonneg_int "${value}"; then
- ryanjson_log_error "${name} 仅支持非负整数,当前值:${value}"
- return 1
- fi
- }
- ryanjson_require_pos_int_optional() {
- # 可选正整数校验(空值跳过)
- local name="$1"
- local value="$2"
- local unit="${3:-}"
- if [[ -n "${value}" ]]; then
- ryanjson_require_pos_int "${name}" "${value}" "${unit}"
- return $?
- fi
- return 0
- }
- ryanjson_require_nonneg_int_optional() {
- # 可选非负整数校验(空值跳过)
- local name="$1"
- local value="$2"
- if [[ -n "${value}" ]]; then
- ryanjson_require_nonneg_int "${name}" "${value}"
- return $?
- fi
- return 0
- }
- ryanjson_require_cmds() {
- # 批量检查命令依赖
- local hint="${1:-}"
- shift || true
- local missing=0
- for cmdName in "$@"; do
- if ! command -v "${cmdName}" >/dev/null 2>&1; then
- ryanjson_log_error "缺少命令: ${cmdName}"
- missing=1
- fi
- done
- if [[ "${missing}" -ne 0 && -n "${hint}" ]]; then
- ryanjson_log_info "提示: ${hint}"
- fi
- return "${missing}"
- }
- ryanjson_require_cmd() {
- # 单命令检查(复用批量版本)
- local cmdName="$1"
- local hint="${2:-}"
- ryanjson_require_cmds "${hint}" "${cmdName}"
- }
- ryanjson_prepare_clean_dir() {
- # 清理并重新创建目录
- local dirPath="$1"
- rm -rf "${dirPath}"
- mkdir -p "${dirPath}"
- }
- ryanjson_run_xmake_config() {
- # 运行 xmake 配置(支持 clean/增量)
- local forceClean="$1"
- local caseName="$2"
- if [[ "${forceClean}" == "1" ]]; then
- ryanjson_log_phase "正在执行 xmake 配置(clean 模式)..."
- if ! xmake f -c; then
- ryanjson_log_error "xmake 配置失败:${caseName}"
- return 1
- fi
- else
- ryanjson_log_phase "正在执行 xmake 配置(增量模式)..."
- if ! xmake f; then
- ryanjson_log_error "xmake 配置失败:${caseName}"
- return 1
- fi
- fi
- }
- ryanjson_run_xmake_build() {
- # 运行 xmake 构建
- local targetName="$1"
- local caseName="$2"
- ryanjson_log_phase "正在执行 xmake 构建(target=${targetName})..."
- if ! xmake -b "${targetName}"; then
- ryanjson_log_error "xmake 构建失败:${caseName}"
- return 1
- fi
- }
- ryanjson_export_semantic_macros() {
- # 统一导出语义宏(strict/addAtHead/scientific)
- local strictKey="$1"
- local addAtHead="$2"
- local scientific="$3"
- export RYANJSON_STRICT_OBJECT_KEY_CHECK="${strictKey}"
- export RYANJSON_DEFAULT_ADD_AT_HEAD="${addAtHead}"
- export RYANJSON_SNPRINTF_SUPPORT_SCIENTIFIC="${scientific}"
- }
- ryanjson_print_semantic_kv() {
- # 统一输出语义宏 KV(配合 banner 使用)
- local strictKey="$1"
- local addAtHead="$2"
- local scientific="$3"
- ryanjson_print_banner_kv "RyanJsonStrictObjectKeyCheck" "${strictKey}"
- ryanjson_print_banner_kv "RyanJsonDefaultAddAtHead" "${addAtHead}"
- ryanjson_print_banner_kv "RyanJsonSnprintfSupportScientific" "${scientific}"
- }
- ryanjson_semantic_log_error() {
- # 语义矩阵输出错误提示
- ryanjson_log_error "$@"
- }
- ryanjson_emit_semantic_cases() {
- # 根据模式输出三元组:strictKey addAtHead scientific
- local mode="$1"
- local modeName="${2:-MODE}"
- case "${mode}" in
- quick)
- printf '%s\n' 'false true true' 'true false true'
- ;;
- nightly)
- local strictKey=""
- local addAtHead=""
- for strictKey in false true; do
- for addAtHead in false true; do
- printf '%s %s true\n' "${strictKey}" "${addAtHead}"
- done
- done
- ;;
- full)
- local strictKey=""
- local addAtHead=""
- local scientific=""
- for strictKey in false true; do
- for addAtHead in false true; do
- for scientific in false true; do
- printf '%s %s %s\n' "${strictKey}" "${addAtHead}" "${scientific}"
- done
- done
- done
- ;;
- *)
- ryanjson_semantic_log_error "${modeName} 仅支持 quick/nightly/full,当前值:${mode}"
- return 1
- ;;
- esac
- }
- ryanjson_semantic_case_name() {
- # 生成可读的用例名称
- local strictKey="$1"
- local addAtHead="$2"
- local scientific="$3"
- printf 'strict_%s__head_%s__sci_%s\n' "${strictKey}" "${addAtHead}" "${scientific}"
- }
|