aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/common.c7
-rwxr-xr-xboot/scripts/embed.sh65
2 files changed, 72 insertions, 0 deletions
diff --git a/boot/common.c b/boot/common.c
index 095aaa6..79f5d63 100644
--- a/boot/common.c
+++ b/boot/common.c
@@ -48,6 +48,13 @@
#define NORETURN _Noreturn
+// macro used as target for embedding binary files during build into a byte array.
+// usage: `const byte test_data[] = CATSKILL_EMBED(./files/test_data.txt);`
+// the array will be filled with hexadecimal values of the file contents,
+// with a nil byte appended at the end.
+// the size of the array can be retrieved through `strlen(array)`, or `ARRAY_SIZE(array)-1`.
+#define CATSKILL_EMBED(...) {0}
+
// ansi escape codes for terminal color and style
#define ANSI(code) "\33[" code "m"
diff --git a/boot/scripts/embed.sh b/boot/scripts/embed.sh
new file mode 100755
index 0000000..f27c2a6
--- /dev/null
+++ b/boot/scripts/embed.sh
@@ -0,0 +1,65 @@
+#!/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. <mel@rnrd.eu>
+#
+# 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