Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ Color me stupified.

Color me stupified.

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


Posted by ThomasWatts   USA  (66 posts)  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]
Top

Posted by Nick Gammon   Australia  (23,133 posts)  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
Top

Posted by Nick Gammon   Australia  (23,133 posts)  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
Top

Posted by ThomasWatts   USA  (66 posts)  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';
	}
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.


12,400 views.

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

Go to topic:           Search the forum


[Go to top] top

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