Sfoglia il codice sorgente

* Merged eAthena changeset ea:15190. (bugreport:5138)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16807 54d463be-8e91-2dee-dedb-b68131a5f0ec
eathenabot 12 anni fa
parent
commit
b15710e75a
2 ha cambiato i file con 87 aggiunte e 35 eliminazioni
  1. 14 0
      src/common/cbasetypes.h
  2. 73 35
      src/common/core.c

+ 14 - 0
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

+ 73 - 35
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/<revision>/<path>)"
+	// - 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