Files
sovereign_browser/embed_web_files.sh

133 lines
4.1 KiB
Bash
Executable File

#!/bin/bash
# embed_web_files.sh — Convert www/ web files into C byte arrays
#
# Scans www/**/*.html, www/**/*.css, www/**/*.js and generates
# src/embedded_web_content.c + src/embedded_web_content.h with the
# file contents as C byte arrays. The sovereign:// URI scheme handler
# looks up files by path via get_embedded_file().
#
# Adapted from ~/lt/c-relay/embed_web_files.sh.
set -e
echo "[embed] Embedding web files into C byte arrays..."
# Output directory for generated files
OUTPUT_DIR="src"
mkdir -p "$OUTPUT_DIR"
# Function to convert a file to a C byte array
file_to_c_array() {
local input_file="$1"
local array_name="$2"
local output_file="$3"
# Get file size
local file_size=$(stat -c%s "$input_file" 2>/dev/null || stat -f%z "$input_file" 2>/dev/null || echo "0")
echo "// Auto-generated from $input_file" >> "$output_file"
echo "static const unsigned char ${array_name}_data[] = {" >> "$output_file"
# Convert file to hex bytes
hexdump -v -e '1/1 "0x%02x,"' "$input_file" >> "$output_file"
echo "};" >> "$output_file"
echo "static const size_t ${array_name}_size = $file_size;" >> "$output_file"
echo "" >> "$output_file"
}
# Generate the header file
HEADER_FILE="$OUTPUT_DIR/embedded_web_content.h"
cat > "$HEADER_FILE" <<'EOF'
// Auto-generated embedded web content header
// Do not edit manually - generated by embed_web_files.sh
#ifndef EMBEDDED_WEB_CONTENT_H
#define EMBEDDED_WEB_CONTENT_H
#include <stddef.h>
typedef struct {
const char *path; /* e.g. "agents/chat.html" */
const unsigned char *data;
size_t size;
const char *mime_type; /* "text/html", "text/css", "application/javascript" */
} embedded_file_t;
/*
* Look up an embedded file by its path (e.g. "agents/chat.html").
* Returns NULL if not found.
*/
const embedded_file_t *get_embedded_file(const char *path);
#endif /* EMBEDDED_WEB_CONTENT_H */
EOF
# Generate the C file
SOURCE_FILE="$OUTPUT_DIR/embedded_web_content.c"
cat > "$SOURCE_FILE" <<'EOF'
// Auto-generated embedded web content
// Do not edit manually - generated by embed_web_files.sh
#include "embedded_web_content.h"
#include <string.h>
EOF
# Process each web file and build the lookup table
declare -a file_entries
for file in $(find www -type f \( -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.mjs' \) | sort); do
if [ -f "$file" ]; then
# Get path relative to www/
rel_path="${file#www/}"
# Create C identifier from path (replace non-alphanumeric with _)
c_name=$(echo "$rel_path" | sed 's/[^a-zA-Z0-9]/_/g' | sed 's/^_//')
# Determine content type
case "$file" in
*.html) content_type="text/html" ;;
*.css) content_type="text/css" ;;
*.js) content_type="text/javascript" ;;
*.mjs) content_type="text/javascript" ;;
*) content_type="text/plain" ;;
esac
echo "[embed] $rel_path -> ${c_name} ($content_type)"
# Generate the byte array
file_to_c_array "$file" "$c_name" "$SOURCE_FILE"
# Remember for the lookup table (no outer braces — the echo loop
# below wraps each entry in a single set of braces)
file_entries+=("\"$rel_path\", ${c_name}_data, ${c_name}_size, \"$content_type\"")
fi
done
# Generate the lookup table
echo "// File mapping" >> "$SOURCE_FILE"
echo "static const embedded_file_t embedded_files[] = {" >> "$SOURCE_FILE"
for entry in "${file_entries[@]}"; do
echo " { $entry }," >> "$SOURCE_FILE"
done
echo " {NULL, NULL, 0, NULL} // Sentinel" >> "$SOURCE_FILE"
echo "};" >> "$SOURCE_FILE"
echo "" >> "$SOURCE_FILE"
# Generate the lookup function
cat >> "$SOURCE_FILE" <<'EOF'
const embedded_file_t *get_embedded_file(const char *path) {
if (!path) return NULL;
for (int i = 0; embedded_files[i].path != NULL; i++) {
if (strcmp(path, embedded_files[i].path) == 0) {
return &embedded_files[i];
}
}
return NULL;
}
EOF
echo "[embed] Generated $HEADER_FILE and $SOURCE_FILE"
echo "[embed] Embedded ${#file_entries[@]} files"