Tools accept - as a placeholder filename for stdin or stdout
Some checks failed
CI / build (push) Has been cancelled
CI / build-macos (push) Has been cancelled

This commit is contained in:
Rangi
2026-06-08 12:58:43 -04:00
parent ee16bd72ee
commit 05e39ed292
3 changed files with 69 additions and 27 deletions

View File

@@ -59,6 +59,9 @@ void *xrealloc(void *m, size_t size) {
}
FILE *xfopen(const char *filename, char rw) {
if (!strcmp(filename, "-")) {
return rw == 'r' ? stdin : stdout;
}
char mode[3] = {rw, 'b', '\0'};
errno = 0;
FILE *f = fopen(filename, mode);
@@ -68,10 +71,16 @@ FILE *xfopen(const char *filename, char rw) {
return f;
}
void xfclose(FILE *f) {
if (f != stdin && f != stdout) {
fclose(f);
}
}
void xfread(uint8_t *data, size_t size, const char *filename, FILE *f) {
errno = 0;
if (fread(data, 1, size, f) != size) {
fclose(f);
xfclose(f);
error_exit("Could not read from file \"%s\": %s\n", filename, strerror(errno));
}
}
@@ -79,7 +88,7 @@ void xfread(uint8_t *data, size_t size, const char *filename, FILE *f) {
void xfwrite(const uint8_t *data, size_t size, const char *filename, FILE *f) {
errno = 0;
if (fwrite(data, 1, size, f) != size) {
fclose(f);
xfclose(f);
error_exit("Could not write to file \"%s\": %s\n", filename, strerror(errno));
}
}
@@ -99,19 +108,41 @@ long xfsize(const char *filename, FILE *f) {
return size;
}
uint8_t *read_stdin(long *size) {
uint8_t buffer[0x1000] = {0};
*size = 0;
uint8_t *data = malloc(0);
for (;;) {
size_t n = fread(buffer, 1, sizeof(buffer), stdin);
if (n == 0) {
if (ferror(stdin)) {
error_exit("Could not read from stdin: %s\n", strerror(errno));
}
break;
}
data = xrealloc(data, *size + n);
memcpy(data + *size, buffer, n);
*size += n;
}
return data;
}
uint8_t *read_u8(const char *filename, long *size) {
FILE *f = xfopen(filename, 'r');
if (f == stdin) {
return read_stdin(size);
}
*size = xfsize(filename, f);
uint8_t *data = xmalloc(*size);
xfread(data, *size, filename, f);
fclose(f);
xfclose(f);
return data;
}
void write_u8(const char *filename, uint8_t *data, size_t size) {
FILE *f = xfopen(filename, 'w');
xfwrite(data, size, filename, f);
fclose(f);
xfclose(f);
}
uint32_t read_png_width(const char *filename) {
@@ -124,12 +155,12 @@ uint32_t read_png_width(const char *filename) {
'I', 'H', 'D', 'R', // IHDR chunk type
};
if (memcmp(header, expected_header, sizeof(header))) {
fclose(f);
xfclose(f);
error_exit("Not a valid PNG file: \"%s\"\n", filename);
}
uint8_t bytes[4] = {0};
xfread(bytes, sizeof(bytes), filename, f);
fclose(f);
xfclose(f);
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
}

View File

@@ -155,7 +155,7 @@ struct Symbol *parse_symbols(const char *filename) {
}
}
fclose(file);
xfclose(file);
buffer_free(buffer);
return symbols;
}
@@ -431,8 +431,8 @@ struct Buffer *process_template(
rewind(orig_rom);
rewind(new_rom);
fclose(input);
fclose(output);
xfclose(input);
xfclose(output);
buffer_free(buffer);
return patches;
}
@@ -514,6 +514,9 @@ int main(int argc, char *argv[]) {
FILE *new_rom = xfopen(argv[1], 'r');
FILE *orig_rom = xfopen(argv[2], 'r');
if (new_rom == stdin || orig_rom == stdin) {
error_exit("Error: Cannot read ROM file from stdin (not rewindable)");
}
struct Buffer *patches = process_template(argv[3], argv[4], new_rom, orig_rom, symbols, ignore_addr, ignore_size);
if (!verify_completeness(orig_rom, new_rom, patches)) {
@@ -521,8 +524,8 @@ int main(int argc, char *argv[]) {
}
symbol_free(symbols);
fclose(new_rom);
fclose(orig_rom);
xfclose(new_rom);
xfclose(orig_rom);
buffer_free(patches);
return 0;
}

View File

@@ -25,22 +25,30 @@ void parse_args(int argc, char *argv[], bool *strict) {
}
}
void scan_file(const char *filename, bool strict) {
errno = 0;
FILE *f = fopen(filename, "rb");
if (!f) {
if (strict) {
error_exit("Could not open file \"%s\": %s\n", filename, strerror(errno));
} else {
return;
void scan_file(const char *filename, bool strict, bool top_level) {
long size = 0;
char *contents = NULL;
if (top_level && !strcmp(filename, "-")) {
contents = (char *)read_stdin(&size);
contents = xrealloc(contents, size + 1);
contents[size] = '\0';
} else {
errno = 0;
FILE *f = fopen(filename, "rb");
if (!f) {
if (strict) {
error_exit("Could not open file \"%s\": %s\n", filename, strerror(errno));
} else {
return;
}
}
}
long size = xfsize(filename, f);
char *contents = xmalloc(size + 1);
xfread((uint8_t *)contents, size, filename, f);
fclose(f);
contents[size] = '\0';
size = xfsize(filename, f);
contents = xmalloc(size + 1);
xfread((uint8_t *)contents, size, filename, f);
xfclose(f);
contents[size] = '\0';
}
for (char *ptr = contents; ptr && ptr < contents + size; ptr++) {
ptr = strpbrk(ptr, ";\"Ii");
@@ -90,7 +98,7 @@ void scan_file(const char *filename, bool strict) {
include_path[length] = '\0';
printf("%s ", include_path);
if (is_include) {
scan_file(include_path, strict);
scan_file(include_path, strict, false);
}
} else {
fprintf(stderr, "%s: no file path after INC%s\n", filename, is_include ? "LUDE" : "BIN");
@@ -117,6 +125,6 @@ int main(int argc, char *argv[]) {
usage_exit(1);
}
scan_file(argv[0], strict);
scan_file(argv[0], strict, true);
return 0;
}