core/sm_stringutil.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jan 27 04:50:48 2007 +0000 (2007-01-27)
changeset 398 626ce2e591ad
parent 389 8ba73c27410b
child 422 5ef0f5610c2a
permissions -rw-r--r--
fixed a bug in the admin plugin
dvander@370
     1
/**
dvander@370
     2
 * ===============================================================
dvander@370
     3
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@370
     4
 * ===============================================================
dvander@370
     5
 *
dvander@370
     6
 * This file is not open source and may not be copied without explicit
dvander@370
     7
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@370
     8
 * in whole or significant part.
dvander@370
     9
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@370
    10
 *
dvander@370
    11
 * Version: $Id$
dvander@370
    12
 */
dvander@370
    13
faluco@230
    14
#include <stdlib.h>
faluco@230
    15
#include <ctype.h>
faluco@274
    16
#include <stdarg.h>
faluco@227
    17
#include "sm_stringutil.h"
faluco@288
    18
#include "CLogger.h"
faluco@389
    19
#include "PluginSys.h"
faluco@389
    20
#include "CTranslator.h"
faluco@227
    21
faluco@227
    22
#define LADJUST			0x00000004		/* left adjustment */
faluco@227
    23
#define ZEROPAD			0x00000080		/* zero (as opposed to blank) pad */
faluco@227
    24
#define to_digit(c)		((c) - '0')
faluco@227
    25
#define is_digit(c)		((unsigned)to_digit(c) <= 9)
faluco@227
    26
faluco@288
    27
#define CHECK_ARGS(x) \
faluco@288
    28
	if ((arg+x) > args) { \
faluco@288
    29
		g_Logger.LogError("String formatted incorrectly - parameter %d (total %d)", arg, args); \
faluco@288
    30
		return 0; \
faluco@227
    31
	}
faluco@227
    32
faluco@389
    33
size_t Translate(char *buffer, size_t maxlen, IPluginContext *pCtx, const char *key, cell_t target, const cell_t *params, int *arg)
faluco@389
    34
{
faluco@389
    35
	unsigned int langid;
faluco@389
    36
	CPlugin *pl = (CPlugin *)g_PluginSys.FindPluginByContext(pCtx->GetContext());
faluco@389
    37
	size_t langcount = pl->GetLangFileCount();
faluco@389
    38
faluco@389
    39
	if (!g_Translator.GetLanguageByCode("en", &langid)) 	//:TODO: hardcoded this just for testing
faluco@389
    40
	{
faluco@389
    41
		//:TODO: error out something
faluco@389
    42
	}
faluco@389
    43
faluco@389
    44
	CPhraseFile *phrfl;
faluco@389
    45
	TransError err = Trans_Okay;
faluco@389
    46
	Translation pTrans;
faluco@389
    47
faluco@389
    48
	for (size_t i=0; i<langcount && err!=Trans_Okay; i++)
faluco@389
    49
	{
faluco@389
    50
		phrfl = g_Translator.GetFileByIndex(pl->GetFileByIndex(i));
faluco@389
    51
		err = phrfl->GetTranslation(key, langid, &pTrans);
faluco@389
    52
	}
faluco@389
    53
faluco@389
    54
	if (err != Trans_Okay)
faluco@389
    55
	{
faluco@389
    56
		//:TODO: we didnt find our translation in any file :o
faluco@389
    57
	}
faluco@389
    58
faluco@389
    59
	void *new_params[MAX_TRANSLATE_PARAMS];
faluco@389
    60
	unsigned int max_params = pTrans.fmt_count;
faluco@389
    61
	for (size_t i=0; i<max_params; i++)
faluco@389
    62
	{
faluco@389
    63
		pCtx->LocalToPhysAddr(params[*arg], reinterpret_cast<cell_t **>(&new_params[i]));
faluco@389
    64
		(*arg)++;
faluco@389
    65
		if ((*arg) + i > (size_t)params[0])
faluco@389
    66
		{
faluco@389
    67
			//:TODO: we are missing arguments zOMG
faluco@389
    68
		}
faluco@389
    69
	}
faluco@389
    70
faluco@389
    71
	return g_Translator.Translate(buffer, maxlen, new_params, &pTrans);
faluco@389
    72
}
faluco@389
    73
dvander@276
    74
//:TODO: review this code before we choose a license
dvander@276
    75
faluco@227
    76
