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 +#include +#include + +#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 + +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 +#include #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));