core/smn_string.cpp
author David Anderson <dvander@alliedmods.net>
Wed Jun 06 22:31:54 2007 +0000 (2007-06-06)
changeset 896 e30eef2642ba
parent 834 d6fac170d744
child 1072 79fb41b647d5
permissions -rw-r--r--
added config options for chat triggers
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
dvander@370
     3
 * ===============================================================
dvander@370
     4
 * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
dvander@370
     5
 * ===============================================================
dvander@370
     6
 *
dvander@370
     7
 * This file is not open source and may not be copied without explicit
dvander@370
     8
 * written permission of AlliedModders LLC.  This file may not be redistributed 
dvander@370
     9
 * in whole or significant part.
dvander@370
    10
 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
dvander@370
    11
 *
dvander@370
    12
 * Version: $Id$
dvander@370
    13
 */
dvander@370
    14
faluco@225
    15
#include <string.h>
dvander@233
    16
#include <stdlib.h>
dvander@233
    17
#include "sm_globals.h"
faluco@230
    18
#include "sm_stringutil.h"
dvander@631
    19
#include "TextParsers.h"
dvander@748
    20
#include <ctype.h>
faluco@225
    21
faluco@225
    22
inline const char *_strstr(const char *str, const char *substr)
faluco@225
    23
{
faluco@225
    24
#ifdef PLATFORM_WINDOWS
faluco@225
    25
	return strstr(str, substr);
dvander@351
    26
#elif defined PLATFORM_LINUX
faluco@225
    27
	return (const char *)strstr(str, substr);
faluco@225
    28
#endif
faluco@225
    29
}
faluco@225
    30
faluco@225
    31
/*********************************************
faluco@225
    32
*                                            *
faluco@225
    33
* STRING MANIPULATION NATIVE IMPLEMENTATIONS *
faluco@225
    34
*                                            *
faluco@225
    35
*********************************************/
faluco@225
    36
faluco@225
    37
static cell_t sm_strlen(IPluginContext *pCtx, const cell_t *params)
faluco@225
    38
{
faluco@225
    39
	char *str;
faluco@225
    40
	pCtx->LocalToString(params[1], &str);
faluco@225
    41
faluco@225
    42
	return strlen(str);
faluco@225
    43
}
faluco@225
    44
faluco@225
    45
static cell_t sm_contain(IPluginContext *pCtx, const cell_t *params)
faluco@225
    46
{
faluco@225
    47
	typedef const char *(*STRSEARCH)(const char *, const char *);
faluco@225
    48
	STRSEARCH func;
faluco@225
    49
	char *str, *substr;
faluco@225
    50
faluco@225
    51
	pCtx->LocalToString(params[1], &str);
faluco@225
    52
	pCtx->LocalToString(params[2], &substr);
faluco@225
    53
faluco@225
    54
	func = (params[3]) ? _strstr : stristr;
faluco@225
    55
	const char *pos = func(str, substr);
faluco@225
    56
	if (pos)
faluco@225
    57
	{
faluco@225
    58
		return (pos - str);
faluco@225
    59
	}
faluco@225
    60
faluco@225
    61
	return -1;
faluco@225
    62
}
faluco@225
    63
dvander@233
    64
static cell_t sm_strcmp(IPluginContext *pCtx, const cell_t *params)
faluco@225
    65
{
faluco@225
    66
	typedef int (*STRCOMPARE)(const char *, const char *);
faluco@225
    67
	STRCOMPARE func;
faluco@225
    68
	char *str1, *str2;
faluco@225
    69
faluco@225
    70
	pCtx->LocalToString(params[1], &str1);
faluco@225
    71
	pCtx->LocalToString(params[2], &str2);
faluco@225
    72
faluco@225
    73
	func = (params[3]) ? strcmp : stricmp;
faluco@225
    74
dvander@233
    75
	return (func(str1, str2));
faluco@225
    76
}
faluco@225
    77
dvander@680
    78
static cell_t sm_strncmp(IPluginContext *pCtx, const cell_t *params)
dvander@680
    79
{
dvander@680
    80
	char *str1, *str2;
dvander@680
    81
dvander@680
    82
	pCtx->LocalToString(params[1], &str1);
dvander@680
    83
	pCtx->LocalToString(params[2], &str2);
dvander@680
    84
	
dvander@680
    85
	if  (params[4])
dvander@680
    86
	{
dvander@680
    87
		return strncmp(str1, str2, (size_t)params[3]);
dvander@680
    88
	} else {
dvander@680
    89
		return strncasecmp(str1, str2, (size_t)params[3]);
dvander@680
    90
	}
dvander@680
    91
}
dvander@680
    92
