#!/usr/bin/env bash # embed.sh # a simple script to handle embedding binary file contents into invocations # of the CATSKILL_EMBED macro within catboot compiler source files. # invoked with `./embed.sh source-1.c source-2.c header.h` # outputs a file structure within the ./build/ directory matching the source # directory, with the correct replacements done. # # Copyright (c) 2026, Mel G. # # SPDX-License-Identifier: MPL-2.0 set -euo pipefail build_directory="./build/" process_file() { local source_file="$1" local output_file="$build_directory/$source_file" mkdir -p $(dirname "$output_file") cp "$source_file" "$output_file" local embed_regex='CATSKILL_EMBED\("([^)]+)"\)' # const byte data[] = CATSKILL_EMBED("./file"); local comment_regex='^\s*//' # // the macro CATSKILL_EMBED does... local define_regex='^\s*#define' # #define CATSKILL_EMBED {0} while IFS= read -r line; do # skip lines which are just comments mentioning the macro and # the line where we define the macro in the first place. if [[ $line =~ $comment_regex ]] || [[ $line =~ $define_regex ]]; then continue fi if [[ $line =~ $embed_regex ]]; then local pattern="${BASH_REMATCH[0]}" local embed_path="${BASH_REMATCH[1]}" # check that the file we want to embed actually exists if [ ! -f "$embed_path" ]; then echo "error: file not found: $embed_path (in $source_file)" >&2 exit 1 fi # get hexadecimal representation of file contents. # trim of start and end to get just the files, merge into one line and remove trailing whitespace. local hex_bytes=$(xxd -i "$embed_path" | tail -n+2 | head -n-2 | tr -d '\n' | xargs) # add in nil byte at the end of the binary data, for easier # interoperation with c-type strings local replacement="{ $hex_bytes, 0x00 }" local content=$(<"$output_file") content="${content//$pattern/$replacement}" # replace invocation with binary contents w/ bash. echo "$content" > "$output_file" fi done < "$source_file" } for source_file in "$@"; do process_file "$source_file" done