diff --git a/src/credits.c b/src/credits.c index 59025a6a..390ae327 100644 --- a/src/credits.c +++ b/src/credits.c @@ -220,7 +220,7 @@ static void credits_add(char *data, int time) { for(c = data; *c; ++c) { if(*c == '\n') { buf[i] = 0; - e->data[l] = strdup(buf); + e->data[l] = mem_strdup(buf); i = 0; ++l; } else { @@ -229,7 +229,7 @@ static void credits_add(char *data, int time) { } buf[i] = 0; - e->data[l] = strdup(buf); + e->data[l] = mem_strdup(buf); credits.end += time; } diff --git a/src/filewatch/filewatch_inotify.c b/src/filewatch/filewatch_inotify.c index cae4dfc5..b0422ba0 100644 --- a/src/filewatch/filewatch_inotify.c +++ b/src/filewatch/filewatch_inotify.c @@ -156,7 +156,7 @@ static DirWatch *dirwatch_get(const char *path, bool create) { } dw = ALLOC(typeof(*dw)); - dw->path = strdup(path); + dw->path = mem_strdup(path); dw->wd = wd; WDRecord *wdrec = NOT_NULL(wdrecord_get(wd, true)); @@ -355,7 +355,7 @@ FileWatch *filewatch_watch(const char *syspath) { auto fw = list_push(&dw->filewatch_list, ALLOC(FileWatch, { .dw = dw, - .filename = strdup(filename), + .filename = mem_strdup(filename), })); SDL_UnlockMutex(FW.modify_mtx); diff --git a/src/hashtable.inc.h b/src/hashtable.inc.h index 60b29886..8387781f 100644 --- a/src/hashtable.inc.h +++ b/src/hashtable.inc.h @@ -157,7 +157,7 @@ * * Example: * - * #define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) + * #define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) */ #ifndef HT_FUNC_COPY_KEY #define HT_FUNC_COPY_KEY(dst, src) (*(dst) = (src)) diff --git a/src/hashtable_predefs.inc.h b/src/hashtable_predefs.inc.h index 5bb6f4d4..0bad3393 100644 --- a/src/hashtable_predefs.inc.h +++ b/src/hashtable_predefs.inc.h @@ -21,7 +21,7 @@ #define HT_FUNC_FREE_KEY(key) mem_free(key) #define HT_FUNC_KEYS_EQUAL(key1, key2) (!strcmp(key1, key2)) #define HT_FUNC_HASH_KEY(key) htutil_hashfunc_string(key) -#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) +#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) #define HT_KEY_FMT "s" #define HT_KEY_PRINTABLE(key) (key) #define HT_VALUE_FMT "p" @@ -41,7 +41,7 @@ #define HT_FUNC_FREE_KEY(key) mem_free(key) #define HT_FUNC_KEYS_EQUAL(key1, key2) (!strcmp(key1, key2)) #define HT_FUNC_HASH_KEY(key) htutil_hashfunc_string(key) -#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) +#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) #define HT_KEY_FMT "s" #define HT_KEY_PRINTABLE(key) (key) #define HT_VALUE_FMT "p" @@ -62,7 +62,7 @@ #define HT_FUNC_FREE_KEY(key) mem_free(key) #define HT_FUNC_KEYS_EQUAL(key1, key2) (!strcmp(key1, key2)) #define HT_FUNC_HASH_KEY(key) htutil_hashfunc_string(key) -#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) +#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) #define HT_KEY_FMT "s" #define HT_KEY_PRINTABLE(key) (key) #define HT_VALUE_FMT PRIi64 @@ -81,7 +81,7 @@ #define HT_FUNC_FREE_KEY(key) mem_free(key) #define HT_FUNC_KEYS_EQUAL(key1, key2) (!strcmp(key1, key2)) #define HT_FUNC_HASH_KEY(key) htutil_hashfunc_string(key) -#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) +#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) #define HT_KEY_FMT "s" #define HT_KEY_PRINTABLE(key) (key) #define HT_VALUE_FMT PRIi64 @@ -233,7 +233,7 @@ #define HT_FUNC_FREE_KEY(key) mem_free(key) #define HT_FUNC_KEYS_EQUAL(key1, key2) (!strcmp(key1, key2)) #define HT_FUNC_HASH_KEY(key) htutil_hashfunc_string(key) -#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = strdup(src)) +#define HT_FUNC_COPY_KEY(dst, src) (*(dst) = mem_strdup(src)) #define HT_KEY_FMT "s" #define HT_KEY_PRINTABLE(key) (key) #define HT_VALUE_FMT "s" diff --git a/src/log.c b/src/log.c index 99abb009..4f9c9afc 100644 --- a/src/log.c +++ b/src/log.c @@ -771,7 +771,7 @@ static char *copy_pattern(const char *p) { return NULL; } - return strdup(orig); + return mem_strdup(orig); } void log_add_filter(LogLevelDiff diff, const char *pmod, const char *pfunc) { diff --git a/src/memory/memory.h b/src/memory/memory.h index 7f4db09b..0754f7d8 100644 --- a/src/memory/memory.h +++ b/src/memory/memory.h @@ -56,6 +56,12 @@ void *mem_dup(const void *src, size_t size) #define memdup mem_dup +INLINE attr_returns_allocated attr_nonnull(1) +char *mem_strdup(const char *str) { + size_t sz = strlen(str) + 1; + return memcpy(mem_alloc(sz), str, sz); +} + /* * This macro transparently handles allocation of both normal and over-aligned types. * The allocation must be free'd with mem_free(). diff --git a/src/menu/menu.c b/src/menu/menu.c index c0122321..2241ed32 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -22,7 +22,7 @@ MenuEntry *add_menu_entry(MenuData *menu, const char *name, MenuAction action, v .action = action, .arg = arg, .transition = menu->transition, - .name = name ? strdup(name) : NULL, + .name = name ? mem_strdup(name) : NULL, }); } diff --git a/src/menu/options.c b/src/menu/options.c index 10aafb9a..4e070e3e 100644 --- a/src/menu/options.c +++ b/src/menu/options.c @@ -313,7 +313,7 @@ static int bind_addvalue(OptionBinding *b, char *val) { } b->values = mem_realloc(b->values, (1 + b->valrange_max) * sizeof(char*)); - b->values[b->valrange_max] = strdup(val); + b->values[b->valrange_max] = mem_strdup(val); return b->valrange_max; } @@ -965,7 +965,7 @@ static MenuData* create_options_menu_gamepad(MenuData *parent) { m->end = destroy_options_menu_gamepad; OptionsMenuContext *ctx = m->context; - ctx->data = strdup(config_get_str(CONFIG_GAMEPAD_DEVICE)); + ctx->data = mem_strdup(config_get_str(CONFIG_GAMEPAD_DEVICE)); ctx->draw_overlay = draw_gamepad_options_overlay; ctx->gamepad_testmode.allowed = true; diff --git a/src/menu/replayview.c b/src/menu/replayview.c index e1597fa7..ee89f190 100644 --- a/src/menu/replayview.c +++ b/src/menu/replayview.c @@ -400,7 +400,7 @@ static int fill_replayview_menu(MenuData *m) { auto ictx = ALLOC(ReplayviewItemContext, { .replay = rpy, - .replayname = strdup(filename), + .replayname = mem_strdup(filename), }); add_menu_entry(m, " ", replayview_run, ictx)->transition = /*rpy->numstages < 2 ? TransFadeBlack :*/ NULL; diff --git a/src/pixmap/pixmap.c b/src/pixmap/pixmap.c index d14dd15d..7acd83ae 100644 --- a/src/pixmap/pixmap.c +++ b/src/pixmap/pixmap.c @@ -195,7 +195,7 @@ char *pixmap_source_path(const char *prefix, const char *path) { strcpy(base_path + strlen(prefix), path); if(pixmap_check_filename(base_path) && vfs_query(base_path).exists) { - return strdup(base_path); + return mem_strdup(base_path); } char *dot = strrchr(base_path, '.'); diff --git a/src/renderer/common/shaderlib/lang_spirv.c b/src/renderer/common/shaderlib/lang_spirv.c index a18b4502..21919904 100644 --- a/src/renderer/common/shaderlib/lang_spirv.c +++ b/src/renderer/common/shaderlib/lang_spirv.c @@ -218,7 +218,7 @@ static spvc_result write_glsl_attribs(spvc_compiler compiler, ShaderSource *out) log_debug("[%i] %s\t\tid=%i\t\tbase_type_id=%i\t\ttype_id=%i\t\tlocation=%i", i, res->name, res->id, res->base_type_id, res->type_id, location); - attrs[i].name = strdup(res->name); + attrs[i].name = mem_strdup(res->name); attrs[i].location = location; } @@ -284,7 +284,7 @@ bool _spirv_decompile(const ShaderSource *in, ShaderSource *out, const SPIRVDeco assume(code != NULL); - out->content = strdup(code); + out->content = mem_strdup(code); out->content_size = strlen(code) + 1; out->stage = in->stage; out->lang = *options->lang; diff --git a/src/renderer/gl33/shader_object.c b/src/renderer/gl33/shader_object.c index d581b22e..668eb8cb 100644 --- a/src/renderer/gl33/shader_object.c +++ b/src/renderer/gl33/shader_object.c @@ -110,7 +110,7 @@ ShaderObject *gl33_shader_object_compile(ShaderSource *source) { for(uint i = 0; i < nattribs; ++i) { GLSLAttribute *a = source->meta.glsl.attributes + i; - shobj->attribs[i].name = strdup(a->name); + shobj->attribs[i].name = mem_strdup(a->name); shobj->attribs[i].location = a->location; } } else { diff --git a/src/resource/resource.c b/src/resource/resource.c index ac7a6a21..f1c843ee 100644 --- a/src/resource/resource.c +++ b/src/resource/resource.c @@ -573,7 +573,7 @@ static void register_watched_path(InternalResource *ires, const char *vfspath, F free_slot = dynarray_append(&ires->watched_paths, {}); } - free_slot->vfs_path = strdup(vfspath); + free_slot->vfs_path = mem_strdup(vfspath); free_slot->watch = w; done: @@ -816,7 +816,7 @@ struct valfunc_arg { static void *valfunc_begin_load_resource(void *varg) { struct valfunc_arg *arg = varg; auto ires = ires_alloc(arg->type); - ires->name = strdup(NOT_NULL(arg->name)); + ires->name = mem_strdup(NOT_NULL(arg->name)); ires->refcount.value = 1; return ires; } @@ -1702,7 +1702,7 @@ void res_util_strip_ext(char *path) { char *res_util_basename(const char *prefix, const char *path) { assert(strstartswith(path, prefix)); - char *out = strdup(path + strlen(prefix)); + char *out = mem_strdup(path + strlen(prefix)); res_util_strip_ext(out); return out; diff --git a/src/resource/sprite.c b/src/resource/sprite.c index 8c210178..4e26d18e 100644 --- a/src/resource/sprite.c +++ b/src/resource/sprite.c @@ -43,7 +43,7 @@ static void load_sprite_stage1(ResourceLoadState *st) { auto state = ALLOC(struct sprite_load_state, { .spr = spr }); if(texture_res_handler.procs.check(st->path)) { - state->texture_name = strdup(st->name); + state->texture_name = mem_strdup(st->name); res_load_dependency(st, RES_TEXTURE, state->texture_name); res_load_continue_after_dependencies(st, load_sprite_stage2, state); return; @@ -88,7 +88,7 @@ static void load_sprite_stage1(ResourceLoadState *st) { } if(!state->texture_name) { - state->texture_name = strdup(st->name); + state->texture_name = mem_strdup(st->name); log_info("%s: inferred texture name from sprite name", state->texture_name); } diff --git a/src/resource/texture_loader/texture_loader.c b/src/resource/texture_loader/texture_loader.c index 284384a3..d97a929e 100644 --- a/src/resource/texture_loader/texture_loader.c +++ b/src/resource/texture_loader/texture_loader.c @@ -669,7 +669,7 @@ void texture_loader_stage1(ResourceLoadState *st) { return; } } else { - ld->src_paths.main = strdup(st->path); + ld->src_paths.main = mem_strdup(st->path); } diff --git a/src/stageinfo.c b/src/stageinfo.c index 23934b33..5ec27f47 100644 --- a/src/stageinfo.c +++ b/src/stageinfo.c @@ -31,8 +31,8 @@ static void add_stage( .type = type, .spell = spell, .difficulty = diff, - .title = title ? strdup(title) : NULL, - .subtitle = subtitle ? strdup(subtitle) : NULL, + .title = title ? mem_strdup(title) : NULL, + .subtitle = subtitle ? mem_strdup(subtitle) : NULL, }); } diff --git a/src/util/consideredharmful.h b/src/util/consideredharmful.h index 482c847e..3fe1f047 100644 --- a/src/util/consideredharmful.h +++ b/src/util/consideredharmful.h @@ -96,4 +96,8 @@ INLINE void *libc_realloc(void *ptr, size_t size) { return realloc(ptr, size); } attr_deprecated("Use the memory.h API instead") void *realloc(void *ptr, size_t size); +#undef strdup +attr_deprecated("Use mem_strdup from memory.h instead") +char *strdup(const char *s); + PRAGMA(GCC diagnostic pop) diff --git a/src/util/kvparser.c b/src/util/kvparser.c index 58aaaa10..90ebbb6d 100644 --- a/src/util/kvparser.c +++ b/src/util/kvparser.c @@ -87,7 +87,7 @@ bool parse_keyvalue_file_cb(const char *filename, KVCallback callback, void *dat static bool kvcallback_hashtable(const char *key, const char *val, void *data) { ht_str2ptr_t *ht = data; - ht_set(ht, key, strdup(val)); + ht_set(ht, key, mem_strdup(val)); return true; } diff --git a/src/util/stringops.c b/src/util/stringops.c index 2f159d17..6d197d3b 100644 --- a/src/util/stringops.c +++ b/src/util/stringops.c @@ -51,7 +51,7 @@ bool strstartswith_any(const char *s, const char **earray) { void stralloc(char **dest, const char *src) { mem_free(*dest); - *dest = src ? strdup(src) : NULL; + *dest = src ? mem_strdup(src) : NULL; } char* strjoin(const char *first, ...) { @@ -124,7 +124,7 @@ char* strftimealloc(const char *fmt, const struct tm *timeinfo) { char str[sz_allocated]; if(strftime(str, sz_allocated, fmt, timeinfo)) { - return strdup(str); + return mem_strdup(str); } sz_allocated *= 2; @@ -133,7 +133,7 @@ char* strftimealloc(const char *fmt, const struct tm *timeinfo) { char* strappend(char **dst, const char *src) { if(!*dst) { - return *dst = strdup(src); + return *dst = mem_strdup(src); } *dst = mem_realloc(*dst, strlen(*dst) + strlen(src) + 1); diff --git a/src/util/stringops.h b/src/util/stringops.h index 6bd04ebd..0719aad4 100644 --- a/src/util/stringops.h +++ b/src/util/stringops.h @@ -25,13 +25,6 @@ #undef strlcpy #define strlcpy SDL_strlcpy -#undef strdup -#define strdup _ts_strdup -INLINE attr_returns_allocated attr_nonnull(1) char *strdup(const char *str) { - size_t sz = strlen(str) + 1; - return memcpy(mem_alloc(sz), str, sz); -} - #ifndef TAISEI_BUILDCONF_HAVE_STRTOK_R #undef strtok_r #define strtok_r _ts_strtok_r diff --git a/src/vfs/pathutil.c b/src/vfs/pathutil.c index a55c4e5e..f6bd6a80 100644 --- a/src/vfs/pathutil.c +++ b/src/vfs/pathutil.c @@ -61,7 +61,7 @@ char *vfs_path_normalize(const char *path, char *out) { } char *vfs_path_normalize_alloc(const char *path) { - return vfs_path_normalize(path, strdup(path)); + return vfs_path_normalize(path, mem_strdup(path)); } char *vfs_path_normalize_inplace(char *path) { @@ -145,5 +145,5 @@ char *vfs_syspath_normalize_inplace(char *path) { char *vfs_syspath_join_alloc(const char *parent, const char *child) { char buf[strlen(parent) + strlen(child) + 2]; vfs_syspath_join(buf, sizeof(buf), parent, child); - return strdup(buf); + return mem_strdup(buf); } diff --git a/src/vfs/public.c b/src/vfs/public.c index f710bbf1..0d70abd5 100644 --- a/src/vfs/public.c +++ b/src/vfs/public.c @@ -281,7 +281,7 @@ char** vfs_dir_list_sorted(const char *path, size_t *out_size, int (*compare)(co continue; } - dynarray_append(&results, strdup(e)); + dynarray_append(&results, mem_strdup(e)); } vfs_dir_close(dir); diff --git a/src/vfs/syspath_posix.c b/src/vfs/syspath_posix.c index 6f99854a..92e2d646 100644 --- a/src/vfs/syspath_posix.c +++ b/src/vfs/syspath_posix.c @@ -95,7 +95,7 @@ static char *vfs_syspath_repr(VFSNode *node) { } static char *vfs_syspath_syspath(VFSNode *node) { - char *p = strdup(VFS_NODE_CAST(VFSSysPathNode, node)->path); + char *p = mem_strdup(VFS_NODE_CAST(VFSSysPathNode, node)->path); vfs_syspath_normalize_inplace(p); return p; } @@ -186,5 +186,5 @@ static VFSNode *vfs_syspath_create_internal(char *path) { } VFSNode *vfs_syspath_create(const char *path) { - return vfs_syspath_create_internal(strdup(path)); + return vfs_syspath_create_internal(mem_strdup(path)); } diff --git a/src/vfs/syspath_win32.c b/src/vfs/syspath_win32.c index bf5e91b6..e5c68f51 100644 --- a/src/vfs/syspath_win32.c +++ b/src/vfs/syspath_win32.c @@ -187,7 +187,7 @@ static char* vfs_syspath_repr(VFSNode *node) { static char* vfs_syspath_syspath(VFSNode *node) { auto pnode = VFS_NODE_CAST(VFSSysPathNode, node); - char *p = strdup(pnode->path); + char *p = mem_strdup(pnode->path); vfs_syspath_normalize_inplace(p); return p; } @@ -322,5 +322,5 @@ static VFSNode *vfs_syspath_create_internal(char *path) { } VFSNode *vfs_syspath_create(const char *path) { - return vfs_syspath_create_internal(strdup(path)); + return vfs_syspath_create_internal(mem_strdup(path)); } diff --git a/src/vfs/vdir.c b/src/vfs/vdir.c index 0cc2d81f..e19e7d1f 100644 --- a/src/vfs/vdir.c +++ b/src/vfs/vdir.c @@ -114,7 +114,7 @@ static bool vfs_vdir_mkdir(VFSNode *node, const char *subdir) { } static char *vfs_vdir_repr(VFSNode *node) { - return strdup("virtual directory"); + return mem_strdup("virtual directory"); } VFS_NODE_FUNCS(VFSVDirNode, { diff --git a/src/vfs/zipfile.c b/src/vfs/zipfile.c index cf1db736..8efb022f 100644 --- a/src/vfs/zipfile.c +++ b/src/vfs/zipfile.c @@ -228,7 +228,7 @@ const char *vfs_zipfile_iter_shared(VFSZipFileIterData *idata, VFSZipFileTLS *tl // strip the trailing slash mem_free(idata->allocated); - idata->allocated = strdup(p); + idata->allocated = mem_strdup(p); *strchr(idata->allocated, '/') = 0; r = idata->allocated; } else {