Skip to content

Commit a75dd22

Browse files
committed
Slightly refactor some C tools
1 parent 7e78c11 commit a75dd22

File tree

5 files changed

+325
-310
lines changed

5 files changed

+325
-310
lines changed

‎Makefile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ clean: tidy
4848
find gfx \( -iname '*.1bpp' -o -iname '*.2bpp' -o -iname '*.pic' \) -delete
4949

5050
tidy:
51-
rm -f $(roms) $(pokered_obj) $(pokeblue_obj) $(pokeblue_debug_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
51+
$(RM) $(roms) $(pokered_obj) $(pokeblue_obj) $(pokeblue_debug_obj) $(roms:.gbc=.map) $(roms:.gbc=.sym) rgbdscheck.o
5252
$(MAKE) clean -C tools/
5353

5454
compare: $(roms)

‎tools/Makefile‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
.PHONY: all clean
22

33
CC := gcc
4-
CFLAGS := -O3 -std=c99 -Wall -Wextra -Wno-missing-field-initializers
4+
CFLAGS := -O3 -std=c11 -Wall -Wextra -pedantic -Wno-missing-field-initializers
55

6-
tools := scan_includes gfx pkmncompress
6+
tools := \
7+
gfx \
8+
pkmncompress \
9+
scan_includes
710

811
all: $(tools)
912
@:
1013

1114
clean:
12-
rm -f $(tools)
15+
$(RM) $(tools)
1316

1417
gfx: common.h
18+
scan_includes: common.h
19+
1520
%: %.c
1621
$(CC) $(CFLAGS) -o $@ $<

‎tools/common.h‎

Lines changed: 111 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,132 @@
11
#ifndef GUARD_COMMON_H
22
#define GUARD_COMMON_H
33

4-
int __getopt_long_i__;
5-
#define getopt_long(c, v, s, l) getopt_long(c, v, s, l, &__getopt_long_i__)
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
#include <stdint.h>
7+
#include <stdbool.h>
8+
#include <inttypes.h>
9+
#include <string.h>
10+
#include <errno.h>
11+
#include <getopt.h>
612

7-
FILE *fopen_verbose(char *filename, char *mode) {
13+
#ifndef PROGRAM_NAME
14+
#error Define PROGRAM_NAME before including common.h!
15+
#endif
16+
#ifndef USAGE_OPTS
17+
#error Define USAGE_OPTS before including common.h!
18+
#endif
19+
20+
#define error_exit(...) exit((fprintf(stderr, PROGRAM_NAME ": " __VA_ARGS__), 1))
21+
22+
void usage_exit(int status) {
23+
fprintf(stderr, "Usage: " PROGRAM_NAME " " USAGE_OPTS "\n");
24+
exit(status);
25+
}
26+
27+
int getopt_long_index;
28+
#define getopt_long(argc, argv, optstring, longopts) getopt_long(argc, argv, optstring, longopts, &getopt_long_index)
29+
30+
void *xmalloc(size_t size) {
31+
errno = 0;
32+
void *m = malloc(size);
33+
if (!m) {
34+
error_exit("Could not allocate %zu bytes: %s\n", size, strerror(errno));
35+
}
36+
return m;
37+
}
38+
39+
void *xcalloc(size_t size) {
40+
errno = 0;
41+
void *m = calloc(size, 1);
42+
if (!m) {
43+
error_exit("Could not allocate %zu bytes: %s\n", size, strerror(errno));
44+
}
45+
return m;
46+
}
47+
48+
void *xrealloc(void *m, size_t size) {
49+
errno = 0;
50+
m = realloc(m, size);
51+
if (!m) {
52+
error_exit("Could not allocate %zu bytes: %s\n", size, strerror(errno));
53+
}
54+
return m;
55+
}
56+
57+
FILE *xfopen(const char *filename, char rw) {
58+
char mode[3] = {rw, 'b', '\0'};
59+
errno = 0;
860
FILE *f = fopen(filename, mode);
961
if (!f) {
10-
fprintf(stderr, "Could not open file: \"%s\"\n", filename);
62+
error_exit("Could not open file \"%s\": %s\n", filename, strerror(errno));
1163
}
1264
return f;
1365
}
1466

15-
uint8_t *read_u8(char *filename, int *size) {
16-
FILE *f = fopen_verbose(filename, "rb");
17-
if (!f) {
18-
exit(1);
67+
void xfread(uint8_t *data, size_t size, const char *filename, FILE *f) {
68+
errno = 0;
69+
if (fread(data, 1, size, f) != size) {
70+
fclose(f);
71+
error_exit("Could not read from file \"%s\": %s\n", filename, strerror(errno));
72+
}
73+
}
74+
75+
void xfwrite(const uint8_t *data, size_t size, const char *filename, FILE *f) {
76+
errno = 0;
77+
if (fwrite(data, 1, size, f) != size) {
78+
fclose(f);
79+
error_exit("Could not write to file \"%s\": %s\n", filename, strerror(errno));
80+
}
81+
}
82+
83+
long xfsize(const char *filename, FILE *f) {
84+
long size = -1;
85+
errno = 0;
86+
if (!fseek(f, 0, SEEK_END)) {
87+
size = ftell(f);
88+
if (size != -1) {
89+
rewind(f);
90+
}
1991
}
20-
fseek(f, 0, SEEK_END);
21-
*size = ftell(f);
22-
rewind(f);
23-
uint8_t *data = malloc(*size);
24-
if (*size != (int)fread(data, 1, *size, f)) {
25-
fprintf(stderr, "Could not read file: \"%s\"\n", filename);
26-
exit(1);
92+
if (size == -1) {
93+
error_exit("Could not measure file \"%s\": %s\n", filename, strerror(errno));
2794
}
95+
return size;
96+
}
97+
98+
uint8_t *read_u8(const char *filename, long *size) {
99+
FILE *f = xfopen(filename, 'r');
100+
*size = xfsize(filename, f);
101+
uint8_t *data = xmalloc(*size);
102+
xfread(data, *size, filename, f);
28103
fclose(f);
29104
return data;
30105
}
31106

32-
void write_u8(char *filename, uint8_t *data, int size) {
33-
FILE *f = fopen_verbose(filename, "wb");
34-
if (f) {
35-
fwrite(data, 1, size, f);
107+
void write_u8(const char *filename, uint8_t *data, size_t size) {
108+
FILE *f = xfopen(filename, 'w');
109+
xfwrite(data, size, filename, f);
110+
fclose(f);
111+
}
112+
113+
uint32_t read_png_width(const char *filename) {
114+
FILE *f = xfopen(filename, 'r');
115+
uint8_t header[16] = {0};
116+
xfread(header, sizeof(header), filename, f);
117+
static uint8_t expected_header[16] = {
118+
0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n', // signature
119+
0, 0, 0, 13, // IHDR chunk length
120+
'I', 'H', 'D', 'R', // IHDR chunk type
121+
};
122+
if (memcmp(header, expected_header, sizeof(header))) {
36123
fclose(f);
124+
error_exit("Not a valid PNG file: \"%s\"\n", filename);
37125
}
126+
uint8_t bytes[4] = {0};
127+
xfread(bytes, sizeof(bytes), filename, f);
128+
fclose(f);
129+
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
38130
}
39131

40132
#endif // GUARD_COMMON_H

0 commit comments

Comments
 (0)