93 lines
2.3 KiB
Bash
93 lines
2.3 KiB
Bash
|
#!/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 )"
|
||
|
|
||
|
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 "${@}"
|