changeset 1008:51885857c019

Removed assumptions that path separators are Unix style outside of Unix-only verions of functions
author Michael Pavone <pavone@retrodev.com>
date Sun, 01 May 2016 21:39:43 -0700
parents 5165537244e2
children 883fe974f72b
files blastem.c menu.c util.c util.h
diffstat 4 files changed, 49 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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);
 			}
--- 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);
--- 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);
--- 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