* implemented DefScript "list" datatype.
* wiki information & documentation will come soon.
This commit is contained in:
parent
c2e83e27fb
commit
dff2d2085e
@ -89,6 +89,24 @@ void DefScriptPackage::_InitFunctions(void)
|
||||
AddFunc("lowercase",&DefScriptPackage::func_lowercase);
|
||||
AddFunc("random",&DefScriptPackage::func_random);
|
||||
AddFunc("fileexists",&DefScriptPackage::func_fileexists);
|
||||
|
||||
// list functions
|
||||
AddFunc("lpushback",&DefScriptPackage::func_lpushback);
|
||||
AddFunc("lappend",&DefScriptPackage::func_lpushback); // alias for lpushback
|
||||
AddFunc("lpushfront",&DefScriptPackage::func_lpushfront);
|
||||
AddFunc("lpopback",&DefScriptPackage::func_lpopback);
|
||||
AddFunc("lpopfront",&DefScriptPackage::func_lpopfront);
|
||||
AddFunc("ldelete",&DefScriptPackage::func_ldelete);
|
||||
AddFunc("lexists",&DefScriptPackage::func_lexists);
|
||||
AddFunc("llen",&DefScriptPackage::func_llen);
|
||||
AddFunc("linsert",&DefScriptPackage::func_linsert);
|
||||
AddFunc("lsplit",&DefScriptPackage::func_lsplit);
|
||||
AddFunc("lcsplit",&DefScriptPackage::func_lcsplit);
|
||||
AddFunc("ljoin",&DefScriptPackage::func_ljoin);
|
||||
AddFunc("lindex",&DefScriptPackage::func_lindex);
|
||||
AddFunc("lclean",&DefScriptPackage::func_lclean);
|
||||
AddFunc("lmclean",&DefScriptPackage::func_lmclean);
|
||||
AddFunc("lerase",&DefScriptPackage::func_lerase);
|
||||
}
|
||||
|
||||
void DefScriptPackage::AddFunc(std::string n,DefReturnResult (DefScriptPackage::*f)(CmdSet& Set))
|
||||
@ -386,12 +404,11 @@ CmdSet::~CmdSet()
|
||||
|
||||
void CmdSet::Clear()
|
||||
{
|
||||
for(unsigned int i=0;i<MAXARGS;i++){
|
||||
arg[i]="";
|
||||
}
|
||||
cmd="";
|
||||
arg.clear();
|
||||
cmd="";
|
||||
defaultarg="";
|
||||
caller="";
|
||||
myname="";
|
||||
}
|
||||
|
||||
|
||||
@ -696,27 +713,13 @@ std::string DefScriptPackage::RemoveBracketsFromString(std::string t){
|
||||
return t;
|
||||
}
|
||||
|
||||
void DefScriptPackage::RemoveBrackets(CmdSet& Set){
|
||||
std::string t;
|
||||
for(unsigned int a=0;a<MAXARGS+2;a++){
|
||||
if(a==0)
|
||||
t=Set.defaultarg;
|
||||
else if(a==1)
|
||||
t=Set.cmd;
|
||||
else
|
||||
t=Set.arg[a-2];
|
||||
|
||||
if(t.empty()) // skip empty args
|
||||
continue;
|
||||
|
||||
t=RemoveBracketsFromString(t);
|
||||
|
||||
if(a==0)
|
||||
Set.defaultarg=t;
|
||||
else if(a==1)
|
||||
Set.cmd=t;
|
||||
else
|
||||
Set.arg[a-2]=t;
|
||||
void DefScriptPackage::RemoveBrackets(CmdSet& Set)
|
||||
{
|
||||
Set.defaultarg=RemoveBracketsFromString(Set.defaultarg);
|
||||
Set.cmd=RemoveBracketsFromString(Set.cmd);
|
||||
for(_CmdSetArgMap::iterator i=Set.arg.begin(); i!=Set.arg.end(); i++)
|
||||
{
|
||||
i->second=RemoveBracketsFromString(i->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <deque>
|
||||
#include "VarSet.h"
|
||||
#include "DynamicEvent.h"
|
||||
#include "ListStorage.h"
|
||||
|
||||
#include "DefScriptDefines.h"
|
||||
|
||||
@ -24,6 +25,8 @@ struct DefReturnResult
|
||||
{
|
||||
DefReturnResult() { ok=true; mustreturn=false; ret="true"; }
|
||||
DefReturnResult(bool b) { ok=true; mustreturn=false; ret=b?"true":"false"; }
|
||||
DefReturnResult(std::string s) { ok=true; mustreturn=false; ret=s; }
|
||||
DefReturnResult(const char *s) { DefReturnResult(std::string(s)); }
|
||||
bool ok; // true if the execution of the current statement was successful
|
||||
bool mustreturn;
|
||||
std::string ret; // return value used by ?{..}
|
||||
@ -39,7 +42,9 @@ struct DefXChgResult
|
||||
bool changed;
|
||||
std::string str;
|
||||
DefReturnResult result;
|
||||
};
|
||||
};
|
||||
|
||||
typedef std::map<unsigned int,std::string> _CmdSetArgMap;
|
||||
|
||||
class CmdSet {
|
||||
public:
|
||||
@ -47,7 +52,7 @@ class CmdSet {
|
||||
~CmdSet();
|
||||
void Clear();
|
||||
std::string cmd;
|
||||
std::string arg[MAXARGS];
|
||||
_CmdSetArgMap arg;
|
||||
std::string defaultarg;
|
||||
std::string myname;
|
||||
std::string caller;
|
||||
@ -118,6 +123,7 @@ public:
|
||||
void AddFunc(std::string n,DefReturnResult (DefScriptPackage::*)(CmdSet& Set));
|
||||
bool HasFunc(std::string);
|
||||
void DelFunc(std::string);
|
||||
ListStorage lists;
|
||||
|
||||
|
||||
std::string scPath;
|
||||
@ -178,6 +184,24 @@ private:
|
||||
DefReturnResult func_lowercase(CmdSet&);
|
||||
DefReturnResult func_random(CmdSet&);
|
||||
DefReturnResult func_fileexists(CmdSet&);
|
||||
|
||||
// list functions
|
||||
DefReturnResult func_lpushback(CmdSet&);
|
||||
DefReturnResult func_lpushfront(CmdSet&);
|
||||
DefReturnResult func_lpopback(CmdSet&);
|
||||
DefReturnResult func_lpopfront(CmdSet&);
|
||||
DefReturnResult func_ldelete(CmdSet&);
|
||||
DefReturnResult func_lexists(CmdSet&);
|
||||
DefReturnResult func_llen(CmdSet&);
|
||||
DefReturnResult func_linsert(CmdSet&);
|
||||
DefReturnResult func_lsplit(CmdSet&);
|
||||
DefReturnResult func_lcsplit(CmdSet&);
|
||||
DefReturnResult func_ljoin(CmdSet&);
|
||||
DefReturnResult func_lindex(CmdSet&);
|
||||
DefReturnResult func_lclean(CmdSet&);
|
||||
DefReturnResult func_lmclean(CmdSet&);
|
||||
DefReturnResult func_lerase(CmdSet&);
|
||||
|
||||
// setup own function declarations here
|
||||
# include "DefScriptInterfaceInclude.h"
|
||||
|
||||
|
||||
@ -1,29 +1,28 @@
|
||||
#ifndef DEFSCRIPTDEFINES_H
|
||||
#define DEFSCRIPTDEFINES_H
|
||||
|
||||
#define MAXARGS 99
|
||||
#ifdef _DEBUG
|
||||
# define _DEFSC_DEBUG(code) code;
|
||||
#else
|
||||
# define _DEFSC_DEBUG(code)
|
||||
#endif
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#else
|
||||
typedef __int64_t int64;
|
||||
typedef __uint64_t uint64;
|
||||
// TODO: correct ATOI64 for linux if necessary
|
||||
#endif
|
||||
|
||||
enum VariableType
|
||||
{
|
||||
DEFSCRIPT_NONE=0,
|
||||
DEFSCRIPT_VAR,
|
||||
DEFSCRIPT_FUNC
|
||||
};
|
||||
|
||||
typedef long double ldbl;
|
||||
|
||||
#if COMPILER == COMPILER_MICROSOFT
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
#else
|
||||
typedef __int64_t int64;
|
||||
typedef __uint64_t uint64;
|
||||
// TODO: correct ATOI64 for linux if necessary
|
||||
#endif
|
||||
|
||||
enum VariableType
|
||||
{
|
||||
DEFSCRIPT_NONE=0,
|
||||
DEFSCRIPT_VAR,
|
||||
DEFSCRIPT_FUNC
|
||||
};
|
||||
|
||||
typedef long double ldbl;
|
||||
|
||||
#endif
|
||||
274
src/Client/DefScript/DefScriptListFunctions.cpp
Normal file
274
src/Client/DefScript/DefScriptListFunctions.cpp
Normal file
@ -0,0 +1,274 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include "DefScript.h"
|
||||
#include "DefScriptTools.h"
|
||||
|
||||
using namespace DefScriptTools;
|
||||
|
||||
DefReturnResult DefScriptPackage::func_lpushback(CmdSet& Set)
|
||||
{
|
||||
DefList *l = lists.Get(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
l->push_back(Set.defaultarg);
|
||||
return true;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::func_lpushfront(CmdSet& Set)
|
||||
{
|
||||
DefList *l = lists.Get(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
l->push_front(Set.defaultarg);
|
||||
return true;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::func_lpopback(CmdSet& Set)
|
||||
{
|
||||
std::string r;
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
if( (!l) || (!l->size()) ) // cant pop any element if the list doesnt exist or is empty
|
||||
return "";
|
||||
r= l->back();
|
||||
l->pop_back();
|
||||
return r;
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::func_lpopfront(CmdSet& Set)
|
||||
{
|
||||
std::string r;
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
if( (!l) || (!l->size()) ) // cant pop any element if the list doesnt exist or is empty
|
||||
return "";
|
||||
r = l->front();
|
||||
l->pop_front();
|
||||
return r;
|
||||
}
|
||||
|
||||
// delete a list and all its elements
|
||||
DefReturnResult DefScriptPackage::func_ldelete(CmdSet& Set)
|
||||
{
|
||||
lists.Delete(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if a list with the given name exists, else false
|
||||
DefReturnResult DefScriptPackage::func_lexists(CmdSet& Set)
|
||||
{
|
||||
return lists.Exists(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
}
|
||||
|
||||
// return list element count
|
||||
DefReturnResult DefScriptPackage::func_llen(CmdSet& Set)
|
||||
{
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.defaultarg,Set.myname));
|
||||
if(!l)
|
||||
return ""; // return nothing if list doesnt exist
|
||||
return toString((uint64)l->size()); // return any number
|
||||
}
|
||||
|
||||
// insert item at some position in the list
|
||||
DefReturnResult DefScriptPackage::func_linsert(CmdSet& Set)
|
||||
{
|
||||
bool result;
|
||||
DefList *l = lists.Get(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
unsigned int pos = (unsigned int)toNumber(Set.arg[1]);
|
||||
if(pos > l->size()) // if the list is too short to insert at that pos...
|
||||
{
|
||||
l->push_back(Set.defaultarg); // ... just append at the end
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DefList::iterator it = l->begin();
|
||||
advance(it,pos);
|
||||
l->insert(it,Set.defaultarg); // ... else insert at correct position
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// returns the amount of string fragments added to the list
|
||||
// arg0: list name; arg1: delimiter string; defaultarg: string to split
|
||||
DefReturnResult DefScriptPackage::func_lsplit(CmdSet& Set)
|
||||
{
|
||||
// 1st create a new list, or get an already existing one and clear it
|
||||
DefList *l = lists.Get(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
l->clear();
|
||||
if(Set.defaultarg.empty()) // we cant split an empty string, return nothing, and keep empty list
|
||||
return "";
|
||||
|
||||
// special case: empty delimiter -> split in chars
|
||||
if(Set.arg[1].empty())
|
||||
{
|
||||
for(unsigned int i=0; i<Set.defaultarg.length(); i++)
|
||||
{
|
||||
std::string tmp;
|
||||
tmp = Set.defaultarg[i];
|
||||
l->push_back(tmp);
|
||||
}
|
||||
return toString((uint64)l->size());
|
||||
}
|
||||
|
||||
unsigned int p,q=0; // p=position of substr; q=next pos to start searching at
|
||||
while( (p = Set.defaultarg.find(Set.arg[1].c_str(),q)) != std::string::npos)
|
||||
{
|
||||
l->push_back( Set.defaultarg.substr(q,p - q) );
|
||||
q = p + Set.arg[1].length();
|
||||
}
|
||||
if(q < Set.defaultarg.length()) // also append the last string fragment (that has no delimiter)
|
||||
{
|
||||
l->push_back(Set.defaultarg.c_str() + q);
|
||||
}
|
||||
return toString((uint64)l->size());
|
||||
}
|
||||
|
||||
// multi-split by chars
|
||||
// returns the amount of string fragments added to the list
|
||||
// arg0: list name; args: delimit; defaultarg: string to split
|
||||
DefReturnResult DefScriptPackage::func_lcsplit(CmdSet& Set)
|
||||
{
|
||||
// 1st create a new list, or get an already existing one and clear it
|
||||
DefList *l = lists.Get(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
l->clear();
|
||||
if(Set.defaultarg.empty()) // we cant split an empty string, return nothing, and keep empty list
|
||||
return "";
|
||||
|
||||
unsigned int p,q=0; // p=position of substr; q=next pos to start searching at
|
||||
while( (p = Set.defaultarg.find_first_of(Set.arg[1].c_str(),q)) != std::string::npos)
|
||||
{
|
||||
l->push_back( Set.defaultarg.substr(q,p - q) );
|
||||
q = p + 1;
|
||||
}
|
||||
if(q < Set.defaultarg.length()) // also append the last string fragment (that has no delimiter)
|
||||
{
|
||||
l->push_back(Set.defaultarg.c_str() + q);
|
||||
}
|
||||
return toString((uint64)l->size());
|
||||
}
|
||||
|
||||
// create a string from a list, using <defaultarg> as delimiter
|
||||
DefReturnResult DefScriptPackage::func_ljoin(CmdSet& Set)
|
||||
{
|
||||
std::string r;
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
if(!l)
|
||||
return "";
|
||||
for(unsigned int i = 0; i < l->size(); i++)
|
||||
{
|
||||
r += (*l)[i];
|
||||
if( i+1 != l->size() )
|
||||
r += Set.defaultarg;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// return list item at position xx
|
||||
DefReturnResult DefScriptPackage::func_lindex(CmdSet& Set)
|
||||
{
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
if(!l)
|
||||
return "";
|
||||
unsigned int pos = (unsigned int)toNumber(Set.defaultarg);
|
||||
if(pos+1 > l->size()) // ot of bounds?
|
||||
return "";
|
||||
return (*l)[pos];
|
||||
}
|
||||
|
||||
// clean list: remove every element that matches @def
|
||||
// use this function only to remove empty straings from a list
|
||||
DefReturnResult DefScriptPackage::func_lclean(CmdSet& Set)
|
||||
{
|
||||
unsigned int r=0;
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
if(!l)
|
||||
return "";
|
||||
for(DefList::iterator i=l->begin(); i!=l->end(); i++)
|
||||
{
|
||||
if(*i == Set.defaultarg)
|
||||
{
|
||||
l->erase(i);
|
||||
r++;
|
||||
}
|
||||
}
|
||||
return toString((uint64)r);
|
||||
}
|
||||
|
||||
// multi-clean list: remove every element that matches any of the args, if it isn't empty
|
||||
// NOTE: arg0 = list name, this one is skipped!
|
||||
// this func does NOT remove empty strings from a list, use lclean instead!!
|
||||
DefReturnResult DefScriptPackage::func_lmclean(CmdSet& Set)
|
||||
{
|
||||
unsigned int r=0;
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
if(!l)
|
||||
return "";
|
||||
|
||||
_CmdSetArgMap::iterator it=Set.arg.begin();
|
||||
advance(it,1); // skip list name
|
||||
|
||||
for( ; it != Set.arg.end(); it++)
|
||||
{
|
||||
if(it->second.length())
|
||||
{
|
||||
for(DefList::iterator i=l->begin(); i!=l->end(); i++)
|
||||
{
|
||||
if(*i == it->second)
|
||||
{
|
||||
l->erase(i);
|
||||
r++;
|
||||
if(i==l->end()) // must be checked here, else causing crash (?!)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// erase defaultarg if given
|
||||
if(Set.defaultarg.length())
|
||||
{
|
||||
for(DefList::iterator i=l->begin(); i!=l->end(); i++)
|
||||
{
|
||||
if(*i == Set.defaultarg)
|
||||
{
|
||||
l->erase(i);
|
||||
r++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return toString((uint64)r);
|
||||
}
|
||||
|
||||
DefReturnResult DefScriptPackage::func_lerase(CmdSet& Set)
|
||||
{
|
||||
DefList *l = lists.GetNoCreate(_NormalizeVarName(Set.arg[0],Set.myname));
|
||||
if(!l)
|
||||
return "";
|
||||
std::string r;
|
||||
unsigned int pos = (unsigned int)toNumber(Set.defaultarg);
|
||||
if(pos > l->size()) // if the list is too short to erase at that pos...
|
||||
return ""; // ... return nothing
|
||||
|
||||
DefList::iterator it = l->begin();
|
||||
advance(it,pos);
|
||||
r = *it;
|
||||
l->erase(it); // ... else erase at correct position
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//DefReturnResult DefScriptPackage::func_lmerge(CmdSet& Set)
|
||||
//{
|
||||
|
||||
// to be continued...
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
45
src/Client/DefScript/ListStorage.cpp
Normal file
45
src/Client/DefScript/ListStorage.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include "ListStorage.h"
|
||||
|
||||
bool ListStorage::Exists(std::string s)
|
||||
{
|
||||
for(DefListMap::iterator it = _storage.begin(); it != _storage.end(); it++)
|
||||
{
|
||||
if(it->first == s)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DefList *ListStorage::_Create(std::string s)
|
||||
{
|
||||
DefList *l = new DefList();
|
||||
_storage[s] = l;
|
||||
return l;
|
||||
}
|
||||
|
||||
void ListStorage::Delete(std::string s)
|
||||
{
|
||||
for(DefListMap::iterator it = _storage.begin(); it != _storage.end(); it++)
|
||||
{
|
||||
if(it->first == s)
|
||||
{
|
||||
delete it->second;
|
||||
_storage.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefList *ListStorage::GetNoCreate(std::string s)
|
||||
{
|
||||
for(DefListMap::iterator it = _storage.begin(); it != _storage.end(); it++)
|
||||
if(it->first == s)
|
||||
return it->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DefList *ListStorage::Get(std::string s)
|
||||
{
|
||||
DefList *l = GetNoCreate(s);
|
||||
return l ? l : _Create(s);
|
||||
}
|
||||
25
src/Client/DefScript/ListStorage.h
Normal file
25
src/Client/DefScript/ListStorage.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef DEFSCRIPT_LISTSTORAGE_H
|
||||
#define DEFSCRIPT_LISTSTORAGE_H
|
||||
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
typedef std::deque<std::string> DefList;
|
||||
typedef std::map<std::string,DefList*> DefListMap;
|
||||
|
||||
class ListStorage
|
||||
{
|
||||
public:
|
||||
bool Exists(std::string);
|
||||
void Delete(std::string);
|
||||
DefList *Get(std::string);
|
||||
DefList *GetNoCreate(std::string);
|
||||
inline void Assign(std::string s,DefList *l) { _storage[s] = l; }
|
||||
|
||||
private:
|
||||
DefList *_Create(std::string);
|
||||
DefListMap _storage;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -246,6 +246,9 @@
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\DefScriptFunctions.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\DefScriptListFunctions.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\DefScriptTools.cpp">
|
||||
</File>
|
||||
@ -258,6 +261,12 @@
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\DynamicEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\ListStorage.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\ListStorage.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\DefScript\VarSet.cpp">
|
||||
</File>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user