faluco@225
    93
static cell_t sm_strcopy(IPluginContext *pCtx, const cell_t *params)
faluco@225
    94
{
faluco@230
    95
	char *dest, *src;
faluco@225
    96
faluco@225
    97
	pCtx->LocalToString(params[1], &dest);
faluco@225
    98
	pCtx->LocalToString(params[3], &src);
faluco@225
    99
faluco@230
   100
	return strncopy(dest, src, params[2]);
faluco@225
   101
}
faluco@226
   102
dvander@233
   103
static cell_t sm_strconvint(IPluginContext *pCtx, const cell_t *params)
faluco@226
   104
{
dvander@233
   105
	char *str, *dummy;
faluco@226
   106
	pCtx->LocalToString(params[1], &str);
faluco@226
   107
dvander@233
   108
	return static_cast<cell_t>(strtol(str, &dummy, params[2]));
faluco@226
   109
}
faluco@226
   110
faluco@226
   111
static cell_t sm_numtostr(IPluginContext *pCtx, const cell_t *params)
faluco@226
   112
{
faluco@226
   113
	char *str;
faluco@226
   114
	pCtx->LocalToString(params[2], &str);
faluco@274
   115
	size_t res = UTIL_Format(str, params[3], "%d", params[1]);
faluco@226
   116
faluco@274
   117
	return static_cast<cell_t>(res);
faluco@226
   118
}
faluco@226
   119
faluco@226
   120
static cell_t sm_strtofloat(IPluginContext *pCtx, const cell_t *params)
faluco@226
   121
{
dvander@233
   122
	char *str, *dummy;
faluco@226
   123
	pCtx->LocalToString(params[1], &str);
faluco@226
   124
dvander@233
   125
	float val = (float)strtod(str, &dummy);
dvander@233
   126
dvander@233
   127
	return sp_ftoc(val);
faluco@226
   128
}
faluco@226
   129
faluco@226
   130
static cell_t sm_floattostr(IPluginContext *pCtx, const cell_t *params)
faluco@226
   131
{
faluco@226
   132
	char *str;
faluco@226
   133
	pCtx->LocalToString(params[2], &str);
faluco@274
   134
	size_t res = UTIL_Format(str, params[3], "%f", sp_ctof(params[1]));
faluco@226
   135
faluco@274
   136
	return static_cast<cell_t>(res);
faluco@226
   137
}
dvander@233
   138
faluco@236
   139
static cell_t sm_formatex(IPluginContext *pCtx, const cell_t *params)
faluco@236
   140
{
faluco@236
   141
	char *buf, *fmt;
faluco@236
   142
	size_t res;
faluco@236
   143
	int arg = 4;
faluco@236
   144
faluco@236
   145
	pCtx->LocalToString(params[1], &buf);
faluco@236
   146
	pCtx->LocalToString(params[3], &fmt);
faluco@236
   147
	res = atcprintf(buf, static_cast<size_t>(params[2]), fmt, pCtx, params, &arg);
faluco@236
   148
faluco@236
   149
	return static_cast<cell_t>(res);
faluco@236
   150
}
faluco@236
   151
faluco@236
   152
static char g_formatbuf[2048];
faluco@236
   153
static cell_t sm_format(IPluginContext *pCtx, const cell_t *params)
faluco@236
   154
{
faluco@236
   155
	char *buf, *fmt, *destbuf;
faluco@236
   156
	cell_t start_addr, end_addr, maxparam;
faluco@236
   157
	size_t res, maxlen;
faluco@236
   158
	int arg = 4;
faluco@236
   159
	bool copy = false;
faluco@236
   160
faluco@236
   161
	pCtx->LocalToString(params[1], &destbuf);
faluco@236
   162
	pCtx->LocalToString(params[3], &fmt);
faluco@236
   163
faluco@236
   164
	maxlen = static_cast<size_t>(params[2]);
faluco@236
   165
	start_addr = params[1];
faluco@236
   166
	end_addr = params[1] + maxlen;
faluco@236
   167
	maxparam = params[0];
faluco@236
   168
faluco@236
   169
	for (cell_t i=3; i<=maxparam; i++)
faluco@236
   170
	{
faluco@236
   171
		if ((params[i] >= start_addr) && (params[i] <= end_addr))
faluco@236
   172
		{
faluco@236
   173
			copy = true;
faluco@236
   174
			break;
faluco@236
   175
		}
faluco@236
   176
	}
faluco@236
   177
	buf = (copy) ? g_formatbuf : destbuf;
faluco@236
   178
	res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg);
