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
This commit is contained in:
ultramage 2008-05-02 09:27:03 +00:00
parent 6559c24882
commit 0ce34d51a4
2 changed files with 37 additions and 7 deletions

View File

@ -322,4 +322,15 @@ typedef char bool;
// length of a static array // length of a static array
#define ARRAYLENGTH(A) ( sizeof(A)/sizeof((A)[0]) ) #define ARRAYLENGTH(A) ( sizeof(A)/sizeof((A)[0]) )
//////////////////////////////////////////////////////////////////////////
// Make sure va_copy exists
#include <stdarg.h> // 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_ */ #endif /* _CBASETYPES_H_ */

View File

@ -1487,11 +1487,17 @@ static unsigned int db_obj_vgetall(DBMap* self, void **buf, unsigned int max, DB
node = db->ht[i]; node = db->ht[i];
while (node) { while (node) {
parent = node->parent; parent = node->parent;
if (!(node->deleted) && match(node->key, node->data, args) == 0) { if (!(node->deleted))
{
va_list argscopy;
va_copy(argscopy, args);
if (match(node->key, node->data, argscopy) == 0) {
if (buf && ret < max) if (buf && ret < max)
buf[ret] = node->data; buf[ret] = node->data;
ret++; ret++;
} }
va_end(argscopy);
}
if (node->left) { if (node->left) {
node = node->left; node = node->left;
continue; continue;
@ -1597,6 +1603,7 @@ static void *db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list
} }
// Create node if necessary // Create node if necessary
if (node == NULL) { if (node == NULL) {
va_list argscopy;
if (db->item_count == UINT32_MAX) { if (db->item_count == UINT32_MAX) {
ShowError("db_vensure: item_count overflow, aborting item insertion.\n" ShowError("db_vensure: item_count overflow, aborting item insertion.\n"
"Database allocated at %s:%d", "Database allocated at %s:%d",
@ -1633,7 +1640,9 @@ static void *db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_list
} else { } else {
node->key = key; node->key = key;
} }
node->data = create(key, args); va_copy(argscopy, args);
node->data = create(key, argscopy);
va_end(argscopy);
} }
data = node->data; data = node->data;
db->cache = node; db->cache = node;
@ -1860,7 +1869,12 @@ static int db_obj_vforeach(DBMap* self, DBApply func, va_list args)
while (node) { while (node) {
parent = node->parent; parent = node->parent;
if (!(node->deleted)) 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) { if (node->left) {
node = node->left; node = node->left;
continue; continue;
@ -1952,7 +1966,12 @@ static int db_obj_vclear(DBMap* self, DBApply func, va_list args)
db_dup_key_free(db, node->key); db_dup_key_free(db, node->key);
} else { } else {
if (func) 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); db->release(node->key, node->data, DB_RELEASE_BOTH);
node->deleted = 1; node->deleted = 1;
} }