mirror of
https://github.com/a2-4am/4cade.git
synced 2024-11-26 01:49:25 +00:00
97 lines
3.2 KiB
Bash
Executable File
97 lines
3.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# flags
|
|
# -a append to data file (default off = truncate)
|
|
# -p pad sizes within data file to next block size (default off)
|
|
|
|
# parameters
|
|
# stdin - input containing list of files (e.g. FX.CONF)
|
|
# stdout - binary OKVS data structure
|
|
# 1 - output filename for data file
|
|
# 2 - input directory of files to merge into data file
|
|
# 3 - (optional) output filename for log of key,offset,size
|
|
|
|
pad=false
|
|
append=false
|
|
standardoffset=0
|
|
standardsize=0
|
|
while getopts ":ap" opt; do
|
|
case $opt in
|
|
a) append=true
|
|
;;
|
|
p) pad=true
|
|
;;
|
|
esac
|
|
done
|
|
shift $((OPTIND-1))
|
|
|
|
if [ "$append" = false ]; then
|
|
rm -f "$1"
|
|
fi
|
|
touch "$1"
|
|
|
|
if [ "${#3}" -ne "0" ]; then
|
|
rm -f "$3"
|
|
touch "$3"
|
|
fi
|
|
|
|
# if there is a file called "STANDARD" in the input directory, add it now
|
|
# because we will reuse it for any files that don't exist
|
|
if [ -f "$2"/STANDARD ]; then
|
|
standardoffset=$(wc -c < "$1")
|
|
standardsize=$(wc -c < "$2/STANDARD")
|
|
cat "$2"/STANDARD >> "$1"
|
|
fi
|
|
|
|
# make temp file with list of lines that contain keys
|
|
records=$(mktemp)
|
|
tr -d "\r" | awk '!/^$|^#|^\[/' > "$records"
|
|
|
|
# make temp assembly source file that represents the binary OKVS data structure
|
|
source=$(mktemp)
|
|
(echo "*=0" # dummy program counter for assembler
|
|
echo "!le16 $(wc -l <"$records"), 0" # OKVS header
|
|
while IFS="=" read -r filename dummy; do
|
|
key=$(echo "$filename" | awk -F'#' '{ print $1 }')
|
|
addr=$(echo "$filename" | awk -F'#' '{ print $2 }')
|
|
if [ "${#addr}" -ne "0" ]; then # if filename is in the form 'NAME#06ADDR' then create extended index record
|
|
addr=$(echo "$addr" | cut -c3-) # trim '06' so we get just the starting address
|
|
echo "!byte ${#key}+9" # OKVS record length
|
|
else
|
|
echo "!byte ${#key}+7" # OKVS record length
|
|
fi
|
|
echo "!byte ${#key}" # OKVS key length
|
|
echo "!text \"$key\"" # OKVS key
|
|
if [ ! -e "$2/$filename" ]; then # if file does not exist, use standard offset and size
|
|
offset="$standardoffset"
|
|
size="$standardsize"
|
|
else # otherwise calculate offset and size from file and options
|
|
offset=$(wc -c < "$1")
|
|
size=$(wc -c < "$2/$filename")
|
|
if [ "$pad" = true ]; then
|
|
# If offset+size does not cross a block boundary, use file's true size.
|
|
# Otherwise, round up size to the next block boundary.
|
|
# This padding does not get added to the file; it is just an
|
|
# optimization to avoid a partial copy on the last block read.
|
|
if [ $(($offset / 512)) -ne $((($offset + $size) / 512)) ]; then
|
|
size=$(((($offset + $size + 511) & -512) - $offset))
|
|
fi
|
|
fi
|
|
cat "$2/$filename" >> "$1" # append this file to the end of the merged data file
|
|
fi
|
|
echo "!be24 $offset"
|
|
echo "!le16 $size"
|
|
[ "${#addr}" -ne "0" ] && echo '!le16 $'"$addr"
|
|
[ "${#3}" -ne "0" ] && echo "$key,$offset,$size" >> "$3"
|
|
done < "$records") > "$source"
|
|
|
|
# assemble temp source file into binary OKVS data structure, then output that
|
|
out=$(mktemp)
|
|
acme -o "$out" "$source"
|
|
cat "$out"
|
|
|
|
# clean up
|
|
rm "$out"
|
|
rm "$source"
|
|
rm "$records"
|