Mercurial > repos > blastem
comparison util.c @ 1648:b7ecd0d6a77b mame_interp
Merge from default
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 25 Dec 2018 11:12:26 -0800 |
parents | 137dbd05ceab |
children | ab3b465c052c |
comparison
equal
deleted
inserted
replaced
1509:36732f5c2281 | 1648:b7ecd0d6a77b |
---|---|
202 size--; | 202 size--; |
203 } | 203 } |
204 *(output++) = 0; | 204 *(output++) = 0; |
205 } | 205 } |
206 | 206 |
207 char *utf16be_to_utf8(uint8_t *buf, uint32_t max_size) | |
208 { | |
209 uint8_t *cur = buf; | |
210 uint32_t converted_size = 0; | |
211 for (uint32_t i = 0; i < max_size; i++, cur+=2) | |
212 { | |
213 uint16_t code = *cur << 16 | cur[1]; | |
214 if (!code) { | |
215 break; | |
216 } | |
217 if (code < 0x80) { | |
218 converted_size++; | |
219 } else if (code < 0x800) { | |
220 converted_size += 2; | |
221 } else { | |
222 //TODO: Deal with surrogate pairs | |
223 converted_size += 3; | |
224 } | |
225 } | |
226 char *out = malloc(converted_size + 1); | |
227 char *cur_out = out; | |
228 cur = buf; | |
229 for (uint32_t i = 0; i < max_size; i++, cur+=2) | |
230 { | |
231 uint16_t code = *cur << 16 | cur[1]; | |
232 if (!code) { | |
233 break; | |
234 } | |
235 if (code < 0x80) { | |
236 *(cur_out++) = code; | |
237 } else if (code < 0x800) { | |
238 *(cur_out++) = 0xC0 | code >> 6; | |
239 *(cur_out++) = 0x80 | (code & 0x3F); | |
240 } else { | |
241 //TODO: Deal with surrogate pairs | |
242 *(cur_out++) = 0xF0 | code >> 12; | |
243 *(cur_out++) = 0x80 | (code >> 6 & 0x3F); | |
244 *(cur_out++) = 0x80 | (code & 0x3F); | |
245 } | |
246 } | |
247 *cur_out = 0; | |
248 return out; | |
249 } | |
250 | |
251 int utf8_codepoint(const char **text) | |
252 { | |
253 uint8_t initial = **text; | |
254 (*text)++; | |
255 if (initial < 0x80) { | |
256 return initial; | |
257 } | |
258 int base = 0; | |
259 uint8_t extended_bytes = 0; | |
260 if ((initial & 0xE0) == 0xC0) { | |
261 base = 0x80; | |
262 initial &= 0x1F; | |
263 extended_bytes = 1; | |
264 } else if ((initial & 0xF0) == 0xE0) { | |
265 base = 0x800; | |
266 initial &= 0xF; | |
267 extended_bytes = 2; | |
268 } else if ((initial & 0xF8) == 0xF0) { | |
269 base = 0x10000; | |
270 initial &= 0x7; | |
271 extended_bytes = 3; | |
272 } | |
273 int value = initial; | |
274 for (uint8_t i = 0; i < extended_bytes; i++) | |
275 { | |
276 if ((**text & 0xC0) != 0x80) { | |
277 return -1; | |
278 } | |
279 value = value << 6; | |
280 value |= (**text) & 0x3F; | |
281 (*text)++; | |
282 } | |
283 return value + base; | |
284 } | |
285 | |
207 char is_path_sep(char c) | 286 char is_path_sep(char c) |
208 { | 287 { |
209 #ifdef _WIN32 | 288 #ifdef _WIN32 |
210 if (c == '\\') { | 289 if (c == '\\') { |
211 return 1; | 290 return 1; |
222 } | 301 } |
223 #endif | 302 #endif |
224 return is_path_sep(path[0]); | 303 return is_path_sep(path[0]); |
225 } | 304 } |
226 | 305 |
227 char * basename_no_extension(char *path) | 306 char * basename_no_extension(const char *path) |
228 { | 307 { |
229 char *lastdot = NULL; | 308 const char *lastdot = NULL; |
230 char *lastslash = NULL; | 309 const char *lastslash = NULL; |
231 char *cur; | 310 const char *cur; |
232 for (cur = path; *cur; cur++) | 311 for (cur = path; *cur; cur++) |
233 { | 312 { |
234 if (*cur == '.') { | 313 if (*cur == '.') { |
235 lastdot = cur; | 314 lastdot = cur; |
236 } else if (is_path_sep(*cur)) { | 315 } else if (is_path_sep(*cur)) { |
248 barename[lastdot-lastslash] = 0; | 327 barename[lastdot-lastslash] = 0; |
249 | 328 |
250 return barename; | 329 return barename; |
251 } | 330 } |
252 | 331 |
253 char *path_extension(char *path) | 332 char *path_extension(char const *path) |
254 { | 333 { |
255 char *lastdot = NULL; | 334 char const *lastdot = NULL; |
256 char *lastslash = NULL; | 335 char const *lastslash = NULL; |
257 char *cur; | 336 char const *cur; |
258 for (cur = path; *cur; cur++) | 337 for (cur = path; *cur; cur++) |
259 { | 338 { |
260 if (*cur == '.') { | 339 if (*cur == '.') { |
261 lastdot = cur; | 340 lastdot = cur; |
262 } else if (is_path_sep(*cur)) { | 341 } else if (is_path_sep(*cur)) { |
268 return NULL; | 347 return NULL; |
269 } | 348 } |
270 return strdup(lastdot+1); | 349 return strdup(lastdot+1); |
271 } | 350 } |
272 | 351 |
273 char * path_dirname(char *path) | 352 uint8_t path_matches_extensions(char *path, char **ext_list, uint32_t num_exts) |
274 { | 353 { |
275 char *lastslash = NULL; | 354 char *ext = path_extension(path); |
276 char *cur; | 355 if (!ext) { |
356 return 0; | |
357 } | |
358 uint32_t extidx; | |
359 for (extidx = 0; extidx < num_exts; extidx++) | |
360 { | |
361 if (!strcasecmp(ext, ext_list[extidx])) { | |
362 free(ext); | |
363 return 1; | |
364 } | |
365 } | |
366 free(ext); | |
367 return 0; | |
368 } | |
369 | |
370 char * path_dirname(const char *path) | |
371 { | |
372 const char *lastslash = NULL; | |
373 const char *cur; | |
277 for (cur = path; *cur; cur++) | 374 for (cur = path; *cur; cur++) |
278 { | 375 { |
279 if (is_path_sep(*cur)) { | 376 if (is_path_sep(*cur)) { |
280 lastslash = cur; | 377 lastslash = cur; |
281 } | 378 } |
487 //adjust for difference between Windows and Unix Epoch | 584 //adjust for difference between Windows and Unix Epoch |
488 wintime -= 11644473600LL; | 585 wintime -= 11644473600LL; |
489 return (time_t)wintime; | 586 return (time_t)wintime; |
490 } | 587 } |
491 | 588 |
492 int ensure_dir_exists(char *path) | 589 int ensure_dir_exists(const char *path) |
493 { | 590 { |
494 if (CreateDirectory(path, NULL)) { | 591 if (CreateDirectory(path, NULL)) { |
495 return 1; | 592 return 1; |
496 } | 593 } |
497 if (GetLastError() == ERROR_ALREADY_EXISTS) { | 594 if (GetLastError() == ERROR_ALREADY_EXISTS) { |
624 ret[pos++].is_dir = entry->d_type == DT_DIR; | 721 ret[pos++].is_dir = entry->d_type == DT_DIR; |
625 } | 722 } |
626 if (numret) { | 723 if (numret) { |
627 *numret = pos; | 724 *numret = pos; |
628 } | 725 } |
726 closedir(d); | |
629 return ret; | 727 return ret; |
630 } | 728 } |
631 | 729 |
632 time_t get_modification_time(char *path) | 730 time_t get_modification_time(char *path) |
633 { | 731 { |
641 //Android's Bionic doesn't support the new style so we'll use the old one instead | 739 //Android's Bionic doesn't support the new style so we'll use the old one instead |
642 return st.st_mtime; | 740 return st.st_mtime; |
643 #endif | 741 #endif |
644 } | 742 } |
645 | 743 |
646 int ensure_dir_exists(char *path) | 744 int ensure_dir_exists(const char *path) |
647 { | 745 { |
648 struct stat st; | 746 struct stat st; |
649 if (stat(path, &st)) { | 747 if (stat(path, &st)) { |
650 if (errno == ENOENT) { | 748 if (errno == ENOENT) { |
651 char *parent = strdup(path); | 749 char *parent = strdup(path); |
678 free(list[i].name); | 776 free(list[i].name); |
679 } | 777 } |
680 free(list); | 778 free(list); |
681 } | 779 } |
682 | 780 |
781 static int sort_dir_alpha(const void *a, const void *b) | |
782 { | |
783 const dir_entry *da, *db; | |
784 da = a; | |
785 db = b; | |
786 if (da->is_dir != db->is_dir) { | |
787 return db->is_dir - da->is_dir; | |
788 } | |
789 return strcasecmp(((dir_entry *)a)->name, ((dir_entry *)b)->name); | |
790 } | |
791 | |
792 void sort_dir_list(dir_entry *list, size_t num_entries) | |
793 { | |
794 qsort(list, num_entries, sizeof(dir_entry), sort_dir_alpha); | |
795 } | |
796 | |
683 #ifdef __ANDROID__ | 797 #ifdef __ANDROID__ |
684 | 798 |
685 #include <SDL.h> | 799 #include <SDL.h> |
686 char *read_bundled_file(char *name, uint32_t *sizeret) | 800 char *read_bundled_file(char *name, uint32_t *sizeret) |
687 { | 801 { |
757 ret = NULL; | 871 ret = NULL; |
758 } | 872 } |
759 } else { | 873 } else { |
760 ret = NULL; | 874 ret = NULL; |
761 } | 875 } |
876 fclose(f); | |
762 return ret; | 877 return ret; |
763 } | 878 } |
764 | 879 |
765 | 880 |
766 #ifdef _WIN32 | 881 #ifdef _WIN32 |