#!/bin/sh
# Print the xvm kernel .config against libkrunfw's config-libkrunfw_riscv64 (RFC 005 §2.5).
# Usage: kconfig-diff.sh [--summary] <base config> <our .config>
# Lines: "-SYM=val" set only in base, "+SYM=val" set only in ours, "~SYM base -> ours" changed.
# Symbols that are unset in both, and the toolchain-derived CC/AS/LD/RUSTC/PAHOLE version
# symbols, are ignored. The base is libkrunfw's 6.12.20 file before olddefconfig, so "-" also
# lists symbols 6.18 renamed or dropped.
set -eu
summary=0
[ "${1:-}" = --summary ] && { summary=1; shift; }
base=${1:?usage: $0 [--summary] <base config> <our .config>}
ours=${2:?usage: $0 [--summary] <base config> <our .config>}
awk -v summary="$summary" '
function val(line,   v) { v = line; sub(/^[^=]*=/, "", v); return v }
function sym(line,   s) { s = line; sub(/^CONFIG_/, "", s); sub(/=.*/, "", s); return s }
function ignored(s) { return s ~ /^(CC_VERSION_TEXT|GCC_VERSION|CLANG_VERSION|AS_VERSION|LD_VERSION|LLD_VERSION|RUSTC_VERSION|RUSTC_LLVM_VERSION|PAHOLE_VERSION|BUILD_SALT|CC_IS_|AS_IS_|LD_IS_|TOOLCHAIN_HAS_|CC_HAS_|AS_HAS_|GCC_|RUSTC_)/ }
FNR == NR { if ($0 ~ /^CONFIG_/) { b[sym($0)] = val($0) } next }
$0 ~ /^CONFIG_/ { o[sym($0)] = val($0) }
END {
  for (s in b) if (!ignored(s) && !(s in o)) { rem[++nr] = s }
  for (s in o) if (!ignored(s) && !(s in b)) { add[++na] = s }
  for (s in o) if (!ignored(s) && (s in b) && b[s] != o[s]) { chg[++nc] = s }
  if (summary) {
    printf "  base %d symbols set, ours %d; removed %d, added %d, changed %d (toolchain symbols ignored)\n", length(b), length(o), nr, na, nc
    exit
  }
  for (i = 1; i <= nr; i++) printf "1 -%s=%s\n", rem[i], b[rem[i]]
  for (i = 1; i <= na; i++) printf "2 +%s=%s\n", add[i], o[add[i]]
  for (i = 1; i <= nc; i++) printf "3 ~%s %s -> %s\n", chg[i], b[chg[i]], o[chg[i]]
}' "$base" "$ours" | LC_ALL=C sort | cut -c3-
