Browse Source

- Added StringBuf_Vprintf to utils.c and changed the showmsg.c buffer.
Now it uses a static buffer and a StringBuf when needed (a debug message indicating the static buffer needs to be increased is shown).

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9414 54d463be-8e91-2dee-dedb-b68131a5f0ec

FlavioJS 18 years ago
parent
commit
53a7ca362b
4 changed files with 73 additions and 27 deletions
  1. 4 0
      Changelog-Trunk.txt
  2. 52 21
      src/common/showmsg.c
  3. 16 6
      src/common/utils.c
  4. 1 0
      src/common/utils.h

+ 4 - 0
Changelog-Trunk.txt

@@ -3,6 +3,10 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2004/12/06
+	* Added StringBuf_Vprintf to utils.c and changed the showmsg.c buffer.
+	  Now it uses a static buffer and a StringBuf when needed (a debug message 
+	  indicating the static buffer needs to be increased is shown). [FlavioJS]
 2004/12/05
 	* The can log value now is "reset" when you die allowing you to
 	  respawn/quit instantly after death. [Skotlex]

+ 52 - 21
src/common/showmsg.c

@@ -6,8 +6,9 @@
 #include <stdarg.h>
 #include <time.h>
 #include <stdlib.h> // atexit
-#include "../common/cbasetypes.h"
+#include "cbasetypes.h"
 #include "showmsg.h"
+#include "utils.h"
 
 #ifdef _WIN32
 	#define WIN32_LEAN_AND_MEAN
@@ -50,13 +51,45 @@ int stdout_with_ansisequence = 1;
 int msg_silent; //Specifies how silent the console is.
 
 ///////////////////////////////////////////////////////////////////////////////
-/// small reallocating temporary printer buffer
-static char *tempbuf = NULL;
-static size_t     sz = 0;
-#define      tempbuf_size() (sz)
-static void  tempbuf_free(void){ free(tempbuf); }
-static void  tempbuf_alloc(void){ sz = 256; tempbuf = (char *)malloc(sz); atexit(tempbuf_free); }
-static void  tempbuf_realloc(void){	sz <<= 1; tempbuf = (char *)realloc(tempbuf,sz); }
+/// static/dynamic buffer for the messages
+
+#define SBUF_SIZE 2048 // never put less that what's required for the debug message
+
+#define NEWBUF(buf)				\
+	struct {					\
+		char s_[SBUF_SIZE];		\
+		struct StringBuf *d_;	\
+		char *v_;				\
+		int l_;					\
+	} buf ={"",NULL,NULL,0};	\
+//define NEWBUF
+
+#define BUFVPRINTF(buf,fmt,args)						\
+	buf.l_ = vsnprintf(buf.s_, SBUF_SIZE, fmt, args);	\
+	if( buf.l_ >= 0 && buf.l_ < SBUF_SIZE )				\
+	{/* static buffer */								\
+		buf.v_ = buf.s_;								\
+	}													\
+	else												\
+	{/* dynamic buffer */								\
+		buf.d_ = StringBuf_Malloc();					\
+		buf.l_ = StringBuf_Vprintf(buf.d_, fmt, args);	\
+		buf.v_ = StringBuf_Value(buf.d_);				\
+		ShowDebug("showmsg: dynamic buffer used, increase the static buffer size to %d or more.", buf.l_+1);\
+	}													\
+//define BUFVPRINTF
+
+#define BUFVAL(buf) buf.v_
+#define BUFLEN(buf) buf.l_
+
+#define FREEBUF(buf)			\
+	if( buf.d_ )				\
+	{							\
+		StringBuf_Free(buf.d_);	\
+		buf.d_ = NULL;			\
+	}							\
+	buf.v_ = NULL;				\
+//define FREEBUF
 
 ///////////////////////////////////////////////////////////////////////////////
 #ifdef _WIN32
@@ -166,24 +199,22 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 	/////////////////////////////////////////////////////////////////
 	unsigned long	written;
 	char *p, *q;
+	NEWBUF(tempbuf); // temporary buffer
 
 	if(!fmt || !*fmt)
 		return 0;
 
-	if(tempbuf == NULL)
-		tempbuf_alloc();
-	for(; vsnprintf(tempbuf, tempbuf_size(), fmt, argptr)<0; tempbuf_realloc());
-	// vsnprintf returns -1 in case of insufficient buffer size
-	// tempbuf_realloc doubles the size of the buffer in this case
+	// Print everything to the buffer
+	BUFVPRINTF(tempbuf,fmt,argptr);
 
 	if( !is_console(handle) && stdout_with_ansisequence )
 	{
-		WriteFile(handle,tempbuf, strlen(tempbuf), &written, 0);
+		WriteFile(handle, BUFVAL(tempbuf), BUFLEN(tempbuf), &written, 0);
 		return 0;
 	}
 
 	// start with processing