faluco@236
   179
faluco@236
   180
	if (copy)
faluco@236
   181
	{
faluco@236
   182
		memcpy(destbuf, g_formatbuf, res+1);
faluco@236
   183
	}
faluco@236
   184
faluco@236
   185
	return static_cast<cell_t>(res);
faluco@236
   186
}
faluco@236
   187
dvander@411
   188
static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params)
dvander@411
   189
{
dvander@411
   190
	int vargPos = static_cast<int>(params[4]);
dvander@411
   191
dvander@411
   192
	/* Get the parent parameter array */
dvander@411
   193
	sp_context_t *ctx = pContext->GetContext();
dvander@411
   194
	cell_t *local_params = (cell_t *)(ctx->memory + ctx->frm + (2 * sizeof(cell_t)));
dvander@411
   195
dvander@411
   196
	cell_t max = local_params[0];
dvander@411
   197
	if (vargPos > (int)max + 1)
dvander@411
   198
	{
dvander@411
   199
		return pContext->ThrowNativeError("Argument index is invalid: %d", vargPos);
dvander@411
   200
	}
dvander@411
   201
dvander@411
   202
	cell_t addr_start = params[1];
dvander@411
   203
	cell_t addr_end = addr_start + params[2];
dvander@411
   204
	bool copy = false;
dvander@411
   205
	for (int i=vargPos; i<=max; i++)
dvander@411
   206
	{
dvander@411
   207
		/* Does this clip bounds? */
dvander@411
   208
		if ((local_params[i] >= addr_start)
dvander@411
   209
			&& (local_params[i] <= addr_end))
dvander@411
   210
		{
dvander@411
   211
			copy = true;
dvander@411
   212
			break;
dvander@411
   213
		}
dvander@411
   214
	}
dvander@411
   215
dvander@411
   216
	/* Get destination info */
dvander@411
   217
	char *format, *destination;
dvander@411
   218
	size_t maxlen = static_cast<size_t>(params[2]);
dvander@411
   219
dvander@411
   220
	if (copy)
dvander@411
   221
	{
dvander@411
   222
		destination = g_formatbuf;
dvander@411
   223
	} else {
dvander@411
   224
		pContext->LocalToString(params[1], &destination);
dvander@411
   225
	}
dvander@411
   226
dvander@411
   227
	pContext->LocalToString(params[3], &format);
dvander@411
   228
dvander@411
   229
	size_t total = atcprintf(destination, maxlen, format, pContext, local_params, &vargPos);
dvander@411
   230
dvander@411
   231
	/* Perform copy-on-write if we need to */
dvander@411
   232
	if (copy)
dvander@411
   233
	{
dvander@411
   234
		pContext->StringToLocal(params[1], maxlen, g_formatbuf);
dvander@411
   235
	}
dvander@411
   236
dvander@411
   237
	return total;
dvander@411
   238
}
dvander@411
   239
dvander@631
   240
/* :TODO: make this UTF8 safe */
ds@830
   241
