mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-19 12:07:13 +01:00
Adjust the string explode and implode utilities.
This commit is contained in:
parent
bba09395d0
commit
862c09150f
@ -1060,13 +1060,57 @@ static bool OnlyDelimiter(CSStr str, SQChar chr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static Array StrExplode(CSStr str, SQChar chr, bool empty)
|
static SQInteger SqStrExplode(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
|
const Int32 top = sq_gettop(vm);
|
||||||
|
// Was the delimiter character specified?
|
||||||
|
if (top <= 1)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, _SC("Missing delimiter character"));
|
||||||
|
}
|
||||||
|
// Was the boolean empty specified?
|
||||||
|
else if (top <= 2)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, _SC("Missing boolean empty"));
|
||||||
|
}
|
||||||
|
// Was the string value specified?
|
||||||
|
else if (top <= 3)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, _SC("Missing string value"));
|
||||||
|
}
|
||||||
|
// Attempt to generate the string value
|
||||||
|
StackStrF val(vm, 4);
|
||||||
|
// Have we failed to retrieve the string?
|
||||||
|
if (SQ_FAILED(val.mRes))
|
||||||
|
{
|
||||||
|
return val.mRes; // Propagate the error!
|
||||||
|
}
|
||||||
|
// The delimiter character and boolean empty
|
||||||
|
SQChar delim = 0;
|
||||||
|
bool empty = 0;
|
||||||
|
// Attempt to retrieve the remaining arguments from the stack
|
||||||
|
try
|
||||||
|
{
|
||||||
|
delim = Var< SQChar >(vm, 2).value;
|
||||||
|
empty = Var< bool >(vm, 3).value;
|
||||||
|
}
|
||||||
|
catch (const Sqrat::Exception & e)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, e.Message().c_str());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return sq_throwerror(vm, _SC("Unable to retrieve arguments"));
|
||||||
|
}
|
||||||
|
// Grab the string value to a shorter name
|
||||||
|
CSStr str = val.mPtr;
|
||||||
|
// Create an empty array on the stack
|
||||||
|
sq_newarray(vm, 0);
|
||||||
// See if we actually have something to explode
|
// See if we actually have something to explode
|
||||||
if(!str || *str == '\0')
|
if(!str || *str == '\0')
|
||||||
{
|
{
|
||||||
// Default to an empty array
|
// Specify that we have an argument on the stack
|
||||||
return Array(DefaultVM::Get(), 0);
|
return 1;
|
||||||
}
|
}
|
||||||
// Don't modify the specified string pointer
|
// Don't modify the specified string pointer
|
||||||
CSStr itr = str, last = str;
|
CSStr itr = str, last = str;
|
||||||
@ -1076,7 +1120,7 @@ static Array StrExplode(CSStr str, SQChar chr, bool empty)
|
|||||||
while (*itr != '\0')
|
while (*itr != '\0')
|
||||||
{
|
{
|
||||||
// Is this our delimiter?
|
// Is this our delimiter?
|
||||||
if (*(itr++) == chr)
|
if (*(itr++) == delim)
|
||||||
{
|
{
|
||||||
// Are we allowed to include empty elements?
|
// Are we allowed to include empty elements?
|
||||||
if (empty || (itr - last) > 1)
|
if (empty || (itr - last) > 1)
|
||||||
@ -1089,39 +1133,46 @@ static Array StrExplode(CSStr str, SQChar chr, bool empty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Were there no delimiters found and can we include empty elements?
|
// Were there no delimiters found and can we include empty elements?
|
||||||
if (num == 0 && !empty && (str[1] == '\0' || OnlyDelimiter(str, chr)))
|
if (num == 0 && !empty && (str[1] == '\0' || OnlyDelimiter(str, delim)))
|
||||||
{
|
{
|
||||||
// Default to an empty array
|
// Specify that we have an argument on the stack
|
||||||
return Array(DefaultVM::Get(), 0);
|
return 1;
|
||||||
}
|
}
|
||||||
// Have we found any delimiters?
|
// Have we found any delimiters?
|
||||||
else if (num == 0)
|
else if (num == 0)
|
||||||
{
|
{
|
||||||
// Create an array with just one element
|
|
||||||
Array arr(DefaultVM::Get(), 1);
|
|
||||||
// Test against strings with only delimiters
|
// Test against strings with only delimiters
|
||||||
if (str[1] == '\0' || OnlyDelimiter(str, chr))
|
if (str[1] == '\0' || OnlyDelimiter(str, delim))
|
||||||
{
|
{
|
||||||
arr.SetValue(0, _SC("")); // Add an empty string
|
sq_pushstring(vm, _SC(""), 0); // Add an empty string
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arr.SetValue(0, str); // Add the whole string
|
sq_pushstring(vm, val.mPtr, val.mLen); // Add the whole string
|
||||||
}
|
}
|
||||||
// Return the resulted array
|
// Append the string on the stack to the array
|
||||||
return arr;
|
const SQRESULT r = sq_arrayappend(vm, -2);
|
||||||
|
// Check the result
|
||||||
|
if (SQ_FAILED(r))
|
||||||
|
{
|
||||||
|
return r; // Propagate the error
|
||||||
|
}
|
||||||
|
// Specify that we have an argument on the stack
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
// Is there anything after the last delimiter?
|
// Is there anything after the last delimiter?
|
||||||
if (itr != last && *last != chr)
|
if (itr != last && *last != delim)
|
||||||
{
|
{
|
||||||
++num; // Add it to the counter
|
++num; // Add it to the counter
|
||||||
}
|
}
|
||||||
|
SQRESULT r = SQ_OK;
|
||||||
// Pre-allocate an array with the number of found delimiters
|
// Pre-allocate an array with the number of found delimiters
|
||||||
Array arr(DefaultVM::Get(), num);
|
r = sq_arrayresize(vm, -1, num);
|
||||||
// Remember the initial stack size
|
// Check the result
|
||||||
StackGuard sg;
|
if (SQ_FAILED(r))
|
||||||
// Push the array object on the stack
|
{
|
||||||
sq_pushobject(DefaultVM::Get(), arr.GetObject());
|
return r; // Propagate the error
|
||||||
|
}
|
||||||
// Don't modify the specified string pointer
|
// Don't modify the specified string pointer
|
||||||
itr = str, last = str;
|
itr = str, last = str;
|
||||||
// Reset the counter and use it as the element index
|
// Reset the counter and use it as the element index
|
||||||
@ -1130,38 +1181,48 @@ static Array StrExplode(CSStr str, SQChar chr, bool empty)
|
|||||||
while (*itr != '\0')
|
while (*itr != '\0')
|
||||||
{
|
{
|
||||||
// Is this our delimiter?
|
// Is this our delimiter?
|
||||||
if (*itr++ == chr)
|
if (*itr++ == delim)
|
||||||
{
|
{
|
||||||
// Are we allowed to include empty elements?
|
// Are we allowed to include empty elements?
|
||||||
if (empty || (itr - last) > 1)
|
if (empty || (itr - last) > 1)
|
||||||
{
|
{
|
||||||
// Push the element index on the stack and advance to the next one
|
// Push the element index on the stack and advance to the next one
|
||||||
sq_pushinteger(DefaultVM::Get(), num++);
|
sq_pushinteger(vm, num++);
|
||||||
// Push the string portion on the stack
|
// Push the string portion on the stack
|
||||||
sq_pushstring(DefaultVM::Get(), last, itr - last - 1);
|
sq_pushstring(vm, last, itr - last - 1);
|
||||||
// Assign the string onto the
|
// Assign the string onto the
|
||||||
sq_set(DefaultVM::Get(), -3);
|
r = sq_set(vm, -3);
|
||||||
|
// Check the result
|
||||||
|
if (SQ_FAILED(r))
|
||||||
|
{
|
||||||
|
return r; // Propagate the error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Update the last delimiter position
|
// Update the last delimiter position
|
||||||
last = itr;
|
last = itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Is there anything after the last delimiter?
|
// Is there anything after the last delimiter?
|
||||||
if (itr != last && *last != chr)
|
if (itr != last && *last != delim)
|
||||||
{
|
{
|
||||||
// Push the element index on the stack
|
// Push the element index on the stack
|
||||||
sq_pushinteger(DefaultVM::Get(), num);
|
sq_pushinteger(vm, num);
|
||||||
// Add the remaining string as an element
|
// Add the remaining string as an element
|
||||||
sq_pushstring(DefaultVM::Get(), last, itr - last);
|
sq_pushstring(vm, last, itr - last);
|
||||||
// Assign the string onto the
|
// Assign the string onto the
|
||||||
sq_set(DefaultVM::Get(), -3);
|
r = sq_set(vm, -3);
|
||||||
|
// Check the result
|
||||||
|
if (SQ_FAILED(r))
|
||||||
|
{
|
||||||
|
return r; // Propagate the error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Return the resulted array and let the stack guard handle the cleanup
|
// Specify that we have an argument on the stack
|
||||||
return arr;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static CSStr StrImplode(Array & arr, SQChar chr)
|
static CSStr StrImplode(SQChar chr, Array & arr)
|
||||||
{
|
{
|
||||||
// Determine array size
|
// Determine array size
|
||||||
const Int32 length = static_cast< Int32 >(arr.Length());
|
const Int32 length = static_cast< Int32 >(arr.Length());
|
||||||
@ -1236,7 +1297,7 @@ void Register_String(HSQUIRRELVM vm)
|
|||||||
Table strns(vm);
|
Table strns(vm);
|
||||||
|
|
||||||
strns.Func(_SC("FromArray"), &FromArray)
|
strns.Func(_SC("FromArray"), &FromArray)
|
||||||
.Func(_SC("Explode"), &StrExplode)
|
.SquirrelFunc(_SC("Explode"), &SqStrExplode)
|
||||||
.Func(_SC("Implode"), &StrImplode)
|
.Func(_SC("Implode"), &StrImplode)
|
||||||
.SquirrelFunc(_SC("Center"), &SqCenterStr)
|
.SquirrelFunc(_SC("Center"), &SqCenterStr)
|
||||||
.SquirrelFunc(_SC("Left"), &SqLeftStr)
|
.SquirrelFunc(_SC("Left"), &SqLeftStr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user