From eb0e04d3a52c4b700db29e8b88bf5b737ba1903b Mon Sep 17 00:00:00 2001 From: eathenabot Date: Sat, 29 Sep 2012 18:11:51 +0000 Subject: * Merged eAthena changeset ea:15190. (bugreport:5138) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16807 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/common/cbasetypes.h | 14 +++++++ src/common/core.c | 108 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 87 insertions(+), 35 deletions(-) (limited to 'src') diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 62cb8fe21..731a8b578 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -307,10 +307,14 @@ typedef char bool; #if defined(WIN32) #define PATHSEP '\\' +#define PATHSEP_STR "\\" #elif defined(__APPLE__) +// FIXME Mac OS X is unix based, is this still correct? #define PATHSEP ':' +#define PATHSEP_STR ":" #else #define PATHSEP '/' +#define PATHSEP_STR "/" #endif ////////////////////////////////////////////////////////////////////////// @@ -365,6 +369,16 @@ typedef char bool; #endif +////////////////////////////////////////////////////////////////////////// +// Use the preprocessor to 'stringify' stuff (concert to a string). +// example: +// #define TESTE blabla +// QUOTE(TESTE) -> "TESTE" +// EXPAND_AND_QUOTE(TESTE) -> "blabla" +#define QUOTE(x) #x +#define EXPAND_AND_QUOTE(x) QUOTE(x) + + ////////////////////////////////////////////////////////////////////////// // Set a pointer variable to a pointer value. #ifdef __cplusplus diff --git a/src/common/core.c b/src/common/core.c index baa2d3a25..39beef763 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -37,7 +37,6 @@ char **arg_v = NULL; char *SERVER_NAME = NULL; char SERVER_TYPE = ATHENA_SERVER_NONE; -static char rA_svn_version[10] = ""; #ifndef MINICORE // minimalist Core // Added by Gabuzomeu @@ -155,13 +154,70 @@ void signals_init (void) } #endif +#ifdef SVNVERSION + const char *get_svn_revision(void) + { + return EXPAND_AND_QUOTE(SVNVERSION); + } +#else// not SVNVERSION const char* get_svn_revision(void) { + static char svn_version_buffer[16] = ""; FILE *fp; - if(*rA_svn_version) - return rA_svn_version; + if( svn_version_buffer[0] != '\0' ) + return svn_version_buffer; + + // subversion 1.7 uses a sqlite3 database + // FIXME this is hackish at best... + // - ignores database file structure + // - assumes the data in NODES.dav_cache column ends with "!svn/ver//)" + // - since it's a cache column, the data might not even exist + if( (fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL ) + { + #ifndef SVNNODEPATH + //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up + #define SVNNODEPATH trunk + #endif + const char* prefix = "!svn/ver/"; + const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this + size_t prefix_len = strlen(prefix); + size_t postfix_len = strlen(postfix); + size_t i,j,len; + char* buffer; + + // read file to buffer + fseek(fp, 0, SEEK_END); + len = ftell(fp); + buffer = (char*)aMalloc(len + 1); + fseek(fp, 0, SEEK_SET); + len = fread(buffer, 1, len, fp); + buffer[len] = '\0'; + fclose(fp); + + // parse buffer + for( i = prefix_len + 1; i + postfix_len <= len; ++i ) + { + if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 ) + continue; // postfix missmatch + for( j = i; j > 0; --j ) + {// skip digits + if( !ISDIGIT(buffer[j - 1]) ) + break; + } + if( memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0 ) + continue; // prefix missmatch + // done + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j)); + break; + } + aFree(buffer); + + if( svn_version_buffer[0] != '\0' ) + return svn_version_buffer; + } + // subversion 1.6 and older? if ((fp = fopen(".svn/entries", "r")) != NULL) { char line[1024]; @@ -175,49 +231,31 @@ const char* get_svn_revision(void) while (fgets(line,sizeof(line),fp)) if (strstr(line,"revision=")) break; if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) { - snprintf(rA_svn_version, sizeof(rA_svn_version), "%d", rev); + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev); } - } else { + } + else + { // Bin File format - bool fgresult; - fgresult = ( fgets(line, sizeof(line), fp) != NULL ); // Get the name - fgresult = ( fgets(line, sizeof(line), fp) != NULL ); // Get the entries kind + fgets(line, sizeof(line), fp); // Get the name + fgets(line, sizeof(line), fp); // Get the entries kind if(fgets(line, sizeof(line), fp)) // Get the rev numver { - snprintf(rA_svn_version, sizeof(rA_svn_version), "%d", atoi(line)); - } - } - } - fclose(fp); - } - /** - * subversion 1.7 introduces the use of a .db file to store it, and we go through it - * TODO: In some cases it may be not accurate - **/ - if(!(*rA_svn_version) && ((fp = fopen(".svn/wc.db", "rb")) != NULL || (fp = fopen("../.svn/wc.db", "rb")) != NULL)) { - char lines[64]; - int revision,last_known = 0; - while(fread(lines, sizeof(char), sizeof(lines), fp)) { - if( strstr(lines,"!svn/ver/") ) { - if (sscanf(strstr(lines,"!svn/ver/"),"!svn/ver/%d/%*s", &revision) == 1) { - if( revision > last_known ) { - last_known = revision; - } + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line)); } } } fclose(fp); - if( last_known != 0 ) - snprintf(rA_svn_version, sizeof(rA_svn_version), "%d", last_known); + + if( svn_version_buffer[0] != '\0' ) + return svn_version_buffer; } - /** - * we definitely didn't find it. - **/ - if(!(*rA_svn_version)) - snprintf(rA_svn_version, sizeof(rA_svn_version), "Unknown"); - return rA_svn_version; + // fallback + snprintf(svn_version_buffer, sizeof(svn_version_buffer), "Unknown"); + return svn_version_buffer; } +#endif /*====================================== * CORE : Display title -- cgit v1.2.3-60-g2f50