about summary refs log tree commit diff
path: root/boot/scripts
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2026-01-22 18:27:28 +0100
committerMel <mel@rnrd.eu>2026-01-22 19:12:20 +0100
commitfce4a99dbfab5af623bb05d9e10807efeced5a47 (patch)
tree791fd7b45ac2a44b5878e41448aa048c66ae4732 /boot/scripts
parent7f5d765c929a4dc2deddb7b68a41a3a841940837 (diff)
downloadcatskill-fce4a99dbfab5af623bb05d9e10807efeced5a47.tar.zst
catskill-fce4a99dbfab5af623bb05d9e10807efeced5a47.zip
Implement file embedding into compiler sources during build
Signed-off-by: Mel <mel@rnrd.eu>
Diffstat (limited to 'boot/scripts')
-rwxr-xr-xboot/scripts/embed.sh65
1 files changed, 65 insertions, 0 deletions
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