2929[[ -n " ${_PKG_LIB_LOADED:- } " ]] && return 0 2> /dev/null
3030_PKG_LIB_LOADED=1
3131# shellcheck disable=SC2034 # version checked by consumers
32- PKG_LIB_VERSION=" 1.0.8 "
32+ PKG_LIB_VERSION=" 1.0.9 "
3333
3434# Configurable defaults — consuming projects override via environment
3535PKG_NO_COLOR=" ${PKG_NO_COLOR:- 0} "
@@ -2455,6 +2455,13 @@ pkg_config_set() {
24552455# substitute old value; otherwise keep new default
24562456# 3. Preserves comments, ordering, whitespace from new template
24572457# 4. Safe for quoted values, multi-word values, empty values
2458+ # A line is treated as an assignment only when it matches a real shell
2459+ # assignment anchor (^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*=). Lines containing
2460+ # `=` or `==` inside conditional expressions (e.g. `[ "$X" = "1" ]`,
2461+ # `[[ "$Y" == "auto" ]]`) are passed through unchanged. Files that assign
2462+ # the same variable in multiple branches (e.g. if/else STATE_MATCH=...)
2463+ # remain unsafe to merge — the last-seen value collapses both branches.
2464+ # Use this function only on flat VAR=value config files.
24582465# Returns 1 on failure.
24592466pkg_config_merge () {
24602467 local old_conf=" $1 " new_conf=" $2 " output=" $3 "
@@ -2502,18 +2509,23 @@ pkg_config_merge() {
25022509 }
25032510
25042511 awk -v oldfile=" $old_conf " '
2512+ # Anchored shell assignment: optional leading whitespace, identifier, "="
2513+ # Excludes conditional expressions like `[ "$X" = "1" ]` and
2514+ # `[[ "$Y" == "auto" ]]` which contain `=` but are not assignments.
2515+ function is_assignment(line, _ws) {
2516+ _ws = "^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*="
2517+ return (line ~ _ws)
2518+ }
25052519 # First file (old config): collect VAR=value pairs
25062520 FILENAME == oldfile {
2507- # Skip comments and empty lines
2521+ # Skip comments, empty lines, and non-assignment shell code
25082522 if ($0 ~ /^[[:space:]]*#/ || $0 ~ /^[[:space:]]*$/) next
2509- # Match VAR=value
2523+ if (!is_assignment($0)) next
25102524 pos = index($0, "=")
2511- if (pos > 0) {
2512- varname = substr($0, 1, pos - 1)
2513- gsub(/^[[:space:]]+|[[:space:]]+$/, "", varname)
2514- val = substr($0, pos + 1)
2515- old[varname] = val
2516- }
2525+ varname = substr($0, 1, pos - 1)
2526+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", varname)
2527+ val = substr($0, pos + 1)
2528+ old[varname] = val
25172529 next
25182530 }
25192531 # Second file (new template): output with old values merged
@@ -2523,18 +2535,21 @@ pkg_config_merge() {
25232535 print
25242536 next
25252537 }
2526- # Check for VAR=value pattern
2538+ # Non-assignment shell code (conditionals, function bodies, etc.)
2539+ # passes through verbatim — never reinterpret as VAR=value.
2540+ if (!is_assignment($0)) {
2541+ print
2542+ next
2543+ }
25272544 pos = index($0, "=")
2528- if (pos > 0) {
2529- varname = substr($0, 1, pos - 1)
2530- gsub(/^[[:space:]]+|[[:space:]]+$/, "", varname)
2531- if (varname in old) {
2532- # Substitute old value into new template line
2533- print varname "=" old[varname]
2534- next
2535- }
2545+ varname = substr($0, 1, pos - 1)
2546+ gsub(/^[[:space:]]+|[[:space:]]+$/, "", varname)
2547+ if (varname in old) {
2548+ # Substitute old value into new template line
2549+ print varname "=" old[varname]
2550+ next
25362551 }
2537- # No match — keep new template line as-is
2552+ # Variable not in old config — keep new template line as-is
25382553 print
25392554 }
25402555 ' " $old_conf " " $new_conf " > " $_tmp_output " || {
0 commit comments