* implemented DefScript "list" datatype.

* wiki information & documentation will come soon.
This commit is contained in:
False.Genesis 2007-06-09 17:54:13 +00:00
parent c2e83e27fb
commit dff2d2085e
7 changed files with 425 additions and 46 deletions

View File

@ -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);
}
}

View File

@ -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 ?{..}
@ -41,13 +44,15 @@ struct DefXChgResult
DefReturnResult result;
};
typedef std::map<unsigned int,std::string> _CmdSetArgMap;
class CmdSet {
public:
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"

View File

@ -1,7 +1,6 @@
#ifndef DEFSCRIPTDEFINES_H
#define DEFSCRIPTDEFINES_H
#define MAXARGS 99
#ifdef _DEBUG
# define _DEFSC_DEBUG(code) code;
#else

View 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...

View 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);
}

View 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

View File

@ -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>