added StrBreak from AMX Mod X, with various improvements
authorDavid Anderson <dvander@alliedmods.net>
Fri Mar 16 20:10:13 2007 +0000 (2007-03-16)
changeset 63176dc2aa558e5
parent 630 2b1aca886622
child 632 5fd3bbbf2dc0
added StrBreak from AMX Mod X, with various improvements
core/TextParsers.cpp
core/TextParsers.h
core/smn_string.cpp
plugins/include/string.inc
     1.1 --- a/core/TextParsers.cpp	Fri Mar 16 18:19:26 2007 +0000
     1.2 +++ b/core/TextParsers.cpp	Fri Mar 16 20:10:13 2007 +0000
     1.3 @@ -25,6 +25,11 @@
     1.4  static int g_ini_chartable1[255] = {0};
     1.5  static int g_ws_chartable[255] = {0};
     1.6  
     1.7 +bool IsWhitespace(const char *stream)
     1.8 +{
     1.9 +	return g_ws_chartable[(unsigned)*stream] == 1;
    1.10 +}
    1.11 +
    1.12  TextParsers::TextParsers()
    1.13  {
    1.14  	g_ini_chartable1[(unsigned)'_'] = 1;
     2.1 --- a/core/TextParsers.h	Fri Mar 16 18:19:26 2007 +0000
     2.2 +++ b/core/TextParsers.h	Fri Mar 16 20:10:13 2007 +0000
     2.3 @@ -37,6 +37,8 @@
     2.4  	return 1;
     2.5  }
     2.6  
     2.7 +bool IsWhitespace(const char *stream);
     2.8 +
     2.9  /**
    2.10   * @param void *			IN: Stream pointer
    2.11   * @param char *			IN/OUT: Stream buffer
     3.1 --- a/core/smn_string.cpp	Fri Mar 16 18:19:26 2007 +0000
     3.2 +++ b/core/smn_string.cpp	Fri Mar 16 20:10:13 2007 +0000
     3.3 @@ -15,6 +15,7 @@
     3.4  #include <stdlib.h>
     3.5  #include "sm_globals.h"
     3.6  #include "sm_stringutil.h"
     3.7 +#include "TextParsers.h"
     3.8  
     3.9  inline const char *_strstr(const char *str, const char *substr)
    3.10  {
    3.11 @@ -219,9 +220,99 @@
    3.12  	return total;
    3.13  }
    3.14  
    3.15 -REGISTER_NATIVES(basicstrings)
    3.16 +/* :TODO: make this UTF8 safe */
    3.17 +static cell_t StrBreak(IPluginContext *pContext, const cell_t *params)
    3.18 +{
    3.19 +	const char *input;
    3.20 +	char *out;
    3.21 +	size_t outMax;
    3.22 +
    3.23 +	/* Get parameters */
    3.24 +	pContext->LocalToString(params[1], (char **)&input);
    3.25 +	pContext->LocalToString(params[2], &out);
    3.26 +	outMax = params[3];
    3.27 +
    3.28 +	const char *inptr = input;
    3.29 +	/* Eat up whitespace */
    3.30 +	while (*inptr != '\0' && IsWhitespace(inptr))
    3.31 +	{
    3.32 +		inptr++;
    3.33 +	}
    3.34 +
    3.35 +	if (*inptr == '\0')
    3.36 +	{
    3.37 +		if (outMax)
    3.38 +		{
    3.39 +			*out = '\0';
    3.40 +		}
    3.41 +		return -1;
    3.42 +	}
    3.43 +
    3.44 +	const char *start, *end = NULL;
    3.45 +
    3.46 +	bool quoted = (*inptr == '"');
    3.47 +	if (quoted)
    3.48 +	{
    3.49 +		inptr++;
    3.50 +		start = inptr;
    3.51 +		/* Read input until we reach a quote. */
    3.52 +		while (*inptr != '\0' && *inptr != '"')
    3.53 +		{
    3.54 +			/* Update the end point, increment the stream. */
    3.55 +			end = inptr++;
    3.56 +		}
    3.57 +		/* Read one more token if we reached an end quote */
    3.58 +		if (*inptr == '"')
    3.59 +		{
    3.60 +			inptr++;
    3.61 +		}
    3.62 +	} else {
    3.63 +		start = inptr;
    3.64 +		/* Read input until we reach a space */
    3.65 +		while (*inptr != '\0' && !IsWhitespace(inptr))
    3.66 +		{
    3.67 +			/* Update the end point, increment the stream. */
    3.68 +			end = inptr++;
    3.69 +		}
    3.70 +	}
    3.71 +
    3.72 +	/* Copy the string we found, if necessary */
    3.73 +	if (end == NULL)
    3.74 +	{
    3.75 +		if (outMax)
    3.76 +		{
    3.77 +			*out = '\0';
    3.78 +		}
    3.79 +	} else if (outMax) {
    3.80 +		char *outptr = out;
    3.81 +		outMax--;
    3.82 +		for (const char *ptr=start;
    3.83 +			(ptr <= end) && ((unsigned)(outptr - out) < (outMax));
    3.84 +			ptr++, outptr++)
    3.85 +			{
    3.86 +			*outptr = *ptr;
    3.87 +		}
    3.88 +		*outptr = '\0';
    3.89 +	}
    3.90 +
    3.91 +	/* Consume more of the string until we reach non-whitespace */
    3.92 +	while (*inptr != '\0' && IsWhitespace(inptr))
    3.93 +	{
    3.94 +		inptr++;
    3.95 +	}
    3.96 +
    3.97 +	if (*inptr == '\0')
    3.98 +	{
    3.99 +		return -1;
   3.100 +	}
   3.101 +
   3.102 +	return inptr - input;
   3.103 +}
   3.104 +
   3.105 +REGISTER_NATIVES(basicStrings)
   3.106  {
   3.107  	{"strlen",				sm_strlen},
   3.108 +	{"StrBreak",			StrBreak},
   3.109  	{"StrContains",			sm_contain},
   3.110  	{"StrCompare",			sm_strcmp},
   3.111  	{"StrCopy",				sm_strcopy},
     4.1 --- a/plugins/include/string.inc	Fri Mar 16 18:19:26 2007 +0000
     4.2 +++ b/plugins/include/string.inc	Fri Mar 16 20:10:13 2007 +0000
     4.3 @@ -23,7 +23,7 @@
     4.4   * and maximum length should have the null terminator INCLUDED in the length.  This means 
     4.5   * that this is valid: StrCopy(string, sizeof(string), ...)
     4.6   */
     4.7 -
     4.8 + 
     4.9  /**
    4.10   * Calculates the length of a string.
    4.11   *
    4.12 @@ -159,3 +159,17 @@
    4.13   * @return				Number of cells written to buffer.
    4.14   */
    4.15  native FloatToString(Float:num, String:str[], maxlength);
    4.16 +
    4.17 +/**
    4.18 + * Finds the first "argument" in a string; either a set of space
    4.19 + * terminated characters, or a fully quoted string.  After the 
    4.20 + * argument is found, whitespace is read until the next portion
    4.21 + * of the string is reached.  If nothing remains, -1 is returned.
    4.22 + * Otherwise, the index to the first character is returned.
    4.23 + *
    4.24 + * @param source		Source input string.
    4.25 + * @param arg			Stores argument read from string.
    4.26 + * @param argLen		Maximum length of argument buffer.
    4.27 + * @return				Index to next piece of string, or -1 if none.
    4.28 + */
    4.29 +native StrBreak(const String:source[], String:arg[], argLen);
    4.30 \ No newline at end of file