core/sm_stringutil.cpp
changeset 1677 9e81dcf43499
parent 1621 ac5d4c68a99a
child 1738 cb3be0b31d99
     1.1 --- a/core/sm_stringutil.cpp	Mon Nov 12 21:51:54 2007 +0000
     1.2 +++ b/core/sm_stringutil.cpp	Tue Nov 13 16:36:50 2007 +0000
     1.3 @@ -207,7 +207,9 @@
     1.4  				break;
     1.5  			}
     1.6  		}
     1.7 -	} else {
     1.8 +	}
     1.9 +	else
    1.10 +	{
    1.11  		while (string[size++]);
    1.12  		size--;
    1.13  	}
    1.14 @@ -234,78 +236,125 @@
    1.15  	*buf_p = buf;
    1.16  }
    1.17  
    1.18 -void AddFloat(char **buf_p, size_t &maxlen, double fval, int width, int prec)
    1.19 +void AddFloat(char **buf_p, size_t &maxlen, double fval, int width, int prec, int flags)
    1.20  {
    1.21 -	char text[32];
    1.22 -	int digits;
    1.23 -	double signedVal;
    1.24 -	char *buf;
    1.25 -	int val;
    1.26 -
    1.27 -	// get the sign
    1.28 -	signedVal = fval;
    1.29 -	if (fval < 0)
    1.30 -	{
    1.31 -		fval = -fval;
    1.32 -	}
    1.33 +	int digits;					// non-fraction part digits
    1.34 +	double tmp;					// temporary
    1.35 +	char *buf = *buf_p;			// output buffer pointer
    1.36 +	int val;					// temporary
    1.37 +	int sign = 0;				// 0: positive, 1: negative
    1.38 +	int fieldlength;			// for padding
    1.39 +	int significant_digits = 0;	// number of significant digits written
    1.40 +	const int MAX_SIGNIFICANT_DIGITS = 16;
    1.41  
    1.42 -	// write the float number
    1.43 -	digits = 0;
    1.44 -	val = (int)fval;
    1.45 -	do
    1.46 -	{
    1.47 -		text[digits++] = '0' + val % 10;
    1.48 -		val /= 10;
    1.49 -	} while (val);
    1.50 -
    1.51 -	if (signedVal < 0)
    1.52 -	{
    1.53 -		text[digits++] = '-';
    1.54 -	}
    1.55 -
    1.56 -	buf = *buf_p;
    1.57 -
    1.58 -	while ((digits < width) && maxlen)
    1.59 -	{
    1.60 -		*buf++ = ' ';
    1.61 -		width--;
    1.62 -		maxlen--;
    1.63 -	}
    1.64 -
    1.65 -	while ((digits--) && maxlen)
    1.66 -	{
    1.67 -		*buf++ = text[digits];
    1.68 -		maxlen--;
    1.69 -	}
    1.70 -
    1.71 -	*buf_p = buf;
    1.72 -
    1.73 +	// default precision
    1.74  	if (prec < 0)
    1.75  	{
    1.76  		prec = 6;
    1.77  	}
    1.78 -	// write the fraction
    1.79 -	digits = 0;
    1.80 -	while (digits < prec)
    1.81 +
    1.82 +	// get the sign
    1.83 +	if (fval < 0)
    1.84 +	{
    1.85 +		fval = -fval;
    1.86 +		sign = 1;
    1.87 +	}
    1.88 +
    1.89 +	// compute whole-part digits count
    1.90 +	digits = (int)log10(fval) + 1;
    1.91 +
    1.92 +	// Only print 0.something if 0 < fval < 1
    1.93 +	if (digits < 1)
    1.94  	{
    1.95 -		fval -= (int)fval;
    1.96 -		fval *= 10.0;
    1.97 -		val = (int)fval;
    1.98 -		text[digits++] = '0' + val % 10;
    1.99 +		digits = 1;
   1.100 +	}
   1.101 +
   1.102 +	// compute the field length
   1.103 +	fieldlength = digits + prec + ((prec > 0) ? 1 : 0) + sign;
   1.104 +
   1.105 +	// minus sign BEFORE left padding if padding with zeros
   1.106 +	if (sign && maxlen && (flags & ZEROPAD))
   1.107 +	{
   1.108 +		*buf++ = '-';
   1.109 +		maxlen--;
   1.110 +	}
   1.111 +
   1.112 +	// right justify if required
   1.113 +	if ((flags & LADJUST) == 0)
   1.114 +	{
   1.115 +		while ((fieldlength < width) && maxlen)
   1.116 +		{
   1.117 +			*buf++ = (flags & ZEROPAD) ? '0' : ' ';
   1.118 +			width--;
   1.119 +			maxlen--;
   1.120 +		}
   1.121 +	}
   1.122 +
   1.123 +	// minus sign AFTER left padding if padding with spaces
   1.124 +	if (sign && maxlen && !(flags & ZEROPAD))
   1.125 +	{
   1.126 +		*buf++ = '-';
   1.127 +		maxlen--;
   1.128  	}
   1.129  
   1.130 -	if ((digits > 0) && maxlen)
   1.131 +	// write the whole part
   1.132 +	tmp = pow(10.0, digits-1);
   1.133 +	while ((digits--) && maxlen)
   1.134  	{
   1.135 -		buf = *buf_p;
   1.136 +		if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
   1.137 +		{
   1.138 +			*buf++ = '0';
   1.139 +		}
   1.140 +		else
   1.141 +		{
   1.142 +			val = (int)(fval / tmp);
   1.143 +			*buf++ = '0' + val;
   1.144 +			fval -= val * tmp;
   1.145 +			tmp *= 0.1;
   1.146 +		}
   1.147 +		maxlen--;
   1.148 +	}
   1.149 +
   1.150 +	// write the fraction part
   1.151 +	if (maxlen)
   1.152 +	{
   1.153  		*buf++ = '.';
   1.154  		maxlen--;
   1.155 -		for (prec = 0; maxlen && (prec < digits); prec++)
   1.156 +	}
   1.157 +
   1.158 +	tmp = pow(10.0, prec);
   1.159 +
   1.160 +	fval *= tmp;
   1.161 +	while (prec-- && maxlen)
   1.162 +	{
   1.163 +		if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
   1.164 +		{
   1.165 +			*buf++ = '0';
   1.166 +		}
   1.167 +		else
   1.168  		{
   1.169 -			*buf++ = text[prec];
   1.170 +			tmp *= 0.1;
   1.171 +			val = (int)(fval / tmp);
   1.172 +			*buf++ = '0' + val;
   1.173 +			fval -= val * tmp;
   1.174 +		}
   1.175 +		maxlen--;
   1.176 +	}
   1.177 +
   1.178 +	// left justify if required
   1.179 +	if (flags & LADJUST)
   1.180 +	{
   1.181 +		while ((fieldlength < width) && maxlen)
   1.182 +		{
   1.183 +			// right-padding only with spaces, ZEROPAD is ignored
   1.184 +			*buf++ = ' ';
   1.185 +			width--;
   1.186  			maxlen--;
   1.187  		}
   1.188 -		*buf_p = buf;
   1.189  	}
   1.190 +
   1.191 +	// update parent's buffer pointer
   1.192 +	*buf_p = buf;
   1.193  }
   1.194  
   1.195  void AddUInt(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
   1.196 @@ -366,9 +415,12 @@
   1.197  	{
   1.198  		/* we want the unsigned version */
   1.199  		unsignedVal = abs(val);
   1.200 -	} else {
   1.201 +	}
   1.202 +	else
   1.203 +	{
   1.204  		unsignedVal = val;
   1.205  	}
   1.206 +
   1.207  	do
   1.208  	{
   1.209  		text[digits++] = '0' + unsignedVal % 10;
   1.210 @@ -422,7 +474,9 @@
   1.211  	if (flags & UPPERDIGITS)
   1.212  	{
   1.213  		hexadjust = 'A' - '9' - 1;
   1.214 -	} else {
   1.215 +	}
   1.216 +	else
   1.217 +	{
   1.218  		hexadjust = 'a' - '9' - 1;
   1.219  	}
   1.220  
   1.221 @@ -587,7 +641,7 @@
   1.222  		case 'f':
   1.223  			{
   1.224  				float *value = (float *)args[arg];
   1.225 -				AddFloat(&buf_p, llen, *value, width, prec);
   1.226 +				AddFloat(&buf_p, llen, *value, width, prec, flags);
   1.227  				arg++;
   1.228  				break;
   1.229  			}
   1.230 @@ -779,7 +833,7 @@
   1.231  				CHECK_ARGS(0);
   1.232  				cell_t *value;
   1.233  				pCtx->LocalToPhysAddr(params[arg], &value);
   1.234 -				AddFloat(&buf_p, llen, sp_ctof(*value), width, prec);
   1.235 +				AddFloat(&buf_p, llen, sp_ctof(*value), width, prec, flags);
   1.236  				arg++;
   1.237  				break;
   1.238  			}
   1.239 @@ -808,7 +862,9 @@
   1.240  						player->GetName(),
   1.241  						userid,
   1.242  						auth);
   1.243 -				} else {
   1.244 +				}
   1.245 +				else
   1.246 +				{
   1.247  					UTIL_Format(buffer,
   1.248  						sizeof(buffer),
   1.249  						"Console<0><Console><Console>");
   1.250 @@ -964,7 +1020,9 @@
   1.251  			{
   1.252  				return prevloc;
   1.253  			}
   1.254 -		} else {
   1.255 +		}
   1.256 +		else
   1.257 +		{
   1.258  			haystack = ++prevloc;
   1.259  			needle = (char *)substr;
   1.260  		}
   1.261 @@ -1001,7 +1059,9 @@
   1.262  	{
   1.263  		buffer[maxlength - 1] = '\0';
   1.264  		return (maxlength - 1);
   1.265 -	} else {
   1.266 +	}
   1.267 +	else
   1.268 +	{
   1.269  		return len;
   1.270  	}
   1.271  }
   1.272 @@ -1014,7 +1074,9 @@
   1.273  	{
   1.274  		buffer[maxlength - 1] = '\0';
   1.275  		return (maxlength - 1);
   1.276 -	} else {
   1.277 +	}
   1.278 +	else
   1.279 +	{
   1.280  		return len;
   1.281  	}
   1.282  }
   1.283 @@ -1117,7 +1179,9 @@
   1.284  						replaceLen = maxLen - browsed;
   1.285  						/* Note, we add one to the final result for the null terminator */
   1.286  						strncopy(ptr, replace, replaceLen+1);
   1.287 -					} else {
   1.288 +					}
   1.289 +					else
   1.290 +					{
   1.291  						/* EXAMPLE CASE:
   1.292  						 * Subject: AABBBCCC
   1.293  						 * Buffer : 12 bytes
   1.294 @@ -1138,7 +1202,9 @@
   1.295  						/* Now, do our replacement. */
   1.296  						memcpy(ptr, replace, replaceLen);
   1.297  					}
   1.298 -				} else {
   1.299 +				}
   1.300 +				else
   1.301 +				{
   1.302  					/* EXAMPLE CASE:
   1.303  					 * Subject: AABBBCCC
   1.304  					 * Buffer : 12 bytes
   1.305 @@ -1158,7 +1224,9 @@
   1.306  					/* Now do our replacement. */
   1.307  					memcpy(ptr, replace, replaceLen);
   1.308  				}
   1.309 -			} else if (replaceLen < searchLen) {
   1.310 +			}
   1.311 +			else if (replaceLen < searchLen)
   1.312 +			{
   1.313  				/* EXAMPLE CASE:
   1.314  				 * Subject: AABBBCCC
   1.315  				 * Buffer : 12 bytes
   1.316 @@ -1184,7 +1252,9 @@
   1.317  
   1.318  				/* Move the rest of the string down */
   1.319  				memmove(moveTo, moveFrom, bytesToCopy);
   1.320 -			} else {
   1.321 +			}
   1.322 +			else
   1.323 +			{
   1.324  				/* EXAMPLE CASE:
   1.325  				 * Subject: AABBBCCC
   1.326  				 * Buffer : 12 bytes