-	p = tempbuf;
+	p = BUFVAL(tempbuf);
 	while ((q = strchr(p, 0x1b)) != NULL)
 	{	// find the escape character
 		if( 0==WriteConsole(handle, p, q-p, &written, 0) ) // write up to the escape
@@ -469,6 +500,7 @@ int	VFPRINTF(HANDLE handle, const char *fmt, va_list argptr)
 	if (*p)	// write the rest of the buffer
 		if( 0==WriteConsole(handle, p, strlen(p), &written, 0) )
 			WriteFile(handle,p, strlen(p), &written, 0);
+	FREEBUF(tempbuf);
 	return 0;
 }
 
@@ -499,6 +531,7 @@ int	FPRINTF(HANDLE handle, const char *fmt, ...)
 int	VFPRINTF(FILE *file, const char *fmt, va_list argptr)
 {
 	char *p, *q;
+	NEWBUF(tempbuf); // temporary buffer
 
 	if(!fmt || !*fmt)
 		return 0;
@@ -509,14 +542,11 @@ int	VFPRINTF(FILE *file, const char *fmt, va_list argptr)
 		return 0;
 	}
 
-	if(tempbuf == NULL)
-		tempbuf_alloc();
-	for(; vsnprintf(tempbuf, tempbuf_size(), fmt, argptr)<0; tempbuf_realloc());
-	// vsnprintf returns -1 in case of insufficient buffer size
-	// tempbuf.realloc doubles the size of the buffer in this case
+	// Print everything to the buffer
+	BUFVPRINTF(tempbuf,fmt,argptr);
 
 	// start with processing
-	p = tempbuf;
+	p = BUFVAL(tempbuf);
 	while ((q = strchr(p, 0x1b)) != NULL)
 	{	// find the escape character
 		fprintf(file, "%.*s", (int)(q-p), p); // write up to the escape
@@ -610,6 +640,7 @@ int	VFPRINTF(FILE *file, const char *fmt, va_list argptr)
 	}
 	if (*p)	// write the rest of the buffer
 		fprintf(file, "%s", p);
+	FREEBUF(tempbuf);
 	return 0;
 }
 int	FPRINTF(FILE *file, const char *fmt, ...)

+ 16 - 6
src/common/utils.c

@@ -155,18 +155,15 @@ void StringBuf_Init(struct StringBuf * sbuf)  {
 	sbuf->ptr_ = sbuf->buf_ = (char *) aMallocA(sbuf->max_ + 1);
 }
 
-// printf into a StringBuf, moving the pointer [MouseJstr]
-int StringBuf_Printf(struct StringBuf *sbuf,const char *fmt,...) 
+// vprintf into a StringBuf, moving the pointer [MouseJstr]
+int StringBuf_Vprintf(struct StringBuf *sbuf,const char *fmt,va_list ap) 
 {
-	va_list ap;
-        int n, size, off;
+	int n, size, off;
 
 	while (1) {
 		/* Try to print in the allocated space. */
-		va_start(ap, fmt);
 		size = sbuf->max_ - (sbuf->ptr_ - sbuf->buf_);
 		n = vsnprintf (sbuf->ptr_, size, fmt, ap);
-		va_end(ap);
 		/* If that worked, return the length. */
 		if (n > -1 && n < size) {
 			sbuf->ptr_ += n;
@@ -180,6 +177,19 @@ int StringBuf_Printf(struct StringBuf *sbuf,const char *fmt,...)
 	}
 }
 
+// printf into a StringBuf, moving the pointer [MouseJstr]
+int StringBuf_Printf(struct StringBuf *sbuf,const char *fmt,...) 
+{
+	int len;
+	va_list ap;
+
+	va_start(ap,fmt);
+	len = StringBuf_Vprintf(sbuf,fmt,ap);
+	va_end(ap);
+
+	return len;
+}
+
 // Append buf2 onto the end of buf1 [MouseJstr]
 int StringBuf_Append(struct StringBuf *buf1,const struct StringBuf *buf2) 
 {

+ 1 - 0
src/common/utils.h

@@ -32,6 +32,7 @@ struct StringBuf {
 
 struct StringBuf * StringBuf_Malloc(void);
 void StringBuf_Init(struct StringBuf *);
+int StringBuf_Vprintf(struct StringBuf *,const char *,va_list);
 int StringBuf_Printf(struct StringBuf *,const char *,...);
 int StringBuf_Append(struct StringBuf *,const struct StringBuf *);
 char * StringBuf_Value(struct StringBuf *);