# HG changeset patch # User Michael Pavone # Date 1462163983 25200 # Node ID 51885857c019247eba48cd7427fabaeaeabf0063 # Parent 5165537244e21695bbc5bf77e424fe05b6aa17a5 Removed assumptions that path separators are Unix style outside of Unix-only verions of functions diff -r 5165537244e2 -r 51885857c019 blastem.c --- a/blastem.c Sun May 01 17:43:28 2016 -0700 +++ b/blastem.c Sun May 01 21:39:43 2016 -0700 @@ -330,7 +330,7 @@ } else { char slotname[] = "slot_0.gst"; slotname[5] = '0' + slot; - char const *parts[] = {gen->save_dir, "/", slotname}; + char const *parts[] = {gen->save_dir, PATH_SEP, slotname}; save_path = alloc_concat_m(3, parts); } save_gst(gen, save_path, address); @@ -1027,7 +1027,7 @@ void setup_saves(char *fname, rom_info *info, genesis_context *context) { char * barename = basename_no_extension(fname); - char const * parts[3] = {get_save_dir(), "/", barename}; + char const * parts[3] = {get_save_dir(), PATH_SEP, barename}; char *save_dir = alloc_concat_m(3, parts); if (!ensure_dir_exists(save_dir)) { warning("Failed to create save directory %s\n", save_dir); @@ -1170,7 +1170,7 @@ if (!romfname) { romfname = "menu.bin"; } - if (romfname[0] == '/') { + if (is_absolute_path(romfname)) { if (!(rom_size = load_rom(romfname))) { fatal_error("Failed to open UI ROM %s for reading", romfname); } diff -r 5165537244e2 -r 51885857c019 menu.c --- a/menu.c Sun May 01 17:43:28 2016 -0700 +++ b/menu.c Sun May 01 21:39:43 2016 -0700 @@ -195,14 +195,14 @@ size_t len = strlen(menu->curpath); while (len > 1) { --len; - if (menu->curpath[len] == '/') { + if (is_path_sep(menu->curpath[len])) { menu->curpath[len] = 0; break; } } } else { char *tmp = menu->curpath; - char const *pieces[] = {menu->curpath, "/", buf}; + char const *pieces[] = {menu->curpath, PATH_SEP, buf}; menu->curpath = alloc_concat_m(3, pieces); free(tmp); } @@ -211,7 +211,7 @@ case 2: { char buf[4096]; copy_string_from_guest(m68k, dst, buf, sizeof(buf)); - char const *pieces[] = {menu->curpath, "/", buf}; + char const *pieces[] = {menu->curpath, PATH_SEP, buf}; gen->next_rom = alloc_concat_m(3, pieces); m68k->should_return = 1; break; @@ -236,7 +236,7 @@ if (gen->next_context && gen->next_context->save_dir) { char *end = buffer + SAVE_INFO_BUFFER_SIZE; char slotfile[] = "slot_0.gst"; - char const * parts[3] = {gen->next_context->save_dir, "/", slotfile}; + char const * parts[3] = {gen->next_context->save_dir, PATH_SEP, slotfile}; struct tm ltime; char *fname; time_t modtime; @@ -297,7 +297,7 @@ numslotname[5] = '0' + dst; slotname = numslotname; } - char const *parts[] = {gen->next_context->save_dir, "/", slotname}; + char const *parts[] = {gen->next_context->save_dir, PATH_SEP, slotname}; char *gstpath = alloc_concat_m(3, parts); uint32_t pc = load_gst(gen->next_context, gstpath); free(gstpath); diff -r 5165537244e2 -r 51885857c019 util.c --- a/util.c Sun May 01 17:43:28 2016 -0700 +++ b/util.c Sun May 01 21:39:43 2016 -0700 @@ -94,6 +94,26 @@ return text+1; } +char is_path_sep(char c) +{ +#ifdef _WIN32 + if (c == '\\') { + return 1; + } +#endif + return c == '/'; +} + +char is_absolute_path(char *path) +{ +#ifdef _WIN32 + if (path[1] == ':' && is_path_sep(path[2]) && isalpha(path[0])) { + return 1; + } +#endif + return is_path_sep(path[0]); +} + char * basename_no_extension(char *path) { char *lastdot = NULL; @@ -103,7 +123,7 @@ { if (*cur == '.') { lastdot = cur; - } else if (*cur == '/') { + } else if (is_path_sep(*cur)) { lastslash = cur + 1; } } @@ -314,7 +334,13 @@ return 0; } char *parent = strdup(path); - char *sep = strrchr(parent, '/'); + //Windows technically supports both native and Unix-style path separators + //so search for both + char *sep = strrchr(parent, '\\'); + char *osep = strrchr(parent, '/'); + if (osep && (!sep || osep < sep)) { + sep = osep; + } if (!sep || sep == parent) { //relative path, but for some reason we failed return 0; @@ -372,7 +398,7 @@ int linksize = strlen(linktext); for(cur = linktext + linksize - 1; cur != linktext; cur--) { - if (*cur == '/') { + if (is_path_sep(*cur)) { *cur = 0; break; } @@ -387,7 +413,7 @@ int pathsize = strlen(exe_str); for(cur = exe_str + pathsize - 1; cur != exe_str; cur--) { - if (*cur == '/') { + if (is_path_sep(*cur)) { exe_dir = malloc(cur-exe_str+1); memcpy(exe_dir, exe_str, cur-exe_str); exe_dir[cur-exe_str] = 0; @@ -533,7 +559,7 @@ } return NULL; } - char const *pieces[] = {exe_dir, "/", name}; + char const *pieces[] = {exe_dir, PATH_SEP, name}; char *path = alloc_concat_m(3, pieces); FILE *f = fopen(path, "rb"); free(path); diff -r 5165537244e2 -r 51885857c019 util.h --- a/util.h Sun May 01 17:43:28 2016 -0700 +++ b/util.h Sun May 01 21:39:43 2016 -0700 @@ -9,6 +9,12 @@ uint8_t is_dir; } dir_entry; +#ifdef _WIN32 +#define PATH_SEP "\\" +#else +#define PATH_SEP "/" +#endif + //Utility functions //Allocates a new string containing the concatenation of first and second @@ -21,6 +27,10 @@ char * strip_ws(char * text); //Inserts a null after the first word, returns a pointer to the second word char * split_keyval(char * text); +//Determines whether a character is a valid path separator for the current platform +char is_path_sep(char c); +//Determines whether a path is considered an absolute path on the current platform +char is_absolute_path(char *path); //Returns the basename of a path with th extension (if any) stripped char * basename_no_extension(char *path); //Gets the smallest power of two that is >= a certain value, won't work for values > 0x80000000