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