[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  SMAUG
. -> [Folder]  SMAUG coding
. . -> [Subject]  Color me stupified.

Color me stupified.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by ThomasWatts   USA  (66 posts)  [Biography] bio
Date Sun 18 Nov 2007 03:00 AM (UTC)
Message
I need help, I have lost the ability to follow logic and count above five. The follow gives me garbled output almost all of the time. I can not see where I went wrong, can anyone point me in the right direction?

void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, ... ) {
	int length = 0;
	bool inColor = IS_SET(d->telOpts, 15);
	char outTemp[MAX_STRING_LENGTH];
	char outColor[MAX_STRING_LENGTH];
	char colBuf[16];
	char *pnt = NULL, *lst = NULL;
	int first = 0, jump = 0, oCtop = 0;
	int fore = 0, back = 0;
	if( d == NULL ) {
		bug("Write_to_buffer: NULL descriptor");
		return;
	}
	if( d->outbuf == NULL ) // Should never happen, but create if it is
		CREATE(d->outbuf, char, d->outsize);
	strcpy(outTemp, "");
	{
		va_list param;
		va_start(param, txt);
		vsprintf(outTemp + strlen(outTemp), txt, param);
		va_end(param);
	}
	lst = outTemp;
	if( inColor ) { //colorize output
		first = 0; jump = 0; oCtop = 0;
		while( (pnt = strchr(lst, '&')) != NULL ) {
			if( pnt > lst ) {
				first = pnt - lst;
				fore = 9; back = 9;
				if( *(pnt + 1) == '(' ) {
					fore = getColor(*(pnt + 2));
					if( *(pnt + 3) != ')' )
						back = getColor(*(pnt + 3));
					else
						jump = 4;
					if( jump == 0 && *(pnt + 4) == ')' )
						jump = 5;
					else
						jump = 4;
				} else {
					fore = getColor(*(pnt + 1));
					jump = 2;
				}
				strncpy(outColor + oCtop, lst, first);
				oCtop += first;
				sprintf(colBuf, "\033[0;3%d;4%dm", fore, back);
				strncpy(outColor + oCtop, colBuf, 10);
				oCtop += 10;
				lst = pnt + jump;
			} else {
				break;
			}
		}
		if( oCtop == 0 ) {
			strcat(outColor, outTemp);
			oCtop = strlen(outTemp);
		} else {
			strcat(outColor, "\033[0m");
			oCtop += 4;
		}
		outColor[oCtop] = '\0';
	} else { //strip color codes
		first = 0; jump = 0; oCtop = 0;
		while( (pnt = strchr(lst, '&')) != NULL ) {
			if( pnt > lst ) {
				first = pnt - lst;
				if( *(pnt + 1) == '(' ) {
					if( *(pnt + 3) == ')' )
						jump = 4;
					else if( *(pnt + 4) == ')' )
						jump = 5;
				} else {
					jump = 2;
				}
				strncpy(outColor + oCtop, lst, first);
				oCtop += first;
				lst = pnt + jump;
			} else {
				break;
			}
		}
		if( oCtop == 0 ) {
			strcat(outColor, outTemp);
			oCtop = strlen(outTemp);
		}
		outColor[oCtop] = '\0';
	}
	length = strlen(outColor);
	// Expand the buffer as needed.
	// This is not released until close_socket.
	while( d->outtop + length >= d->outsize ) {
		if( d->outsize > MAXOUTSIZE ) {
			bug("Buffer overflow. Closing (%d).", d->uniqueNumber);
			clear_outbuf(d);
			close_socket(d, TRUE);
			return;
		}
		d->outsize *= 2;
		RECREATE(d->outbuf, char, d->outsize);
	}
	// Copy.
	strncpy(d->outbuf + d->outtop, outColor, length);
	d->outtop += length;
	d->outbuf[d->outtop] = '\0';
	return;
}
[\code]
[Go to top] top

Posted by Nick Gammon   Australia  (22,983 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Sun 18 Nov 2007 03:01 AM (UTC)
Message
Before I look at your code, the forum code to end a code block is [/code] not [\code].


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,983 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Sun 18 Nov 2007 03:08 AM (UTC)
Message
This is an ideal candidate for gdb you know - rather than puzzling out what the code is doing wrong, run it through gdb and check that, at each point, it is doing what you expect.

For example, what is the point of this?


strcpy(outTemp, "");
  {
  va_list param;
  va_start(param, txt);
  vsprintf(outTemp + strlen(outTemp), txt, param);
  va_end(param);
  }


Now, outTemp has a zero length, right? You just moved an empty string into it. So why do "+ strlen(outTemp)"? That will always add zero. That is not your bug, but stuff like that is confusing.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by ThomasWatts   USA  (66 posts)  [Biography] bio
Date Reply #3 on Sun 18 Nov 2007 03:00 PM (UTC)
Message
After lots and lots of gdb time, it ended up being expression changes as well as using strncpy vs strcpy. Changes to the above function as follows for those interested. Also, for that comment on vsprintf, Nick, I wrote that so fast I just defaulted to habit, but good eye, thanks.

	strcpy(outColor, "");
	if( inColor ) { //colorize output
		first = 0; jump = 0; oCtop = 0;
		while( (pnt = strchr(lst, '&')) != NULL ) {
			if( pnt >= lst ) {
				first = pnt - lst;
				fore = -1; back = -1;
				if( *(pnt + 1) == '(' ) {
					fore = getColor(*(pnt + 2));
					if( *(pnt + 3) != ')' )
						back = getColor(*(pnt + 3));
					else
						jump = 4;
					if( jump == 0 && *(pnt + 4) == ')' )
						jump = 5;
					else
						jump = 4;
				} else {
					fore = getColor(*(pnt + 1));
					jump = 2;
				}
				strncpy(outColor + oCtop, lst, first);
				oCtop += first;
				snprintf(outColor + oCtop, 3, "\033[0");
				oCtop += 3;
				if( fore != -1 ) {
					snprintf(outColor + oCtop, 3, ";3%d", fore);
					oCtop += 3;
				}
				if( back != -1 ) {
					snprintf(outColor + oCtop, 3, ";4%d", back);
					oCtop += 3;
				}
				snprintf(outColor + oCtop, 1, "m");
				oCtop += 1;
				lst = pnt + jump;
			}
		}
		if( oCtop == 0 ) {
			strcpy(outColor, outTemp);
			oCtop = strlen(outTemp);
		} else if( (length = strlen(lst)) > 0 ) {
			strncpy(outColor + oCtop, lst, length);
			oCtop += length;
			snprintf(outColor + oCtop, 4, "\033[0m");
			oCtop += 4;
		}
		outColor[oCtop] = '\0';
	} else { //strip color codes
		first = 0; jump = 0; oCtop = 0;
		while( (pnt = strchr(lst, '&')) != NULL ) {
			if( pnt >= lst ) {
				first = pnt - lst;
				if( *(pnt + 1) == '(' ) {
					if( *(pnt + 3) == ')' )
						jump = 4;
					else if( *(pnt + 4) == ')' )
						jump = 5;
				} else {
					jump = 2;
				}
				strncpy(outColor + oCtop, lst, first);
				oCtop += first;
				lst = pnt + jump;
			}
		}
		if( oCtop == 0 ) {
			strcpy(outColor, outTemp);
			oCtop = strlen(outTemp);
		} else if( (length = strlen(lst)) > 0 ) {
			strncpy(outColor + oCtop, lst, length);
			oCtop += length;
		}
		outColor[oCtop] = '\0';
	}
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


11,078 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]