/* tools/embed.c - turn runtime sources into C string headers for the compiler.
Lines of the form '#include "..."' are dropped (their content is inlined
around the string); system includes with <...> are kept. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void emit_escaped(const char* s, size_t n) {
for (size_t i = 0; i < n; i++) {
unsigned char c = (unsigned char)s[i];
switch (c) {
case '\\': printf("\\\\"); break;
case '"': printf("\\\""); break;
case '\t': printf("\\t"); break;
case '\r': break;
default:
if (c < 32 || c > 126) printf("\\%03o", c);
else putchar(c);
}
}
}
static void emit_string(const char* name, const char* path) {
FILE* f = fopen(path, "rb");
if (!f) {
fprintf(stderr, "embed: cannot open %s\n", path);
exit(1);
}
printf("static const char %s[] =\n", name);
char line[1024];
int first = 1;
while (fgets(line, sizeof line, f)) {
if (strncmp(line, "#include \"", 10) == 0) continue; /* local include: dropped */
size_t n = strlen(line);
/* strip trailing newline */
while (n > 0 && (line[n - 1] == '\n' || line[n - 1] == '\r')) n--;
if (!first) printf("\n");
printf("\"");
emit_escaped(line, n);
printf("\\n\"");
first = 0;
}
printf(";\n\n");
fclose(f);
}
int main(int argc, char** argv) {
if (argc < 3 || (argc - 1) % 2 != 0) {
fprintf(stderr, "usage: embed <file> <symbol> [<file> <symbol> ...]\n");
return 1;
}
printf("/* generated by tools/embed - do not edit */\n");
printf("#ifndef CR_RT_SRC_H\n#define CR_RT_SRC_H\n\n");
for (int i = 1; i + 1 < argc; i += 2)
emit_string(argv[i + 1], argv[i]);
printf("#endif\n");
return 0;
}