one of the last commit
This commit is contained in:
325
start.sh
Executable file
325
start.sh
Executable file
@@ -0,0 +1,325 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/cowsay-tour.XXXXXX")
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
AUTO_RUN=0
|
||||
COUNTDOWN=10
|
||||
STOP_TOUR=0
|
||||
COMPILER=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
./tour_programmes.sh
|
||||
./tour_programmes.sh --auto
|
||||
|
||||
Options:
|
||||
--auto starts immediately without waiting
|
||||
-h, --help shows this help
|
||||
EOF
|
||||
}
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
--auto)
|
||||
AUTO_RUN=1
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'Unknown option: %s\n\n' "$1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
hr() {
|
||||
printf '\n============================================================\n'
|
||||
}
|
||||
|
||||
show_intro() {
|
||||
hr
|
||||
printf 'Quick cowsay program tour\n'
|
||||
if ((AUTO_RUN == 1)); then
|
||||
printf 'Auto mode: demos start immediately.\n'
|
||||
else
|
||||
printf 'The first demo starts after %d seconds.\n' "$COUNTDOWN"
|
||||
printf 'After each demo, the tour waits %d seconds before the next one.\n' "$COUNTDOWN"
|
||||
printf 'Press Enter to continue faster, or type n then Enter to stop.\n'
|
||||
fi
|
||||
}
|
||||
|
||||
need_commands() {
|
||||
local missing=0
|
||||
local cmd
|
||||
|
||||
for cmd in "$@"; do
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
printf 'Missing dependency: %s\n' "$cmd" >&2
|
||||
missing=1
|
||||
fi
|
||||
done
|
||||
|
||||
return "$missing"
|
||||
}
|
||||
|
||||
detect_compiler() {
|
||||
if [[ -n "$COMPILER" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
local candidate
|
||||
for candidate in cc clang gcc; do
|
||||
if command -v "$candidate" >/dev/null 2>&1; then
|
||||
COMPILER="$candidate"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
printf 'No C compiler found.\n' >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
compile_c() {
|
||||
local source="$1"
|
||||
local output="$2"
|
||||
|
||||
detect_compiler || return 1
|
||||
"$COMPILER" -std=c99 -Wall -Wextra -O2 -D_DEFAULT_SOURCE "$source" -o "$output"
|
||||
}
|
||||
|
||||
run_command() {
|
||||
"$@"
|
||||
}
|
||||
|
||||
run_command_with_input() {
|
||||
local input="$1"
|
||||
shift
|
||||
printf '%s' "$input" | "$@"
|
||||
}
|
||||
|
||||
announce_demo() {
|
||||
local name="$1"
|
||||
local description="$2"
|
||||
|
||||
hr
|
||||
printf '%s: %s\n' "$name" "$description"
|
||||
}
|
||||
|
||||
drain_stdin() {
|
||||
if [[ ! -t 0 ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r -t 0; do
|
||||
:
|
||||
done
|
||||
}
|
||||
|
||||
timed_continue() {
|
||||
local prompt="$1"
|
||||
|
||||
if ((AUTO_RUN == 1)) || [[ ! -t 0 ]]; then
|
||||
printf 'Starting...\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
drain_stdin
|
||||
printf '%s' "$prompt"
|
||||
|
||||
local answer=""
|
||||
if IFS= read -r -t "$COUNTDOWN" answer; then
|
||||
printf '\n'
|
||||
case "${answer,,}" in
|
||||
n)
|
||||
STOP_TOUR=1
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
printf '\n'
|
||||
return 0
|
||||
}
|
||||
|
||||
run_demo() {
|
||||
local name="$1"
|
||||
local function_name="$2"
|
||||
|
||||
"$function_name"
|
||||
local status=$?
|
||||
|
||||
if ((status != 0)); then
|
||||
printf '%s: failed (%d)\n' "$name" "$status" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
demo_cow_kindergarten() {
|
||||
need_commands cowsay || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/cow_kindergarten.sh"
|
||||
}
|
||||
|
||||
demo_cow_primaryschool() {
|
||||
need_commands cowsay || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/cow_primaryschool.sh" 3
|
||||
}
|
||||
|
||||
demo_cow_highschool() {
|
||||
need_commands cowsay || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/cow_highschool.sh" 3
|
||||
}
|
||||
|
||||
demo_cow_college() {
|
||||
need_commands cowsay || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/cow_college.sh" 5
|
||||
}
|
||||
|
||||
demo_cow_university() {
|
||||
need_commands cowsay || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/cow_university.sh" 12
|
||||
}
|
||||
|
||||
demo_smart_cow() {
|
||||
need_commands cowsay bc || return 1
|
||||
run_command bash "$ROOT_DIR/src/bash_scripts/smart_cow.sh" '4+13'
|
||||
}
|
||||
|
||||
demo_crazy_cow() {
|
||||
need_commands cowsay || return 1
|
||||
run_command_with_input $'5\n' bash "$ROOT_DIR/src/bash_scripts/crazy_cow.sh"
|
||||
}
|
||||
|
||||
demo_newcow() {
|
||||
local bin="$TMP_DIR/newcow"
|
||||
compile_c "$ROOT_DIR/src/C/newcow.c" "$bin" || return 1
|
||||
run_command "$bin" -e "^^"
|
||||
}
|
||||
|
||||
demo_newcowt() {
|
||||
local bin="$TMP_DIR/newcowT"
|
||||
compile_c "$ROOT_DIR/src/C/newcows/newcowT.c" "$bin" || return 1
|
||||
run_command "$bin" -T "U"
|
||||
}
|
||||
|
||||
demo_newcowp() {
|
||||
local bin="$TMP_DIR/newcowp"
|
||||
compile_c "$ROOT_DIR/src/C/newcows/newcowp.c" "$bin" || return 1
|
||||
run_command "$bin" -p "Hello"
|
||||
}
|
||||
|
||||
demo_newcow2() {
|
||||
local bin="$TMP_DIR/newcow2"
|
||||
compile_c "$ROOT_DIR/src/C/newcow2.c" "$bin" || return 1
|
||||
run_command "$bin" blink
|
||||
}
|
||||
|
||||
demo_reading_cow() {
|
||||
local bin="$TMP_DIR/reading_cow"
|
||||
local sample="$TMP_DIR/reading_demo.txt"
|
||||
|
||||
compile_c "$ROOT_DIR/src/C/reading_cow.c" "$bin" || return 1
|
||||
printf 'Hello.\nI read.\n' >"$sample"
|
||||
run_command "$bin" --i 0.10 "$sample"
|
||||
}
|
||||
|
||||
demo_tamagoshi_cow() {
|
||||
local bin="$TMP_DIR/tamagoshi_cow"
|
||||
|
||||
if ((AUTO_RUN == 1)) || [[ ! -t 0 ]]; then
|
||||
printf 'Tamagoshi skipped in auto mode.\n'
|
||||
return 0
|
||||
fi
|
||||
|
||||
compile_c "$ROOT_DIR/src/C/tamagoshi_cow.c" "$bin" || return 1
|
||||
run_command "$bin"
|
||||
}
|
||||
|
||||
visit_programs() {
|
||||
local -a names=(
|
||||
'cow_kindergarten.sh'
|
||||
'cow_primaryschool.sh'
|
||||
'cow_highschool.sh'
|
||||
'cow_college.sh'
|
||||
'cow_university.sh'
|
||||
'smart_cow.sh'
|
||||
'crazy_cow.sh'
|
||||
'newcow.c'
|
||||
'newcowT.c'
|
||||
'newcowp.c'
|
||||
'newcow2.c'
|
||||
'reading_cow.c'
|
||||
'tamagoshi_cow.c'
|
||||
)
|
||||
local -a descriptions=(
|
||||
'Counts from 1 to 10.'
|
||||
'Counts up to n.'
|
||||
'Shows square numbers.'
|
||||
'Shows Fibonacci.'
|
||||
'Shows prime numbers.'
|
||||
'Calculates an expression.'
|
||||
'Generates a weird sequence.'
|
||||
'Basic cow.'
|
||||
'Cow with a tongue option.'
|
||||
'Cow with a speech bubble.'
|
||||
'Compiles a .c file into .out.'
|
||||
'Animates the cow.'
|
||||
'The cow reads a file.'
|
||||
'Small cow game.'
|
||||
)
|
||||
local -a functions=(
|
||||
'demo_cow_kindergarten'
|
||||
'demo_cow_primaryschool'
|
||||
'demo_cow_highschool'
|
||||
'demo_cow_college'
|
||||
'demo_cow_university'
|
||||
'demo_smart_cow'
|
||||
'demo_crazy_cow'
|
||||
'demo_newcow'
|
||||
'demo_newcowt'
|
||||
'demo_newcowp'
|
||||
'demo_newcow2'
|
||||
'demo_reading_cow'
|
||||
'demo_tamagoshi_cow'
|
||||
)
|
||||
|
||||
local total=${#names[@]}
|
||||
local i
|
||||
|
||||
for ((i = 0; i < total; i++)); do
|
||||
announce_demo "${names[i]}" "${descriptions[i]}"
|
||||
|
||||
if ((i == 0)); then
|
||||
timed_continue "Press Enter to start, type n then Enter to stop, auto-start in ${COUNTDOWN} seconds... " || return
|
||||
else
|
||||
timed_continue "Press Enter to start the next program, type n then Enter to stop, or wait ${COUNTDOWN} seconds... " || return
|
||||
fi
|
||||
|
||||
run_demo "${names[i]}" "${functions[i]}"
|
||||
((STOP_TOUR == 1)) && return
|
||||
done
|
||||
}
|
||||
|
||||
show_outro() {
|
||||
hr
|
||||
if ((STOP_TOUR == 1)); then
|
||||
printf 'Tour stopped.\n'
|
||||
else
|
||||
printf 'End of tour.\n'
|
||||
fi
|
||||
}
|
||||
|
||||
show_intro
|
||||
visit_programs
|
||||
show_outro
|
||||
Reference in New Issue
Block a user