Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/n64graphics_ci_dir/utils.c
7857 views
1
#include <dirent.h>
2
#include <fcntl.h>
3
#include <stdint.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <sys/stat.h>
8
#if defined(_MSC_VER) || defined(__MINGW32__)
9
#include <io.h>
10
#include <sys/utime.h>
11
#else
12
#include <unistd.h>
13
#include <utime.h>
14
#endif
15
16
#include "utils.h"
17
18
// global verbosity setting
19
int g_verbosity = 0;
20
21
int read_s16_be(unsigned char *buf)
22
{
23
unsigned tmp = read_u16_be(buf);
24
int ret;
25
if (tmp > 0x7FFF) {
26
ret = -((int)0x10000 - (int)tmp);
27
} else {
28
ret = (int)tmp;
29
}
30
return ret;
31
}
32
33
float read_f32_be(unsigned char *buf)
34
{
35
union {uint32_t i; float f;} ret;
36
ret.i = read_u32_be(buf);
37
return ret.f;
38
}
39
40
int is_power2(unsigned int val)
41
{
42
while (((val & 1) == 0) && (val > 1)) {
43
val >>= 1;
44
}
45
return (val == 1);
46
}
47
48
void fprint_hex(FILE *fp, const unsigned char *buf, int length)
49
{
50
int i;
51
for (i = 0; i < length; i++) {
52
fprint_byte(fp, buf[i]);
53
fputc(' ', fp);
54
}
55
}
56
57
void fprint_hex_source(FILE *fp, const unsigned char *buf, int length)
58
{
59
int i;
60
for (i = 0; i < length; i++) {
61
if (i > 0) fputs(", ", fp);
62
fputs("0x", fp);
63
fprint_byte(fp, buf[i]);
64
}
65
}
66
67
void print_hex(const unsigned char *buf, int length)
68
{
69
fprint_hex(stdout, buf, length);
70
}
71
72
void swap_bytes(unsigned char *data, long length)
73
{
74
long i;
75
unsigned char tmp;
76
for (i = 0; i < length; i += 2) {
77
tmp = data[i];
78
data[i] = data[i+1];
79
data[i+1] = tmp;
80
}
81
}
82
83
void reverse_endian(unsigned char *data, long length)
84
{
85
long i;
86
unsigned char tmp;
87
for (i = 0; i < length; i += 4) {
88
tmp = data[i];
89
data[i] = data[i+3];
90
data[i+3] = tmp;
91
tmp = data[i+1];
92
data[i+1] = data[i+2];
93
data[i+2] = tmp;
94
}
95
}
96
97
long filesize(const char *filename)
98
{
99
struct stat st;
100
101
if (stat(filename, &st) == 0) {
102
return st.st_size;
103
}
104
105
return -1;
106
}
107
108
void touch_file(const char *filename)
109
{
110
int fd;
111
//fd = open(filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666);
112
fd = open(filename, O_WRONLY|O_CREAT, 0666);
113
if (fd >= 0) {
114
utime(filename, NULL);
115
close(fd);
116
}
117
}
118
119
long read_file(const char *file_name, unsigned char **data)
120
{
121
FILE *in;
122
unsigned char *in_buf = NULL;
123
long file_size;
124
long bytes_read;
125
in = fopen(file_name, "rb");
126
if (in == NULL) {
127
return -1;
128
}
129
130
// allocate buffer to read from offset to end of file
131
fseek(in, 0, SEEK_END);
132
file_size = ftell(in);
133
134
// sanity check
135
if (file_size > 256*MB) {
136
return -2;
137
}
138
139
in_buf = malloc(file_size);
140
fseek(in, 0, SEEK_SET);
141
142
// read bytes
143
bytes_read = fread(in_buf, 1, file_size, in);
144
if (bytes_read != file_size) {
145
return -3;
146
}
147
148
fclose(in);
149
*data = in_buf;
150
return bytes_read;
151
}
152
153
long write_file(const char *file_name, unsigned char *data, long length)
154
{
155
FILE *out;
156
long bytes_written;
157
// open output file
158
out = fopen(file_name, "wb");
159
if (out == NULL) {
160
perror(file_name);
161
return -1;
162
}
163
bytes_written = fwrite(data, 1, length, out);
164
fclose(out);
165
return bytes_written;
166
}
167
168
void generate_filename(const char *in_name, char *out_name, char *extension)
169
{
170
char tmp_name[FILENAME_MAX];
171
int len;
172
int i;
173
strcpy(tmp_name, in_name);
174
len = strlen(tmp_name);
175
for (i = len - 1; i > 0; i--) {
176
if (tmp_name[i] == '.') {
177
break;
178
}
179
}
180
if (i <= 0) {
181
i = len;
182
}
183
tmp_name[i] = '\0';
184
sprintf(out_name, "%s.%s", tmp_name, extension);
185
}
186
187
char *basename(const char *name)
188
{
189
const char *base = name;
190
while (*name) {
191
if (*name++ == '/') {
192
base = name;
193
}
194
}
195
return (char *)base;
196
}
197
198
void make_dir(const char *dir_name)
199
{
200
struct stat st = {0};
201
if (stat(dir_name, &st) == -1) {
202
mkdir(dir_name, 0755);
203
}
204
}
205
206
long copy_file(const char *src_name, const char *dst_name)
207
{
208
unsigned char *buf;
209
long bytes_written;
210
long bytes_read;
211
212
bytes_read = read_file(src_name, &buf);
213
214
if (bytes_read > 0) {
215
bytes_written = write_file(dst_name, buf, bytes_read);
216
if (bytes_written != bytes_read) {
217
bytes_read = -1;
218
}
219
free(buf);
220
}
221
222
return bytes_read;
223
}
224
225
void dir_list_ext(const char *dir, const char *extension, dir_list *list)
226
{
227
char *pool;
228
char *pool_ptr;
229
struct dirent *entry;
230
DIR *dfd;
231
int idx;
232
233
dfd = opendir(dir);
234
if (dfd == NULL) {
235
ERROR("Can't open '%s'\n", dir);
236
exit(1);
237
}
238
239
pool = malloc(FILENAME_MAX * MAX_DIR_FILES);
240
pool_ptr = pool;
241
242
idx = 0;
243
while ((entry = readdir(dfd)) != NULL && idx < MAX_DIR_FILES) {
244
if (!extension || str_ends_with(entry->d_name, extension)) {
245
sprintf(pool_ptr, "%s/%s", dir, entry->d_name);
246
list->files[idx] = pool_ptr;
247
pool_ptr += strlen(pool_ptr) + 1;
248
idx++;
249
}
250
}
251
list->count = idx;
252
253
closedir(dfd);
254
}
255
256
void dir_list_free(dir_list *list)
257
{
258
// assume first entry in array is allocated
259
if (list->files[0]) {
260
free(list->files[0]);
261
list->files[0] = NULL;
262
}
263
}
264
265
int str_ends_with(const char *str, const char *suffix)
266
{
267
if (!str || !suffix) {
268
return 0;
269
}
270
size_t len_str = strlen(str);
271
size_t len_suffix = strlen(suffix);
272
if (len_suffix > len_str) {
273
return 0;
274
}
275
return (0 == strncmp(str + len_str - len_suffix, suffix, len_suffix));
276
}
277
278