void AddString(char **buf_p, size_t &maxlen, const char *string, int width, int prec)
faluco@227
    77
{
faluco@227
    78
	int size = 0;
faluco@227
    79
	char *buf;
faluco@227
    80
	static char nlstr[] = {'(','n','u','l','l',')','\0'};
faluco@227
    81
faluco@227
    82
	buf = *buf_p;
faluco@227
    83
faluco@227
    84
	if (string == NULL)
faluco@227
    85
	{
faluco@227
    86
		string = nlstr;
faluco@227
    87
		prec = -1;
faluco@227
    88
	}
faluco@227
    89
faluco@227
    90
	if (prec >= 0)
faluco@227
    91
	{
faluco@227
    92
		for (size = 0; size < prec; size++) 
faluco@227
    93
		{
faluco@227
    94
			if (string[size] == '\0')
faluco@227
    95
			{
faluco@227
    96
				break;
faluco@227
    97
			}
faluco@227
    98
		}
faluco@227
    99
	} else {
faluco@227
   100
		while (string[size++]);
faluco@227
   101
		size--;
faluco@227
   102
	}
faluco@227
   103
faluco@227
   104
	if (size > (int)maxlen)
faluco@227
   105
	{
faluco@227
   106
		size = maxlen;
faluco@227
   107
	}
faluco@227
   108
faluco@227
   109
	maxlen -= size;
faluco@227
   110
	width -= size;
faluco@227
   111
faluco@227
   112
	while (size--)
faluco@227
   113
	{
faluco@227
   114
		*buf++ = *string++;
faluco@227
   115
	}
faluco@227
   116
faluco@227
   117
	while ((width-- > 0) && maxlen)
faluco@227
   118
	{
faluco@227
   119
		*buf++ = ' ';
faluco@227
   120
		maxlen--;
faluco@227
   121
	}
faluco@227
   122
faluco@227
   123
	*buf_p = buf;
faluco@227
   124
}
faluco@227
   125
faluco@227
   126
void AddFloat(char **buf_p, size_t &maxlen, double fval, int width, int prec)
faluco@227
   127
{
faluco@227
   128
	char text[32];
faluco@227
   129
	int digits;
faluco@227
   130
	double signedVal;
faluco@227
   131
	char *buf;
faluco@227
   132
	int val;
faluco@227
   133
faluco@227
   134
	// get the sign
faluco@227
   135
	signedVal = fval;
faluco@227
   136
	if (fval < 0)
faluco@227
   137
	{
faluco@227
   138
		fval = -fval;
faluco@227
   139
	}
faluco@227
   140
faluco@227
   141
	// write the float number
faluco@227
   142
	digits = 0;
faluco@227
   143
	val = (int)fval;
faluco@227
   144
	do
faluco@227
   145
	{
faluco@227
   146
		text[digits++] = '0' + val % 10;
faluco@227
   147
		val /= 10;
faluco@227
   148
	} while (val);
faluco@227
   149
faluco@227
   150
	if (signedVal < 0)
faluco@227
   151
	{
faluco@227
   152
		text[digits++] = '-';
faluco@227
   153
	}
faluco@227
   154
faluco@227
   155
	buf = *buf_p;
faluco@227
   156
faluco@227
   157
	while ((digits < width) && maxlen)
faluco@227
   158
	{
faluco@227
   159
		*buf++ = ' ';
faluco@227
   160
		width--;
faluco@227
   161
		maxlen--;
faluco@227
   162
	}
faluco@227
   163
faluco@227
   164
	while ((digits--) && maxlen)
faluco@227
   165
	{
faluco@227
   166
		*buf++ = text[digits];
faluco@227
   167
		maxlen--;
faluco@227
   168
	}
faluco@227
   169
faluco@227
   170
	*buf_p = buf;
faluco@227
   171
faluco@227
   172
	if (prec < 0)
faluco@227
   173
	{
faluco@227
   174
		prec = 6;
faluco@227
   175
	}
faluco@227
   176
	// write the fraction
faluco@227
   177
	digits = 0;
faluco@227
   178
	while (digits < prec)
faluco@227
   179
	{
faluco@227
   180
		fval -= (int)fval;
faluco@227
   181
		fval *= 10.0;
faluco@227
   182
		val = (int)fval;
faluco@227
   183
		text[digits++] = '0' + val % 10;
faluco@227
   184
	}
faluco@227
   185
faluco@227
   186
	if ((digits > 0) && maxlen)
faluco@227
   187
	{
faluco@227
   188
		buf = *buf_p;
faluco@227
   189
		*buf++ = '.';
faluco@227
   190
		maxlen--;
faluco@227
   191
		for (prec = 0; maxlen && (prec < digits); prec++)
faluco@227
   192
		{
faluco@227
   193
			*buf++ = text[prec];
faluco@227
   194
			maxlen--;
faluco@227
   195
		}
faluco@227
   196
		*buf_p = buf;
faluco@227
   197
	}
faluco@227
   198
}
faluco@227
   199
