From 0ce34d51a434f6ced4d85ac9ca57df8b6a74aefe Mon Sep 17 00:00:00 2001 From: ultramage Date: Fri, 2 May 2008 09:27:03 +0000 Subject: [PATCH] Added a custom implementation of the va_copy macro for systems that don't provide it. Fixed varargs not being used correctly in foreach() calls in db.c (bugreport:551). git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12682 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/common/cbasetypes.h | 11 +++++++++++ src/common/db.c | 33 ++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index ae0bb8c780..2a2d958ff4 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -322,4 +322,15 @@ typedef char bool; // length of a static array #define ARRAYLENGTH(A) ( sizeof(A)/sizeof((A)[0]) ) +////////////////////////////////////////////////////////////////////////// +// Make sure va_copy exists +#include // va_list, va_copy(?) +#if !defined(va_copy) +#if defined(__va_copy) +#define va_copy __va_copy +#else +#define va_copy(dst, src) ((void) memcpy(&(dst), &(src), sizeof(va_list))) +#endif +#endif + #endif /* _CBASETYPES_H_ */ diff --git a/src/common/db.c b/src/common/db.c index 07adf73f1b..be27146039 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -1487,10 +1487,16 @@ static unsigned int db_obj_vgetall(DBMap* self, void **buf, unsigned int max, DB node = db->ht[i]; while (node) { parent = node->parent; - if (!(node->deleted) && match(node->key, node->data, args) == 0) { - if (buf && ret < max) - buf[ret] = node->data; - ret++; + if (!(node->deleted)) + { + va_list argscopy; + va_copy(argscopy, args); + if (match(node->key, node->data, argscopy) == 0) { + if (buf && ret < max) + buf[ret] = node->data; + ret++; + } + va_end(argscopy); } if (node->left) { node = node->left; @@ -1597,6 +1603,7 @@ static void *db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list } // Create node if necessary if (node == NULL) { + va_list argscopy; if (db->item_count == UINT32_MAX) { ShowError("db_vensure: item_count overflow, aborting item insertion.\n" "Database allocated at %s:%d", @@ -1633,7 +1640,9 @@ static void *db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list } else { node->key = key; } - node->data = create(key, args); + va_copy(argscopy, args); + node->data = create(key, argscopy); + va_end(argscopy); } data = node->data; db->cache = node; @@ -1860,7 +1869,12 @@ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args) while (node) { parent = node->parent; if (!(node->deleted)) - sum += func(node->key, node->data, args); + { + va_list argscopy; + va_copy(argscopy, args); + sum += func(node->key, node->data, argscopy); + va_end(argscopy); + } if (node->left) { node = node->left; continue; @@ -1952,7 +1966,12 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args) db_dup_key_free(db, node->key); } else { if (func) - sum += func(node->key, node->data, args); + { + va_list argscopy; + va_copy(argscopy, args); + sum += func(node->key, node->data, argscopy); + va_end(argscopy); + } db->release(node->key, node->data, DB_RELEASE_BOTH); node->deleted = 1; }