src/mess/tools/messdocs/messdocs.c
| r7564 | r7565 | |
| 1 | #define WIN32_LEAN_AND_MEAN |
| 2 | #include <windows.h> |
| 3 | #include <ctype.h> |
| 4 | #include <tchar.h> |
| 5 | #include <shlwapi.h> |
| 1 | 6 | #include <stdio.h> |
| 2 | 7 | #include <ctype.h> |
| 3 | 8 | |
| r7564 | r7565 | |
| 5 | 10 | #include "sys/stat.h" |
| 6 | 11 | #include "utils.h" |
| 7 | 12 | #include "osdcore.h" |
| 8 | | |
| 13 | #include "strconv.h" |
| 14 | #include "winutf8.h" |
| 9 | 15 | #include "expat.h" |
| 10 | 16 | |
| 11 | 17 | struct messdocs_state |
| r7564 | r7565 | |
| 32 | 38 | static void *expat_realloc(void *ptr, size_t size); |
| 33 | 39 | static void expat_free(void *ptr); |
| 34 | 40 | |
| 41 | //============================================================ |
| 42 | // win_error_to_mame_file_error |
| 43 | //============================================================ |
| 35 | 44 | |
| 45 | static file_error win_error_to_mame_file_error(DWORD error) |
| 46 | { |
| 47 | file_error filerr; |
| 36 | 48 | |
| 49 | // convert a Windows error to a file_error |
| 50 | switch (error) |
| 51 | { |
| 52 | case ERROR_SUCCESS: |
| 53 | filerr = FILERR_NONE; |
| 54 | break; |
| 55 | |
| 56 | case ERROR_OUTOFMEMORY: |
| 57 | filerr = FILERR_OUT_OF_MEMORY; |
| 58 | break; |
| 59 | |
| 60 | case ERROR_FILE_NOT_FOUND: |
| 61 | case ERROR_PATH_NOT_FOUND: |
| 62 | filerr = FILERR_NOT_FOUND; |
| 63 | break; |
| 64 | |
| 65 | case ERROR_ACCESS_DENIED: |
| 66 | filerr = FILERR_ACCESS_DENIED; |
| 67 | break; |
| 68 | |
| 69 | case ERROR_SHARING_VIOLATION: |
| 70 | filerr = FILERR_ALREADY_OPEN; |
| 71 | break; |
| 72 | |
| 73 | default: |
| 74 | filerr = FILERR_FAILURE; |
| 75 | break; |
| 76 | } |
| 77 | return filerr; |
| 78 | } |
| 79 | |
| 80 | //============================================================ |
| 81 | // osd_is_path_separator |
| 82 | //============================================================ |
| 83 | |
| 84 | static int osd_is_path_separator(char c) |
| 85 | { |
| 86 | return (c == '/') || (c == '\\'); |
| 87 | } |
| 88 | |
| 89 | //============================================================ |
| 90 | // osd_mkdir |
| 91 | //============================================================ |
| 92 | |
| 93 | file_error osd_mkdir(const char *dir) |
| 94 | { |
| 95 | file_error filerr = FILERR_NONE; |
| 96 | |
| 97 | TCHAR *tempstr = tstring_from_utf8(dir); |
| 98 | if (!tempstr) |
| 99 | { |
| 100 | filerr = FILERR_OUT_OF_MEMORY; |
| 101 | goto done; |
| 102 | } |
| 103 | |
| 104 | if (!CreateDirectory(tempstr, NULL)) |
| 105 | { |
| 106 | filerr = win_error_to_mame_file_error(GetLastError()); |
| 107 | goto done; |
| 108 | } |
| 109 | |
| 110 | done: |
| 111 | if (tempstr) |
| 112 | free(tempstr); |
| 113 | return filerr; |
| 114 | } |
| 115 | |
| 116 | |
| 117 | //============================================================ |
| 118 | // osd_rmdir |
| 119 | //============================================================ |
| 120 | |
| 121 | file_error osd_rmdir(const char *dir) |
| 122 | { |
| 123 | file_error filerr = FILERR_NONE; |
| 124 | |
| 125 | TCHAR *tempstr = tstring_from_utf8(dir); |
| 126 | if (!tempstr) |
| 127 | { |
| 128 | filerr = FILERR_OUT_OF_MEMORY; |
| 129 | goto done; |
| 130 | } |
| 131 | |
| 132 | if (!RemoveDirectory(tempstr)) |
| 133 | { |
| 134 | filerr = win_error_to_mame_file_error(GetLastError()); |
| 135 | goto done; |
| 136 | } |
| 137 | |
| 138 | done: |
| 139 | if (tempstr) |
| 140 | free(tempstr); |
| 141 | return filerr; |
| 142 | } |
| 143 | |
| 144 | |
| 145 | //============================================================ |
| 146 | // osd_copyfile |
| 147 | //============================================================ |
| 148 | |
| 149 | file_error osd_copyfile(const char *destfile, const char *srcfile) |
| 150 | { |
| 151 | // wrapper for win_copy_file_utf8() |
| 152 | if (!win_copy_file_utf8(srcfile, destfile, TRUE)) |
| 153 | return win_error_to_mame_file_error(GetLastError()); |
| 154 | |
| 155 | return FILERR_NONE; |
| 156 | } |
| 157 | |
| 37 | 158 | /*************************************************************************** |
| 38 | 159 | CORE IMPLEMENTATION |
| 39 | 160 | ***************************************************************************/ |
| r7564 | r7565 | |
| 119 | 240 | snprintf(buf, ARRAY_LENGTH(buf), "%s", dir); |
| 120 | 241 | combine_path(buf, ARRAY_LENGTH(buf), filepath); |
| 121 | 242 | |
| 122 | | path = malloc(strlen(buf) + 1); |
| 243 | path = (char*)malloc(strlen(buf) + 1); |
| 123 | 244 | if (!path) |
| 124 | 245 | return NULL; |
| 125 | 246 | strcpy(path, buf); |
| r7564 | r7565 | |
| 243 | 364 | |
| 244 | 365 | title = find_attribute(attributes, "title"); |
| 245 | 366 | if (title) |
| 246 | | state->title = pool_strdup(state->pool, title); |
| 367 | state->title = pool_strdup_lib(state->pool, title); |
| 247 | 368 | } |
| 248 | 369 | else if (!strcmp(tagname, "topic")) |
| 249 | 370 | { |
| r7564 | r7565 | |
| 261 | 382 | copy_file_to_dest(state->dest_dir, state->toc_dir, filepath); |
| 262 | 383 | |
| 263 | 384 | if (!state->default_topic) |
| 264 | | state->default_topic = pool_strdup(state->pool, filepath); |
| 385 | state->default_topic = pool_strdup_lib(state->pool, filepath); |
| 265 | 386 | } |
| 266 | 387 | else if (!strcmp(tagname, "folder")) |
| 267 | 388 | { |
| r7564 | r7565 | |
| 317 | 438 | s = strchr(buf, '='); |
| 318 | 439 | s = s ? s + 1 : &buf[strlen(buf)]; |
| 319 | 440 | |
| 320 | | sysinfo_array = pool_realloc(state->pool, sysinfo_array, sizeof(*sysinfo_array) * (sys_count + 1)); |
| 441 | sysinfo_array = (system_info*)pool_realloc_lib(state->pool, sysinfo_array, sizeof(*sysinfo_array) * (sys_count + 1)); |
| 321 | 442 | if (!sysinfo_array) |
| 322 | 443 | goto outofmemory; |
| 323 | | sysinfo_array[sys_count].name = pool_strdup(state->pool, s); |
| 444 | sysinfo_array[sys_count].name = pool_strdup_lib(state->pool, s); |
| 324 | 445 | sysinfo_array[sys_count].desc = NULL; |
| 325 | 446 | |
| 326 | 447 | sysname = sysinfo_array[sys_count].name; |
| r7564 | r7565 | |
| 355 | 476 | |
| 356 | 477 | if (!strncmp(buf, "======", 6) && lineno == 0) |
| 357 | 478 | { |
| 358 | | char *heading = malloc(strlen(buf) + 1); |
| 479 | char *heading = (char*)malloc(strlen(buf) + 1); |
| 359 | 480 | memset(heading, 0, strlen(buf) + 1); |
| 360 | 481 | strncpy(heading, buf + 6, strlen(buf) - 12); |
| 361 | 482 | fprintf(sysfile, "<h1>%s</h1>\n", heading); |
| 362 | 483 | fprintf(sysfile, "<p><i>(directory: %s)</i></p>\n", sysname); |
| 363 | 484 | |
| 364 | 485 | if (!sysinfo_array[sys_count-1].desc) |
| 365 | | sysinfo_array[sys_count-1].desc = pool_strdup(state->pool, heading); |
| 486 | sysinfo_array[sys_count-1].desc = pool_strdup_lib(state->pool, heading); |
| 366 | 487 | |
| 367 | 488 | free(heading); |
| 368 | 489 | } |
| 369 | 490 | else if (buf[0] == '=') |
| 370 | 491 | { |
| 371 | 492 | int count; |
| 372 | | char *heading = malloc(strlen(buf) + 1); |
| 493 | char *heading = (char*)malloc(strlen(buf) + 1); |
| 373 | 494 | memset(heading, 0, strlen(buf) + 1); |
| 374 | 495 | |
| 375 | 496 | if (ul) |
| r7564 | r7565 | |
| 475 | 596 | { |
| 476 | 597 | if (strcmp(ent->name, ".") && strcmp(ent->name, "..")) |
| 477 | 598 | { |
| 478 | | newpath = malloc(strlen(dir_path) + 1 + strlen(ent->name) + 1); |
| 599 | newpath = (char*)malloc(strlen(dir_path) + 1 + strlen(ent->name) + 1); |
| 479 | 600 | if (!newpath) |
| 480 | 601 | return -1; |
| 481 | 602 | |
| r7564 | r7565 | |
| 517 | 638 | XML_Memory_Handling_Suite memcallbacks; |
| 518 | 639 | |
| 519 | 640 | memset(&state, 0, sizeof(state)); |
| 520 | | state.pool = pool_alloc(NULL); |
| 641 | state.pool = pool_alloc_lib(NULL); |
| 521 | 642 | |
| 522 | 643 | /* open the DOC */ |
| 523 | 644 | in = fopen(toc_filename, "r"); |
| r7564 | r7565 | |
| 528 | 649 | } |
| 529 | 650 | |
| 530 | 651 | /* figure out the TOC directory */ |
| 531 | | state.toc_dir = pool_strdup(state.pool, toc_filename); |
| 652 | state.toc_dir = pool_strdup_lib(state.pool, toc_filename); |
| 532 | 653 | if (!state.toc_dir) |
| 533 | 654 | goto outofmemory; |
| 534 | 655 | for (i = strlen(state.toc_dir) - 1; (i > 0) && !osd_is_path_separator(state.toc_dir[i]); i--) |
| r7564 | r7565 | |
| 539 | 660 | osd_mkdir(dest_dir); |
| 540 | 661 | |
| 541 | 662 | /* create the help contents file */ |
| 542 | | s = pool_malloc(state.pool, strlen(dest_dir) + 1 + strlen(help_project_filename) + 1); |
| 663 | s = (char*)pool_malloc_lib(state.pool, strlen(dest_dir) + 1 + strlen(help_project_filename) + 1); |
| 543 | 664 | if (!s) |
| 544 | 665 | goto outofmemory; |
| 545 | 666 | strcpy(s, dest_dir); |
| r7564 | r7565 | |
| 595 | 716 | fclose(state.chm_toc); |
| 596 | 717 | |
| 597 | 718 | /* create the help project file */ |
| 598 | | s = pool_malloc(state.pool, strlen(dest_dir) + 1 + strlen(help_project_filename) + 1); |
| 719 | s = (char*)pool_malloc_lib(state.pool, strlen(dest_dir) + 1 + strlen(help_project_filename) + 1); |
| 599 | 720 | if (!s) |
| 600 | 721 | goto outofmemory; |
| 601 | 722 | strcpy(s, dest_dir); |
| r7564 | r7565 | |
| 620 | 741 | /* finish up */ |
| 621 | 742 | XML_ParserFree(state.parser); |
| 622 | 743 | fclose(in); |
| 623 | | pool_free(state.pool); |
| 744 | pool_free_lib(state.pool); |
| 624 | 745 | return state.error ? -1 : 0; |
| 625 | 746 | |
| 626 | 747 | outofmemory: |