From 01c19f943bbb62b05dc122456dbd173987b97291 Mon Sep 17 00:00:00 2001
From: twinaphex <libretro@gmail.com>
Date: Fri, 13 Mar 2015 15:35:55 +0100
Subject: [PATCH] Add stdstring to libretro-common

---
 Makefile.common                            |  1 +
 libretro-common/include/string/stdstring.h | 41 +++++++++++++++
 libretro-common/string/stdstring.c         | 61 ++++++++++++++++++++++
 menu/drivers/xmb.c                         | 53 +++----------------
 4 files changed, 111 insertions(+), 45 deletions(-)
 create mode 100644 libretro-common/include/string/stdstring.h
 create mode 100644 libretro-common/string/stdstring.c

diff --git a/Makefile.common b/Makefile.common
index fce3020d39..eed328a7c2 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -100,6 +100,7 @@ OBJ += frontend/frontend.o \
 		libretro-common/file/file_list.o \
 		libretro-common/file/dir_list.o \
 		libretro-common/string/string_list.o \
+		libretro-common/string/stdstring.o \
 		file_ops.o \
 		libretro-common/file//nbio/nbio_stdio.o \
 		libretro-common/file/file_path.o \
diff --git a/libretro-common/include/string/stdstring.h b/libretro-common/include/string/stdstring.h
new file mode 100644
index 0000000000..635ced1112
--- /dev/null
+++ b/libretro-common/include/string/stdstring.h
@@ -0,0 +1,41 @@
+/* Copyright  (C) 2010-2015 The RetroArch team
+ *
+ * ---------------------------------------------------------------------------------------
+ * The following license statement only applies to this file (stdstring.h).
+ * ---------------------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIBRETRO_SDK_STDSTRING_H
+#define __LIBRETRO_SDK_STDSTRING_H
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *string_replace_substring(const char *in, const char *pattern,
+      const char *by);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libretro-common/string/stdstring.c b/libretro-common/string/stdstring.c
new file mode 100644
index 0000000000..4d6bd14878
--- /dev/null
+++ b/libretro-common/string/stdstring.c
@@ -0,0 +1,61 @@
+/* Copyright  (C) 2010-2015 The RetroArch team
+ *
+ * ---------------------------------------------------------------------------------------
+ * The following license statement only applies to this file (stdstring.c).
+ * ---------------------------------------------------------------------------------------
+ *
+ * Permission is hereby granted, free of charge,
+ * to any person obtaining a copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string/stdstring.h>
+
+char *string_replace_substring(const char *in, const char *pattern, const char *by)
+{
+   char *needle;
+   size_t outsize = strlen(in) + 1;
+   /* use this to iterate over the output */
+   size_t resoffset = 0;
+
+   /* TODO maybe avoid reallocating by counting the 
+    * non-overlapping occurences of pattern */
+   char *res = malloc(outsize);
+
+   if (!res)
+      return NULL;
+
+   while ((needle = strstr(in, pattern)))
+   {
+      /* copy everything up to the pattern */
+      memcpy(res + resoffset, in, needle - in);
+      resoffset += needle - in;
+
+      /* skip the pattern in the input-string */
+      in = needle + strlen(pattern);
+
+      /* adjust space for replacement */
+      outsize = outsize - strlen(pattern) + strlen(by);
+      res = realloc(res, outsize);
+
+      /* copy the pattern */
+      memcpy(res + resoffset, by, strlen(by));
+      resoffset += strlen(by);
+   }
+
+   /* copy the remaining input */
+   strcpy(res + resoffset, in);
+
+   return res;
+}
diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c
index ec6aba0f5a..9bda861c0a 100644
--- a/menu/drivers/xmb.c
+++ b/menu/drivers/xmb.c
@@ -28,6 +28,7 @@
 #include "../../gfx/gl_common.h"
 #include "../../gfx/video_thread_wrapper.h"
 #include <compat/posix_string.h>
+#include <string/stdstring.h>
 
 #include "shared.h"
 
@@ -265,48 +266,6 @@ static int xmb_entry_iterate(unsigned action)
    return -1;
 }
 
-static char *xmb_str_replace (const char *string,
-      const char *substr, const char *replacement)
-{
-   char *tok, *newstr, *head;
-
-   /* if either substr or replacement is NULL, 
-    * duplicate string a let caller handle it. */
-   if (!substr || !replacement)
-      return strdup(string);
-
-   newstr = strdup(string);
-   head   = newstr;
-
-   while ((tok = strstr (head, substr)))
-   {
-      char* oldstr = newstr;
-      newstr = (char*)malloc(
-            strlen(oldstr) - strlen(substr) + strlen(replacement) + 1);
-
-      if (!newstr)
-      {
-         /* Failed to allocate memory,
-          * free old string and return NULL. */
-         free(oldstr);
-         return NULL;
-      }
-
-      memcpy(newstr, oldstr, tok - oldstr);
-      memcpy(newstr + (tok - oldstr), replacement, strlen(replacement));
-      memcpy(newstr + (tok - oldstr) + strlen(replacement),
-            tok + strlen(substr),
-            strlen(oldstr) - strlen(substr) - (tok - oldstr));
-      newstr[strlen(oldstr) - strlen(substr) + strlen(replacement)] = '\0';
-
-      /* Move back head right after the last replacement. */
-      head = newstr + (tok - oldstr) + strlen(replacement);
-      free(oldstr);
-   }
-
-   return newstr;
-}
-
 static void xmb_draw_icon_begin(gl_t *gl, xmb_handle_t *xmb)
 {
    if (!gl)
@@ -1745,9 +1704,13 @@ static void xmb_context_reset(void)
 
       if (info->systemname)
       {
-         char *tmp = xmb_str_replace(info->systemname, "/", " ");
-         strlcpy(core_id, tmp, sizeof(core_id));
-         free(tmp);
+         char *tmp = string_replace_substring(info->systemname, "/", " ");
+
+         if (tmp)
+         {
+            strlcpy(core_id, tmp, sizeof(core_id));
+            free(tmp);
+         }
       }
       else
          strlcpy(core_id, "default", sizeof(core_id));