Introduce API to create Stack structures
This commit is contained in:
parent
0bfcaa85b6
commit
e7b7506efa
|
@ -92,7 +92,8 @@ binary.sources = [
|
||||||
'datastructs.cpp',
|
'datastructs.cpp',
|
||||||
'trie_natives.cpp',
|
'trie_natives.cpp',
|
||||||
'CDataPack.cpp',
|
'CDataPack.cpp',
|
||||||
'datapacks.cpp'
|
'datapacks.cpp',
|
||||||
|
'stackstructs.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if builder.target_platform == 'windows':
|
if builder.target_platform == 'windows':
|
||||||
|
|
|
@ -21,7 +21,7 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
|
||||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
||||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp sorting.cpp \
|
||||||
nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
|
nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
|
||||||
trie_natives.cpp CDataPack.cpp datapacks.cpp
|
trie_natives.cpp CDataPack.cpp datapacks.cpp stackstructs.cpp
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||||
|
|
|
@ -85,6 +85,7 @@ extern AMX_NATIVE_INFO msg_Natives[];
|
||||||
extern AMX_NATIVE_INFO vector_Natives[];
|
extern AMX_NATIVE_INFO vector_Natives[];
|
||||||
extern AMX_NATIVE_INFO g_SortNatives[];
|
extern AMX_NATIVE_INFO g_SortNatives[];
|
||||||
extern AMX_NATIVE_INFO g_DataStructNatives[];
|
extern AMX_NATIVE_INFO g_DataStructNatives[];
|
||||||
|
extern AMX_NATIVE_INFO g_StackNatives[];
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
|
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
|
||||||
|
|
|
@ -230,4 +230,4 @@ inline CellArray* HandleToVector(AMX* amx, int handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -573,6 +573,7 @@ int set_amxnatives(AMX* amx, char error[128])
|
||||||
amx_Register(amx, g_DataStructNatives, -1);
|
amx_Register(amx, g_DataStructNatives, -1);
|
||||||
amx_Register(amx, trie_Natives, -1);
|
amx_Register(amx, trie_Natives, -1);
|
||||||
amx_Register(amx, g_DatapackNatives, -1);
|
amx_Register(amx, g_DatapackNatives, -1);
|
||||||
|
amx_Register(amx, g_StackNatives, -1);
|
||||||
|
|
||||||
//we're not actually gonna check these here anymore
|
//we're not actually gonna check these here anymore
|
||||||
amx->flags |= AMX_FLAG_PRENIT;
|
amx->flags |= AMX_FLAG_PRENIT;
|
||||||
|
|
|
@ -329,6 +329,7 @@
|
||||||
<ClCompile Include="..\power.cpp" />
|
<ClCompile Include="..\power.cpp" />
|
||||||
<ClCompile Include="..\sorting.cpp" />
|
<ClCompile Include="..\sorting.cpp" />
|
||||||
<ClCompile Include="..\srvcmd.cpp" />
|
<ClCompile Include="..\srvcmd.cpp" />
|
||||||
|
<ClCompile Include="..\stackstructs.cpp" />
|
||||||
<ClCompile Include="..\string.cpp">
|
<ClCompile Include="..\string.cpp">
|
||||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">All</AssemblerOutput>
|
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">All</AssemblerOutput>
|
||||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">All</AssemblerOutput>
|
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">All</AssemblerOutput>
|
||||||
|
@ -400,6 +401,7 @@
|
||||||
<ResourceCompile Include="..\version.rc" />
|
<ResourceCompile Include="..\version.rc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="..\..\plugins\include\cellstack.inc" />
|
||||||
<None Include="..\..\plugins\include\datapack.inc" />
|
<None Include="..\..\plugins\include\datapack.inc" />
|
||||||
<None Include="..\amxdefn.asm" />
|
<None Include="..\amxdefn.asm" />
|
||||||
<None Include="..\amxexecn.asm" />
|
<None Include="..\amxexecn.asm" />
|
||||||
|
|
|
@ -174,6 +174,9 @@
|
||||||
<ClCompile Include="..\datapacks.cpp">
|
<ClCompile Include="..\datapacks.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\stackstructs.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\amx.h">
|
<ClInclude Include="..\amx.h">
|
||||||
|
@ -405,6 +408,9 @@
|
||||||
<None Include="..\..\plugins\include\datapack.inc">
|
<None Include="..\..\plugins\include\datapack.inc">
|
||||||
<Filter>Pawn Includes</Filter>
|
<Filter>Pawn Includes</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\..\plugins\include\cellstack.inc">
|
||||||
|
<Filter>Pawn Includes</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Object Include="..\Jit\helpers-x86.obj">
|
<Object Include="..\Jit\helpers-x86.obj">
|
||||||
|
|
293
amxmodx/stackstructs.cpp
Normal file
293
amxmodx/stackstructs.cpp
Normal file
|
@ -0,0 +1,293 @@
|
||||||
|
/* AMX Mod X
|
||||||
|
*
|
||||||
|
* by the AMX Mod X Development Team
|
||||||
|
* originally developed by OLO
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||||||
|
* your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* In addition, as a special exception, the author gives permission to
|
||||||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||||||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||||
|
* respects for all of the code used other than the HL Engine and MODs
|
||||||
|
* from Valve. If you modify this file, you may extend this exception
|
||||||
|
* to your version of the file, but you are not obligated to do so. If
|
||||||
|
* you do not wish to do so, delete this exception statement from your
|
||||||
|
* version.
|
||||||
|
*/
|
||||||
|
#include "amxmodx.h"
|
||||||
|
#include "datastructs.h"
|
||||||
|
|
||||||
|
// native Stack:CreateStack(blocksize = 1);
|
||||||
|
static cell AMX_NATIVE_CALL CreateStack(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
int cellsize = params[1];
|
||||||
|
|
||||||
|
if (cellsize <= 0)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Invalid block size (must be > 0)", cellsize);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan through the vector list to see if any are NULL.
|
||||||
|
// NULL means the vector was previously destroyed.
|
||||||
|
for (unsigned int i = 0; i < VectorHolder.length(); ++i)
|
||||||
|
{
|
||||||
|
if (VectorHolder[i] == NULL)
|
||||||
|
{
|
||||||
|
VectorHolder[i] = new CellArray(cellsize);
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// None are NULL, create a new vector
|
||||||
|
CellArray* NewVector = new CellArray(cellsize);
|
||||||
|
|
||||||
|
VectorHolder.append(NewVector);
|
||||||
|
|
||||||
|
return VectorHolder.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
// native PushStackCell(Stack:handle, any:value);
|
||||||
|
static cell AMX_NATIVE_CALL PushStackCell(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *blk = vec->push();
|
||||||
|
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Failed to grow stack");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*blk = params[2];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native PushStackString(Stack:handle, const value[]);
|
||||||
|
static cell AMX_NATIVE_CALL PushStackString(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *blk = vec->push();
|
||||||
|
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Failed to grow stack");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len;
|
||||||
|
const char *value = get_amxstring(amx, params[2], 0, len);
|
||||||
|
|
||||||
|
strncopy(blk, value, vec->blocksize());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native PushStackArray(Stack:handle, const any:values[], size= -1);
|
||||||
|
static cell AMX_NATIVE_CALL PushStackArray(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *blk = vec->push();
|
||||||
|
|
||||||
|
if (!blk)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Failed to grow stack");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *addr = get_amxaddr(amx, params[2]);
|
||||||
|
size_t indexes = vec->blocksize();
|
||||||
|
|
||||||
|
if (params[3] != -1 && (size_t)params[3] <= vec->blocksize())
|
||||||
|
{
|
||||||
|
indexes = params[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(blk, addr, indexes * sizeof(cell));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native bool:PopStackCell(Stack:handle, &any:value, block = 0, bool:asChar = false);
|
||||||
|
static cell AMX_NATIVE_CALL PopStackCell(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vec->size() == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *buffer = get_amxaddr(amx, params[2]);
|
||||||
|
size_t index = params[3];
|
||||||
|
|
||||||
|
cell *blk = vec->at(vec->size() - 1);
|
||||||
|
size_t idx = (size_t)params[3];
|
||||||
|
|
||||||
|
if (params[4] == 0)
|
||||||
|
{
|
||||||
|
if (idx >= vec->blocksize())
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Invalid block %d (blocksize: %d)", idx, vec->blocksize());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer = blk[idx];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (idx >= vec->blocksize() * 4)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Invalid byte %d (blocksize: %d bytes)", idx, vec->blocksize() * 4);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer = (cell)*((char *)blk + idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec->remove(vec->size() - 1);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native bool:PopStackString(Stack:handle, buffer[], maxlength, &written = 0);
|
||||||
|
static cell AMX_NATIVE_CALL PopStackString(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vec->size() == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = vec->size() - 1;
|
||||||
|
cell *blk = vec->at(idx);
|
||||||
|
|
||||||
|
int numWritten = set_amxstring_utf8(amx, params[2], blk, amxstring_len(blk), params[3] + 1);
|
||||||
|
*get_amxaddr(amx, params[4]) = numWritten;
|
||||||
|
|
||||||
|
vec->remove(idx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native bool:PopStackArray(Stack:handle, any:buffer[], size=-1);
|
||||||
|
static cell AMX_NATIVE_CALL PopStackArray(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vec->size() == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx = vec->size() - 1;
|
||||||
|
cell *blk = vec->at(idx);
|
||||||
|
size_t indexes = vec->blocksize();
|
||||||
|
|
||||||
|
if (params[3] != -1 && (size_t)params[3] <= vec->blocksize())
|
||||||
|
{
|
||||||
|
indexes = params[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *addr = get_amxaddr(amx, params[2]);
|
||||||
|
memcpy(addr, blk, indexes * sizeof(cell));
|
||||||
|
|
||||||
|
vec->remove(idx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native bool:IsStackEmpty(Stack:handle);
|
||||||
|
static cell AMX_NATIVE_CALL IsStackEmpty(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
CellArray* vec = HandleToVector(amx, params[1]);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec->size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// native DestroyStack(&Stack:which);
|
||||||
|
static cell AMX_NATIVE_CALL DestroyStack(AMX* amx, cell* params)
|
||||||
|
{
|
||||||
|
cell *handle = get_amxaddr(amx, params[1]);
|
||||||
|
CellArray *vec = HandleToVector(amx, *handle);
|
||||||
|
|
||||||
|
if (vec == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete vec;
|
||||||
|
|
||||||
|
VectorHolder[*handle - 1] = NULL;
|
||||||
|
|
||||||
|
*handle = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
AMX_NATIVE_INFO g_StackNatives[] =
|
||||||
|
{
|
||||||
|
{ "CreateStack", CreateStack },
|
||||||
|
{ "IsStackEmpty", IsStackEmpty },
|
||||||
|
{ "PopStackArray", PopStackArray },
|
||||||
|
{ "PopStackCell", PopStackCell },
|
||||||
|
{ "PopStackString", PopStackString },
|
||||||
|
{ "PushStackArray", PushStackArray },
|
||||||
|
{ "PushStackCell", PushStackCell },
|
||||||
|
{ "PushStackString", PushStackString },
|
||||||
|
{ "DestroyStack", DestroyStack },
|
||||||
|
{ NULL, NULL },
|
||||||
|
};
|
|
@ -22,6 +22,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sorting>
|
#include <sorting>
|
||||||
#include <cellarray>
|
#include <cellarray>
|
||||||
|
#include <cellstack>
|
||||||
#include <celltrie>
|
#include <celltrie>
|
||||||
#include <datapack>
|
#include <datapack>
|
||||||
#include <newmenus>
|
#include <newmenus>
|
||||||
|
|
146
plugins/include/cellstack.inc
Normal file
146
plugins/include/cellstack.inc
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
|
||||||
|
#if defined _cellstack_included
|
||||||
|
#endinput
|
||||||
|
#endif
|
||||||
|
#define _cellstack_included
|
||||||
|
|
||||||
|
enum Stack
|
||||||
|
{
|
||||||
|
Invalid_Stack = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a stack structure. A stack is a LIFO (last in, first out)
|
||||||
|
* vector (array) of items. It has O(1) insertion and O(1) removal.
|
||||||
|
*
|
||||||
|
* Stacks have two operations: Push (adding an item) and Pop (removes
|
||||||
|
* items in reverse-push order).
|
||||||
|
*
|
||||||
|
* The contents of the stack are uniform; i.e. storing a string and then
|
||||||
|
* retrieving it as an integer is NOT the same as StringToInt()!
|
||||||
|
*
|
||||||
|
* The "blocksize" determines how many cells each slot has; it cannot
|
||||||
|
* be changed after creation.
|
||||||
|
*
|
||||||
|
* @param blocksize The number of cells each entry in the stack can
|
||||||
|
* hold. For example, 32 cells is equivalent to:
|
||||||
|
* new Array[X][32]
|
||||||
|
*
|
||||||
|
* @return New stack Handle.
|
||||||
|
* @error Invalid block size.
|
||||||
|
*/
|
||||||
|
native Stack:CreateStack(blocksize = 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a value onto the end of the stack, adding a new index.
|
||||||
|
*
|
||||||
|
* This may safely be used even if the stack has a blocksize
|
||||||
|
* greater than 1.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param value Value to push.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushStackCell(Stack:handle, any:value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes a string onto the end of a stack, truncating it if it is
|
||||||
|
* too big.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param value String to push.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushStackString(Stack:handle, const value[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an array of cells onto the end of a stack. The cells
|
||||||
|
* are pushed as a block (i.e. the entire array takes up one stack slot),
|
||||||
|
* rather than pushing each cell individually.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param values Block of values to copy.
|
||||||
|
* @param size If not set, the number of elements copied from the array
|
||||||
|
* will be equal to the blocksize. If set higher than the
|
||||||
|
* blocksize, the operation will be truncated.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid handle or out of memory.
|
||||||
|
*/
|
||||||
|
native PushStackArray(Stack:handle, const any:values[], size= -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops a cell value from a stack.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param value Variable to store the value.
|
||||||
|
* @param block Optionally specify which block to read from
|
||||||
|
* (useful if the blocksize > 0).
|
||||||
|
* @param asChar Optionally read as a byte instead of a cell.
|
||||||
|
*
|
||||||
|
* @return True on success, false if the stack is empty.
|
||||||
|
* @error Invalid handle, Invalid block or Invalid byte.
|
||||||
|
*/
|
||||||
|
native bool:PopStackCell(Stack:handle, &any:value, block = 0, bool:asChar = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops a string value from a stack.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param buffer Buffer to store string.
|
||||||
|
* @param maxlength Maximum size of the buffer.
|
||||||
|
* @param written Number of characters copied.
|
||||||
|
*
|
||||||
|
* @return True on success, false if the stack is empty.
|
||||||
|
* @error Invalid handle.
|
||||||
|
*/
|
||||||
|
native bool:PopStackString(Stack:handle, buffer[], maxlength, &written = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops an array of cells from a stack.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
* @param buffer Buffer to store the array in.
|
||||||
|
* @param size If not set, assumes the buffer size is equal to the
|
||||||
|
* blocksize. Otherwise, the size passed is used.
|
||||||
|
*
|
||||||
|
* @return True on success, false if the stack is empty.
|
||||||
|
* @error Invalid handle.
|
||||||
|
*/
|
||||||
|
native bool:PopStackArray(Stack:handle, any:buffer[], size = -1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a stack is empty.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
*
|
||||||
|
* @return True if empty, false if not empty.
|
||||||
|
* @error Invalid handle.
|
||||||
|
*/
|
||||||
|
native bool:IsStackEmpty(Stack:handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops a value off a stack, ignoring it completely.
|
||||||
|
*
|
||||||
|
* @param handle Stack handle.
|
||||||
|
*
|
||||||
|
* @return True if something was popped, false otherwise.
|
||||||
|
* @error Invalid handle.
|
||||||
|
*/
|
||||||
|
stock PopStack(Stack:handle)
|
||||||
|
{
|
||||||
|
new value;
|
||||||
|
return PopStackCell(handle, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the stack, and resets the handle to 0 to prevent accidental usage after it is destroyed.
|
||||||
|
*
|
||||||
|
* @param which The stack to destroy.
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native DestroyStack(&Stack:handle);
|
73
plugins/testsuite/stacktest.sma
Normal file
73
plugins/testsuite/stacktest.sma
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include <amxmodx>
|
||||||
|
|
||||||
|
new FailCount;
|
||||||
|
new PassCount;
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("Stack Tests", AMXX_VERSION_STR, "AMXX Dev Team");
|
||||||
|
register_srvcmd("test_stack", "ServerCommand_TestStack");
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual(const testname[], bool:pass)
|
||||||
|
{
|
||||||
|
if (!pass)
|
||||||
|
{
|
||||||
|
server_print("[FAIL] %s", testname);
|
||||||
|
FailCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
server_print("[PASS] %s", testname);
|
||||||
|
PassCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done()
|
||||||
|
{
|
||||||
|
server_print("Finished. %d tests, %d failed", FailCount + PassCount, FailCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerCommand_TestStack()
|
||||||
|
{
|
||||||
|
new Stack:stack;
|
||||||
|
new test[20];
|
||||||
|
new buffer[42];
|
||||||
|
|
||||||
|
test[0] = 5;
|
||||||
|
test[1] = 7;
|
||||||
|
|
||||||
|
stack = CreateStack(30);
|
||||||
|
{
|
||||||
|
PushStackCell(stack, 50);
|
||||||
|
PushStackArray(stack, test, 2);
|
||||||
|
PushStackArray(stack, test, 2);
|
||||||
|
PushStackString(stack, "space craaab");
|
||||||
|
PushStackCell(stack, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEqual("Size test #1", IsStackEmpty(stack) == false);
|
||||||
|
|
||||||
|
PopStack(stack);
|
||||||
|
PopStackString(stack, buffer, charsmax(buffer));
|
||||||
|
assertEqual("String test", bool:equal(buffer, "space craaab"));
|
||||||
|
|
||||||
|
test[0] = 0;
|
||||||
|
test[1] = 0;
|
||||||
|
assertEqual("Array test #1", test[0] == 0 && test[1] == 0);
|
||||||
|
|
||||||
|
PopStackArray(stack, test, 2);
|
||||||
|
assertEqual("Array test #1", test[0] == 5 && test[1] == 7);
|
||||||
|
|
||||||
|
PopStackCell(stack, test[0], 1);
|
||||||
|
assertEqual("Value test #1", test[0] == 7);
|
||||||
|
|
||||||
|
PopStackCell(stack, test[0]);
|
||||||
|
assertEqual("Value test #2", test[0] == 50);
|
||||||
|
|
||||||
|
assertEqual("Size test #2", IsStackEmpty(stack) == true);
|
||||||
|
|
||||||
|
DestroyStack(stack);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
|
@ -233,6 +233,7 @@ scripting_files = [
|
||||||
'testsuite/sqlxtest.sql',
|
'testsuite/sqlxtest.sql',
|
||||||
'testsuite/trietest.sma',
|
'testsuite/trietest.sma',
|
||||||
'testsuite/utf8test.sma',
|
'testsuite/utf8test.sma',
|
||||||
|
'testsuite/stacktest.sma',
|
||||||
'include/amxconst.inc',
|
'include/amxconst.inc',
|
||||||
'include/amxmisc.inc',
|
'include/amxmisc.inc',
|
||||||
'include/amxmodx.inc',
|
'include/amxmodx.inc',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user