Created
February 13, 2025 20:31
-
-
Save mochaaP/5bf91dbb2690cf89111a183149a9036b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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