static cell_t BreakString(IPluginContext *pContext, const cell_t *params)
dvander@631
   242
{
dvander@631
   243
	const char *input;
dvander@631
   244
	char *out;
dvander@631
   245
	size_t outMax;
dvander@631
   246
dvander@631
   247
	/* Get parameters */
dvander@631
   248
	pContext->LocalToString(params[1], (char **)&input);
dvander@631
   249
	pContext->LocalToString(params[2], &out);
dvander@631
   250
	outMax = params[3];
dvander@631
   251
dvander@631
   252
	const char *inptr = input;
dvander@631
   253
	/* Eat up whitespace */
dvander@631
   254
	while (*inptr != '\0' && IsWhitespace(inptr))
dvander@631
   255
	{
dvander@631
   256
		inptr++;
dvander@631
   257
	}
dvander@631
   258
dvander@631
   259
	if (*inptr == '\0')
dvander@631
   260
	{
dvander@631
   261
		if (outMax)
dvander@631
   262
		{
dvander@631
   263
			*out = '\0';
dvander@631
   264
		}
dvander@631
   265
		return -1;
dvander@631
   266
	}
dvander@631
   267
dvander@631
   268
	const char *start, *end = NULL;
dvander@631
   269
dvander@631
   270
	bool quoted = (*inptr == '"');
dvander@631
   271
	if (quoted)
dvander@631
   272
	{
dvander@631
   273
		inptr++;
dvander@631
   274
		start = inptr;
dvander@631
   275
		/* Read input until we reach a quote. */
dvander@631
   276
		while (*inptr != '\0' && *inptr != '"')
dvander@631
   277
		{
dvander@631
   278
			/* Update the end point, increment the stream. */
dvander@631
   279
			end = inptr++;
dvander@631
   280
		}
dvander@631
   281
		/* Read one more token if we reached an end quote */
dvander@631
   282
		if (*inptr == '"')
dvander@631
   283
		{
dvander@631
   284
			inptr++;
dvander@631
   285
		}
dvander@631
   286
	} else {
dvander@631
   287
		start = inptr;
dvander@631
   288
		/* Read input until we reach a space */
dvander@631
   289
		while (*inptr != '\0' && !IsWhitespace(inptr))
dvander@631
   290
		{
dvander@631
   291
			/* Update the end point, increment the stream. */
dvander@631
   292
			end = inptr++;
dvander@631
   293
		}
dvander@631
   294
	}
dvander@631
   295
dvander@631
   296
	/* Copy the string we found, if necessary */
dvander@631
   297
	if (end == NULL)
dvander@631
   298
	{
dvander@631
   299
		if (outMax)
dvander@631
   300
		{
dvander@631
   301
			*out = '\0';
dvander@631
   302
		}
dvander@631
   303
	} else if (outMax) {
dvander@631
   304
		char *outptr = out;
dvander@631
   305
		outMax--;
dvander@631
   306
		for (const char *ptr=start;
dvander@631
   307
			(ptr <= end) && ((unsigned)(outptr - out) < (outMax));
dvander@631
   308
			ptr++, outptr++)
dvander@631
   309
			{
dvander@631
   310
			*outptr = *ptr;
dvander@631
   311
		}
dvander@631
   312
		*outptr = '\0';
dvander@631
   313
	}
dvander@631
   314
dvander@631
   315
	/* Consume more of the string until we reach non-whitespace */
dvander@631
   316
	while (*inptr != '\0' && IsWhitespace(inptr))
dvander@631
   317
	{
dvander@631
   318
		inptr++;
dvander@631
   319
	}
dvander@631
   320
dvander@631
   321
	if (*inptr == '\0')
dvander@631
   322
	{
dvander@631
   323
		return -1;
dvander@631
   324
	}
dvander@631
   325
dvander@631
   326
	return inptr - input;
dvander@631
   327
}
dvander@631
   328
dvander@748
   329
static cell_t GetCharBytes(IPluginContext *pContext, const cell_t *params)
dvander@748
   330
{
dvander@748
   331
	char *str;
dvander@748
   332
	pContext->LocalToString(params[1], &str);
dvander@748
   333
dvander@748
   334
	return _GetUTF8CharBytes(str);
dvander@748
   335
};
dvander@748
   336
dvander@748
   337
static cell_t IsCharAlpha(IPluginContext *pContext, const cell_t *params)
dvander@748
   338
{
dvander@748
   339
	char chr = params[1];
dvander@748
   340
dvander@748
   341
	if (_GetUTF8CharBytes(&chr) != 1)
dvander@748
   342
	{
dvander@748
   343
		return 0;
dvander@748
   344
	}
dvander@748
   345
dvander@748
   346
	return isalpha(chr);
dvander@748
   347
}
dvander@748
   348
dvander@748
   349
static cell_t IsCharNumeric(IPluginContext *pContext, const cell_t *params)
dvander@748
   350
{
dvander@748
   351
	char chr = params[1];
dvander@748
   352
dvander@748
   353
	if (_GetUTF8CharBytes(&chr) != 1)
dvander@748
   354
	{
dvander@748
   355
		return 0;
dvander@748
   356
	}
dvander@748
   357
dvander@748
   358
	return isdigit(chr);
dvander@748
   359
}
dvander@748
   360
dvander@748
   361
static cell_t IsCharSpace(IPluginContext *pContext, const cell_t *params)
dvander@748
   362
{
dvander@748
   363
	char chr = params[1];
dvander@748
   364
dvander@748
   365
	if (_GetUTF8CharBytes(&chr) != 1)
dvander@748
   366
	{
dvander@748
   367
		return 0;
dvander@748
   368
	}
dvander@748
   369
dvander@748
   370
	return isspace(chr);
dvander@748
   371
}
dvander@748
   372
dvander@748
   373
static cell_t IsCharMB(IPluginContext *pContext, const cell_t *params)
dvander@748
   374
{
dvander@748
   375
	char chr = params[1];
dvander@748
   376
dvander@748
   377
	unsigned int bytes = _GetUTF8CharBytes(&chr);
dvander@748
   378
	if (bytes == 1)
dvander@748
   379
	{
dvander@748
   380
		return 0;
dvander@748
   381
	}
dvander@748
   382
dvander@748
   383
	return bytes;
dvander@748
   384
}
dvander@748
   385
ds@830
   386
static cell_t IsCharUpper(IPluginContext *pContext, const cell_t *params)
dvander@748
   387
{
dvander@748
   388
	char chr = params[1];
dvander@748
   389
dvander@748
   390
	if (_GetUTF8CharBytes(&chr) != 1)
dvander@748
   391
	{
dvander@748
   392
		return 0;
dvander@748
   393
	}
dvander@748
   394
dvander@748
   395
	return isupper(chr);
dvander@748
   396
}
dvander@748
   397
ds@830
   398
static cell_t IsCharLower(IPluginContext *pContext, const cell_t *params)
dvander@748
   399
{
dvander@748
   400
	char chr = params[1];
dvander@748
   401
dvander@748
   402
	if (_GetUTF8CharBytes(&chr) != 1)
dvander@748
   403
	{
dvander@748
   404
		return 0;
dvander@748
   405
	}
dvander@748
   406
dvander@748
   407
	return islower(chr);
dvander@748
   408
}
dvander@748
   409
dvander@833
   410
static cell_t ReplaceString(IPluginContext *pContext, const cell_t *params)
dvander@833
   411
{
dvander@833
   412
	char *text, *search, *replace;
dvander@833
   413
	size_t maxlength;
dvander@833
   414
	
dvander@833
   415
	pContext->LocalToString(params[1], &text);
dvander@833
   416
	pContext->LocalToString(params[3], &search);
dvander@833
   417
	pContext->LocalToString(params[4], &replace);
dvander@833
   418
	maxlength = (size_t)params[2];
dvander@833
   419
dvander@833
   420
dvander@833
   421
	return  UTIL_ReplaceAll(text, maxlength, search, replace);
dvander@833
   422
}
dvander@833
   423
dvander@833
   424
static cell_t ReplaceStringEx(IPluginContext *pContext, const cell_t *params)
dvander@833
   425
{
dvander@833
   426
	char *text, *search, *replace;
dvander@833
   427
	size_t maxlength;
dvander@833
   428
dvander@833
   429
	pContext->LocalToString(params[1], &text);
dvander@833
   430
	pContext->LocalToString(params[3], &search);
dvander@833
   431
	pContext->LocalToString(params[4], &replace);
dvander@833
   432
	maxlength = (size_t)params[2];
dvander@833
   433
dvander@833
   434
	size_t searchLen = (params[5] == -1) ? strlen(search) : (size_t)params[5];
dvander@833
   435
	size_t replaceLen = (params[6] == -1) ? strlen(replace) : (size_t)params[6];
dvander@833
   436
dvander@833
   437
	char *ptr = UTIL_ReplaceEx(text, maxlength, search, searchLen, replace, replaceLen);
dvander@833
   438
dvander@833
   439
	if (ptr == NULL)
dvander@833
   440
	{
dvander@833
   441
		return -1;
dvander@833
   442
	}
dvander@833
   443
dvander@833
   444
	return ptr - text;
dvander@833
   445
}
dvander@833
   446
ds@830
   447
static cell_t TrimString(IPluginContext *pContext, const cell_t *params)
ds@830
   448
{
ds@830
   449
	char *str;
ds@830
   450
	pContext->LocalToString(params[1], &str);
ds@830
   451
ds@830
   452
	size_t chars = strlen(str);
ds@830
   453
ds@830
   454
	if (chars == 0)
ds@830
   455
	{
ds@830
   456
		return 0;
ds@830
   457
	}
ds@830
   458
ds@830
   459
	char *end = str + chars - 1;
ds@830
   460
ds@830
   461
	/* Iterate backwards through string until we reach first non-whitespace char */
ds@830
   462
	while (end >= str && IsWhitespace(end))
ds@830
   463
	{
ds@830
   464
		end--;
ds@830
   465
	}
ds@830
   466
ds@830
   467
	/* Replace first whitespace char (at the end) with null terminator */
ds@830
   468
	*(end + 1) = '\0';
ds@830
   469
ds@830
   470
	/* Iterate forwards through string until first non-whitespace char is reached */
ds@830
   471
	while (IsWhitespace(str))
ds@830
   472
	{
ds@830
   473
		str++;
ds@830
   474
	}
ds@830
   475
ds@830
   476
	size_t bytes;
ds@830
   477
	pContext->StringToLocalUTF8(params[1], chars + 1, str, &bytes);
ds@830
   478
ds@830
   479
	return bytes;
ds@830
   480
}
ds@830
   481
