diff --git a/tools/common.h b/tools/common.h index 2c690423b..d20f3e903 100644 --- a/tools/common.h +++ b/tools/common.h @@ -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]; } diff --git a/tools/make_patch.c b/tools/make_patch.c index 34c99b18f..e4e15d7fd 100644 --- a/tools/make_patch.c +++ b/tools/make_patch.c @@ -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; } diff --git a/tools/scan_includes.c b/tools/scan_includes.c index 9ec5f3c5d..538d9d779 100644 --- a/tools/scan_includes.c +++ b/tools/scan_includes.c @@ -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; }