diff options
author | shennetsind <ind@henn.et> | 2013-05-15 16:47:08 -0300 |
---|---|---|
committer | shennetsind <ind@henn.et> | 2013-05-15 16:47:08 -0300 |
commit | 0aee4fd57f2f4135361f4182a08a98cf52ed9d10 (patch) | |
tree | d7f43f0a5a63e73e21291f906e33109232ce7830 /src/common | |
parent | 75942979098d34d52adc2537b6f28e02be7d7bae (diff) | |
download | hercules-0aee4fd57f2f4135361f4182a08a98cf52ed9d10.tar.gz hercules-0aee4fd57f2f4135361f4182a08a98cf52ed9d10.tar.bz2 hercules-0aee4fd57f2f4135361f4182a08a98cf52ed9d10.tar.xz hercules-0aee4fd57f2f4135361f4182a08a98cf52ed9d10.zip |
HPM Update
Made SQL and strlib functions HPM-friendly, special thanks to Yommy for bringing the issue up.
Added partial map.c support, for the all-handy map[] array, beware that soon the whole map.c renewal design will be commit and when that happens your usage of map.c functions in plugins might require some updates.
Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 72 | ||||
-rw-r--r-- | src/common/HPM.h | 2 | ||||
-rw-r--r-- | src/common/HPMi.h | 3 | ||||
-rw-r--r-- | src/common/core.c | 23 | ||||
-rw-r--r-- | src/common/mmo.h | 2 | ||||
-rw-r--r-- | src/common/showmsg.c | 18 | ||||
-rw-r--r-- | src/common/sql.c | 134 | ||||
-rw-r--r-- | src/common/sql.h | 236 | ||||
-rw-r--r-- | src/common/strlib.c | 362 | ||||
-rw-r--r-- | src/common/strlib.h | 244 | ||||
-rw-r--r-- | src/common/timer.c | 135 | ||||
-rw-r--r-- | src/common/timer.h | 34 |
12 files changed, 625 insertions, 640 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 2df559c82..af06811a5 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -11,6 +11,8 @@ #include "../common/conf.h" #include "../common/utils.h" #include "../common/console.h" +#include "../common/strlib.h" +#include "../common/sql.h" #include "HPM.h" #include <stdio.h> @@ -73,39 +75,34 @@ struct hplugin *hplugin_create(void) { HPM->plugins[HPM->plugin_count - 1]->filename = NULL; return HPM->plugins[HPM->plugin_count - 1]; } -bool hplugin_showmsg_populate(struct hplugin *plugin, const char *filename) { - void **ShowSub; - const char* ShowSubNames[9] = { - "ShowMessage", - "ShowStatus", - "ShowSQL", - "ShowInfo", - "ShowNotice", - "ShowWarning", - "ShowDebug", - "ShowError", - "ShowFatalError", +#define HPM_POP(x) { #x , x } +bool hplugin_populate(struct hplugin *plugin, const char *filename) { + void **Link; + struct { + const char* name; + void *Ref; + } ToLink[] = { + HPM_POP(ShowMessage), + HPM_POP(ShowStatus), + HPM_POP(ShowSQL), + HPM_POP(ShowInfo), + HPM_POP(ShowNotice), + HPM_POP(ShowWarning), + HPM_POP(ShowDebug), + HPM_POP(ShowError), + HPM_POP(ShowFatalError), }; - void* ShowSubRef[9] = { - ShowMessage, - ShowStatus, - ShowSQL, - ShowInfo, - ShowNotice, - ShowWarning, - ShowDebug, - ShowError, - ShowFatalError, - }; - int i; - for(i = 0; i < 9; i++) { - if( !( ShowSub = plugin_import(plugin->dll, ShowSubNames[i],void **) ) ) { - ShowWarning("HPM:plugin_load: failed to retrieve '%s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", ShowSubNames[i], filename); + int i, length = ARRAYLENGTH(ToLink); + + for(i = 0; i < length; i++) { + if( !( Link = plugin_import(plugin->dll, ToLink[i].name,void **) ) ) { + ShowWarning("HPM:plugin_load: failed to retrieve '%s' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", ToLink[i].name, filename); HPM->unload(plugin); return false; } - *ShowSub = ShowSubRef[i]; + *Link = ToLink[i].Ref; } + return true; } void hplugin_load(const char* filename) { @@ -114,6 +111,7 @@ void hplugin_load(const char* filename) { struct HPMi_interface **HPMi; bool anyEvent = false; void **import_symbol_ref; + Sql **sql_handle; if( HPM->exists(filename) ) { ShowWarning("HPM:plugin_load: attempting to load duplicate '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); @@ -153,6 +151,14 @@ void hplugin_load(const char* filename) { *import_symbol_ref = HPM->import_symbol; + if( !( sql_handle = plugin_import(plugin->dll, "mysql_handle",Sql **) ) ) { + ShowWarning("HPM:plugin_load: failed to retrieve 'mysql_handle' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); + HPM->unload(plugin); + return; + } + + *sql_handle = HPM->import_symbol("sql_handle"); + if( !( HPMi = plugin_import(plugin->dll, "HPMi",struct HPMi_interface **) ) ) { ShowWarning("HPM:plugin_load: failed to retrieve 'HPMi' for '"CL_WHITE"%s"CL_RESET"', skipping...\n", filename); HPM->unload(plugin); @@ -181,7 +187,7 @@ void hplugin_load(const char* filename) { return; } - if( !HPM->showmsg_pop(plugin,filename) ) + if( !HPM->populate(plugin,filename) ) return; if( SERVER_TYPE == SERVER_TYPE_MAP ) { @@ -266,6 +272,12 @@ void hplugins_share_defaults(void) { HPM->share(session,"session"); HPM->share(&fd_max,"fd_max"); HPM->share(addr_,"addr"); + /* strlib */ + HPM->share(strlib,"strlib"); + HPM->share(sv,"sv"); + HPM->share(StrBuf,"StrBuf"); + /* sql */ + HPM->share(SQL,"SQL"); /* timer */ HPM->share(gettick,"gettick"); HPM->share(add_timer,"add_timer"); @@ -343,6 +355,6 @@ void hpm_defaults(void) { HPM->share = hplugin_export_symbol; HPM->symbol_defaults = hplugins_share_defaults; HPM->config_read = hplugins_config_read; - HPM->showmsg_pop = hplugin_showmsg_populate; + HPM->populate = hplugin_populate; HPM->symbol_defaults_sub = NULL; } diff --git a/src/common/HPM.h b/src/common/HPM.h index 87d7bdac6..10b1f0e79 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -72,7 +72,7 @@ struct HPM_interface { void (*share) (void *, char *); void (*symbol_defaults) (void); void (*config_read) (void); - bool (*showmsg_pop) (struct hplugin *plugin,const char *filename); + bool (*populate) (struct hplugin *plugin,const char *filename); void (*symbol_defaults_sub) (void); } HPM_s; diff --git a/src/common/HPMi.h b/src/common/HPMi.h index f7832d0ec..a58eeed38 100644 --- a/src/common/HPMi.h +++ b/src/common/HPMi.h @@ -7,6 +7,7 @@ #include "../common/cbasetypes.h" #include "../common/core.h" #include "../common/console.h" +#include "../common/sql.h" struct script_state; struct AtCommandInfo; @@ -42,6 +43,8 @@ struct hplugin_info { }; HPExport void *(*import_symbol) (char *name); +HPExport Sql *mysql_handle; + #define GET_SYMBOL(n) import_symbol(n) #define SERVER_TYPE_ALL SERVER_TYPE_LOGIN|SERVER_TYPE_CHAR|SERVER_TYPE_MAP diff --git a/src/common/core.c b/src/common/core.c index 9fd9747aa..8ed0b5801 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -278,27 +278,32 @@ void usercheck(void) { } #endif } - +void core_defaults(void) { +#ifndef MINICORE + hpm_defaults(); +#endif + console_defaults(); +#ifndef MINICORE + strlib_defaults(); + sql_defaults(); + timer_defaults(); +#endif +} /*====================================== * CORE : MAINROUTINE *--------------------------------------*/ -int main (int argc, char **argv) -{ +int main (int argc, char **argv) { {// initialize program arguments char *p1 = SERVER_NAME = argv[0]; char *p2 = p1; - while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) - { + while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL) { SERVER_NAME = ++p1; p2 = p1; } arg_c = argc; arg_v = argv; } -#ifndef MINICORE - hpm_defaults(); -#endif - console_defaults(); + core_defaults(); malloc_init();// needed for Show* in display_title() [FlavioJS] diff --git a/src/common/mmo.h b/src/common/mmo.h index 257a3b42d..581a7a357 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -47,7 +47,7 @@ // 20120307 - 2012-03-07aRagexeRE+ - 0x970 #ifndef PACKETVER - #define PACKETVER 20120418 + #define PACKETVER 20130320 #endif //Remove/Comment this line to disable sc_data saving. [Skotlex] diff --git a/src/common/showmsg.c b/src/common/showmsg.c index 50fa972f0..2a3146d35 100644 --- a/src/common/showmsg.c +++ b/src/common/showmsg.c @@ -78,9 +78,9 @@ int console_msg_log = 0;//[Ind] msg error logging } \ else \ {/* dynamic buffer */ \ - buf.d_ = StringBuf_Malloc(); \ - buf.l_ = StringBuf_Vprintf(buf.d_, fmt, args); \ - buf.v_ = StringBuf_Value(buf.d_); \ + buf.d_ = StrBuf->Malloc(); \ + buf.l_ = StrBuf->Vprintf(buf.d_, fmt, args); \ + buf.v_ = StrBuf->Value(buf.d_); \ ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.\n", buf.l_+1);\ } \ //define BUFVPRINTF @@ -91,7 +91,7 @@ int console_msg_log = 0;//[Ind] msg error logging #define FREEBUF(buf) \ if( buf.d_ ) \ { \ - StringBuf_Free(buf.d_); \ + StrBuf->Free(buf.d_); \ buf.d_ = NULL; \ } \ buf.v_ = NULL; \ @@ -855,13 +855,13 @@ void ShowConfigWarning(config_setting_t *config, const char *string, ...) { StringBuf buf; va_list ap; - StringBuf_Init(&buf); - StringBuf_AppendStr(&buf, string); - StringBuf_Printf(&buf, " (%s:%d)\n", config_setting_source_file(config), config_setting_source_line(config)); + StrBuf->Init(&buf); + StrBuf->AppendStr(&buf, string); + StrBuf->Printf(&buf, " (%s:%d)\n", config_setting_source_file(config), config_setting_source_line(config)); va_start(ap, string); - _vShowMessage(MSG_WARNING, StringBuf_Value(&buf), ap); + _vShowMessage(MSG_WARNING, StrBuf->Value(&buf), ap); va_end(ap); - StringBuf_Destroy(&buf); + StrBuf->Destroy(&buf); } void ShowDebug(const char *string, ...) { va_list ap; diff --git a/src/common/sql.c b/src/common/sql.c index 3df9bc1c5..391211183 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -22,8 +22,7 @@ int mysql_reconnect_type; unsigned int mysql_reconnect_count; /// Sql handle -struct Sql -{ +struct Sql { StringBuf buf; MYSQL handle; MYSQL_RES* result; @@ -36,8 +35,7 @@ struct Sql // Column length receiver. // Takes care of the possible size missmatch between uint32 and unsigned long. -struct s_column_length -{ +struct s_column_length { uint32* out_length; unsigned long length; }; @@ -46,8 +44,7 @@ typedef struct s_column_length s_column_length; /// Sql statement -struct SqlStmt -{ +struct SqlStmt { StringBuf buf; MYSQL_STMT* stmt; MYSQL_BIND* params; @@ -74,7 +71,7 @@ Sql* Sql_Malloc(void) CREATE(self, Sql, 1); mysql_init(&self->handle); - StringBuf_Init(&self->buf); + StrBuf->Init(&self->buf); self->lengths = NULL; self->result = NULL; self->keepalive = INVALID_TIMER; @@ -92,7 +89,7 @@ int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* hos if( self == NULL ) return SQL_ERROR; - StringBuf_Clear(&self->buf); + StrBuf->Clear(&self->buf); if( !mysql_real_connect(&self->handle, host, user, passwd, db, (unsigned int)port, NULL/*unix_socket*/, 0/*clientflag*/) ) { ShowSQL("%s\n", mysql_error(&self->handle)); @@ -114,18 +111,16 @@ int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* hos /// Retrieves the timeout of the connection. int Sql_GetTimeout(Sql* self, uint32* out_timeout) { - if( self && out_timeout && SQL_SUCCESS == Sql_Query(self, "SHOW VARIABLES LIKE 'wait_timeout'") ) - { + if( self && out_timeout && SQL_SUCCESS == SQL->Query(self, "SHOW VARIABLES LIKE 'wait_timeout'") ) { char* data; size_t len; - if( SQL_SUCCESS == Sql_NextRow(self) && - SQL_SUCCESS == Sql_GetData(self, 1, &data, &len) ) - { + if( SQL_SUCCESS == SQL->NextRow(self) && + SQL_SUCCESS == SQL->GetData(self, 1, &data, &len) ) { *out_timeout = (uint32)strtoul(data, NULL, 10); - Sql_FreeResult(self); + SQL->FreeResult(self); return SQL_SUCCESS; } - Sql_FreeResult(self); + SQL->FreeResult(self); } return SQL_ERROR; } @@ -139,12 +134,11 @@ int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_l size_t len; size_t off = 0; - if( self == NULL || SQL_ERROR == Sql_Query(self, "EXPLAIN `%s`", table) ) + if( self == NULL || SQL_ERROR == SQL->Query(self, "EXPLAIN `%s`", table) ) return SQL_ERROR; out_buf[off] = '\0'; - while( SQL_SUCCESS == Sql_NextRow(self) && SQL_SUCCESS == Sql_GetData(self, 0, &data, &len) ) - { + while( SQL_SUCCESS == SQL->NextRow(self) && SQL_SUCCESS == SQL->GetData(self, 0, &data, &len) ) { len = strnlen(data, len); if( off + len + 2 > buf_len ) { @@ -157,7 +151,7 @@ int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_l out_buf[off++] = sep; } out_buf[off] = '\0'; - Sql_FreeResult(self); + SQL->FreeResult(self); return SQL_SUCCESS; } @@ -250,7 +244,7 @@ int Sql_Query(Sql* self, const char* query, ...) va_list args; va_start(args, query); - res = Sql_QueryV(self, query, args); + res = SQL->QueryV(self, query, args); va_end(args); return res; @@ -264,10 +258,10 @@ int Sql_QueryV(Sql* self, const char* query, va_list args) if( self == NULL ) return SQL_ERROR; - Sql_FreeResult(self); - StringBuf_Clear(&self->buf); - StringBuf_Vprintf(&self->buf, query, args); - if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) + SQL->FreeResult(self); + StrBuf->Clear(&self->buf); + StrBuf->Vprintf(&self->buf, query, args); + if( mysql_real_query(&self->handle, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); @@ -291,10 +285,10 @@ int Sql_QueryStr(Sql* self, const char* query) if( self == NULL ) return SQL_ERROR; - Sql_FreeResult(self); - StringBuf_Clear(&self->buf); - StringBuf_AppendStr(&self->buf, query); - if( mysql_real_query(&self->handle, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) + SQL->FreeResult(self); + StrBuf->Clear(&self->buf); + StrBuf->AppendStr(&self->buf, query); + if( mysql_real_query(&self->handle, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_error(&self->handle)); hercules_mysql_error_handler(mysql_errno(&self->handle)); @@ -344,13 +338,10 @@ uint64 Sql_NumRows(Sql* self) /// Fetches the next row. -int Sql_NextRow(Sql* self) -{ - if( self && self->result ) - { +int Sql_NextRow(Sql* self) { + if( self && self->result ) { self->row = mysql_fetch_row(self->result); - if( self->row ) - { + if( self->row ) { self->lengths = mysql_fetch_lengths(self->result); return SQL_SUCCESS; } @@ -366,15 +357,11 @@ int Sql_NextRow(Sql* self) /// Gets the data of a column. int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len) { - if( self && self->row ) - { - if( col < Sql_NumColumns(self) ) - { + if( self && self->row ) { + if( col < SQL->NumColumns(self) ) { if( out_buf ) *out_buf = self->row[col]; if( out_len ) *out_len = (size_t)self->lengths[col]; - } - else - {// out of range - ignore + } else {// out of range - ignore if( out_buf ) *out_buf = NULL; if( out_len ) *out_len = 0; } @@ -386,10 +373,8 @@ int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len) /// Frees the result of the query. -void Sql_FreeResult(Sql* self) -{ - if( self && self->result ) - { +void Sql_FreeResult(Sql* self) { + if( self && self->result ) { mysql_free_result(self->result); self->result = NULL; self->row = NULL; @@ -404,8 +389,8 @@ void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug { if( self == NULL ) ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line); - else if( StringBuf_Length(&self->buf) > 0 ) - ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf)); + else if( StrBuf->Length(&self->buf) > 0 ) + ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StrBuf->Value(&self->buf)); else ShowDebug("at %s:%lu\n", debug_file, debug_line); } @@ -417,8 +402,8 @@ void Sql_Free(Sql* self) { if( self ) { - Sql_FreeResult(self); - StringBuf_Destroy(&self->buf); + SQL->FreeResult(self); + StrBuf->Destroy(&self->buf); if( self->keepalive != INVALID_TIMER ) delete_timer(self->keepalive, Sql_P_KeepaliveTimer); aFree(self); } @@ -590,8 +575,7 @@ static void SqlStmt_P_ShowDebugTruncatedColumn(SqlStmt* self, size_t i) /// Allocates and initializes a new SqlStmt handle. -SqlStmt* SqlStmt_Malloc(Sql* sql) -{ +SqlStmt* SqlStmt_Malloc(Sql* sql) { SqlStmt* self; MYSQL_STMT* stmt; @@ -599,13 +583,12 @@ SqlStmt* SqlStmt_Malloc(Sql* sql) return NULL; stmt = mysql_stmt_init(&sql->handle); - if( stmt == NULL ) - { + if( stmt == NULL ) { ShowSQL("DB error - %s\n", mysql_error(&sql->handle)); return NULL; } CREATE(self, SqlStmt, 1); - StringBuf_Init(&self->buf); + StrBuf->Init(&self->buf); self->stmt = stmt; self->params = NULL; self->columns = NULL; @@ -642,9 +625,9 @@ int SqlStmt_PrepareV(SqlStmt* self, const char* query, va_list args) return SQL_ERROR; SqlStmt_FreeResult(self); - StringBuf_Clear(&self->buf); - StringBuf_Vprintf(&self->buf, query, args); - if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) + StrBuf->Clear(&self->buf); + StrBuf->Vprintf(&self->buf, query, args); + if( mysql_stmt_prepare(self->stmt, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); @@ -664,9 +647,9 @@ int SqlStmt_PrepareStr(SqlStmt* self, const char* query) return SQL_ERROR; SqlStmt_FreeResult(self); - StringBuf_Clear(&self->buf); - StringBuf_AppendStr(&self->buf, query); - if( mysql_stmt_prepare(self->stmt, StringBuf_Value(&self->buf), (unsigned long)StringBuf_Length(&self->buf)) ) + StrBuf->Clear(&self->buf); + StrBuf->AppendStr(&self->buf, query); + if( mysql_stmt_prepare(self->stmt, StrBuf->Value(&self->buf), (unsigned long)StrBuf->Length(&self->buf)) ) { ShowSQL("DB error - %s\n", mysql_stmt_error(self->stmt)); hercules_mysql_error_handler(mysql_stmt_errno(self->stmt)); @@ -933,8 +916,8 @@ void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned lo { if( self == NULL ) ShowDebug("at %s:%lu - self is NULL\n", debug_file, debug_line); - else if( StringBuf_Length(&self->buf) > 0 ) - ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StringBuf_Value(&self->buf)); + else if( StrBuf->Length(&self->buf) > 0 ) + ShowDebug("at %s:%lu - %s\n", debug_file, debug_line, StrBuf->Value(&self->buf)); else ShowDebug("at %s:%lu\n", debug_file, debug_line); } @@ -947,7 +930,7 @@ void SqlStmt_Free(SqlStmt* self) if( self ) { SqlStmt_FreeResult(self); - StringBuf_Destroy(&self->buf); + StrBuf->Destroy(&self->buf); mysql_stmt_close(self->stmt); if( self->params ) aFree(self->params); @@ -1048,7 +1031,7 @@ void Sql_HerculesUpdateCheck(Sql* self) { if( fgets(timestamp,sizeof(timestamp),ufp) ) { unsigned int timestampui = atol(timestamp); - if( SQL_ERROR == Sql_Query(self, "SELECT 1 FROM `sql_updates` WHERE `timestamp` = '%u' LIMIT 1", timestampui) ) + 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 ) { ShowSQL("'"CL_WHITE"%s"CL_RESET"' wasn't applied to the database\n",path); @@ -1069,3 +1052,26 @@ void Sql_HerculesUpdateCheck(Sql* self) { void Sql_Init(void) { Sql_inter_server_read("conf/inter-server.conf",true); } +void sql_defaults(void) { + SQL = &sql_s; + + SQL->Connect = Sql_Connect; + SQL->GetTimeout = Sql_GetTimeout; + SQL->GetColumnNames = Sql_GetColumnNames; + SQL->SetEncoding = Sql_SetEncoding; + SQL->Ping = Sql_Ping; + SQL->EscapeString = Sql_EscapeString; + SQL->EscapeStringLen = Sql_EscapeStringLen; + SQL->Query = Sql_Query; + SQL->QueryV = Sql_QueryV; + SQL->QueryStr = Sql_QueryStr; + SQL->LastInsertId = Sql_LastInsertId; + SQL->NumColumns = Sql_NumColumns; + SQL->NumRows = Sql_NumRows; + SQL->NextRow = Sql_NextRow; + SQL->GetData = Sql_GetData; + SQL->FreeResult = Sql_FreeResult; + SQL->ShowDebug_ = Sql_ShowDebug_; + SQL->Free = Sql_Free; + SQL->Malloc = Sql_Malloc; +} diff --git a/src/common/sql.h b/src/common/sql.h index 319581504..d5a0eda2c 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -22,8 +22,7 @@ /// Data type identifier. /// String, enum and blob data types need the buffer length specified. -enum SqlDataType -{ +enum SqlDataType { SQLDT_NULL, // fixed size SQLDT_INT8, @@ -64,149 +63,96 @@ typedef enum SqlDataType SqlDataType; typedef struct Sql Sql; typedef struct SqlStmt SqlStmt; - -/// Allocates and initializes a new Sql handle. -struct Sql* Sql_Malloc(void); - - - -/// Establishes a connection. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_Connect(Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db); - - - - -/// Retrieves the timeout of the connection. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_GetTimeout(Sql* self, uint32* out_timeout); - - - - -/// Retrieves the name of the columns of a table into out_buf, with the separator after each name. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_GetColumnNames(Sql* self, const char* table, char* out_buf, size_t buf_len, char sep); - - - - -/// Changes the encoding of the connection. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_SetEncoding(Sql* self, const char* encoding); - - - -/// Pings the connection. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_Ping(Sql* self); - - - -/// Escapes a string. -/// The output buffer must be at least strlen(from)*2+1 in size. -/// -/// @return The size of the escaped string -size_t Sql_EscapeString(Sql* self, char* out_to, const char* from); - - - -/// Escapes a string. -/// The output buffer must be at least from_len*2+1 in size. -/// -/// @return The size of the escaped string -size_t Sql_EscapeStringLen(Sql* self, char* out_to, const char* from, size_t from_len); - - - -/// Executes a query. -/// Any previous result is freed. -/// The query is constructed as if it was sprintf. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_Query(Sql* self, const char* query, ...); - - - -/// Executes a query. -/// Any previous result is freed. -/// The query is constructed as if it was svprintf. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_QueryV(Sql* self, const char* query, va_list args); - - - -/// Executes a query. -/// Any previous result is freed. -/// The query is used directly. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_QueryStr(Sql* self, const char* query); - - - -/// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query. -/// -/// @return Value of the auto-increment column -uint64 Sql_LastInsertId(Sql* self); - - - -/// Returns the number of columns in each row of the result. -/// -/// @return Number of columns -uint32 Sql_NumColumns(Sql* self); - - - -/// Returns the number of rows in the result. -/// -/// @return Number of rows -uint64 Sql_NumRows(Sql* self); - - - -/// Fetches the next row. -/// The data of the previous row is no longer valid. -/// -/// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA -int Sql_NextRow(Sql* self); - - - -/// Gets the data of a column. -/// The data remains valid until the next row is fetched or the result is freed. -/// -/// @return SQL_SUCCESS or SQL_ERROR -int Sql_GetData(Sql* self, size_t col, char** out_buf, size_t* out_len); - - - -/// Frees the result of the query. -void Sql_FreeResult(Sql* self); - - +struct sql_interface { + /// Establishes a connection. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*Connect) (Sql* self, const char* user, const char* passwd, const char* host, uint16 port, const char* db); + /// Retrieves the timeout of the connection. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*GetTimeout) (Sql* self, uint32* out_timeout); + /// Retrieves the name of the columns of a table into out_buf, with the separator after each name. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*GetColumnNames) (Sql* self, const char* table, char* out_buf, size_t buf_len, char sep); + /// Changes the encoding of the connection. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*SetEncoding) (Sql* self, const char* encoding); + /// Pings the connection. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*Ping) (Sql* self); + /// Escapes a string. + /// The output buffer must be at least strlen(from)*2+1 in size. + /// + /// @return The size of the escaped string + size_t (*EscapeString) (Sql* self, char* out_to, const char* from); + /// Escapes a string. + /// The output buffer must be at least from_len*2+1 in size. + /// + /// @return The size of the escaped string + size_t (*EscapeStringLen) (Sql* self, char* out_to, const char* from, size_t from_len); + /// Executes a query. + /// Any previous result is freed. + /// The query is constructed as if it was sprintf. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*Query) (Sql* self, const char* query, ...); + /// Executes a query. + /// Any previous result is freed. + /// The query is constructed as if it was svprintf. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*QueryV) (Sql* self, const char* query, va_list args); + /// Executes a query. + /// Any previous result is freed. + /// The query is used directly. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*QueryStr) (Sql* self, const char* query); + /// Returns the number of the AUTO_INCREMENT column of the last INSERT/UPDATE query. + /// + /// @return Value of the auto-increment column + uint64 (*LastInsertId) (Sql* self); + /// Returns the number of columns in each row of the result. + /// + /// @return Number of columns + uint32 (*NumColumns) (Sql* self); + /// Returns the number of rows in the result. + /// + /// @return Number of rows + uint64 (*NumRows) (Sql* self); + /// Fetches the next row. + /// The data of the previous row is no longer valid. + /// + /// @return SQL_SUCCESS, SQL_ERROR or SQL_NO_DATA + int (*NextRow) (Sql* self); + /// Gets the data of a column. + /// The data remains valid until the next row is fetched or the result is freed. + /// + /// @return SQL_SUCCESS or SQL_ERROR + int (*GetData) (Sql* self, size_t col, char** out_buf, size_t* out_len); + /// Frees the result of the query. + void (*FreeResult) (Sql* self); + /// Shows debug information (last query). + void (*ShowDebug_) (Sql* self, const char* debug_file, const unsigned long debug_line); + /// Frees a Sql handle returned by Sql_Malloc. + void (*Free) (Sql* self); + /// Allocates and initializes a new Sql handle. + struct Sql *(*Malloc) (void); +} sql_s; + +struct sql_interface *SQL; + +void sql_defaults(void); #if defined(SQL_REMOVE_SHOWDEBUG) -#define Sql_ShowDebug(self) (void)0 + #define Sql_ShowDebug(self) (void)0 #else -#define Sql_ShowDebug(self) Sql_ShowDebug_(self, __FILE__, __LINE__) + #define Sql_ShowDebug(self) SQL->ShowDebug_(self, __FILE__, __LINE__) #endif -/// Shows debug information (last query). -void Sql_ShowDebug_(Sql* self, const char* debug_file, const unsigned long debug_line); - - - -/// Frees a Sql handle returned by Sql_Malloc. -void Sql_Free(Sql* self); - - /////////////////////////////////////////////////////////////////////////////// // Prepared Statements @@ -221,8 +167,6 @@ void Sql_Free(Sql* self); // 1) SELECT col FROM table WHERE id=? // 2) INSERT INTO table(col1,col2) VALUES(?,?) - - /// Allocates and initializes a new SqlStmt handle. /// It uses the connection of the parent Sql handle. /// Queries in Sql and SqlStmt are independent and don't affect each other. @@ -239,8 +183,6 @@ struct SqlStmt* SqlStmt_Malloc(Sql* sql); /// @return SQL_SUCCESS or SQL_ERROR int SqlStmt_Prepare(SqlStmt* self, const char* query, ...); - - /// Prepares the statement. /// Any previous result is freed and all parameter bindings are removed. /// The query is constructed as if it was svprintf. @@ -328,9 +270,9 @@ void SqlStmt_FreeResult(SqlStmt* self); void Sql_HerculesUpdateCheck(Sql* self); #if defined(SQL_REMOVE_SHOWDEBUG) -#define SqlStmt_ShowDebug(self) (void)0 + #define SqlStmt_ShowDebug(self) (void)0 #else -#define SqlStmt_ShowDebug(self) SqlStmt_ShowDebug_(self, __FILE__, __LINE__) + #define SqlStmt_ShowDebug(self) SqlStmt_ShowDebug_(self, __FILE__, __LINE__) #endif /// Shows debug information (with statement). void SqlStmt_ShowDebug_(SqlStmt* self, const char* debug_file, const unsigned long debug_line); diff --git a/src/common/strlib.c b/src/common/strlib.c index dfacbf136..278542a24 100644 --- a/src/common/strlib.c +++ b/src/common/strlib.c @@ -1,9 +1,11 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/malloc.h" #include "../common/showmsg.h" +#define STRLIB_C #include "strlib.h" #include <stdio.h> @@ -14,8 +16,7 @@ #define J_MAX_MALLOC_SIZE 65535 // escapes a string in-place (' -> \' , \ -> \\ , % -> _) -char* jstrescape (char* pt) -{ +char* jstrescape (char* pt) { //copy from here char *ptr; int i = 0, j = 0; @@ -220,8 +221,7 @@ const char* stristr(const char* haystack, const char* needle) } #ifdef __WIN32 -char* _strtok_r(char *s1, const char *s2, char **lasts) -{ +char* _strtok_r(char *s1, const char *s2, char **lasts) { char *ret; if (s1 == NULL) @@ -618,8 +618,7 @@ int sv_parse_next(struct s_svstate* sv) /// @param npos Size of the pos array /// @param opt Options that determine the parsing behaviour /// @return Number of fields found in the string or -1 if an error occured -int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt) -{ +int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt) { struct s_svstate sv; int count; @@ -637,8 +636,7 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i // parse count = 0; if( npos > 0 ) out_pos[0] = startoff; - while( !sv.done ) - { + while( !sv.done ) { ++count; if( sv_parse_next(&sv) <= 0 ) return -1;// error @@ -668,8 +666,7 @@ int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, i /// @param nfields Size of the field array /// @param opt Options that determine the parsing behaviour /// @return Number of fields found in the string or -1 if an error occured -int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt) -{ +int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt) { int pos[1024]; int i; int done; @@ -681,30 +678,21 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, in // next line end = str + pos[1]; - if( end[0] == '\0' ) - { + if( end[0] == '\0' ) { *out_fields = end; - } - else if( (opt&SV_TERMINATE_LF) && end[0] == '\n' ) - { + } else if( (opt&SV_TERMINATE_LF) && end[0] == '\n' ) { if( !(opt&SV_KEEP_TERMINATOR) ) end[0] = '\0'; *out_fields = end + 1; - } - else if( (opt&SV_TERMINATE_CRLF) && end[0] == '\r' && end[1] == '\n' ) - { + } else if( (opt&SV_TERMINATE_CRLF) && end[0] == '\r' && end[1] == '\n' ) { if( !(opt&SV_KEEP_TERMINATOR) ) end[0] = end[1] = '\0'; *out_fields = end + 2; - } - else if( (opt&SV_TERMINATE_CR) && end[0] == '\r' ) - { + } else if( (opt&SV_TERMINATE_CR) && end[0] == '\r' ) { if( !(opt&SV_KEEP_TERMINATOR) ) end[0] = '\0'; *out_fields = end + 1; - } - else - { + } else { ShowError("sv_split: unknown line delimiter 0x02%x.\n", (unsigned char)end[0]); return -1;// error } @@ -714,10 +702,8 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, in // fields i = 2; done = 0; - while( done < ret && nfields > 0 ) - { - if( i < ARRAYLENGTH(pos) ) - {// split field + while( done < ret && nfields > 0 ) { + if( i < ARRAYLENGTH(pos) ) { // split field *out_fields = str + pos[i]; end = str + pos[i+1]; *end = '\0'; @@ -726,9 +712,7 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, in ++done; ++out_fields; --nfields; - } - else - {// get more fields + } else { // get more fields sv_parse(str, len, pos[i-1] + 1, delim, pos, ARRAYLENGTH(pos), opt); i = 2; } @@ -748,65 +732,59 @@ int sv_split(char* str, int len, int startoff, char delim, char** out_fields, in /// @param len Length of the source string /// @param escapes Extra characters to be escaped /// @return Length of the escaped string -size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* escapes) -{ +size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* escapes) { size_t i; size_t j; if( out_dest == NULL ) return 0;// nothing to do - if( src == NULL ) - {// nothing to escape + if( src == NULL ) { // nothing to escape *out_dest = 0; return 0; } if( escapes == NULL ) escapes = ""; - for( i = 0, j = 0; i < len; ++i ) - { - switch( src[i] ) - { - case '\0':// octal 0 - out_dest[j++] = '\\'; - out_dest[j++] = '0'; - out_dest[j++] = '0'; - out_dest[j++] = '0'; - break; - case '\r':// carriage return - out_dest[j++] = '\\'; - out_dest[j++] = 'r'; - break; - case '\n':// line feed - out_dest[j++] = '\\'; - out_dest[j++] = 'n'; - break; - case '\\':// escape character - out_dest[j++] = '\\'; - out_dest[j++] = '\\'; - break; - default: - if( strchr(escapes,src[i]) ) - {// escape + for( i = 0, j = 0; i < len; ++i ) { + switch( src[i] ) { + case '\0':// octal 0 out_dest[j++] = '\\'; - switch( src[i] ) - { - case '\a': out_dest[j++] = 'a'; break; - case '\b': out_dest[j++] = 'b'; break; - case '\t': out_dest[j++] = 't'; break; - case '\v': out_dest[j++] = 'v'; break; - case '\f': out_dest[j++] = 'f'; break; - case '\?': out_dest[j++] = '?'; break; - default:// to octal - out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0700)>>6)); - out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0070)>>3)); - out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0007) )); - break; + out_dest[j++] = '0'; + out_dest[j++] = '0'; + out_dest[j++] = '0'; + break; + case '\r':// carriage return + out_dest[j++] = '\\'; + out_dest[j++] = 'r'; + break; + case '\n':// line feed + out_dest[j++] = '\\'; + out_dest[j++] = 'n'; + break; + case '\\':// escape character + out_dest[j++] = '\\'; + out_dest[j++] = '\\'; + break; + default: + if( strchr(escapes,src[i]) ) {// escape + out_dest[j++] = '\\'; + switch( src[i] ) { + case '\a': out_dest[j++] = 'a'; break; + case '\b': out_dest[j++] = 'b'; break; + case '\t': out_dest[j++] = 't'; break; + case '\v': out_dest[j++] = 'v'; break; + case '\f': out_dest[j++] = 'f'; break; + case '\?': out_dest[j++] = '?'; break; + default:// to octal + out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0700)>>6)); + out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0070)>>3)); + out_dest[j++] = '0'+((char)(((unsigned char)src[i]&0007) )); + break; + } } - } - else - out_dest[j++] = src[i]; - break; + else + out_dest[j++] = src[i]; + break; } } out_dest[j] = 0; @@ -821,8 +799,7 @@ size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* esca /// @param src Source string /// @param len Length of the source string /// @return Length of the escaped string -size_t sv_unescape_c(char* out_dest, const char* src, size_t len) -{ +size_t sv_unescape_c(char* out_dest, const char* src, size_t len) { static unsigned char low2hex[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x0? 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,// 0x1? @@ -844,71 +821,58 @@ size_t sv_unescape_c(char* out_dest, const char* src, size_t len) size_t i; size_t j; - for( i = 0, j = 0; i < len; ) - { - if( src[i] == '\\' ) - { + for( i = 0, j = 0; i < len; ) { + if( src[i] == '\\' ) { ++i;// '\\' if( i >= len ) ShowWarning("sv_unescape_c: empty escape sequence\n"); - else if( src[i] == 'x' ) - {// hex escape sequence + else if( src[i] == 'x' ) {// hex escape sequence unsigned char c = 0; unsigned char inrange = 1; ++i;// 'x' - if( i >= len || !ISXDIGIT(src[i]) ) - { + if( i >= len || !ISXDIGIT(src[i]) ) { ShowWarning("sv_unescape_c: \\x with no following hex digits\n"); continue; } - do{ - if( c > 0x0F && inrange ) - { + do { + if( c > 0x0F && inrange ) { ShowWarning("sv_unescape_c: hex escape sequence out of range\n"); inrange = 0; } c = (c<<4)|low2hex[(unsigned char)src[i]];// hex digit ++i; - }while( i < len && ISXDIGIT(src[i]) ); + } while( i < len && ISXDIGIT(src[i]) ); out_dest[j++] = (char)c; - } - else if( src[i] == '0' || src[i] == '1' || src[i] == '2' || src[i] == '3' ) - {// octal escape sequence (255=0377) + } else if( src[i] == '0' || src[i] == '1' || src[i] == '2' || src[i] == '3' ) {// octal escape sequence (255=0377) unsigned char c = src[i]-'0'; ++i;// '0', '1', '2' or '3' - if( i < len && src[i] >= '0' && src[i] <= '7' ) - { + if( i < len && src[i] >= '0' && src[i] <= '7' ) { c = (c<<3)|(src[i]-'0'); ++i;// octal digit } - if( i < len && src[i] >= '0' && src[i] <= '7' ) - { + if( i < len && src[i] >= '0' && src[i] <= '7' ) { c = (c<<3)|(src[i]-'0'); ++i;// octal digit } out_dest[j++] = (char)c; - } - else - {// other escape sequence + } else { // other escape sequence if( strchr(SV_ESCAPE_C_SUPPORTED, src[i]) == NULL ) ShowWarning("sv_unescape_c: unknown escape sequence \\%c\n", src[i]); - switch( src[i] ) - { - case 'a': out_dest[j++] = '\a'; break; - case 'b': out_dest[j++] = '\b'; break; - case 't': out_dest[j++] = '\t'; break; - case 'n': out_dest[j++] = '\n'; break; - case 'v': out_dest[j++] = '\v'; break; - case 'f': out_dest[j++] = '\f'; break; - case 'r': out_dest[j++] = '\r'; break; - case '?': out_dest[j++] = '\?'; break; - default: out_dest[j++] = src[i]; break; + switch( src[i] ) { + case 'a': out_dest[j++] = '\a'; break; + case 'b': out_dest[j++] = '\b'; break; + case 't': out_dest[j++] = '\t'; break; + case 'n': out_dest[j++] = '\n'; break; + case 'v': out_dest[j++] = '\v'; break; + case 'f': out_dest[j++] = '\f'; break; + case 'r': out_dest[j++] = '\r'; break; + case '?': out_dest[j++] = '\?'; break; + default: out_dest[j++] = src[i]; break; } ++i;// escaped character } - } - else + } else out_dest[j++] = src[i++];// normal character } out_dest[j] = 0; @@ -916,31 +880,28 @@ size_t sv_unescape_c(char* out_dest, const char* src, size_t len) } /// Skips a C escape sequence (starting with '\\'). -const char* skip_escaped_c(const char* p) -{ - if( p && *p == '\\' ) - { +const char* skip_escaped_c(const char* p) { + if( p && *p == '\\' ) { ++p; - switch( *p ) - { - case 'x':// hexadecimal - ++p; - while( ISXDIGIT(*p) ) - ++p; - break; - case '0': - case '1': - case '2': - case '3':// octal - ++p; - if( *p >= '0' && *p <= '7' ) + switch( *p ) { + case 'x':// hexadecimal ++p; - if( *p >= '0' && *p <= '7' ) - ++p; - break; - default: - if( *p && strchr(SV_ESCAPE_C_SUPPORTED, *p) ) + while( ISXDIGIT(*p) ) + ++p; + break; + case '0': + case '1': + case '2': + case '3':// octal ++p; + if( *p >= '0' && *p <= '7' ) + ++p; + if( *p >= '0' && *p <= '7' ) + ++p; + break; + default: + if( *p && strchr(SV_ESCAPE_C_SUPPORTED, *p) ) + ++p; } } return p; @@ -958,8 +919,7 @@ const char* skip_escaped_c(const char* p) /// @param maxcols Maximum number of columns of a valid row /// @param parseproc User-supplied row processing function /// @return true on success, false if file could not be opened -bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current)) -{ +bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current)) { FILE* fp; int lines = 0; int entries = 0; @@ -971,9 +931,7 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc snprintf(path, sizeof(path), "%s/%s", directory, filename); // open file - fp = fopen(path, "r"); - if( fp == NULL ) - { + if( (fp = fopen(path, "r")) == NULL ) { ShowError("sv_readdb: can't read %s\n", path); return false; } @@ -983,12 +941,10 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc fields = (char**)aMalloc(fields_length*sizeof(char*)); // process rows one by one - while( fgets(line, sizeof(line), fp) ) - { + while( fgets(line, sizeof(line), fp) ) { lines++; - if( ( match = strstr(line, "//") ) != NULL ) - {// strip comments + if( ( match = strstr(line, "//") ) != NULL ) {// strip comments match[0] = 0; } @@ -998,25 +954,21 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc columns = sv_split(line, strlen(line), 0, delim, fields, fields_length, (e_svopt)(SV_TERMINATE_LF|SV_TERMINATE_CRLF)); - if( columns < mincols ) - { + if( columns < mincols ) { ShowError("sv_readdb: Insufficient columns in line %d of \"%s\" (found %d, need at least %d).\n", lines, path, columns, mincols); continue; // not enough columns } - if( columns > maxcols ) - { + if( columns > maxcols ) { ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols ); continue; // too many columns } - if( entries == maxrows ) - { + if( entries == maxrows ) { ShowError("sv_readdb: Reached the maximum allowed number of entries (%d) when parsing file \"%s\".\n", maxrows, path); break; } // parse this row - if( !parseproc(fields+1, columns, entries) ) - { + if( !parseproc(fields+1, columns, entries) ) { ShowError("sv_readdb: Could not process contents of line %d of \"%s\".\n", lines, path); continue; // invalid row contents } @@ -1039,41 +991,36 @@ bool sv_readdb(const char* directory, const char* filename, char delim, int minc // @author MouseJstr (original) /// Allocates a StringBuf -StringBuf* StringBuf_Malloc() -{ +StringBuf* StringBuf_Malloc() { StringBuf* self; CREATE(self, StringBuf, 1); - StringBuf_Init(self); + StrBuf->Init(self); return self; } /// Initializes a previously allocated StringBuf -void StringBuf_Init(StringBuf* self) -{ +void StringBuf_Init(StringBuf* self) { self->max_ = 1024; self->ptr_ = self->buf_ = (char*)aMalloc(self->max_ + 1); } /// Appends the result of printf to the StringBuf -int StringBuf_Printf(StringBuf* self, const char* fmt, ...) -{ +int StringBuf_Printf(StringBuf* self, const char* fmt, ...) { int len; va_list ap; va_start(ap, fmt); - len = StringBuf_Vprintf(self, fmt, ap); + len = StrBuf->Vprintf(self, fmt, ap); va_end(ap); return len; } /// Appends the result of vprintf to the StringBuf -int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) -{ +int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list ap) { int n, size, off; - for(;;) - { + for(;;) { va_list apcopy; /* Try to print in the allocated space. */ size = self->max_ - (self->ptr_ - self->buf_); @@ -1081,8 +1028,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 && n < size ) { self->ptr_ += n; return (int)(self->ptr_ - self->buf_); } @@ -1095,13 +1041,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 StringBuf_Append(StringBuf* self, const StringBuf* sbuf) { int available = self->max_ - (self->ptr_ - self->buf_); int needed = (int)(sbuf->ptr_ - sbuf->buf_); - if( needed >= available ) - { + if( needed >= available ) { int off = (int)(self->ptr_ - self->buf_); self->max_ += needed; self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); @@ -1114,13 +1058,12 @@ int StringBuf_Append(StringBuf* self, const StringBuf* sbuf) } // Appends str to the StringBuf -int StringBuf_AppendStr(StringBuf* self, const char* str) -{ +int StringBuf_AppendStr(StringBuf* self, const char* str) { int available = self->max_ - (self->ptr_ - self->buf_); int needed = (int)strlen(str); - if( needed >= available ) - {// not enough space, expand the buffer (minimum expansion = 1024) + if( needed >= available ) { + // not enough space, expand the buffer (minimum expansion = 1024) int off = (int)(self->ptr_ - self->buf_); self->max_ += max(needed, 1024); self->buf_ = (char*)aRealloc(self->buf_, self->max_ + 1); @@ -1133,35 +1076,78 @@ int StringBuf_AppendStr(StringBuf* self, const char* str) } // Returns the length of the data in the Stringbuf -int StringBuf_Length(StringBuf* self) -{ +int StringBuf_Length(StringBuf* self) { return (int)(self->ptr_ - self->buf_); } /// Returns the data in the StringBuf -char* StringBuf_Value(StringBuf* self) -{ +char* StringBuf_Value(StringBuf* self) { *self->ptr_ = '\0'; return self->buf_; } /// Clears the contents of the StringBuf -void StringBuf_Clear(StringBuf* self) -{ +void StringBuf_Clear(StringBuf* self) { self->ptr_ = self->buf_; } /// Destroys the StringBuf -void StringBuf_Destroy(StringBuf* self) -{ +void StringBuf_Destroy(StringBuf* self) { aFree(self->buf_); self->ptr_ = self->buf_ = 0; self->max_ = 0; } // Frees a StringBuf returned by StringBuf_Malloc -void StringBuf_Free(StringBuf* self) -{ - StringBuf_Destroy(self); +void StringBuf_Free(StringBuf* self) { + StrBuf->Destroy(self); aFree(self); } +void strlib_defaults(void) { + /* connect */ + strlib = &strlib_s; + StrBuf = &stringbuf_s; + sv = &sv_s; + /* link~u! */ + strlib->jstrescape = jstrescape; + strlib->jmemescapecpy = jmemescapecpy; + strlib->remove_control_chars = remove_control_chars; + strlib->trim = trim; + strlib->normalize_name = normalize_name; + strlib->stristr = stristr; + +#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) + strlib->strnlen = strnlen; +#endif + +#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 + strlib->strtoull = strtoull; +#endif + strlib->e_mail_check = e_mail_check; + strlib->config_switch = config_switch; + strlib->safestrncpy = safestrncpy; + strlib->safestrnlen = safestrnlen; + strlib->safesnprintf = safesnprintf; + strlib->strline = strline; + strlib->bin2hex = bin2hex; + + StrBuf->Malloc = StringBuf_Malloc; + StrBuf->Init = StringBuf_Init; + StrBuf->Printf = StringBuf_Printf; + StrBuf->Vprintf = StringBuf_Vprintf; + StrBuf->Append = StringBuf_Append; + StrBuf->AppendStr = StringBuf_AppendStr; + StrBuf->Length = StringBuf_Length; + StrBuf->Value = StringBuf_Value; + StrBuf->Clear = StringBuf_Clear; + StrBuf->Destroy = StringBuf_Destroy; + StrBuf->Free = StringBuf_Free; + + sv->parse_next = sv_parse_next; + sv->parse = sv_parse; + sv->split = sv_split; + sv->escape_c = sv_escape_c; + sv->unescape_c = sv_unescape_c; + sv->skip_escaped_c = skip_escaped_c; + sv->readdb = sv_readdb; +} diff --git a/src/common/strlib.h b/src/common/strlib.h index bbc2c6105..af0fb2764 100644 --- a/src/common/strlib.h +++ b/src/common/strlib.h @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _STRLIB_H_ #define _STRLIB_H_ @@ -11,56 +12,14 @@ #include <string.h> #undef __USE_GNU -char* jstrescape (char* pt); -char* jstrescapecpy (char* pt, const char* spt); -int jmemescapecpy (char* pt, const char* spt, int size); - -int remove_control_chars(char* str); -char* trim(char* str); -char* normalize_name(char* str,const char* delims); -const char *stristr(const char *haystack, const char *needle); - #ifdef WIN32 -#define HAVE_STRTOK_R -#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr)) -char* _strtok_r(char* s1, const char* s2, char** lasts); -#endif - -#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) -size_t strnlen (const char* string, size_t maxlen); + #define HAVE_STRTOK_R + #define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr)) + char _strtok_r(char* s1, const char* s2, char** lasts); #endif -#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 -uint64 strtoull(const char* str, char** endptr, int base); -#endif - -int e_mail_check(char* email); -int config_switch(const char* str); - -/// strncpy that always nul-terminates the string -char* safestrncpy(char* dst, const char* src, size_t n); - -/// doesn't crash on null pointer -size_t safestrnlen(const char* string, size_t maxlen); - -/// Works like snprintf, but always nul-terminates the buffer. -/// Returns the size of the string (without nul-terminator) -/// or -1 if the buffer is too small. -int safesnprintf(char* buf, size_t sz, const char* fmt, ...); - -/// Returns the line of the target position in the string. -/// Lines start at 1. -int strline(const char* str, size_t pos); - -/// Produces the hexadecimal representation of the given input. -/// The output buffer must be at least count*2+1 in size. -/// Returns true on success, false on failure. -bool bin2hex(char* output, unsigned char* input, size_t count); - - /// Bitfield determining the behaviour of sv_parse and sv_split. -typedef enum e_svopt -{ +typedef enum e_svopt { // default: no escapes and no line terminator SV_NOESCAPE_NOTERMINATE = 0, // Escapes according to the C compiler. @@ -78,8 +37,7 @@ typedef enum e_svopt /// Parse state. /// The field is [start,end[ -struct s_svstate -{ +struct s_svstate { const char* str; //< string to parse int len; //< string length int off; //< current offset in the string @@ -90,66 +48,144 @@ struct s_svstate bool done; //< if all the text has been parsed }; -/// Parses a single field in a delim-separated string. -/// The delimiter after the field is skipped. -/// -/// @param sv Parse state -/// @return 1 if a field was parsed, 0 if done, -1 on error. -int sv_parse_next(struct s_svstate* sv); - -/// Parses a delim-separated string. -/// Starts parsing at startoff and fills the pos array with position pairs. -/// out_pos[0] and out_pos[1] are the start and end of line. -/// Other position pairs are the start and end of fields. -/// Returns the number of fields found or -1 if an error occurs. -int sv_parse(const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt); - -/// Splits a delim-separated string. -/// WARNING: this function modifies the input string -/// Starts splitting at startoff and fills the out_fields array. -/// out_fields[0] is the start of the next line. -/// Other entries are the start of fields (nul-teminated). -/// Returns the number of fields found or -1 if an error occurs. -int sv_split(char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt); - -/// Escapes src to out_dest according to the format of the C compiler. -/// Returns the length of the escaped string. -/// out_dest should be len*4+1 in size. -size_t sv_escape_c(char* out_dest, const char* src, size_t len, const char* escapes); - -/// Unescapes src to out_dest according to the format of the C compiler. -/// Returns the length of the unescaped string. -/// out_dest should be len+1 in size and can be the same buffer as src. -size_t sv_unescape_c(char* out_dest, const char* src, size_t len); - -/// Skips a C escape sequence (starting with '\\'). -const char* skip_escaped_c(const char* p); - -/// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row. -/// Tracks the progress of the operation (current line number, number of successfully processed rows). -/// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read. -bool sv_readdb(const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current)); - /// StringBuf - dynamic string -struct StringBuf -{ +struct StringBuf { char *buf_; char *ptr_; unsigned int max_; }; typedef struct StringBuf StringBuf; -StringBuf* StringBuf_Malloc(void); -void StringBuf_Init(StringBuf* self); -int StringBuf_Printf(StringBuf* self, const char* fmt, ...); -int StringBuf_Vprintf(StringBuf* self, const char* fmt, va_list args); -int StringBuf_Append(StringBuf* self, const StringBuf *sbuf); -int StringBuf_AppendStr(StringBuf* self, const char* str); -int StringBuf_Length(StringBuf* self); -char* StringBuf_Value(StringBuf* self); -void StringBuf_Clear(StringBuf* self); -void StringBuf_Destroy(StringBuf* self); -void StringBuf_Free(StringBuf* self); - +struct strlib_interface { + char *(*jstrescape) (char* pt); + char *(*jstrescapecpy) (char* pt, const char* spt); + int (*jmemescapecpy) (char* pt, const char* spt, int size); + int (*remove_control_chars) (char* str); + char *(*trim) (char* str); + char *(*normalize_name) (char* str,const char* delims); + const char *(*stristr) (const char *haystack, const char *needle); + +#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) + size_t (*strnlen) (const char* string, size_t maxlen); +#endif + +#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 + uint64 (*strtoull) (const char* str, char** endptr, int base); +#endif + + int (*e_mail_check) (char* email); + int (*config_switch) (const char* str); + + /// strncpy that always nul-terminates the string + char *(*safestrncpy) (char* dst, const char* src, size_t n); + + /// doesn't crash on null pointer + size_t (*safestrnlen) (const char* string, size_t maxlen); + + /// Works like snprintf, but always nul-terminates the buffer. + /// Returns the size of the string (without nul-terminator) + /// or -1 if the buffer is too small. + int (*safesnprintf) (char* buf, size_t sz, const char* fmt, ...); + + /// Returns the line of the target position in the string. + /// Lines start at 1. + int (*strline) (const char* str, size_t pos); + + /// Produces the hexadecimal representation of the given input. + /// The output buffer must be at least count*2+1 in size. + /// Returns true on success, false on failure. + bool (*bin2hex) (char* output, unsigned char* input, size_t count); +} strlib_s; + +struct strlib_interface *strlib; + +struct stringbuf_interface { + StringBuf* (*Malloc) (void); + void (*Init) (StringBuf* self); + int (*Printf) (StringBuf* self, const char* fmt, ...); + int (*Vprintf) (StringBuf* self, const char* fmt, va_list args); + int (*Append) (StringBuf* self, const StringBuf *sbuf); + int (*AppendStr) (StringBuf* self, const char* str); + int (*Length) (StringBuf* self); + char* (*Value) (StringBuf* self); + void (*Clear) (StringBuf* self); + void (*Destroy) (StringBuf* self); + void (*Free) (StringBuf* self); +} stringbuf_s; + +struct stringbuf_interface *StrBuf; + +struct sv_interface { + /// Parses a single field in a delim-separated string. + /// The delimiter after the field is skipped. + /// + /// @param sv Parse state + /// @return 1 if a field was parsed, 0 if done, -1 on error. + int (*parse_next) (struct s_svstate* sv); + + /// Parses a delim-separated string. + /// Starts parsing at startoff and fills the pos array with position pairs. + /// out_pos[0] and out_pos[1] are the start and end of line. + /// Other position pairs are the start and end of fields. + /// Returns the number of fields found or -1 if an error occurs. + int (*parse) (const char* str, int len, int startoff, char delim, int* out_pos, int npos, enum e_svopt opt); + + /// Splits a delim-separated string. + /// WARNING: this function modifies the input string + /// Starts splitting at startoff and fills the out_fields array. + /// out_fields[0] is the start of the next line. + /// Other entries are the start of fields (nul-teminated). + /// Returns the number of fields found or -1 if an error occurs. + int (*split) (char* str, int len, int startoff, char delim, char** out_fields, int nfields, enum e_svopt opt); + + /// Escapes src to out_dest according to the format of the C compiler. + /// Returns the length of the escaped string. + /// out_dest should be len*4+1 in size. + size_t (*escape_c) (char* out_dest, const char* src, size_t len, const char* escapes); + + /// Unescapes src to out_dest according to the format of the C compiler. + /// Returns the length of the unescaped string. + /// out_dest should be len+1 in size and can be the same buffer as src. + size_t (*unescape_c) (char* out_dest, const char* src, size_t len); + + /// Skips a C escape sequence (starting with '\\'). + const char* (*skip_escaped_c) (const char* p); + + /// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row. + /// Tracks the progress of the operation (current line number, number of successfully processed rows). + /// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read. + bool (*readdb) (const char* directory, const char* filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char* fields[], int columns, int current)); +} sv_s; + +struct sv_interface *sv; + +void strlib_defaults(void); + +/* the purpose of these macros is simply to not make calling them be an annoyance */ +#ifndef STRLIB_C + #define jstrescape(pt) strlib->jstrescape(pt) + #define jstrescapecpy(pt,spt) strlib->jstrescapecpy(pt,spt) + #define jmemescapecpy(pt,spt,size) strlib->jmemescapecpy(pt,spt,size) + #define remove_control_chars(str) strlib->remove_control_chars(str) + #define trim(str) strlib->trim(str) + #define normalize_name(str,delims) strlib->normalize_name(str,delims) + #define stristr(haystack,needle) strlib->stristr(haystack,needle) + + #if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN) + #define strnln(string,maxlen) strlib->strnlen(string,maxlen) + #endif + + #if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200 + #define strtoull(str,endptr,base) strlib->strtoull(str,endptr,base) + #endif + + #define e_mail_check(email) strlib->e_mail_check(email) + #define config_switch(str) strlib->config_switch(str) + #define safestrncpy(dst,src,n) strlib->safestrncpy(dst,src,n) + #define safestrnlen(string,maxlen) strlib->safestrnlen(string,maxlen) + #define safesnprintf(buf,sz,fmt,...) strlib->safesnprintf(buf,sz,fmt,##__VA_ARGS__) + #define strline(str,pos) strlib->strline(str,pos) + #define bin2hex(output,input,count) strlib->bin2hex(output,input,count) +#endif /* STRLIB_C */ #endif /* _STRLIB_H_ */ diff --git a/src/common/timer.c b/src/common/timer.c index c239a9d70..1ea1a0d1c 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/db.h" @@ -62,7 +63,7 @@ struct timer_func_list { } *tfl_root = NULL; /// Sets the name of a timer function. -int add_timer_func_list(TimerFunc func, char* name) +int timer_add_func_list(TimerFunc func, char* name) { struct timer_func_list* tfl; @@ -70,9 +71,9 @@ int add_timer_func_list(TimerFunc func, char* name) for( tfl=tfl_root; tfl != NULL; tfl=tfl->next ) {// check suspicious cases if( func == tfl->func ) - ShowWarning("add_timer_func_list: duplicating function %p(%s) as %s.\n",tfl->func,tfl->name,name); + ShowWarning("timer_add_func_list: duplicating function %p(%s) as %s.\n",tfl->func,tfl->name,name); else if( strcmp(name,tfl->name) == 0 ) - ShowWarning("add_timer_func_list: function %p has the same name as %p(%s)\n",func,tfl->func,tfl->name); + ShowWarning("timer_add_func_list: function %p has the same name as %p(%s)\n",func,tfl->func,tfl->name); } CREATE(tfl,struct timer_func_list,1); tfl->next = tfl_root; @@ -137,8 +138,7 @@ static void rdtsc_calibrate(){ #endif /// platform-abstracted tick retrieval -static unsigned int tick(void) -{ +static unsigned int tick(void) { #if defined(WIN32) return GetTickCount(); #elif defined(ENABLE_RDTSC) @@ -163,28 +163,25 @@ static unsigned int tick(void) static unsigned int gettick_cache; static int gettick_count = 1; -unsigned int gettick_nocache(void) -{ +unsigned int timer_gettick_nocache(void) { gettick_count = TICK_CACHE; gettick_cache = tick(); return gettick_cache; } -unsigned int gettick(void) -{ +unsigned int timer_gettick(void) { return ( --gettick_count == 0 ) ? gettick_nocache() : gettick_cache; } ////////////////////////////// #else ////////////////////////////// // tick doesn't get cached -unsigned int gettick_nocache(void) +unsigned int timer_gettick_nocache(void) { return tick(); } -unsigned int gettick(void) -{ +unsigned int timer_gettick(void) { return tick(); } ////////////////////////////////////////////////////////////////////////// @@ -196,8 +193,7 @@ unsigned int gettick(void) *--------------------------------------*/ /// Adds a timer to the timer_heap -static void push_timer_heap(int tid) -{ +static void push_timer_heap(int tid) { BHEAP_ENSURE(timer_heap, 1, 256); BHEAP_PUSH(timer_heap, tid, DIFFTICK_MINTOPCMP); } @@ -207,8 +203,7 @@ static void push_timer_heap(int tid) *--------------------------*/ /// Returns a free timer id. -static int acquire_timer(void) -{ +static int acquire_timer(void) { int tid; // select a free timer @@ -240,8 +235,7 @@ static int acquire_timer(void) /// Starts a new timer that is deleted once it expires (single-use). /// Returns the timer's id. -int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data) -{ +int timer_add(unsigned int tick, TimerFunc func, int id, intptr_t data) { int tid; tid = acquire_timer(); @@ -258,13 +252,12 @@ int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data) /// Starts a new timer that automatically restarts itself (infinite loop until manually removed). /// Returns the timer's id, or INVALID_TIMER if it fails. -int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval) +int timer_add_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval) { int tid; - if( interval < 1 ) - { - ShowError("add_timer_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick())); + if( interval < 1 ) { + ShowError("timer_add_interval: invalid interval (tick=%u %p[%s] id=%d data=%d diff_tick=%d)\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, gettick())); return INVALID_TIMER; } @@ -281,24 +274,20 @@ int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, } /// Retrieves internal timer data -const struct TimerData* get_timer(int tid) -{ +const struct TimerData* timer_get(int tid) { return ( tid >= 0 && tid < timer_data_num ) ? &timer_data[tid] : NULL; } /// Marks a timer specified by 'id' for immediate deletion once it expires. /// Param 'func' is used for debug/verification purposes. /// Returns 0 on success, < 0 on failure. -int delete_timer(int tid, TimerFunc func) -{ - if( tid < 0 || tid >= timer_data_num ) - { - ShowError("delete_timer error : no such timer %d (%p(%s))\n", tid, func, search_timer_func_list(func)); +int timer_delete(int tid, TimerFunc func) { + if( tid < 0 || tid >= timer_data_num ) { + ShowError("timer_delete error : no such timer %d (%p(%s))\n", tid, func, search_timer_func_list(func)); return -1; } - if( timer_data[tid].func != func ) - { - ShowError("delete_timer error : function mismatch %p(%s) != %p(%s)\n", timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func)); + if( timer_data[tid].func != func ) { + ShowError("timer_delete error : function mismatch %p(%s) != %p(%s)\n", timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func)); return -2; } @@ -310,22 +299,19 @@ int delete_timer(int tid, TimerFunc func) /// Adjusts a timer's expiration time. /// Returns the new tick value, or -1 if it fails. -int addtick_timer(int tid, unsigned int tick) -{ +int timer_addtick(int tid, unsigned int tick) { return settick_timer(tid, timer_data[tid].tick+tick); } /// Modifies a timer's expiration time (an alternative to deleting a timer and starting a new one). /// Returns the new tick value, or -1 if it fails. -int settick_timer(int tid, unsigned int tick) -{ +int timer_settick(int tid, unsigned int tick) { size_t i; // search timer position ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid); - if( i == BHEAP_LENGTH(timer_heap) ) - { - ShowError("settick_timer: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + if( i == BHEAP_LENGTH(timer_heap) ) { + ShowError("timer_settick: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); return -1; } @@ -344,13 +330,11 @@ int settick_timer(int tid, unsigned int tick) /// Executes all expired timers. /// Returns the value of the smallest non-expired timer (or 1 second if there aren't any). -int do_timer(unsigned int tick) -{ +int do_timer(unsigned int tick) { int diff = TIMER_MAX_INTERVAL; // return value // process all timers one by one - while( BHEAP_LENGTH(timer_heap) ) - { + while( BHEAP_LENGTH(timer_heap) ) { int tid = BHEAP_PEEK(timer_heap);// top element in heap (smallest tick) diff = DIFF_TICK(timer_data[tid].tick, tick); @@ -361,8 +345,7 @@ int do_timer(unsigned int tick) BHEAP_POP(timer_heap, DIFFTICK_MINTOPCMP); timer_data[tid].type |= TIMER_REMOVE_HEAP; - if( timer_data[tid].func ) - { + if( timer_data[tid].func ) { if( diff < -1000 ) // timer was delayed for more than 1 second, use current tick instead timer_data[tid].func(tid, tick, timer_data[tid].id, timer_data[tid].data); @@ -371,29 +354,27 @@ int do_timer(unsigned int tick) } // in the case the function didn't change anything... - if( timer_data[tid].type & TIMER_REMOVE_HEAP ) - { + if( timer_data[tid].type & TIMER_REMOVE_HEAP ) { timer_data[tid].type &= ~TIMER_REMOVE_HEAP; - switch( timer_data[tid].type ) - { - default: - case TIMER_ONCE_AUTODEL: - timer_data[tid].type = 0; - if (free_timer_list_pos >= free_timer_list_max) { - free_timer_list_max += 256; - RECREATE(free_timer_list,int,free_timer_list_max); - memset(free_timer_list + (free_timer_list_max - 256), 0, 256 * sizeof(int)); - } - free_timer_list[free_timer_list_pos++] = tid; - break; - case TIMER_INTERVAL: - if( DIFF_TICK(timer_data[tid].tick, tick) < -1000 ) - timer_data[tid].tick = tick + timer_data[tid].interval; - else - timer_data[tid].tick += timer_data[tid].interval; - push_timer_heap(tid); - break; + switch( timer_data[tid].type ) { + default: + case TIMER_ONCE_AUTODEL: + timer_data[tid].type = 0; + if (free_timer_list_pos >= free_timer_list_max) { + free_timer_list_max += 256; + RECREATE(free_timer_list,int,free_timer_list_max); + memset(free_timer_list + (free_timer_list_max - 256), 0, 256 * sizeof(int)); + } + free_timer_list[free_timer_list_pos++] = tid; + break; + case TIMER_INTERVAL: + if( DIFF_TICK(timer_data[tid].tick, tick) < -1000 ) + timer_data[tid].tick = tick + timer_data[tid].interval; + else + timer_data[tid].tick += timer_data[tid].interval; + push_timer_heap(tid); + break; } } } @@ -401,8 +382,7 @@ int do_timer(unsigned int tick) return cap_value(diff, TIMER_MIN_INTERVAL, TIMER_MAX_INTERVAL); } -unsigned long get_uptime(void) -{ +unsigned long timer_get_uptime(void) { return (unsigned long)difftime(time(NULL), start_time); } @@ -415,8 +395,7 @@ void timer_init(void) time(&start_time); } -void timer_final(void) -{ +void timer_final(void) { struct timer_func_list *tfl; struct timer_func_list *next; @@ -430,3 +409,15 @@ void timer_final(void) BHEAP_CLEAR(timer_heap); if (free_timer_list) aFree(free_timer_list); } +void timer_defaults(void) { + gettick = timer_gettick; + gettick_nocache = timer_gettick_nocache; + add_timer = timer_add; + add_timer_interval = timer_add_interval; + add_timer_func_list = timer_add_func_list; + get_timer = timer_get; + delete_timer = timer_delete; + addtick_timer = timer_addtick; + settick_timer = timer_settick; + get_uptime = timer_get_uptime; +} diff --git a/src/common/timer.h b/src/common/timer.h index d45c73d12..902679f51 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -1,5 +1,6 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #ifndef _TIMER_H_ #define _TIMER_H_ @@ -35,23 +36,26 @@ struct TimerData { // Function prototype declaration -unsigned int gettick(void); -unsigned int gettick_nocache(void); +int do_timer(unsigned int tick); +void timer_init(void); +void timer_final(void); -int add_timer(unsigned int tick, TimerFunc func, int id, intptr_t data); -int add_timer_interval(unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); -const struct TimerData* get_timer(int tid); -int delete_timer(int tid, TimerFunc func); +/* Hercules Renewal Phase One */ +unsigned int (*gettick) (void); +unsigned int (*gettick_nocache) (void); -int addtick_timer(int tid, unsigned int tick); -int settick_timer(int tid, unsigned int tick); +int (*add_timer) (unsigned int tick, TimerFunc func, int id, intptr_t data); +int (*add_timer_interval) (unsigned int tick, TimerFunc func, int id, intptr_t data, int interval); +const struct TimerData *(*get_timer) (int tid); +int (*delete_timer) (int tid, TimerFunc func); -int add_timer_func_list(TimerFunc func, char* name); +int (*addtick_timer) (int tid, unsigned int tick); +int (*settick_timer) (int tid, unsigned int tick); -unsigned long get_uptime(void); +int (*add_timer_func_list) (TimerFunc func, char* name); -int do_timer(unsigned int tick); -void timer_init(void); -void timer_final(void); +unsigned long (*get_uptime) (void); + +void timer_defaults(void); #endif /* _TIMER_H_ */ |