diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 69 | ||||
-rw-r--r-- | src/common/HPM.h | 15 | ||||
-rw-r--r-- | src/common/HPMi.h | 11 | ||||
-rw-r--r-- | src/common/Makefile.in | 9 | ||||
-rw-r--r-- | src/common/cbasetypes.h | 26 | ||||
-rw-r--r-- | src/common/core.c | 3 | ||||
-rw-r--r-- | src/common/db.c | 8 | ||||
-rw-r--r-- | src/common/db.h | 6 | ||||
-rw-r--r-- | src/common/ers.c | 4 | ||||
-rw-r--r-- | src/common/ers.h | 9 | ||||
-rw-r--r-- | src/common/grfio.c | 23 | ||||
-rw-r--r-- | src/common/malloc.c | 35 | ||||
-rw-r--r-- | src/common/malloc.h | 4 | ||||
-rw-r--r-- | src/common/mapindex.c | 92 | ||||
-rw-r--r-- | src/common/mapindex.h | 54 | ||||
-rw-r--r-- | src/common/mmo.h | 21 | ||||
-rw-r--r-- | src/common/nullpo.c | 94 | ||||
-rw-r--r-- | src/common/nullpo.h | 302 | ||||
-rw-r--r-- | src/common/socket.c | 12 | ||||
-rw-r--r-- | src/common/sql.c | 4 | ||||
-rw-r--r-- | src/common/strlib.c | 19 | ||||
-rw-r--r-- | src/common/timer.c | 8 |
22 files changed, 419 insertions, 409 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 005bc2ddc..426fac94a 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -215,6 +215,7 @@ struct hplugin *hplugin_load(const char* filename) { plugin->hpi->HookStop = HPM->import_symbol("HookStop",plugin->idx); plugin->hpi->HookStopped = HPM->import_symbol("HookStopped",plugin->idx); plugin->hpi->addArg = HPM->import_symbol("addArg",plugin->idx); + plugin->hpi->addConf = HPM->import_symbol("addConf",plugin->idx); /* server specific */ if( HPM->load_sub ) HPM->load_sub(plugin); @@ -532,6 +533,9 @@ void* HPM_calloc(size_t num, size_t size, const char *file, int line, const char void* HPM_realloc(void *p, size_t size, const char *file, int line, const char *func) { return iMalloc->realloc(p,size,HPM_file2ptr(file),line,func); } +void* HPM_reallocz(void *p, size_t size, const char *file, int line, const char *func) { + return iMalloc->reallocz(p,size,HPM_file2ptr(file),line,func); +} char* HPM_astrdup(const char *p, const char *file, int line, const char *func) { return iMalloc->astrdup(p,HPM_file2ptr(file),line,func); } @@ -602,6 +606,48 @@ bool hpm_add_arg(unsigned int pluginID, char *name, bool has_param, void (*func) return true; } +bool hplugins_addconf(unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)) { + struct HPConfListenStorage *conf; + unsigned int i; + + if( type >= HPCT_MAX ) { + ShowError("HPM->addConf:%s: unknown point '%u' specified for config '%s'\n",HPM->pid2name(pluginID),type,name); + return false; + } + + for(i = 0; i < HPM->confsc[type]; i++) { + if( !strcmpi(name,HPM->confs[type][i].key) ) { + ShowError("HPM->addConf:%s: duplicate '%s', already in use by '%s'!",HPM->pid2name(pluginID),name,HPM->pid2name(HPM->confs[type][i].pluginID)); + return false; + } + } + + RECREATE(HPM->confs[type], struct HPConfListenStorage, ++HPM->confsc[type]); + conf = &HPM->confs[type][HPM->confsc[type] - 1]; + + conf->pluginID = pluginID; + safestrncpy(conf->key, name, HPM_ADDCONF_LENGTH); + conf->func = func; + + return true; +} +bool hplugins_parse_conf(const char *w1, const char *w2, enum HPluginConfType point) { + unsigned int i; + + /* exists? */ + for(i = 0; i < HPM->confsc[point]; i++) { + if( !strcmpi(w1,HPM->confs[point][i].key) ) + break; + } + + /* trigger and we're set! */ + if( i != HPM->confsc[point] ) { + HPM->confs[point][i].func(w2); + return true; + } + + return false; +} void hplugins_share_defaults(void) { /* console */ @@ -617,6 +663,7 @@ void hplugins_share_defaults(void) { HPM->share(HPM_HookStop,"HookStop"); HPM->share(HPM_HookStopped,"HookStopped"); HPM->share(hpm_add_arg,"addArg"); + HPM->share(hplugins_addconf,"addConf"); /* core */ HPM->share(&runflag,"runflag"); HPM->share(arg_v,"arg_v"); @@ -661,6 +708,7 @@ void hpm_init(void) { HPMiMalloc->malloc = HPM_mmalloc; HPMiMalloc->calloc = HPM_calloc; HPMiMalloc->realloc = HPM_realloc; + HPMiMalloc->reallocz = HPM_reallocz; HPMiMalloc->astrdup = HPM_astrdup; sscanf(HPM_VERSION, "%u.%u", &HPM->version[0], &HPM->version[1]); @@ -728,6 +776,11 @@ void hpm_final(void) { aFree(HPM->packets[i]); } + for( i = 0; i < HPCT_MAX; i++ ) { + if( HPM->confsc[i] ) + aFree(HPM->confs[i]); + } + HPM->arg_db->destroy(HPM->arg_db,HPM->arg_db_clear_sub); /* HPM->fnames is cleared after the memory manager goes down */ @@ -736,13 +789,26 @@ void hpm_final(void) { return; } void hpm_defaults(void) { + unsigned int i; HPM = &HPM_s; HPM->fnames = NULL; HPM->fnamec = 0; HPM->force_return = false; HPM->hooking = false; - + /* */ + HPM->fnames = NULL; + HPM->fnamec = 0; + for(i = 0; i < hpPHP_MAX; i++) { + HPM->packets[i] = NULL; + HPM->packetsc[i] = 0; + } + for(i = 0; i < HPCT_MAX; i++) { + HPM->confs[i] = NULL; + HPM->confsc[i] = 0; + } + HPM->arg_db = NULL; + /* */ HPM->init = hpm_init; HPM->final = hpm_final; @@ -767,4 +833,5 @@ void hpm_defaults(void) { HPM->arg_help = hpm_arg_help; HPM->grabHPData = hplugins_grabHPData; HPM->grabHPDataSub = NULL; + HPM->parseConf = hplugins_parse_conf; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 5466693ab..1f2ba4648 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -28,8 +28,10 @@ #define plugin_import(x,y,z) (z)dlsym((x),(y)) #define plugin_close(x) dlclose(x) - #ifdef CYGWIN + #if defined CYGWIN #define DLL_EXT ".dll" + #elif defined __DARWIN__ + #define DLL_EXT ".dylib" #else #define DLL_EXT ".so" #endif @@ -86,6 +88,12 @@ struct HPDataOperationStorage { void **HPDataSRCPtr; unsigned int *hdatac; }; +/* */ +struct HPConfListenStorage { + unsigned int pluginID; + char key[HPM_ADDCONF_LENGTH]; + void (*func) (const char *val); +}; /* Hercules Plugin Manager Interface */ struct HPM_interface { @@ -106,6 +114,9 @@ struct HPM_interface { /* plugin file ptr caching */ struct HPMFileNameCache *fnames; unsigned int fnamec; + /* config listen */ + struct HPConfListenStorage *confs[HPCT_MAX]; + unsigned int confsc[HPCT_MAX]; /* --command-line */ DBMap *arg_db; /* funcs */ @@ -133,6 +144,8 @@ struct HPM_interface { void (*grabHPData) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); /* for server-specific HPData e.g. map_session_data */ void (*grabHPDataSub) (struct HPDataOperationStorage *ret, enum HPluginDataTypes type, void *ptr); + /* for custom config parsing */ + bool (*parseConf) (const char *w1, const char *w2, enum HPluginConfType point); } HPM_s; struct HPM_interface *HPM; diff --git a/src/common/HPMi.h b/src/common/HPMi.h index 2cd1075c4..742132cde 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -36,6 +36,7 @@ struct map_session_data; #include "../common/showmsg.h" #define HPM_VERSION "1.0" +#define HPM_ADDCONF_LENGTH 40 struct hplugin_info { char* name; @@ -83,6 +84,12 @@ enum HPluginDataTypes { HPDT_NPCD, }; +/* used in macros and conf storage */ +enum HPluginConfType { + HPCT_BATTLE, /* battle-conf (map-server */ + HPCT_MAX, +}; + #define addHookPre(tname,hook) (HPMi->AddHook(HOOK_TYPE_PRE,(tname),(hook),HPMi->pid)) #define addHookPost(tname,hook) (HPMi->AddHook(HOOK_TYPE_POST,(tname),(hook),HPMi->pid)) /* need better names ;/ */ @@ -128,6 +135,8 @@ enum HPluginDataTypes { } /* HPMi->addPacket */ #define addPacket(cmd,len,receive,point) HPMi->addPacket(cmd,len,receive,point,HPMi->pid) +/* HPMi->addBattleConf */ +#define addBattleConf(bcname,funcname) HPMi->addConf(HPMi->pid,HPCT_BATTLE,bcname,funcname) /* Hercules Plugin Mananger Include Interface */ HPExport struct HPMi_interface { @@ -150,6 +159,8 @@ HPExport struct HPMi_interface { bool (*HookStopped) (void); /* program --arg/-a */ bool (*addArg) (unsigned int pluginID, char *name, bool has_param,void (*func) (char *param),void (*help) (void)); + /* battle-config recv param */ + bool (*addConf) (unsigned int pluginID, enum HPluginConfType type, char *name, void (*func) (const char *val)); } HPMi_s; #ifndef _HPM_H_ HPExport struct HPMi_interface *HPMi; diff --git a/src/common/Makefile.in b/src/common/Makefile.in index 1e23ab5e8..7bb9ae630 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -15,8 +15,8 @@ MT19937AR_H = $(MT19937AR_D)/mt19937ar.h MT19937AR_INCLUDE = -I$(MT19937AR_D) COMMON_SHARED_C = conf.c db.c des.c ers.c grfio.c HPM.c mapindex.c md5calc.c \ - mempool.c mutex.c nullpo.c raconf.c random.c showmsg.c strlib.c \ - thread.c timer.c utils.c + mutex.c nullpo.c random.c showmsg.c strlib.c thread.c \ + timer.c utils.c COMMON_C = $(COMMON_SHARED_C) COMMON_SHARED_OBJ = $(patsubst %.c,%.o,$(COMMON_SHARED_C)) COMMON_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ @@ -25,9 +25,8 @@ COMMON_MINI_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \ miniconsole.o minicore.o minimalloc.o minisocket.o) COMMON_C += console.c core.c malloc.c socket.c COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \ - evdp.h grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h \ - mempool.h mmo.h mutex.h netbuffer.h network.h nullpo.h raconf.h \ - random.h showmsg.h socket.h spinlock.h sql.h strlib.h \ + grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h mmo.h mutex.h \ + nullpo.h random.h showmsg.h socket.h spinlock.h sql.h strlib.h \ thread.h timer.h utils.h winapi.h COMMON_SQL_OBJ = obj_sql/sql.o diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 6de2ace01..120f4f861 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -255,6 +255,13 @@ typedef uintptr_t uintptr; #define ra_align(n) __attribute__(( aligned(n) )) #endif +// Directives for the (clang) static analyzer +#ifdef __clang__ +#define analyzer_noreturn __attribute__((analyzer_noreturn)) +#else +#define analyzer_noreturn +#endif + ///////////////////////////// // for those still not building c++ @@ -353,23 +360,6 @@ typedef char bool; #endif ////////////////////////////////////////////////////////////////////////// -// Assert - -#if ! defined(Assert) -#if defined(RELEASE) -#define Assert(EX) -#else -// extern "C" { -#include <assert.h> -// } -#if !defined(DEFCPP) && defined(WIN32) && !defined(MINGW) -#include <crtdbg.h> -#endif -#define Assert(EX) assert(EX) -#endif -#endif /* ! defined(Assert) */ - -////////////////////////////////////////////////////////////////////////// // Has to be unsigned to avoid problems in some systems // Problems arise when these functions expect an argument in the range [0,256[ and are fed a signed char. #include <ctype.h> @@ -405,7 +395,7 @@ typedef char bool; ////////////////////////////////////////////////////////////////////////// -// Use the preprocessor to 'stringify' stuff (concert to a string). +// Use the preprocessor to 'stringify' stuff (convert to a string). // example: // #define TESTE blabla // QUOTE(TESTE) -> "TESTE" diff --git a/src/common/core.c b/src/common/core.c index dd839b372..8178a48a5 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -15,7 +15,6 @@ #include "../common/socket.h" #include "../common/timer.h" #include "../common/thread.h" - #include "../common/mempool.h" #include "../common/sql.h" #include "../config/core.h" #include "../common/HPM.h" @@ -328,7 +327,6 @@ int main (int argc, char **argv) { Sql_Init(); rathread_init(); - mempool_init(); DB->init(); signals_init(); @@ -370,7 +368,6 @@ int main (int argc, char **argv) { timer->final(); socket_final(); DB->final(); - mempool_final(); rathread_final(); #endif diff --git a/src/common/db.c b/src/common/db.c index c3ca7e0a4..efe7ca8b2 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -1696,7 +1696,7 @@ static DBData* db_obj_vensure(DBMap* self, DBKey key, DBCreateData create, va_li if (db->options&DB_OPT_DUP_KEY) { node->key = db_dup_key(db, key); if (db->options&DB_OPT_RELEASE_KEY) - db->release(key, *data, DB_RELEASE_KEY); + db->release(key, node->data, DB_RELEASE_KEY); } else { node->key = key; } @@ -2446,7 +2446,7 @@ DBMap* db_alloc(const char *file, const char *func, int line, DBType type, DBOpt db->free_lock = 0; /* Other */ snprintf(ers_name, 50, "db_alloc:nodes:%s:%s:%d",func,file,line); - db->nodes = ers_new(sizeof(struct dbn),ers_name,ERS_OPT_WAIT|ERS_OPT_FREE_NAME); + db->nodes = ers_new(sizeof(struct dbn),ers_name,ERS_OPT_WAIT|ERS_OPT_FREE_NAME|ERS_OPT_CLEAN); db->cmp = DB->default_cmp(type); db->hash = DB->default_hash(type); db->release = DB->default_release(type, options); @@ -2609,8 +2609,8 @@ void* db_data2ptr(DBData *data) * @see #db_final(void) */ void db_init(void) { - db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_NONE); - db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_NONE); + db_iterator_ers = ers_new(sizeof(struct DBIterator_impl),"db.c::db_iterator_ers",ERS_OPT_CLEAN); + db_alloc_ers = ers_new(sizeof(struct DBMap_impl),"db.c::db_alloc_ers",ERS_OPT_CLEAN); ers_chunk_size(db_alloc_ers, 50); DB_COUNTSTAT(db_init); } diff --git a/src/common/db.h b/src/common/db.h index b9d6af382..5f4478909 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -1121,8 +1121,10 @@ void linkdb_foreach (struct linkdb_node** head, LinkDBFunc func, ...); #define VECTOR_ENSURE(__vec,__n,__step) \ do{ \ size_t _empty_ = VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec); \ - while( (__n) > _empty_ ) _empty_ += (__step); \ - if( _empty_ != VECTOR_CAPACITY(__vec)-VECTOR_LENGTH(__vec) ) VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \ + if( (__n) > _empty_ ) { \ + while( (__n) > _empty_ ) _empty_ += (__step); \ + VECTOR_RESIZE(__vec,_empty_+VECTOR_LENGTH(__vec)); \ + } \ }while(0) diff --git a/src/common/ers.c b/src/common/ers.c index 22269a51f..a7dad49ab 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -40,6 +40,7 @@ * @see common#ers.h * \*****************************************************************************/ #include <stdlib.h> +#include <string.h> #include "../common/cbasetypes.h" #include "../common/malloc.h" // CREATE, RECREATE, aMalloc, aFree @@ -238,6 +239,9 @@ static void ers_obj_free_entry(ERS self, void *entry) return; } + if( instance->Options & ERS_OPT_CLEAN ) + memset((unsigned char*)reuse + sizeof(struct ers_list), 0, instance->Cache->ObjectSize - sizeof(struct ers_list)); + reuse->Next = instance->Cache->ReuseList; instance->Cache->ReuseList = reuse; instance->Count--; diff --git a/src/common/ers.h b/src/common/ers.h index 4ff2a6230..e63711b81 100644 --- a/src/common/ers.h +++ b/src/common/ers.h @@ -71,10 +71,11 @@ #endif /* not ERS_ALIGN_ENTRY */ enum ERSOptions { - ERS_OPT_NONE = 0x0, - ERS_OPT_CLEAR = 0x1,/* silently clears any entries left in the manager upon destruction */ - ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */ - ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */ + ERS_OPT_NONE = 0x0, + ERS_OPT_CLEAR = 0x1,/* silently clears any entries left in the manager upon destruction */ + ERS_OPT_WAIT = 0x2,/* wait for entries to come in order to list! */ + ERS_OPT_FREE_NAME = 0x4,/* name is dynamic memory, and should be freed */ + ERS_OPT_CLEAN = 0x8,/* clears used memory upon ers_free so that its all new to be reused on the next alloc */ }; /** diff --git a/src/common/grfio.c b/src/common/grfio.c index 77b976926..57e8a5187 100644 --- a/src/common/grfio.c +++ b/src/common/grfio.c @@ -8,6 +8,7 @@ #include "../common/showmsg.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/nullpo.h" #include "grfio.h" #include <stdio.h> @@ -305,17 +306,21 @@ static FILELIST* filelist_find(const char* fname) // returns the original file name char* grfio_find_file(const char* fname) { - FILELIST *filelist = filelist_find(fname); - if (!filelist) return NULL; - return (!filelist->fnd ? filelist->fn : filelist->fnd); + FILELIST *flist = filelist_find(fname); + if (!flist) return NULL; + return (!flist->fnd ? flist->fn : flist->fnd); } // adds a FILELIST entry into the list of loaded files -static FILELIST* filelist_add(FILELIST* entry) -{ +static FILELIST* filelist_add(FILELIST* entry) { int hash; + nullpo_ret(entry); +#ifdef __clang_analyzer__ + // Make clang's static analyzer shut up about a possible NULL pointer in &filelist[filelist_entrys] + nullpo_ret(&filelist[filelist_entrys]); +#endif // __clang_analyzer__ - #define FILELIST_ADDS 1024 // number increment of file lists ` +#define FILELIST_ADDS 1024 // number increment of file lists ` if (filelist_entrys >= filelist_maxentry) { filelist = (FILELIST *)aRealloc(filelist, (filelist_maxentry + FILELIST_ADDS) * sizeof(FILELIST)); @@ -323,7 +328,9 @@ static FILELIST* filelist_add(FILELIST* entry) filelist_maxentry += FILELIST_ADDS; } - memcpy (&filelist[filelist_entrys], entry, sizeof(FILELIST)); +#undef FILELIST_ADDS + + memcpy(&filelist[filelist_entrys], entry, sizeof(FILELIST)); hash = filehash(entry->fn); filelist[filelist_entrys].next = filelist_hash[hash]; @@ -405,7 +412,7 @@ void* grfio_reads(const char* fname, int* size) if( in != NULL ) { int declen; fseek(in,0,SEEK_END); - declen = ftell(in); + declen = (int)ftell(in); fseek(in,0,SEEK_SET); buf2 = (unsigned char *)aMalloc(declen+1); // +1 for resnametable zero-termination if(fread(buf2, 1, declen, in) != (size_t)declen) ShowError("An error occured in fread grfio_reads, fname=%s \n",fname); diff --git a/src/common/malloc.c b/src/common/malloc.c index 1cb7836ab..f7f108304 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -369,6 +369,37 @@ void* _mrealloc(void *memblock, size_t size, const char *file, int line, const c } } +/* a _mrealloc clone with the difference it 'z'eroes the newly created memory */ +void* _mreallocz(void *memblock, size_t size, const char *file, int line, const char *func ) { + size_t old_size; + void *p = NULL; + + if(memblock == NULL) { + p = iMalloc->malloc(size,file,line,func); + memset(p,0,size); + return p; + } + + old_size = ((struct unit_head *)((char *)memblock - sizeof(struct unit_head) + sizeof(long)))->size; + if( old_size == 0 ) { + old_size = ((struct unit_head_large *)((char *)memblock - sizeof(struct unit_head_large) + sizeof(long)))->size; + } + if(old_size > size) { + // Size reduction - return> as it is (negligence) + return memblock; + } else { + // Size Large + p = iMalloc->malloc(size,file,line,func); + if(p != NULL) { + memcpy(p,memblock,old_size); + memset((char*)p+old_size,0,size-old_size); + } + iMalloc->free(memblock,file,line,func); + return p; + } +} + + char* _mstrdup(const char *p, const char *file, int line, const char *func ) { if(p == NULL) { @@ -669,7 +700,7 @@ void memmgr_report (int extra) { struct { const char *file; unsigned short line; - unsigned int size; + size_t size; unsigned int count; } data[100]; memset(&data, 0, sizeof(data)); @@ -822,12 +853,14 @@ void malloc_defaults(void) { iMalloc->malloc = _mmalloc; iMalloc->calloc = _mcalloc; iMalloc->realloc = _mrealloc; + iMalloc->reallocz= _mreallocz; iMalloc->astrdup = _mstrdup; iMalloc->free = _mfree; #else iMalloc->malloc = aMalloc_; iMalloc->calloc = aCalloc_; iMalloc->realloc = aRealloc_; + iMalloc->reallocz= aRealloc_;/* not using memory manager huhum o.o perhaps we could still do something about */ iMalloc->astrdup = aStrdup_; iMalloc->free = aFree_; #endif diff --git a/src/common/malloc.h b/src/common/malloc.h index cd0ef238b..19b5213bb 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -33,6 +33,7 @@ # define aMalloc(n) (iMalloc->malloc((n),ALC_MARK)) # define aCalloc(m,n) (iMalloc->calloc((m),(n),ALC_MARK)) # define aRealloc(p,n) (iMalloc->realloc((p),(n),ALC_MARK)) +# define aReallocz(p,n) (iMalloc->reallocz((p),(n),ALC_MARK)) # define aStrdup(p) (iMalloc->astrdup((p),ALC_MARK)) # define aFree(p) (iMalloc->free((p),ALC_MARK)) @@ -54,7 +55,7 @@ ////////////// Others ////////////////////////// // should be merged with any of above later #define CREATE(result, type, number) ((result) = (type *) aCalloc((number), sizeof(type))) -#define RECREATE(result, type, number) ((result) = (type *) aRealloc((result), sizeof(type) * (number))) +#define RECREATE(result, type, number) ((result) = (type *) aReallocz((result), sizeof(type) * (number))) //////////////////////////////////////////////// @@ -73,6 +74,7 @@ struct malloc_interface { void* (*malloc )(size_t size, const char *file, int line, const char *func); void* (*calloc )(size_t num, size_t size, const char *file, int line, const char *func); void* (*realloc )(void *p, size_t size, const char *file, int line, const char *func); + void* (*reallocz)(void *p, size_t size, const char *file, int line, const char *func); char* (*astrdup )(const char *p, const char *file, int line, const char *func); void (*free )(void *p, const char *file, int line, const char *func); /* */ diff --git a/src/common/mapindex.c b/src/common/mapindex.c index 1d2569afe..3128a3cb0 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -13,19 +13,8 @@ #include <stdio.h> #include <stdlib.h> -struct _indexes { - char name[MAP_NAME_LENGTH]; //Stores map name -} indexes[MAX_MAPINDEX]; - -int max_index = 0; - -char mapindex_cfgfile[80] = "db/map_index.txt"; - -#define mapindex_exists_sub(id) (indexes[id].name[0] != '\0') - -bool mapindex_exists(int id) { - return mapindex_exists_sub(id); -} +/* mapindex.c interface source */ +struct mapindex_interface mapindex_s; /// Retrieves the map name from 'string' (removing .gat extension if present). /// Result gets placed either into 'buf' or in a static local buffer. @@ -83,9 +72,8 @@ int mapindex_addmap(int index, const char* name) { char map_name[MAP_NAME_LENGTH]; if (index == -1){ - for (index = 1; index < max_index; index++) { - //if (strcmp(indexes[index].name,"#CLEARED#")==0) - if (indexes[index].name[0] == '\0') + for (index = 1; index < mapindex->num; index++) { + if (mapindex->list[index].name[0] == '\0') break; } } @@ -95,7 +83,7 @@ int mapindex_addmap(int index, const char* name) { return 0; } - mapindex_getmapname(name, map_name); + mapindex->getmapname(name, map_name); if (map_name[0] == '\0') { ShowError("(mapindex_add) Cannot add maps with no name.\n"); @@ -107,15 +95,16 @@ int mapindex_addmap(int index, const char* name) { return 0; } - if (mapindex_exists_sub(index)) { - ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name); - strdb_remove(mapindex_db, indexes[index].name); + if (mapindex_exists(index)) { + ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, mapindex->list[index].name, map_name); + strdb_remove(mapindex->db, mapindex->list[index].name); } - safestrncpy(indexes[index].name, map_name, MAP_NAME_LENGTH); - strdb_iput(mapindex_db, map_name, index); - if (max_index <= index) - max_index = index+1; + safestrncpy(mapindex->list[index].name, map_name, MAP_NAME_LENGTH); + strdb_iput(mapindex->db, map_name, index); + + if (mapindex->num <= index) + mapindex->num = index+1; return index; } @@ -124,9 +113,9 @@ unsigned short mapindex_name2id(const char* name) { int i; char map_name[MAP_NAME_LENGTH]; - mapindex_getmapname(name, map_name); + mapindex->getmapname(name, map_name); - if( (i = strdb_iget(mapindex_db, map_name)) ) + if( (i = strdb_iget(mapindex->db, map_name)) ) return i; ShowDebug("mapindex_name2id: Map \"%s\" not found in index list!\n", map_name); @@ -134,11 +123,11 @@ unsigned short mapindex_name2id(const char* name) { } const char* mapindex_id2name_sub(unsigned short id,const char *file, int line, const char *func) { - if (id > MAX_MAPINDEX || !mapindex_exists_sub(id)) { + if (id > MAX_MAPINDEX || !mapindex_exists(id)) { ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache. %s:%s:%d\n", id,file,func,line); - return indexes[0].name; // dummy empty string so that the callee doesn't crash + return mapindex->list[0].name; // dummy empty string so that the callee doesn't crash } - return indexes[id].name; + return mapindex->list[id].name; } int mapindex_init(void) { @@ -148,12 +137,13 @@ int mapindex_init(void) { int index, total = 0; char map_name[12]; - if( ( fp = fopen(mapindex_cfgfile,"r") ) == NULL ){ - ShowFatalError("Unable to read mapindex config file %s!\n", mapindex_cfgfile); + if( ( fp = fopen(mapindex->config_file,"r") ) == NULL ){ + ShowFatalError("Unable to read mapindex config file %s!\n", mapindex->config_file); exit(EXIT_FAILURE); //Server can't really run without this file. } - memset (&indexes, 0, sizeof (indexes)); - mapindex_db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); + + mapindex->db = strdb_alloc(DB_OPT_DUP_KEY, MAP_NAME_LENGTH); + while(fgets(line, sizeof(line), fp)) { if(line[0] == '/' && line[1] == '/') continue; @@ -162,7 +152,7 @@ int mapindex_init(void) { case 1: //Map with no ID given, auto-assign index = last_index+1; case 2: //Map with ID given - mapindex_addmap(index,map_name); + mapindex->addmap(index,map_name); total++; break; default: @@ -172,18 +162,40 @@ int mapindex_init(void) { } fclose(fp); - if( !strdb_iget(mapindex_db, MAP_DEFAULT) ) { + if( !strdb_iget(mapindex->db, MAP_DEFAULT) ) { ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT); } + return total; } -int mapindex_removemap(int index){ - strdb_remove(mapindex_db, indexes[index].name); - indexes[index].name[0] = '\0'; - return 0; +void mapindex_removemap(int index){ + strdb_remove(mapindex->db, mapindex->list[index].name); + mapindex->list[index].name[0] = '\0'; } void mapindex_final(void) { - db_destroy(mapindex_db); + db_destroy(mapindex->db); +} + +void mapindex_defaults(void) { + mapindex = &mapindex_s; + + /* TODO: place it in inter-server.conf? */ + snprintf(mapindex->config_file, 80, "%s","db/map_index.txt"); + /* */ + mapindex->db = NULL; + mapindex->num = 0; + memset (&mapindex->list, 0, sizeof (mapindex->list)); + + /* */ + mapindex->init = mapindex_init; + mapindex->final = mapindex_final; + /* */ + mapindex->addmap = mapindex_addmap; + mapindex->removemap = mapindex_removemap; + mapindex->getmapname = mapindex_getmapname; + mapindex->getmapname_ext = mapindex_getmapname_ext; + mapindex->name2id = mapindex_name2id; + mapindex->id2name = mapindex_id2name_sub; } diff --git a/src/common/mapindex.h b/src/common/mapindex.h index cf5486808..98150f441 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -6,17 +6,16 @@ #define _MAPINDEX_H_ #include "../common/db.h" +#include "../common/mmo.h" + +#define MAX_MAPINDEX 2000 + +/* wohoo, someone look at all those |: map_default could (or *should*) be a char-server.conf */ // When a map index search fails, return results from what map? default:prontera #define MAP_DEFAULT "prontera" #define MAP_DEFAULT_X 150 #define MAP_DEFAULT_Y 150 -DBMap *mapindex_db; - -//File in charge of assigning a numberic ID to each map in existance for space saving when passing map info between servers. -extern char mapindex_cfgfile[80]; - -#define MAX_MAPINDEX 2000 //Some definitions for the mayor city maps. #define MAP_PRONTERA "prontera" @@ -56,16 +55,39 @@ extern char mapindex_cfgfile[80]; #define MAP_MALAYA "malaya" #define MAP_ECLAGE "eclage" -bool mapindex_exists(int id); -const char* mapindex_getmapname(const char* string, char* output); -const char* mapindex_getmapname_ext(const char* string, char* output); -unsigned short mapindex_name2id(const char*); -#define mapindex_id2name(n) mapindex_id2name_sub((n),__FILE__, __LINE__, __func__) -const char* mapindex_id2name_sub(unsigned short,const char *file, int line, const char *func); -int mapindex_init(void); -void mapindex_final(void); +#define mapindex_id2name(n) mapindex->id2name((n),__FILE__, __LINE__, __func__) +#define mapindex_exists(n) ( mapindex->list[(n)].name[0] != '\0' ) + +/** + * mapindex.c interface + **/ +struct mapindex_interface { + char config_file[80]; + /* mapname (str) -> index (int) */ + DBMap *db; + /* number of entries in the index table */ + int num; + /* index list -- since map server map count is *unlimited* this should be too */ + struct { + char name[MAP_NAME_LENGTH]; + } list[MAX_MAPINDEX]; + /* */ + int (*init) (void); + void (*final) (void); + /* */ + int (*addmap) (int index, const char* name); + void (*removemap) (int index); + const char* (*getmapname) (const char* string, char* output); + /* TODO: server shouldn't be handling the extension, game client automatically adds .gat/.rsw/.whatever + * and there are official map names taking advantage of it that we cant support due to the .gat room being saved */ + const char* (*getmapname_ext) (const char* string, char* output); + /* TODO: Hello World! make up your mind, this thing is int on some places and unsigned short on others */ + unsigned short (*name2id) (const char*); + const char* (*id2name) (unsigned short,const char *file, int line, const char *func); +}; + +struct mapindex_interface *mapindex; -int mapindex_addmap(int index, const char* name); -int mapindex_removemap(int index); +void mapindex_defaults(void); #endif /* _MAPINDEX_H_ */ diff --git a/src/common/mmo.h b/src/common/mmo.h index 5816b467c..b33b01fa7 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -119,7 +119,6 @@ #define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan] #define MAX_GUILDLEVEL 50 #define MAX_GUARDIANS 8 // Local max per castle. [Skotlex] -#define MAX_QUEST_DB 2670 // Max quests that the server will load #define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest #define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95] @@ -202,14 +201,19 @@ enum item_types { }; -// Questlog system [Kevin] [Inkfish] -typedef enum quest_state { Q_INACTIVE, Q_ACTIVE, Q_COMPLETE } quest_state; +// Questlog states +enum quest_state { + Q_INACTIVE, ///< Inactive quest (the user can toggle between active and inactive quests) + Q_ACTIVE, ///< Active quest + Q_COMPLETE, ///< Completed quest +}; +/// Questlog entry struct quest { - int quest_id; - unsigned int time; - int count[MAX_QUEST_OBJECTIVES]; - quest_state state; + int quest_id; ///< Quest ID + unsigned int time; ///< Expiration time + int count[MAX_QUEST_OBJECTIVES]; ///< Kill counters of each quest objective + enum quest_state state; ///< Current quest state }; struct item { @@ -280,7 +284,8 @@ struct accreg { // For saving status changes across sessions. [Skotlex] struct status_change_data { unsigned short type; //SC_type - long val1, val2, val3, val4, tick; //Remaining duration. + int val1, val2, val3, val4; + unsigned int tick; //Remaining duration. }; struct storage_data { diff --git a/src/common/nullpo.c b/src/common/nullpo.c index 4383109a7..20180dd3b 100644 --- a/src/common/nullpo.c +++ b/src/common/nullpo.c @@ -4,88 +4,26 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> -#include "nullpo.h" +#include "../common/nullpo.h" #include "../common/showmsg.h" -// #include "logs.h" // 布石してみる -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap); - -/*====================================== - * Nullチェック 及び 情報出力 - *--------------------------------------*/ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) -{ - va_list ap; - - if (target != NULL) - return 0; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); - return 1; -} - -int nullpo_chk(const char *file, int line, const char *func, const void *target) -{ - if (target != NULL) - return 0; - - nullpo_info_core(file, line, func, NULL, NULL); - return 1; -} - - -/*====================================== - * nullpo情報出力(外部呼出し向けラッパ) - *--------------------------------------*/ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - nullpo_info_core(file, line, func, fmt, ap); - va_end(ap); -} - -void nullpo_info(const char *file, int line, const char *func) -{ - nullpo_info_core(file, line, func, NULL, NULL); -} - - -/*====================================== - * nullpo情報出力(Main) - *--------------------------------------*/ -static void nullpo_info_core(const char *file, int line, const char *func, - const char *fmt, va_list ap) -{ +/** + * Reports failed assertions or NULL pointers + * + * @param file Source file where the error was detected + * @param line Line + * @param func Function + * @param targetname Name of the checked symbol + * @param title Message title to display (i.e. failed assertion or nullpo info) + */ +void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title) { if (file == NULL) file = "??"; - func = - func == NULL ? "unknown": - func[0] == '\0' ? "unknown": - func; - - ShowMessage("--- nullpo info --------------------------------------------\n"); - ShowMessage("%s:%d: in func `%s'\n", file, line, func); - if (fmt != NULL) - { - if (fmt[0] != '\0') - { - vprintf(fmt, ap); - - // 最後に改行したか確認 - if (fmt[strlen(fmt)-1] != '\n') - ShowMessage("\n"); - } - } - ShowMessage("--- end nullpo info ----------------------------------------\n"); + if (func == NULL || *func == '\0') + func = "unknown"; - // ここらでnullpoログをファイルに書き出せたら - // まとめて提出できるなと思っていたり。 + ShowError("--- %s --------------------------------------------\n", title); + ShowError("%s:%d: '%s' in function `%s'\n", file, line, targetname, func); + ShowError("--- end %s ----------------------------------------\n", title); } diff --git a/src/common/nullpo.h b/src/common/nullpo.h index 8ee86a782..05484135c 100644 --- a/src/common/nullpo.h +++ b/src/common/nullpo.h @@ -1,225 +1,127 @@ // Copyright (c) Athena Dev Teams - Licensed under GNU GPL // For more information, see LICENCE in the main folder -#ifndef _NULLPO_H_ -#define _NULLPO_H_ - +#ifndef COMMON_NULLPO_H +#define COMMON_NULLPO_H #include "../common/cbasetypes.h" -#define NLP_MARK __FILE__, __LINE__, __func__ - // enabled by default on debug builds #if defined(DEBUG) && !defined(NULLPO_CHECK) #define NULLPO_CHECK #endif -/*---------------------------------------------------------------------------- - * Macros - *---------------------------------------------------------------------------- - */ -/*====================================== - * Nullチェック 及び 情報出力後 return - *・展開するとifとかreturn等が出るので - * 一行単体で使ってください。 - *・nullpo_ret(x = func()); - * のような使用法も想定しています。 - *-------------------------------------- - * nullpo_ret(t) - * 戻り値 0固定 - * [引数] - * t チェック対象 - *-------------------------------------- - * nullpo_retv(t) - * 戻り値 なし - * [引数] - * t チェック対象 - *-------------------------------------- - * nullpo_retr(ret, t) - * 戻り値 指定 - * [引数] - * ret return(ret); - * t チェック対象 - *-------------------------------------- - * nullpo_ret_f(t, fmt, ...) - * 詳細情報出力用 - * 戻り値 0 - * [引数] - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- - * nullpo_retv_f(t, fmt, ...) - * 詳細情報出力用 - * 戻り値 なし - * [引数] - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- - * nullpo_retr_f(ret, t, fmt, ...) - * 詳細情報出力用 - * 戻り値 指定 - * [引数] - * ret return(ret); - * t チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- - */ +// Skip assert checks on release builds +#if !defined(RELEASE) && !defined(ASSERT_CHECK) +#define ASSERT_CHECK +#endif + +/** Assert */ + +#if defined(ASSERT_CHECK) +// extern "C" { +#include <assert.h> +// } +#if !defined(DEFCPP) && defined(WIN32) && !defined(MINGW) +#include <crtdbg.h> +#endif // !DEFCPP && WIN && !MINGW +#define Assert(EX) assert(EX) +#define Assert_chk(EX) ( (EX) ? false : (assert_report(__FILE__, __LINE__, __func__, #EX, "failed assertion"), true) ) +#else // ! ASSERT_CHECK +#define Assert(EX) (EX) +#define Assert_chk(EX) ((EX), false) +#endif // ASSERT_CHECK #if defined(NULLPO_CHECK) +/** + * Reports NULL pointer information if the passed pointer is NULL + * + * @param t pointer to check + * @return true if the passed pointer is NULL, false otherwise + */ +#define nullpo_chk(t) ( (t) != NULL ? false : (assert_report(__FILE__, __LINE__, __func__, #t, "nullpo info"), true) ) +#else // ! NULLPO_CHECK +#define nullpo_chk(t) ((void)(t), false) +#endif // NULLPO_CHECK + +/** + * The following macros check for NULL pointers and return from the current + * function or block in case one is found. + * + * It is guaranteed that the argument is evaluated once and only once, so it + * is safe to call them as: + * nullpo_ret(x = func()); + * The macros can be used safely in any context, as they expand to a do/while + * construct, except nullpo_retb, which expands to an if/else construct. + */ +/** + * Returns 0 if a NULL pointer is found. + * + * @param t pointer to check + */ #define nullpo_ret(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(0);} - -#define nullpo_retv(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return;} - -#define nullpo_retr(ret, t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {return(ret);} - -#define nullpo_retb(t) \ - if (nullpo_chk(NLP_MARK, (void *)(t))) {break;} - -// 可変引数マクロに関する条件コンパイル -#if __STDC_VERSION__ >= 199901L -/* C99に対応 */ -#define nullpo_ret_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(0);} - -#define nullpo_retv_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return;} - -#define nullpo_retr_f(ret, t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {return(ret);} - -#define nullpo_retb_f(t, fmt, ...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), __VA_ARGS__)) {break;} + do { if (nullpo_chk(t)) return(0); } while(0) -#elif __GNUC__ >= 2 -/* GCC用 */ -#define nullpo_ret_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(0);} - -#define nullpo_retv_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return;} - -#define nullpo_retr_f(ret, t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {return(ret);} - -#define nullpo_retb_f(t, fmt, args...) \ - if (nullpo_chk_f(NLP_MARK, (void *)(t), (fmt), ## args)) {break;} - -#else - -/* その他の場合・・・ orz */ - -#endif - -#else /* NULLPO_CHECK */ -/* No Nullpo check */ - -// if((t)){;} -// 良い方法が思いつかなかったので・・・苦肉の策です。 -// 一応ワーニングは出ないはず - -#define nullpo_ret(t) (void)(t) -#define nullpo_retv(t) (void)(t) -#define nullpo_retr(ret, t) (void)(t) -#define nullpo_retb(t) (void)(t) - -// 可変引数マクロに関する条件コンパイル -#if __STDC_VERSION__ >= 199901L -/* C99に対応 */ -#define nullpo_ret_f(t, fmt, ...) (void)(t) -#define nullpo_retv_f(t, fmt, ...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, ...) (void)(t) -#define nullpo_retb_f(t, fmt, ...) (void)(t) - -#elif __GNUC__ >= 2 -/* GCC用 */ -#define nullpo_ret_f(t, fmt, args...) (void)(t) -#define nullpo_retv_f(t, fmt, args...) (void)(t) -#define nullpo_retr_f(ret, t, fmt, args...) (void)(t) -#define nullpo_retb_f(t, fmt, args...) (void)(t) - -#else -/* その他の場合・・・ orz */ -#endif +/** + * Returns 0 if the given assertion fails. + * + * @param t statement to check + */ +#define Assert_ret(t) \ + do { if (Assert_chk(t)) return(0); } while(0) -#endif /* NULLPO_CHECK */ +/** + * Returns void if a NULL pointer is found. + * + * @param t pointer to check + */ +#define nullpo_retv(t) \ + do { if (nullpo_chk(t)) return; } while(0) -/*---------------------------------------------------------------------------- - * Functions - *---------------------------------------------------------------------------- +/** + * Returns void if the given assertion fails. + * + * @param t statement to check */ -/*====================================== - * nullpo_chk - * Nullチェック 及び 情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * target チェック対象 - * [返り値] - * 0 OK - * 1 NULL - *-------------------------------------- +#define Assert_retv(t) \ + do { if (Assert_chk(t)) return; } while(0) + +/** + * Returns the given value if a NULL pointer is found. + * + * @param ret value to return + * @param t pointer to check */ -int nullpo_chk(const char *file, int line, const char *func, const void *target); - - -/*====================================== - * nullpo_chk_f - * Nullチェック 及び 詳細な情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * target チェック対象 - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - * [返り値] - * 0 OK - * 1 NULL - *-------------------------------------- +#define nullpo_retr(ret, t) \ + do { if (nullpo_chk(t)) return(ret); } while(0) + +/** + * Returns the given value if the given assertion fails. + * + * @param ret value to return + * @param t statement to check */ -int nullpo_chk_f(const char *file, int line, const char *func, const void *target, - const char *fmt, ...) - __attribute__((format(printf,5,6))); - - -/*====================================== - * nullpo_info - * nullpo情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - *-------------------------------------- +#define Assert_retr(ret, t) \ + do { if (Assert_chk(t)) return(ret); } while(0) + +/** + * Breaks from the current loop/switch if a NULL pointer is found. + * + * @param t pointer to check */ -void nullpo_info(const char *file, int line, const char *func); - - -/*====================================== - * nullpo_info_f - * nullpo詳細情報出力 - * [引数] - * file __FILE__ - * line __LINE__ - * func __func__ (関数名) - * これらには NLP_MARK を使うとよい - * fmt ... vprintfに渡される - * 備考や関係変数の書き出しなどに - *-------------------------------------- +#define nullpo_retb(t) \ + if (nullpo_chk(t)) break; else (void)0 + +/** + * Breaks from the current loop/switch if the given assertion fails. + * + * @param t statement to check */ -void nullpo_info_f(const char *file, int line, const char *func, - const char *fmt, ...) - __attribute__((format(printf,4,5))); +#define Assert_retb(t) \ + if (Assert_chk(t)) break; else (void)0 + +void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title); -#endif /* _NULLPO_H_ */ +#endif /* COMMON_NULLPO_H */ diff --git a/src/common/socket.c b/src/common/socket.c index 2ae9d44b3..9c6938008 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -340,7 +340,7 @@ void set_eof(int fd) int recv_to_fifo(int fd) { - int len; + ssize_t len; if( !session_isActive(fd) ) return -1; @@ -377,7 +377,7 @@ int recv_to_fifo(int fd) int send_from_fifo(int fd) { - int len; + ssize_t len; if( !session_isValid(fd) ) return -1; @@ -855,6 +855,10 @@ int do_sockets(int next) } } +#ifdef __clang_analyzer__ + // Let Clang's static analyzer know this never happens (it thinks it might because of a NULL check in session_isValid) + if (!session[i]) continue; +#endif // __clang_analyzer__ session[i]->func_parse(i); if(!session[i]) @@ -1330,7 +1334,7 @@ int socket_getips(uint32* ips, int max) void socket_init(void) { char *SOCKET_CONF_FILENAME = "conf/packet.conf"; - unsigned int rlim_cur = FD_SETSIZE; + uint64 rlim_cur = FD_SETSIZE; #ifdef WIN32 {// Start up windows networking @@ -1403,7 +1407,7 @@ void socket_init(void) timer->add_interval(timer->gettick()+1000, connect_check_clear, 0, 0, 5*60*1000); #endif - ShowInfo("Server supports up to '"CL_WHITE"%u"CL_RESET"' concurrent connections.\n", rlim_cur); + ShowInfo("Server supports up to '"CL_WHITE"%lld"CL_RESET"' concurrent connections.\n", rlim_cur); /* Hercules Plugin Manager */ HPM->share(session,"session"); diff --git a/src/common/sql.c b/src/common/sql.c index 0e06d6d18..79ccc8e92 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -1036,7 +1036,7 @@ void Sql_HerculesUpdateCheck(Sql* self) { fseek (ufp,1,SEEK_SET);/* woo. skip the # */ if( fgets(timestamp,sizeof(timestamp),ufp) ) { - unsigned int timestampui = atol(timestamp); + unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); if( Sql_NumRows(self) != 1 ) { @@ -1079,7 +1079,7 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename) { fseek (ifp,1,SEEK_SET);/* woo. skip the # */ if( fgets(timestamp,sizeof(timestamp),ifp) ) { - unsigned int timestampui = atol(timestamp); + unsigned int timestampui = (unsigned int)atol(timestamp); if( SQL_ERROR == SQL->Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) Sql_ShowDebug(self); else if( Sql_NumRows(self) == 1 ) { diff --git a/src/common/strlib.c b/src/common/strlib.c index e45cb0789..0f68eb206 100644 --- a/src/common/strlib.c +++ b/src/common/strlib.c @@ -952,7 +952,7 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc if( line[0] == '\0' || line[0] == '\n' || line[0] == '\r') continue; - columns = sv_split(line, strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); + columns = sv_split(line, (int)strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); if( columns < mincols ) { ShowError("sv_readdb: Insufficient columns in line %d of \"%s\" (found %d, need at least %d).\n", lines, path, columns, mincols); @@ -1018,7 +1018,8 @@ int StringBuf_Printf(StringBuf* self, const char* fmt, ...) { /// Appends the result of vprintf to the StringBuf int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { - int n, size, off; + int n, off; + size_t size; for(;;) { va_list apcopy; @@ -1028,7 +1029,7 @@ int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { n = vsnprintf(self->ptr_, size, fmt, apcopy); va_end(apcopy); /* If that worked, return the length. */ - if( n > -1 && n < size ) { + if( n > -1 && (size_t)n < size ) { self->ptr_ += n; return (int)(self->ptr_ - self->buf_); } @@ -1042,11 +1043,11 @@ int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { /// Appends the contents of another StringBuf to the StringBuf int StringBuf_Append(StringBuf* self, const StringBuf* sbuf) { - int available = self->max_ - (self->ptr_ - self->buf_); - int needed = (int)(sbuf->ptr_ - sbuf->buf_); + size_t available = self->max_ - (self->ptr_ - self->buf_); + size_t needed = sbuf->ptr_ - sbuf->buf_; if( needed >= available ) { - int off = (int)(self->ptr_ - self->buf_); + size_t off = (self->ptr_ - self->buf_); self->max_ += needed; self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); self->ptr_ = self->buf_ + off; @@ -1059,12 +1060,12 @@ int StringBuf_Append(StringBuf* self, const StringBuf* sbuf) { // Appends str to the StringBuf int StringBuf_AppendStr(StringBuf* self, const char* str) { - int available = self->max_ - (self->ptr_ - self->buf_); - int needed = (int)strlen(str); + size_t available = self->max_ - (self->ptr_ - self->buf_); + size_t needed = strlen(str); if( needed >= available ) { // not enough space, expand the buffer (minimum expansion = 1024) - int off = (int)(self->ptr_ - self->buf_); + size_t off = (self->ptr_ - self->buf_); self->max_ += max(needed, 1024); self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); self->ptr_ = self->buf_ + off; diff --git a/src/common/timer.c b/src/common/timer.c index e5cf5df2a..7f9e20dad 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -142,7 +142,7 @@ static void rdtsc_calibrate(){ * platform-abstracted tick retrieval * @return server's current tick */ -static int64 tick(void) { +static int64 sys_tick(void) { #if defined(WIN32) // Windows: GetTickCount/GetTickCount64: Return the number of // milliseconds that have elapsed since the system was started. @@ -206,7 +206,7 @@ static int gettick_count = 1; int64 timer_gettick_nocache(void) { gettick_count = TICK_CACHE; - gettick_cache = tick(); + gettick_cache = sys_tick(); return gettick_cache; } @@ -219,11 +219,11 @@ int64 timer_gettick(void) { // tick doesn't get cached int64 timer_gettick_nocache(void) { - return tick(); + return sys_tick(); } int64 timer_gettick(void) { - return tick(); + return sys_tick(); } ////////////////////////////////////////////////////////////////////////// #endif |