faluco@227
   200
void AddUInt(char **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
faluco@227
   201
{
faluco@227
   202
	char text[32];
faluco@227
   203
	int digits;
faluco@227
   204
	char *buf;
faluco@227
   205
faluco@227
   206
	digits = 0;
faluco@227
   207
	do
faluco@227
   208
	{
faluco@227
   209
		text[digits++] = '0' + val % 10;
faluco@227
   210
		val /= 10;
faluco@227
   211
	} while (val);
faluco@227
   212
faluco@227
   213
	buf = *buf_p;
faluco@227
   214
faluco@227
   215
	if (!(flags & LADJUST))
faluco@227
   216
	{
faluco@227
   217
		while (digits < width && maxlen)
faluco@227
   218
		{
faluco@227
   219
			*buf++ = (flags & ZEROPAD) ? '0' : ' ';
faluco@227
   220
			width--;
faluco@227
   221
			maxlen--;
faluco@227
   222
		}
faluco@227
   223
	}
faluco@227
   224
faluco@227
   225
	while (digits-- && maxlen)
faluco@227
   226
	{
faluco@227
   227
		*buf++ = text[digits];
faluco@227
   228
		width--;
faluco@227
   229
		maxlen--;
faluco@227
   230
	}
faluco@227
   231
faluco@227
   232
	if (flags & LADJUST)
faluco@227
   233
	{
faluco@227
   234
		while (width-- && maxlen)
faluco@227
   235
		{
faluco@227
   236
			*buf++ = (flags & ZEROPAD) ? '0' : ' ';
faluco@227
   237
			maxlen--;
faluco@227
   238
		}
faluco@227
   239
	}
faluco@227
   240
faluco@227
   241
	*buf_p = buf;
faluco@227
   242
}
faluco@227
   243
faluco@227
   244
void AddInt(char **buf_p, size_t &maxlen, int val, int width, int flags)
faluco@227
   245
{
faluco@227
   246
	char text[32];
faluco@227
   247
	int digits;
faluco@227
   248
	int signedVal;
faluco@227
   249
	char *buf;
faluco@227
   250
	unsigned int unsignedVal;
faluco@227
   251
faluco@227
   252
	digits = 0;
faluco@227
   253
	signedVal = val;
faluco@227
   254
	if (val < 0)
faluco@227
   255
	{
faluco@227
   256
		/* we want the unsigned version */
faluco@227
   257
		unsignedVal = abs(val);
faluco@227
   258
	} else {
faluco@227
   259
		unsignedVal = val;
faluco@227
   260
	}
faluco@227
   261
	do
faluco@227
   262
	{
faluco@227
   263
		text[digits++] = '0' + unsignedVal % 10;
faluco@227
   264
		unsignedVal /= 10;
faluco@227
   265
	} while (unsignedVal);
faluco@227
   266
faluco@227
   267
	if (signedVal < 0)
faluco@227
   268
	{
faluco@227
   269
		text[digits++] = '-';
faluco@227
   270
	}
faluco@227
   271
faluco@227
   272
	buf = *buf_p;
faluco@227
   273
faluco@227
   274
	if (!(flags & LADJUST))
faluco@227
   275
	{
faluco@227
   276
		while ((digits < width) && maxlen)
faluco@227
   277
		{
faluco@227
   278
			*buf++ = (flags & ZEROPAD) ? '0' : ' ';
faluco@227
   279
			width--;
faluco@227
   280
			maxlen--;
faluco@227
   281
		}
faluco@227
   282
	}
faluco@227
   283
faluco@227
   284
	while (digits-- && maxlen)
faluco@227
   285
	{
faluco@227
   286
		*buf++ = text[digits];
faluco@227
   287
		width--;
faluco@227
   288
		maxlen--;
faluco@227
   289
	}
faluco@227
   290
faluco@227
   291
	if (flags & LADJUST)
faluco@227
   292
	{
faluco@227
   293
		while (width-- && maxlen)
faluco@227
   294
		{
faluco@227
   295
			*buf++ = (flags & ZEROPAD) ? '0' : ' ';
faluco@227
   296
			maxlen--;
faluco@227
   297
		}
faluco@227
   298
	}
faluco@227
   299
faluco@227
   300
	*buf_p = buf;
faluco@227
   301
}
faluco@227
   302
dvander@276
   303
size_t gnprintf(char *buffer, size_t maxlen, const char *format, void **args)
dvander@276
   304
{
dvander@276
   305
	if (!buffer || !maxlen)
dvander@276
   306
	{
dvander@276
   307
		return 0;
dvander@276
   308
	}
dvander@276
   309
dvander@276
   310
	int arg = 0;
dvander@276
   311
	char *buf_p;
dvander@276
   312
	char ch;
dvander@276
   313
	int flags;
dvander@276
   314
	int width;
dvander@276
   315
	int prec;
dvander@276
   316
	int n;
dvander@276
   317
	char sign;
dvander@276
   318
	const char *fmt;
dvander@276
   319
	size_t llen = maxlen - 1;
dvander@276
   320
dvander@276
   321
	buf_p = buffer;
dvander@276
   322
	fmt = format;
dvander@276
   323
dvander@276
   324
	while (true)
dvander@276
   325
	{
dvander@276
   326
		// run through the format string until we hit a '%' or '\0'
dvander@276
   327
		for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++)
dvander@276
   328
		{
dvander@276
   329
			*buf_p++ = ch;
dvander@276
   330
			llen--;
dvander@276
   331
		}
dvander@276
   332
		if ((ch == '\0') || (llen <= 0))
dvander@276
   333
		{
dvander@276
   334
			goto done;
dvander@276
   335
		}
dvander@276
   336
dvander@276
   337
		// skip over the '%'
dvander@276
   338
		fmt++;
dvander@276
   339
dvander@276
   340
		// reset formatting state
dvander@276
   341
		flags = 0;
dvander@276
   342
		width = 0;
dvander@276
   343
		prec = -1;
dvander@276
   344
		sign = '\0';
dvander@276
   345
dvander@276
   346
rflag:
dvander@276
   347
		ch = *fmt++;
dvander@276
   348
reswitch:
dvander@276
   349
		switch(ch)
dvander@276
   350
		{
dvander@276
   351
		case '-':
dvander@276
   352
			{
dvander@276
   353
				flags |= LADJUST;
dvander@276
   354
				goto rflag;
dvander@276
   355
			}
dvander@276
   356
		case '.':
dvander@276
   357
			{
dvander@276
   358
				n = 0;
dvander@276
   359
				while(is_digit((ch = *fmt++)))
dvander@276
   360
				{
dvander@276
   361
					n = 10 * n + (ch - '0');
dvander@276
   362
				}
dvander@276
   363
				prec = (n < 0) ? -1 : n;
dvander@276
   364
				goto reswitch;
dvander@276
   365
			}
dvander@276
   366
		case '0':
dvander@276
   367
			{
dvander@276
   368
				flags |= ZEROPAD;
dvander@276
   369
				goto rflag;
dvander@276
   370
			}
dvander@276
   371
		case '1':
dvander@276
   372
		case '2':
dvander@276
   373
		case '3':
dvander@276
   374
		case '4':
dvander@276
   375
		case '5':
dvander@276
   376
		case '6':
dvander@276
   377
		case '7':
dvander@276
   378
		case '8':
dvander@276
   379
		case '9':
dvander@276
   380
			{
dvander@276
   381
				n = 0;
dvander@276
   382
				do
dvander@276
   383
				{
dvander@276
   384
					n = 10 * n + (ch - '0');
dvander@276
   385
					ch = *fmt++;
dvander@276
   386
				} while(is_digit(ch));
dvander@276
   387
				width = n;
dvander@276
   388
				goto reswitch;
dvander@276
   389
			}
dvander@276
   390
		case 'c':
dvander@276
   391
			{
dvander@276
   392
				if (!llen)
dvander@276
   393
				{
dvander@276
   394
					goto done;
dvander@276
   395
				}
dvander@276
   396
				char *c = (char *)args[arg];
dvander@276
   397
				*buf_p++ = *c;
dvander@276
   398
				llen--;
dvander@276
   399
				arg++;
dvander@276
   400
				break;
dvander@276
   401
			}
dvander@276
   402
		case 'd':
dvander@276
   403
		case 'i':
dvander@276
   404
			{
dvander@276
   405
				int *value = (int *)args[arg];
dvander@276
   406
				AddInt(&buf_p, llen, *value, width, flags);
dvander@276
   407
				arg++;
dvander@276
   408
				break;
dvander@276
   409
			}
dvander@276
   410
		case 'u':
dvander@276
   411
			{
dvander@276
   412
				unsigned int *value = (unsigned int *)args[arg];
dvander@276
   413
				AddUInt(&buf_p, llen, *value, width, flags);
dvander@276
   414
				arg++;
dvander@276
   415
				break;
dvander@276
   416
			}
dvander@276
   417
		case 'f':
dvander@276
   418
			{
dvander@276
   419
				float *value = (float *)args[arg];
dvander@276
   420
				AddFloat(&buf_p, llen, *value, width, prec);
dvander@276
   421
				arg++;
dvander@276
   422
				break;
dvander@276
   423
			}
dvander@276
   424
		case 's':
dvander@276
   425
			{
dvander@276
   426
				const char *str = (const char *)args[arg];
dvander@276
   427
				AddString(&buf_p, llen, str, width, prec);
dvander@276
   428
				arg++;
dvander@276
   429
				break;
dvander@276
   430
			}
dvander@276
   431
		case '%':
dvander@276
   432
			{
dvander@276
   433
				if (!llen)
dvander@276
   434
				{
dvander@276
   435
					goto done;
dvander@276
   436
				}
dvander@276
   437
				*buf_p++ = ch;
dvander@276
   438
				llen--;
dvander@276
   439
				break;
dvander@276
   440
			}
dvander@276
   441
		case '\0':
dvander@276
   442
			{
dvander@276
   443
				if (!llen)
dvander@276
   444
				{
dvander@276
   445
					goto done;
dvander@276
   446
				}
dvander@276
   447
				*buf_p++ = '%';
dvander@276
   448
				llen--;
dvander@276
   449
				goto done;
dvander@276
   450
			}
dvander@276
   451
		default:
dvander@276
   452
			{
dvander@276
   453
				if (!llen)
dvander@276
   454
				{
dvander@276
   455
					goto done;
dvander@276
   456
				}
dvander@276
   457
				*buf_p++ = ch;
dvander@276
   458
				llen--;
dvander@276
   459
				break;
dvander@276
   460
			}
dvander@276
   461
		}
dvander@276
   462
	}
dvander@276
   463
dvander@276
   464
done:
dvander@276
   465
	*buf_p = '\0';
dvander@276
   466
dvander@276
   467
	return (maxlen - llen - 1);
dvander@276
   468
}
dvander@276
   469
