Skip to content

Instantly share code, notes, and snippets.

@mochaaP
Created February 13, 2025 20:31
Show Gist options
  • Save mochaaP/5bf91dbb2690cf89111a183149a9036b to your computer and use it in GitHub Desktop.
Save mochaaP/5bf91dbb2690cf89111a183149a9036b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# SPDX-License-Identifier: 0BSD
# SPDX-FileCopyrightText: (C) 2025 Zephyr Lykos
import argparse
import io
import json
import sys
from itertools import islice
from typing import cast
parser = argparse.ArgumentParser(
prog="cembed",
description="Create C header with file data embedded in a char array",
)
parser.add_argument(
"infile",
nargs="?",
type=argparse.FileType("rb"),
default=sys.stdin.buffer,
)
parser.add_argument(
"outfile",
nargs="?",
type=argparse.FileType("w", encoding="utf-8"),
default=sys.stdout,
)
parser.add_argument(
"--shader",
action="store_true",
)
parser.add_argument(
"--msvc",
action="store_true",
)
args = parser.parse_args()
infile = cast(io.BufferedReader, args.infile)
outfile = cast(io.TextIOWrapper, args.outfile)
lines: list[str] = []
if args.shader and not args.msvc:
for line in infile:
if line == b"\n":
lines.append("\n")
elif line.strip().startswith(b"#line"):
lines.append(line.decode().rstrip())
else:
if line.endswith(b";\n") or line.endswith(b"{\n") or line.endswith(b"}\n"):
line = line[:-1]
stripped = line.lstrip()
lines.append(
" " * (len(line) - len(stripped)) + json.dumps(stripped.decode())
)
TEMPLATE = rf"""
#ifndef SHADER_MINIFIER_IMPL
#ifndef SHADER_MINIFIER_HEADER
# define SHADER_MINIFIER_HEADER
# define VAR_resolution "resolution"
# define VAR_time "time"
#endif
#else
{"\n".join(lines)},
#endif
"""
else:
size = 0
while buffer := infile.read(0x1000):
it = iter(buffer)
size += len(buffer)
while batch := tuple(islice(it, 0x10)):
lines.append("".join(format(i, "#04x") + "," for i in batch))
if args.shader:
TEMPLATE = rf"""
#ifndef SHADER_MINIFIER_IMPL
#ifndef SHADER_MINIFIER_HEADER
# define SHADER_MINIFIER_HEADER
# define VAR_resolution "resolution"
# define VAR_time "time"
#endif
#else
(const char[{size:#x}]) {{
{"\n".join(lines)}
}},
#endif
"""
else:
TEMPLATE = rf"""
#define i_embed (const char[{size:#x}]) {{ \
{"\\\n".join(lines)} \
}}
"""
outfile.write(f"""// clang-format off
{TEMPLATE.strip()}
// clang-format on""")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment