Files
LithosAnanake/scripts/4th-apply-init.sh
T

223 lines
6.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#
# StarForth — Steady-State Virtual Machine Runtime
#
# Copyright (c) 20232025 Robert A. James
# All rights reserved.
#
# This file is part of the StarForth project.
#
# Licensed under the StarForth License, Version 1.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at:
# https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
#
# This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
# express or implied, including but not limited to the warranties of
# merchantability, fitness for a particular purpose, and noninfringement.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
# StarForth — Steady-State Virtual Machine Runtime
# Copyright (c) 20232025 Robert A. James
# All rights reserved.
#
# This file is part of the StarForth project.
#
# Licensed under the StarForth License, Version 1.0 (the "License");
# you may not use this file except in compliance with the License.
#
# You may obtain a copy of the License at:
# https://github.com/star.4th@proton.me/StarForth/LICENSE.txt
#
# This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND,
# express or implied, including but not limited to the warranties of
# merchantability, fitness for a particular purpose, and noninfringement.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# scripts/apply-init.sh — interactive wrapper for tools/apply-init
# Reads ./conf/init-4.4th and writes its Block N sections into a selected disk image.
set -euo pipefail
# --- Layout ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
TOOLS_DIR="${REPO_ROOT}/tools"
DISKS_DIR="${REPO_ROOT}/disks"
CONF_DIR="${REPO_ROOT}/conf"
SRC_C="${TOOLS_DIR}/apply_init.c"
BIN="${TOOLS_DIR}/apply-init"
# Defaults
IN_DEFAULT="${CONF_DIR}/init.4th"
FBS_DEFAULT="1024"
START_GUARD_DEFAULT="0" # bump to 1024 if you want to default-guard boot area
END_GUARD_DEFAULT="-1" # -1 = no upper guard
BOLD="$(printf '\033[1m')"
DIM="$(printf '\033[2m')"
RESET="$(printf '\033[0m')"
die(){ echo "ERROR: $*" >&2; exit 1; }
have_cmd(){ command -v "$1" >/dev/null 2>&1; }
pick_cc(){
if have_cmd gcc; then echo gcc
elif have_cmd cc; then echo cc
else die "No C compiler found (need gcc or cc)."
fi
}
stat_mtime(){
stat -c '%Y' "$1" 2>/dev/null || stat -f '%m' "$1"
}
need_rebuild(){
local src="$1" bin="$2"
[[ ! -f "$bin" ]] && return 0
[[ ! -f "$src" ]] && return 1
local s b; s="$(stat_mtime "$src")"; b="$(stat_mtime "$bin")"
[[ "$s" -gt "$b" ]] && return 0 || return 1
}
build_apply(){
[[ -f "$SRC_C" ]] || die "Missing source: $SRC_C"
mkdir -p "$TOOLS_DIR"
local CC FLAGS
CC="$(pick_cc)"
FLAGS="-std=gnu99 -D_FILE_OFFSET_BITS=64 -O2 -Wall -Wextra -Werror"
echo "${DIM}Building: $CC $FLAGS -o $BIN $SRC_C${RESET}"
"$CC" $FLAGS -o "$BIN" "$SRC_C"
echo "${DIM}Built $BIN${RESET}"
}
ensure_layout(){
[[ -d "$DISKS_DIR" ]] || die "Missing disks directory: $DISKS_DIR"
[[ -d "$CONF_DIR" ]] || mkdir -p "$CONF_DIR"
if need_rebuild "$SRC_C" "$BIN"; then build_apply; fi
[[ -x "$BIN" ]] || die "apply-init not executable: $BIN"
}
ask_yes_no(){
local prompt="$1" default="${2:-y}" ans def_disp="Y/n"
[[ "$default" == "n" ]] && def_disp="y/N"
read -r -p "$prompt [$def_disp] " ans || true
ans="${ans:-$default}"
case "$ans" in y|Y|yes|YES) return 0 ;; n|N|no|NO) return 1 ;; *) echo "y or n, please." >&2; ask_yes_no "$prompt" "$default" ;; esac
}
list_disks(){
find "$DISKS_DIR" -maxdepth 1 -type f -printf "%f\n" | sort
}
pick_disk(){
echo "${BOLD}Select a disk image from ${DISKS_DIR}:${RESET}"
mapfile -t DISKS < <(list_disks)
[[ "${#DISKS[@]}" -gt 0 ]] || die "No disk images found in $DISKS_DIR"
local i=1
for d in "${DISKS[@]}"; do printf " %2d) %s\n" "$i" "$d"; i=$((i+1)); done
local choice
while :; do
read -r -p "Enter choice [1-${#DISKS[@]}]: " choice || true
[[ "$choice" =~ ^[0-9]+$ ]] || { echo "Not a number."; continue; }
(( choice>=1 && choice<=${#DISKS[@]} )) || { echo "Out of range."; continue; }
DISK_CHOSEN="${DISKS_DIR}/${DISKS[$((choice-1))]}"
break
done
echo "Selected: ${BOLD}${DISK_CHOSEN}${RESET}"
}
ask_int(){
local prompt="$1" default="$2" __out="$3" val
read -r -p "$prompt (default ${default}): " val || true
val="${val:-$default}"
[[ "$val" =~ ^-?[0-9]+$ ]] || { echo "Not a valid integer: $val"; ask_int "$prompt" "$default" "$__out"; return; }
printf -v "$__out" "%s" "$val"
}
collect_params(){
echo
read -r -p "Path to init.4th [default ${IN_DEFAULT}]: " IN_PATH || true
IN_PATH="${IN_PATH:-$IN_DEFAULT}"
[[ -f "$IN_PATH" ]] || die "Input file not found: $IN_PATH"
echo
ask_int "Forth block size (FBS)" "$FBS_DEFAULT" FBS
FBS_FLAG="--fbs=${FBS}"
echo
ask_int "Guard: minimum block to allow (start)" "$START_GUARD_DEFAULT" START_GUARD
ask_int "Guard: maximum block to allow (end, -1 for none)" "$END_GUARD_DEFAULT" END_GUARD
echo
if ask_yes_no "Truncate block text if longer than FBS? (--clip)" "n"; then
CLIP_FLAG="--clip"
else
CLIP_FLAG=""
fi
if ask_yes_no "Dry run (no writes)?" "n"; then
DRY_FLAG="--dry-run"
else
DRY_FLAG=""
fi
if ask_yes_no "Verify after write (read-back & compare)?" "y"; then
VERIFY_FLAG="--verify"
else
VERIFY_FLAG=""
fi
if ask_yes_no "Verbose logging?" "n"; then
VERBOSE_FLAG="--verbose"
else
VERBOSE_FLAG=""
fi
}
build_command(){
CMD=( "$BIN"
"--img=${DISK_CHOSEN}"
"--in=${IN_PATH}"
"$FBS_FLAG"
)
# Guards
[[ "$START_GUARD" != "0" ]] && CMD+=( "--start=${START_GUARD}" ) || CMD+=( "--start=0" )
[[ "$END_GUARD" != "-1" ]] && CMD+=( "--end=${END_GUARD}" )
# Toggles
[[ -n "$CLIP_FLAG" ]] && CMD+=( "$CLIP_FLAG" )
[[ -n "$DRY_FLAG" ]] && CMD+=( "$DRY_FLAG" )
[[ -n "$VERIFY_FLAG" ]] && CMD+=( "$VERIFY_FLAG" )
[[ -n "$VERBOSE_FLAG" ]] && CMD+=( "$VERBOSE_FLAG" )
}
main(){
ensure_layout
pick_disk
collect_params
build_command
echo
echo "${BOLD}About to run:${RESET}"
printf " %q " "${CMD[@]}"; echo
echo
if ask_yes_no "Proceed?" "y"; then
"${CMD[@]}"
echo
echo "${BOLD}Done.${RESET} Applied init.4th → ${DISK_CHOSEN}"
else
echo "Aborted."
exit 1
fi
}
main "$@"