faluco@227
   470
size_t atcprintf(char *buffer, size_t maxlen, const char *format, IPluginContext *pCtx, const cell_t *params, int *param)
faluco@227
   471
{
dvander@276
   472
	if (!buffer || !maxlen)
dvander@276
   473
	{
dvander@276
   474
		return 0;
dvander@276
   475
	}
dvander@276
   476
faluco@227
   477
	int arg;
faluco@288
   478
	int args = params[0];
faluco@227
   479
	char *buf_p;
faluco@227
   480
	char ch;
faluco@227
   481
	int flags;
faluco@227
   482
	int width;
faluco@227
   483
	int prec;
faluco@227
   484
	int n;
faluco@227
   485
	char sign;
faluco@227
   486
	const char *fmt;
faluco@230
   487
	size_t llen = maxlen - 1;
faluco@227
   488
faluco@227
   489
	buf_p = buffer;
faluco@227
   490
	arg = *param;
faluco@227
   491
	fmt = format;
faluco@227
   492
faluco@227
   493
	while (true)
faluco@227
   494
	{
faluco@227
   495
		// run through the format string until we hit a '%' or '\0'
faluco@227
   496
		for (ch = *fmt; llen && ((ch = *fmt) != '\0') && (ch != '%'); fmt++)
faluco@227
   497
		{
faluco@227
   498
			*buf_p++ = ch;
faluco@227
   499
			llen--;
faluco@227
   500
		}
faluco@227
   501
		if ((ch == '\0') || (llen <= 0))
faluco@227
   502
		{
faluco@227
   503
			goto done;
faluco@227
   504
		}
faluco@227
   505
faluco@227
   506
		// skip over the '%'
faluco@227
   507
		fmt++;
faluco@227
   508
faluco@227
   509
		// reset formatting state
faluco@227
   510
		flags = 0;
faluco@227
   511
		width = 0;
faluco@227
   512
		prec = -1;
faluco@227
   513
		sign = '\0';
faluco@227
   514
faluco@227
   515
rflag:
faluco@227
   516
		ch = *fmt++;
faluco@227
   517
reswitch:
faluco@227
   518
		switch(ch)
faluco@227
   519
		{
faluco@227
   520
		case '-':
faluco@227
   521
			{
faluco@227
   522
				flags |= LADJUST;
faluco@227
   523
				goto rflag;
faluco@227
   524
			}
faluco@227
   525
		case '.':
faluco@227
   526
			{
faluco@227
   527
				n = 0;
faluco@227
   528
				while(is_digit((ch = *fmt++)))
faluco@227
   529
				{
faluco@227
   530
					n = 10 * n + (ch - '0');
faluco@227
   531
				}
faluco@227
   532
				prec = (n < 0) ? -1 : n;
faluco@227
   533
				goto reswitch;
faluco@227
   534
			}
faluco@227
   535
		case '0':
faluco@227
   536
			{
faluco@227
   537
				flags |= ZEROPAD;
faluco@227
   538
				goto rflag;
faluco@227
   539
			}
faluco@227
   540
		case '1':
faluco@227
   541
		case '2':
faluco@227
   542
		case '3':
faluco@227
   543
		case '4':
faluco@227
   544
		case '5':
faluco@227
   545
		case '6':
faluco@227
   546
		case '7':
faluco@227
   547
		case '8':
faluco@227
   548
		case '9':
faluco@227
   549
			{
faluco@227
   550
				n = 0;
faluco@227
   551
				do
faluco@227
   552
				{
faluco@227
   553
					n = 10 * n + (ch - '0');
faluco@227
   554
					ch = *fmt++;
faluco@227
   555
				} while(is_digit(ch));
faluco@227
   556
				width = n;
faluco@227
   557
				goto reswitch;
faluco@227
   558
			}
faluco@227
   559
		case 'c':
faluco@227
   560
			{
faluco@227
   561
				CHECK_ARGS(0);
faluco@230
   562
				if (!llen)
faluco@227
   563
				{
faluco@227
   564
					goto done;
faluco@227
   565
				}
faluco@227
   566
				char *c;
faluco@227
   567
				pCtx->LocalToString(params[arg], &c);
faluco@227
   568
				*buf_p++ = *c;
faluco@227
   569
				llen--;
faluco@227
   570
				arg++;
faluco@227
   571
				break;
faluco@227
   572
			}
faluco@227
   573
		case 'd':
faluco@227
   574
		case 'i':
faluco@227
   575
			{
faluco@227
   576
				CHECK_ARGS(0);
faluco@227
   577
				cell_t *value;
faluco@227
   578
				pCtx->LocalToPhysAddr(params[arg], &value);
faluco@227
   579
				AddInt(&buf_p, llen, static_cast<int>(*value), width, flags);
faluco@227
   580
				arg++;
faluco@227
   581
				break;
faluco@227
   582
			}
faluco@227
   583
		case 'u':
faluco@227
   584
			{
faluco@227
   585
				CHECK_ARGS(0);
faluco@227
   586
				cell_t *value;
faluco@227
   587
				pCtx->LocalToPhysAddr(params[arg], &value);
faluco@227
   588
				AddUInt(&buf_p, llen, static_cast<unsigned int>(*value), width, flags);
faluco@227
   589
				arg++;
faluco@227
   590
				break;
faluco@227
   591
			}
faluco@227
   592
		case 'f':
faluco@227
   593
			{
faluco@227
   594
				CHECK_ARGS(0);
faluco@227
   595
				cell_t *value;
faluco@227
   596
				pCtx->LocalToPhysAddr(params[arg], &value);
dvander@233
   597
				AddFloat(&buf_p, llen, sp_ctof(*value), width, prec);
faluco@227
   598
				arg++;
faluco@227
   599
				break;
faluco@227
   600
			}
faluco@227
   601
		case 's':
faluco@227
   602
			{
faluco@227
   603
				CHECK_ARGS(0);
faluco@227
   604
				char *str;
faluco@227
   605
				pCtx->LocalToString(params[arg], &str);
faluco@227
   606
				AddString(&buf_p, llen, str, width, prec);
faluco@227
   607
				arg++;
faluco@227
   608
				break;
faluco@227
   609
			}
faluco@389
   610
		case 'T':
faluco@389
   611
			{
faluco@389
   612
				CHECK_ARGS(0);
faluco@389
   613
				char *key;
faluco@389
   614
				cell_t target = params[arg++];
faluco@389
   615
				pCtx->LocalToString(params[arg++], &key);
faluco@389
   616
				llen -= Translate(buf_p, llen, pCtx, key, target, params, &arg);
faluco@389
   617
				buf_p += llen;
faluco@389
   618
				break;
faluco@389
   619
			}
faluco@227
   620
		case '%':
faluco@227
   621
			{
faluco@230
   622
				if (!llen)
faluco@227
   623
				{
faluco@227
   624
					goto done;
faluco@227
   625
				}
faluco@227
   626
				*buf_p++ = ch;
faluco@227
   627
				llen--;
faluco@227
   628
				break;
faluco@227
   629
			}
faluco@227
   630
		case '\0':
faluco@227
   631
			{
faluco@230
   632
				if (!llen)
faluco@227
   633
				{
faluco@227
   634
					goto done;
faluco@227
   635
				}
faluco@227
   636
				*buf_p++ = '%';
faluco@227
   637
				llen--;
faluco@227
   638
				goto done;
faluco@227
   639
			}
faluco@227
   640
		default:
faluco@227
   641
			{
faluco@230
   642
				if (!llen)
faluco@227
   643
				{
faluco@227
   644
					goto done;
faluco@227
   645
				}
faluco@227
   646
				*buf_p++ = ch;
faluco@227
   647
				llen--;
faluco@227
   648
				break;
faluco@227
   649
			}
faluco@227
   650
		}
faluco@227
   651
	}
faluco@227
   652
faluco@227
   653
done:
faluco@227
   654
	*buf_p = '\0';
faluco@227
   655
	*param = arg;
faluco@236
   656
	return (maxlen - llen - 1);
faluco@227
   657
}
faluco@230
   658