dvander@834
   482
static cell_t SplitString(IPluginContext *pContext, const cell_t *params)
dvander@834
   483
{
dvander@834
   484
	char *text, *split;
dvander@834
   485
	
dvander@834
   486
	pContext->LocalToString(params[1], &text);
dvander@834
   487
	pContext->LocalToString(params[2], &split);
dvander@834
   488
dvander@834
   489
	size_t maxLen = (size_t)params[4];
dvander@834
   490
	size_t textLen = strlen(text);
dvander@834
   491
	size_t splitLen = strlen(split);
dvander@834
   492
dvander@834
   493
	if (splitLen > textLen)
dvander@834
   494
	{
dvander@834
   495
		return -1;
dvander@834
   496
	}
dvander@834
   497
dvander@834
   498
	for (size_t i=0; i<textLen - splitLen; i++)
dvander@834
   499
	{
dvander@834
   500
		if (strncmp(&text[i], split, splitLen) == 0)
dvander@834
   501
		{
dvander@834
   502
			/* Split hereeeee */
dvander@834
   503
			if (i >= maxLen)
dvander@834
   504
			{
dvander@834
   505
				pContext->StringToLocalUTF8(params[3], maxLen, text, NULL);
dvander@834
   506
			} else {
dvander@834
   507
				pContext->StringToLocalUTF8(params[3], i+1, text, NULL);
dvander@834
   508
			}
dvander@834
   509
			return (cell_t)(i + splitLen);
dvander@834
   510
		}
dvander@834
   511
	}
dvander@834
   512
dvander@834
   513
	return -1;
dvander@834
   514
}
dvander@834
   515
dvander@631
   516
REGISTER_NATIVES(basicStrings)
dvander@233
   517
{
dvander@833
   518
	{"BreakString",			BreakString},
dvander@833
   519
	{"FloatToString",		sm_floattostr},
dvander@833
   520
	{"Format",				sm_format},
dvander@833
   521
	{"FormatEx",			sm_formatex},
dvander@748
   522
	{"GetCharBytes",		GetCharBytes},
dvander@748
   523
	{"IntToString",			sm_numtostr},
dvander@748
   524
	{"IsCharAlpha",			IsCharAlpha},
dvander@748
   525
	{"IsCharLower",			IsCharLower},
dvander@748
   526
	{"IsCharMB",			IsCharMB},
dvander@748
   527
	{"IsCharNumeric",		IsCharNumeric},
dvander@748
   528
	{"IsCharSpace",			IsCharSpace},
dvander@748
   529
	{"IsCharUpper",			IsCharUpper},
dvander@833
   530
	{"ReplaceString",		ReplaceString},
dvander@833
   531
	{"ReplaceStringEx",		ReplaceStringEx},
dvander@834
   532
	{"SplitString",			SplitString},
dvander@233
   533
	{"strlen",				sm_strlen},
ds@830
   534
	{"StrBreak",			BreakString},		/* Backwards compat shim */
dvander@233
   535
	{"StrContains",			sm_contain},
dvander@681
   536
	{"strcmp",				sm_strcmp},
dvander@681
   537
	{"StrCompare",			sm_strcmp},			/* Backwards compat shim */
dvander@681
   538
	{"strncmp",				sm_strncmp},
dvander@681
   539
	{"strcopy",				sm_strcopy},
dvander@681
   540
	{"StrCopy",				sm_strcopy},		/* Backwards compat shim */
dvander@233
   541
	{"StringToInt",			sm_strconvint},
dvander@233
   542
	{"StringToFloat",		sm_strtofloat},
dvander@833
   543
	{"TrimString",			TrimString},
dvander@411
   544
	{"VFormat",				sm_vformat},
dvander@233
   545
	{NULL,					NULL},
dvander@233
   546
};