void SCR_DrawCenterString (void)
{
char *start;
- int l;
int x, y;
int remaining;
int color;
do
{
// scan the number of characters on the line, not counting color codes
- int chars = 0;
- for (l=0 ; l<vid_conwidth.integer/8 ; l++)
- {
- if (start[l] == '\n' || !start[l])
- break;
- // color codes add no visible characters, so don't count them
- if (start[l] == STRING_COLOR_TAG && (start[l+1] >= '0' && start[l+1] <= '9'))
- l++;
- else
- chars++;
- }
+ char *newline = strchr(start, '\n');
+ int l = newline ? (newline - start) : (int)strlen(start);
+ int chars = COM_StringLengthNoColors(start, l, NULL);
+
x = (vid_conwidth.integer - chars*8)/2;
if (l > 0)
{
if (remaining <= 0)
return;
}
-
y += 8;
- while (*start && *start != '\n')
- start++;
-
- if (!*start)
+ if (!newline)
break;
- start++; // skip the \n
+ start = newline + 1; // skip the \n
} while (1);
}
fix would be adding a STRING_COLOR_TAG at the end of the string.
valid can be set to NULL if the caller doesn't care.
+
+For size_s, specify the maximum number of characters from s to use, or 0 to use
+all characters until the zero terminator.
============
*/
size_t
-COM_StringLengthNoColors(const char *s, qboolean *valid)
+COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid)
{
+ const char *end = size_s ? (s + size_s) : NULL;
size_t len = 0;
for(;;)
{
- switch(*s)
+ switch((s == end) ? 0 : *s)
{
case 0:
if(valid)
return len;
case STRING_COLOR_TAG:
++s;
- switch(*s)
+ switch((s == end) ? 0 : *s)
{
case 0: // ends with unfinished color code!
++len;
strlen(str)+1 bytes, and if escape_carets is true, it can need strlen(str)+2
bytes. In any case, the function makes sure that the resulting string is
zero terminated.
+
+For size_in, specify the maximum number of characters from in to use, or 0 to use
+all characters until the zero terminator.
============
*/
qboolean
-COM_StringDecolorize(const char *in, char *out, size_t size_out, qboolean escape_carets)
+COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qboolean escape_carets)
{
#define APPEND(ch) do { if(--size_out) { *out++ = (ch); } else { *out++ = 0; return FALSE; } } while(0)
+ const char *end = size_in ? (in + size_in) : NULL;
if(size_out < 1)
return FALSE;
for(;;)
{
- switch(*in)
+ switch((in == end) ? 0 : *in)
{
case 0:
*out++ = 0;
return TRUE;
case STRING_COLOR_TAG:
++in;
- switch(*in)
+ switch((in == end) ? 0 : *in)
{
case 0: // ends with unfinished color code!
APPEND(STRING_COLOR_TAG);
int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *tokenbuf, int tokenbufsize, const char *commentprefix);
-size_t COM_StringLengthNoColors(const char *s, qboolean *valid);
-qboolean COM_StringDecolorize(const char *in, char *out, size_t size_out, qboolean escape_carets);
+size_t COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid);
+qboolean COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qboolean escape_carets);
typedef struct stringlist_s
{
// point the string back at updateclient->name to keep it safe
strlcpy (host_client->name, newName, sizeof (host_client->name));
- COM_StringLengthNoColors(host_client->name, &valid_colors);
+ COM_StringLengthNoColors(host_client->name, 0, &valid_colors);
if(!valid_colors) // NOTE: this also proves the string is not empty, as "" is a valid colored string
{
size_t l;
VM_SAFEPARMCOUNT(1,VM_strdecolorize);
szString = PRVM_G_STRING(OFS_PARM0);
- COM_StringDecolorize(szString, szNewString, sizeof(szNewString), TRUE);
+ COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(szNewString);
}
szString = PRVM_G_STRING(OFS_PARM0);
- nCnt = COM_StringLengthNoColors(szString, NULL);
+ nCnt = COM_StringLengthNoColors(szString, 0, NULL);
PRVM_G_FLOAT(OFS_RETURN) = nCnt;
}