faluco@230
   659
const char *stristr(const char *str, const char *substr)
faluco@230
   660
{
faluco@230
   661
	if (!*substr)
faluco@230
   662
	{
faluco@230
   663
		return ((char *)str);
faluco@230
   664
	}
faluco@230
   665
faluco@230
   666
	char *needle = (char *)substr;
faluco@230
   667
	char *prevloc = (char *)str;
faluco@230
   668
	char *haystack = (char *)str;
faluco@230
   669
faluco@230
   670
	while (*haystack)
faluco@230
   671
	{
faluco@230
   672
		if (tolower(*haystack) == tolower(*needle))
faluco@230
   673
		{
faluco@230
   674
			haystack++;
faluco@230
   675
			if (!*++needle)
faluco@230
   676
			{
faluco@230
   677
				return prevloc;
faluco@230
   678
			}
faluco@230
   679
		} else {
faluco@230
   680
			haystack = ++prevloc;
faluco@230
   681
			needle = (char *)substr;
faluco@230
   682
		}
faluco@230
   683
	}
faluco@230
   684
faluco@230
   685
	return NULL;
faluco@230
   686
}
faluco@230
   687
dvander@233
   688
unsigned int strncopy(char *dest, const char *src, size_t count)
faluco@230
   689
{
faluco@230
   690
	if (!count)
faluco@230
   691
	{
faluco@230
   692
		return 0;
faluco@230
   693
	}
faluco@230
   694
faluco@230
   695
	char *start = dest;
faluco@230
   696
	while ((*src) && (--count))
faluco@230
   697
	{
faluco@230
   698
		*dest++ = *src++;
faluco@230
   699
	}
faluco@230
   700
	*dest = '\0';
faluco@230
   701
faluco@230
   702
	return (dest - start);
faluco@230
   703
}
faluco@274
   704
faluco@274
   705
size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
faluco@274
   706
{
faluco@274
   707
	va_list ap;
faluco@274
   708
	va_start(ap, fmt);
faluco@274
   709
	size_t len = vsnprintf(buffer, maxlength, fmt, ap);
faluco@274
   710
	va_end(ap);
faluco@274
   711
faluco@274
   712
	return (len >= maxlength) ? (maxlength - 1) : len;
dvander@351
   713
}
dvander@351
   714