94 lines
2.3 KiB
Bash
Executable File
94 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Bisect parsing a file at various line cut-off points to see which line causes the parse to differ from emacs.
|
|
set -euo pipefail
|
|
IFS=$'\n\t'
|
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
|
|
cd "$DIR/../"
|
|
REALPATH=$(command -v uu-realpath || command -v realpath)
|
|
|
|
############## Setup #########################
|
|
|
|
function cleanup {
|
|
for f in "${folders[@]}"; do
|
|
log "Deleting $f"
|
|
rm -rf "$f"
|
|
done
|
|
}
|
|
folders=()
|
|
for sig in EXIT INT QUIT HUP TERM; do
|
|
trap "set +e; cleanup" "$sig"
|
|
done
|
|
|
|
function die {
|
|
local status_code="$1"
|
|
shift
|
|
(>&2 echo "${@}")
|
|
exit "$status_code"
|
|
}
|
|
|
|
function log {
|
|
(>&2 echo "${@}")
|
|
}
|
|
|
|
############## Program #########################
|
|
|
|
function main {
|
|
log "Is is recommended that the output of \`mktemp -d -t 'compare_bisect.XXXXXXXX'\` is inside a tmpfs filesystem since this script will make many writes to these folders."
|
|
|
|
local target_full_path=$($REALPATH "$1")
|
|
SOURCE_FOLDER=$(dirname "$target_full_path")
|
|
TARGET_DOCUMENT=$(basename "$target_full_path")
|
|
|
|
|
|
local good=0
|
|
local bad=$(wc -l "$SOURCE_FOLDER/$TARGET_DOCUMENT" | awk '{print $1}')
|
|
|
|
set +e
|
|
run_parse "$bad" &> /dev/null
|
|
local status=$?
|
|
set -e
|
|
if [ $status -eq 0 ]; then
|
|
log "Entire file passes."
|
|
exit 0
|
|
fi
|
|
|
|
while [[ "$((bad - good))" -gt 1 ]]; do
|
|
local next_line=$((((bad - good) / 2) + good))
|
|
log "Testing line $next_line"
|
|
set +e
|
|
run_parse "$next_line" &> /dev/null
|
|
local status=$?
|
|
set -e
|
|
if [ $status -eq 0 ]; then
|
|
good="$next_line"
|
|
log "Line $next_line good"
|
|
else
|
|
bad="$next_line"
|
|
log "Line $next_line bad"
|
|
fi
|
|
done
|
|
echo "Bad line: $bad"
|
|
}
|
|
|
|
function setup_temp_dir {
|
|
local temp_dir=$(mktemp -d -t 'compare_bisect.XXXXXXXX')
|
|
cp -r "$SOURCE_FOLDER/"* "$temp_dir/"
|
|
echo "$temp_dir"
|
|
}
|
|
|
|
function run_parse {
|
|
local lines="$1"
|
|
local temp_dir=$(setup_temp_dir)
|
|
folders+=("$temp_dir")
|
|
cat "$SOURCE_FOLDER/$TARGET_DOCUMENT" | head -n "$lines" > "$temp_dir/$TARGET_DOCUMENT"
|
|
"${DIR}/run_docker_compare.bash" "$temp_dir/$TARGET_DOCUMENT"
|
|
local status=$?
|
|
rm -rf "$temp_dir"
|
|
# TODO: Remove temp_dir from folders
|
|
return "$status"
|
|
}
|
|
|
|
main "${@}"
|