⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 script.cpp

📁 GNU ccScript is a C++ class framework for creating a virtual machine execution system for use with a
💻 CPP
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//  // 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.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however// invalidate any other reasons why the executable file might be covered by// the GNU General Public License.//// This exception applies only to the code released under the name GNU// ccScript.  If you copy code from other releases into a copy of GNU// ccScript, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU ccScript, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include "engine.h"#if defined(_MSC_VER) && _MSC_VER >= 1300#if defined(_WIN64_) || defined(__WIN64__)#define RLL_SUFFIX ".x64"#elif defined(_M_IX86)#define RLL_SUFFIX ".x86"#else#define RLL_SUFFIX ".xlo"#endif#endif#if defined(__MINGW32__) | defined(__CYGWIN32__)#define RLL_SUFFIX ".dso"#endif#ifdef  W32#ifndef RLL_SUFFIX#define RLL_SUFFIX ".rll"#endif#endif#ifndef RLL_SUFFIX#define RLL_SUFFIX ".dso"#endifusing namespace std;using namespace ost;bool Script::fastStart = true;unsigned Script::fastStepping = 32;unsigned Script::autoStepping = 1;bool Script::useBigmem = true;size_t Script::pagesize = 1024;unsigned Script::symsize = 64;unsigned Script::symlimit = 960;char Script::decimal = '.';bool Script::use_definitions = false;bool Script::use_macros = false;bool Script::use_prefix = false;bool Script::use_merge = false;bool Script::use_funcs = false;const char *Script::plugins = NULL;const char *Script::altplugins = NULL;const char *Script::etc_prefix = ".";const char *Script::var_prefix = ".";const char *Script::log_prefix = ".";const char *Script::access_user = NULL;const char *Script::access_pass = NULL;const char *Script::access_host = "localhost";#ifdef	WIN32const char *Script::apps_extensions = ".app.apps";const char *Script::exec_extensions = ".bat";#elseconst char *Script::apps_extensions = ".app.exec.apps";const char *Script::exec_extensions = ".sh";#endifconst char *Script::exec_token = "script:";const char *Script::exec_prefix = "exec:";const char *Script::exit_token = "exit";const char *Script::apps_prefix = "libexec";bool Script::exec_funcs = false;Script::Test *Script::test = NULL;Script::Fun *Script::ifun = NULL;Script::Package *Script::Package::first = NULL;class ScriptSysRegistry : public Script{public:	ScriptSysRegistry();};static class ScriptSysRegistry registry;#if     defined(CAPE_REGISTRY_PREFIX) #define REGISTRY_SCRIPT_SETTINGS CAPE_REGISTRY_PREFIX "\\Script Settings"#else#define REGISTRY_SCRIPT_SETTINGS "SOFTWARE\\CAPE Framework\\Script Settings"#endifScriptSysRegistry::ScriptSysRegistry() {#ifdef	WIN32        static TCHAR regpath[256];        LONG value;        HKEY key;        char *env;        Script::plugins = 		"C:/Program Files/Common Files/GNU Telephony/Script Plugins";#ifdef	DEBUG#define	PLUGINS "Debug"#else#define	PLUGINS "Plugins"#endif        if(RegOpenKey(HKEY_LOCAL_MACHINE, REGISTRY_SCRIPT_SETTINGS, &key) == ERROR_SUCCESS)        {			if(RegQueryValue(key, PLUGINS, regpath, &value) == ERROR_SUCCESS)			{                        Script::plugins = regpath;                        env = regpath;                        while(NULL != (env = strchr(env, '\\')))                                *env = '/';            }		if(RegQueryValue(key, "paging", NULL, &value) == ERROR_SUCCESS)		{			pagesize = value;			symlimit = value - sizeof(Symbol) - 32;		}		if(RegQueryValue(key, "symsize", NULL, &value) == ERROR_SUCCESS)			symsize = value;		if(RegQueryValue(key, "autostep", NULL, &value) == ERROR_SUCCESS)			autoStepping = value;        	if(RegQueryValue(key, "faststep", NULL, &value) == ERROR_SUCCESS)                         fastStepping = value;                RegCloseKey(key);        }#else	plugins = SCRIPT_LIBPATH;#endif}bool Script::isScript(Name *scr){	const char *ext = strrchr(scr->filename, '.');	if(!ext)		return false;	if(!stricmp(ext, ".scr"))		return true;	if(!stricmp(ext, ".mac"))		return true;	return false;}bool Script::isSymbol(const char *id){	if(*id == '%' || *id == '&' || *id == '@')		return true;	return false;}bool Script::isFunction(Name *scr){	switch(scr->access)	{	case scrFUNCTION:	case scrLOCAL:		return true;	default:		return false;	}}bool Script::isPrivate(Name *scr){	switch(scr->access)	{	case scrLOCAL:	case scrPRIVATE:		return true;	default:		return false;	}}unsigned Script::getIndex(const char *id){        unsigned int key = 0;        while(*id)                key ^= (key << 1) ^ (*(id++) & 0x1f);        return key % SCRIPT_INDEX_SIZE;}Script::Symbol *Script::deref(Symbol *sym){	while(sym && sym->type == symREF)		memcpy(&sym, sym->data, sizeof(sym));	return sym;}bool Script::symindex(Symbol *sym, short index){	Array *a;	if(!sym)		return false;	a = (Array *)&sym->data;	switch(sym->type)	{	case symFIFO:                if(index < 0)                        index = a->tail + index;                if(index < 0 || index > a->tail)                        return false;                a->head = index;		if(a->head == a->tail)			a->head = a->tail = 0;                return true;	case symSTACK:                if(index < 0)                        index = a->tail + index;                if(index < 0 || index > a->tail)                        return false;		a->tail = index;		return true;	case symARRAY:		if(index < 0)			index = a->tail + index;		if(index < 0 || index >= a->count)			return false;		a->head = index;		return true;	default:		return false;	}}void Script::clear(Symbol *sym){	unsigned dec;	unsigned pos = 1;	Array *a = (Array *)&sym->data;	ScriptProperty *p;	switch(sym->type)	{	case symARRAY:	case symSTACK:	case symFIFO:		a->head = a->tail = 0;		sym->data[sizeof(Array)] = 0;		return;			case symNUMBER:		dec = sym->size - 11;		if(dec)			++dec;		sym->data[0] = '0';		if(dec)		{			sym->data[pos++] = decimal;			while(pos < dec)				sym->data[pos++] = '0';		}		sym->data[pos] = 0;		return;	case symPROPERTY:		memcpy(&p, &sym->data, sizeof(p));		p->clear(sym->data + sizeof(p), sym->size - sizeof(p));		return;	case symMODIFIED:		sym->type = symORIGINAL;	case symORIGINAL:	case symLOCK:	case symNORMAL:		if(!stricmp(sym->id, "script.error"))			strcpy(sym->data, "none");		else			sym->data[0] = 0;		return;	case symSEQUENCE:		sym->data[sym->size] = 0;		return;	case symCOUNTER:		sym->data[0] = '0';		sym->data[1] = 0;		return;		case symTIMER:		sym->data[0] = 0;	default:		return;					}}unsigned Script::count(Symbol *sym){	Array *a = (Array *)&sym->data;	switch(sym->type)	{	case symCONST:	case symCOUNTER:	case symTIMER:	case symLOCK:		return 0;	case symARRAY:		return a->count;	case symSTACK:	case symFIFO:		return a->count - 1;	default:		return 1;	}}unsigned Script::storage(Symbol *sym){	Array *a = (Array *)&sym->data;	switch(sym->type)	{	case symARRAY:	case symSTACK:	case symFIFO:		return a->rec;	case symPROPERTY:		return sym->size - sizeof(ScriptProperty *);	case symORIGINAL:	case symMODIFIED:	case symINITIAL:	case symNORMAL:		return sym->size;			default:		return 0;	}}const char *Script::extract(Symbol *sym){        long value;        const char *data;        unsigned short pos, len;	Array *a;	time_t now;	if(!sym)		return NULL;	a = (Array *)&sym->data;	switch(sym->type)	{	case symLOCK:		data = strchr(sym->data, ':');		if(data)			return ++data;		return NULL;	case symPROPERTY:		return sym->data + sizeof(ScriptProperty *);	case symORIGINAL:	case symMODIFIED:	case symNORMAL:	case symCONST:	case symNUMBER:		return sym->data;	case symTIMER:		if(sym->data[0])		{			time(&now);			snprintf(sym->data + 12, 12, "%ld",  now - atol(sym->data));		}		else			setString(sym->data + 12, 12, "0");		return sym->data + 12;	case symCOUNTER:		value = atoi(sym->data);                snprintf(sym->data, sym->size + 1, "%ld", ++value);                return sym->data;        case symARRAY:		pos = a->head;		if(pos >= a->count || pos >= a->tail)			return "";				return sym->data + sizeof(Array) + pos * (a->rec + 1);        case symSTACK:		if(a->tail == a->head)		{			a->tail = a->head = 0;			return "";		}		pos = a->tail;		if(a->tail == 0)			a->tail = a->count - 1;		else			--a->tail;		return sym->data + sizeof(Array) + pos * (a->rec + 1);        case symSEQUENCE:		len = sym->size / sizeof(const char *);				pos = sym->data[sym->size];		memcpy(&data, &sym->data[pos * sizeof(data)], sizeof(data));		if(++pos >= len)			pos = 0;		sym->data[sym->size] = (unsigned char)pos;		return data;		        case symFIFO:		if(a->head == a->tail)			return "";					data = sym->data + a->head * (a->rec + 1) + sizeof(Array);		if(++a->head >= a->count)			a->head = 0;		return data;	default:		return NULL;	}}bool Script::append(Symbol *sym, const char *value){	switch(sym->type)	{	case symNUMBER:	case symPROPERTY:	case symCOUNTER:	case symTIMER:		return false;	case symORIGINAL:		sym->type = symMODIFIED;		sym->data[0] = 0;	case symMODIFIED:                addString(sym->data, sym->size + 1, value);		return true;	case symNORMAL:	case symINITIAL:		addString(sym->data, sym->size + 1, value);		sym->type = symNORMAL;		return true;	default:		return commit(sym, value);	}}bool Script::commit(Symbol *sym, const char *value){	Array *a;	long val;	unsigned short pos, npos, len;	int dec = 0;	char *dp;	const char *sp;	long v1, v2;	char vbuf[12];	ScriptProperty *p;	time_t now;	if(!sym)		return false;	a = (Array *)&sym->data;	switch(sym->type)	{	case symNUMBER:		v1 = atol(value);		sp = strchr(value, '.');		if(!sp)			sp = strchr(value, decimal);		if(sp)			v2 = atol(++sp);		else			v2 = 0;		dp = NULL;		if(sym->size > 11)		{			dec = sym->size - 12;			snprintf(vbuf, sizeof(vbuf), "%ld", v2);			len = (unsigned short)strlen(vbuf);			sp = vbuf;			if(len > dec && vbuf[dec] >= '5')			{				while(--dec > -1)				{					if(vbuf[dec] < '9')					{						++vbuf[dec];						break;					}					vbuf[dec] = '0';				}				if(dec < 0 && v1 < 0)					--v1;				else if(dec < 0)					++v1;			}				dec = sym->size - 12;			snprintf(sym->data, 12, "%ld", v1);                	len = (unsigned short)strlen(sym->data);			sym->data[len++] = decimal;			dp = sym->data + len;			while(dec--)				sym->data[len++] = '0';			sym->data[len] = 0;		}		else		{			if(sp && *sp >= '5')			{				if(v1 > 0)					++v1;				else					--v1;			}			snprintf(sym->data, sym->size + 1, "%ld", v1);		}		if(sp && dp)		{			len = (unsigned short)strlen(sp);			if(len > sym->size - 12)				len = sym->size - 12;			memcpy(dp, sp, len);		}		return true;				case symARRAY:		if(a->head >= a->count)			return false;		setString(sym->data + sizeof(Array) + a->head * (a->rec + 1), a->rec + 1, value);		if(++a->head > a->count)			a->head = a->count;		if(a->head > a->tail)			a->tail = a->head;		return true;	case symFIFO:	case symSTACK:		len = a->rec + 1;		pos = a->tail;		if(sym->type == symSTACK)			npos = ++pos;		else		{			npos = pos;			++npos;		}		if(npos >= a->count)			npos = 0;		if(npos == a->head)			return false;	// full		a->tail = npos;		setString(sym->data + sizeof(Array) + (pos * len), len,	value);		return true;	case symTIMER:		if(sym->data[0] == 0)		{			time(&now);			val = (long)now + atol(value);		}		else			val = atol(sym->data) + atol(value);		snprintf(sym->data, sym->size + 1, "%ld", val);		return true;	case symCOUNTER:		val = atoi(value);		snprintf(sym->data, sym->size + 1, "%ld", --val);		return true;	case symORIGINAL:		sym->type = symMODIFIED;	case symMODIFIED:		setString(sym->data, sym->size + 1, value);		return true;	case symNORMAL:	case symINITIAL:		setString(sym->data, sym->size + 1, value);		sym->type = symNORMAL;		return true;	case symPROPERTY:		memcpy(&p, &sym->data, sizeof(p));		p->set(value, sym->data + sizeof(p), sym->size - sizeof(p));		return true;	default:		return false;	}}bool Script::use(const char *name){	Package *pkg = Package::first;	char buffer[256];	const char *dpath = plugins;	const char *alt = altplugins;	const char *ns = name;retry:	if(strchr(name, '/'))		return false;#ifdef	WIN32	if(strchr(name, '\\'))		return false;	if(strchr(name, ':'))		return false;#endif	snprintf(buffer, sizeof(buffer), "%s/%s" RLL_SUFFIX, dpath, name);	name = buffer;	while(pkg)	{		if(!strcmp(pkg->filename, name))			return true;		pkg = pkg->next;	}	if(!canAccess(name))	{		if(alt)		{			dpath = alt;			alt = NULL;			name = ns;			goto retry;		}                slog.error() << "use: cannot find " << name << std::endl;                return false;        }	        pkg = new Package(name);	if(pkg->isValid())		return true;        slog.error() << "use: cannot load " << name << std::endl;        delete pkg;        return false;}Script::Package::Package(const char *name) :DSO(name){        filename = newString(name);        next = first;        first = this;}void Script::addFunction(const char *id, unsigned args, Script::Function handler){        Script::Fun *rf = new Script::Fun;        rf->id = id;        rf->args = args;        rf->fn = handler;        rf->next = ifun;        ifun = rf;}void Script::addConditional(const char *id, Script::Cond handler){        Script::Test *rt = new Script::Test;        rt->id = id;        rt->handler = handler;        rt->next = test;        test = rt;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -