📄 methods.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"using namespace std;using namespace ost;static long tens[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};bool ScriptMethods::scrNop(void){ skip(); return true;}bool ScriptMethods::scrIf(void) { if(conditional()) { if(frame[stack].index < frame[stack].line->argc) return intGoto(); skip(); if(frame[stack].line->scr.method == (Method)&ScriptMethods::scrThen) skip(); return true; } skip(); return true;}bool ScriptMethods::scrIfThen(void){ if(!conditional()) skip(); skip(); return true;}bool ScriptMethods::scrSlog(void){ const char *member = getMember(); const char *opt; if(member) { if(!stricmp(member, "debug")) slog(Slog::levelDebug); else if(!stricmp(member, "info")) slog(Slog::levelInfo); else if(!stricmp(member, "notice")) slog(Slog::levelNotice); else if(!strnicmp(member, "warn", 4)) slog(Slog::levelWarning); else if(!strnicmp(member, "err", 3)) slog(Slog::levelError); else if(!strnicmp(member, "crit", 4)) slog(Slog::levelCritical); else if(!stricmp(member, "alert")) slog(Slog::levelAlert); else if(!strnicmp(member, "emerg", 5)) slog(Slog::levelEmergency); else slog(Slog::levelNotice); } else slog(Slog::levelNotice); slog() << logname << ": "; while(NULL != (opt = getValue(NULL))) slog() << opt; slog() << endl; skip(); return true;}bool ScriptMethods::scrThen(void){ int level = 0; Line *line; skip(); while(NULL != (line = frame[stack].line)) { skip(); if(line->scr.method == (Method)&ScriptMethods::scrThen) ++level; else if(line->scr.method == (Method)&ScriptMethods::scrElse) { if(!level) return true; } else if(line->scr.method == (Method)&ScriptMethods::scrEndif) { if(!level) return true; --level; } } return true;}bool ScriptMethods::scrElse(void){ int level = 0; Line *line; skip(); while(NULL != (line = frame[stack].line)) { skip(); if(line->scr.method == (Method)&ScriptMethods::scrThen) ++level; else if(line->scr.method == (Method)&ScriptMethods::scrEndif) { if(!level) return true; } } return true;}bool ScriptMethods::scrEndif(void){ frame[stack].tranflag = false; skip(); return true;}bool ScriptMethods::scrInit(void){ const char *cp, *value; Line *line = getLine(); unsigned idx = 0; ScriptSymbols *syms; Symbol *sym; syms = getLocal(); while(idx < line->argc) { cp = line->args[idx++]; if(*cp != '=') continue; value = getContent(line->args[idx++]); syms = getLocal(); sym = syms->find(++cp, (unsigned short)strlen(value)); if(!sym) continue; if(sym->type != symINITIAL) continue; setString(sym->data, sym->size + 1, value); sym->type = symCONST; } skip(); return true;}static bool gotField(const char *cp, char pack, unsigned count, const char* match, unsigned len){ while(count-- && cp) { cp = strchr(cp, pack); if(cp && *cp == pack) ++cp; } if(!cp) cp = ","; if(strnicmp(cp, match, len)) return false; if(cp[len] == pack || !cp[len]) return true; return false;}bool ScriptMethods::scrRemove(void){ Symbol *sym; Array *a; ScriptProperty *p; const char *opt, *key; char buffer[1024]; char pack = getPackToken(); unsigned idx, ndx; char *cp, *dp; Line *line = getLine(); bool queue = false; unsigned offset = 0, len, count; opt = getKeyword("offset"); if(!opt) opt = getKeyword("field"); if(opt) offset = atoi(opt); opt = getKeyword("token"); if(opt && *opt) pack = *opt; if(!stricmp(line->cmd, "last") || !stricmp(line->cmd, "first")) queue = true; opt = getOption(NULL); sym = mapSymbol(opt); if(!sym) { error("symbol-missing"); return true; } buffer[0] = 0; while(NULL != (opt = getValue(NULL))) addString(buffer, sizeof(buffer), opt); key = opt = buffer; count = offset; while(key && count--) { key = strchr(key, pack); if(key && *key == pack) ++key; } if(!key) key = ","; count = 0; while(key[count] && key[count] != pack) ++count; a = (Array *)&sym->data; switch(sym->type) { case symFIFO: case symSTACK: if(a->head == a->tail) break; if(sym->type == symFIFO) { dp = sym->data + sizeof(Array) + a->head * (a->rec + 1); if(gotField(dp, pack, offset, key, count)) { ++a->head; if(a->head >= a->count) a->head = 0; break; } } if(sym->type == symSTACK) { dp = sym->data + sizeof(Array) + a->tail * (a->rec + 1); if(gotField(dp, pack, offset, key, count)) { if(!a->tail) a->tail = a->count; --a->tail; break; } } idx = a->head; if(sym->type == symSTACK) if(++idx >= a->count) idx = 0; for(;;) { if(++idx >= a->count) idx = 0; if(idx == a->tail) break; dp = sym->data + sizeof(Array) + idx * (a->rec + 1); if(gotField(dp, pack, offset, key, count)) break; } if(idx == a->tail) break; for(;;) { ndx = idx + 1; if(ndx >= a->count) ndx = 0; if(ndx == a->tail && sym->type == symFIFO) break; if(idx == a->tail && sym->type == symSTACK) break; strcpy(sym->data + sizeof(Array) + idx * (a->rec + 1),sym->data + sizeof(Array) + ndx * (a->rec + 1)); ++idx; if(idx >= a->count) break; } a->tail = idx; if(sym->type == symSTACK) { if(!a->tail) a->tail = a->count; --a->tail; } break; case symARRAY: if(queue) { error("invalid-queue-symbol"); break; } idx = 0; if(!a->tail) break; len = (unsigned)strlen(opt); while(idx < a->tail) { dp = sym->data + sizeof(Array) + idx * (a->rec + 1); if(gotField(dp, pack, offset, key, count)) break; ++idx; } if(a->head > idx) --a->head; while(idx < (unsigned)(a->tail - 1)) { strcpy(sym->data + sizeof(Array) + idx * (a->rec + 1), sym->data + sizeof(Array) + (idx + 1) * (a->rec + 1)); ++idx; } if(a->tail) --a->tail; break; case symPROPERTY: memcpy(&p, &sym->data, sizeof(p)); if(p->token()) pack = p->token(); case symNORMAL: case symNUMBER: if(queue) { error("invalid-queue-symbol"); break; } cp = (char *)extract(sym); len = (unsigned int)strlen(buffer); while(cp && *cp) { if(!strncmp(cp, opt, len)) if(cp[len] == pack || !cp[len]) break; cp = strchr(cp, pack); if(cp && *cp == pack) ++cp; } if(!cp || !*cp) break; while(cp[len]) { *cp = cp[len]; ++cp; } *cp = 0; break; default: error("symbol-invalid"); return true; } if(!stricmp(line->cmd, "last")) append(sym, opt); if(!stricmp(line->cmd, "first") && sym->type == symFIFO) { idx = a->head; if(!idx) idx = a->count; if(--idx != a->tail) { a->head = idx; snprintf(sym->data + sizeof(Array) + a->head * (a->rec + 1), a->rec + 1, "%s", opt); } } if(!stricmp(line->cmd, "first") && sym->type == symSTACK) { idx = a->tail; if(++idx >= a->count) idx = 0; if(idx != a->tail) { a->tail = idx; snprintf(sym->data + sizeof(Array)+ a->tail * (a->rec + 1), a->rec + 1, "%s", opt); } } skip(); return true;}bool ScriptMethods::scrArray(void){ unsigned short rec = symsize - 10; unsigned char count; const char *kw = getKeyword("count"); const char *mem = getMember(); Symbol *sym; Array *a; unsigned size; char *err = NULL; Line *line = getLine(); if(kw) count = atoi(kw); else count = atoi(mem); kw = getKeyword("size"); if(kw) rec = atoi(kw); if(!count || !rec) { error("symbol-no-size"); return true; } kw = line->cmd; if(!strnicmp(kw, "stack", 5) || !strnicmp(kw, "fifo", 4) || !strnicmp(kw, "lifo", 4)) ++count; size = (rec + 1) * count + sizeof(Array); while(NULL != (mem = getOption(NULL))) { sym = mapSymbol(mem, size); if(!sym) { err = "symbol-invalid"; continue; } if(sym->type != symINITIAL || sym->size != size) { err = "symbol-already-defined"; continue; } if(!strnicmp(kw, "array", 5)) sym->type = symARRAY; else if(!strnicmp(kw, "fifo", 4)) sym->type = symFIFO; else if(!strnicmp(kw, "stack", 5) || !strnicmp(kw, "lifo", 4)) sym->type = symSTACK; a = (Array *)&sym->data; a->head = a->tail = 0; a->rec = rec; a->count = count; } skip(); return true;}bool ScriptMethods::scrSet(void){ unsigned max = symlimit; char buffer[1024]; const char *id = getOption(NULL); const char *opt = getMember(); ScriptProperty *prop = ScriptProperty::find(opt); unsigned short size = symsize; Symbol *sym; Line *line = getLine(); bool cat = false; bool rtn; bool pset = false; unsigned ss = stack, len; int maxsize = 0, pos = 0; char *ep; if(opt && isdigit(*opt)) size = atoi(opt); opt = getKeyword("size"); if(opt) { maxsize = atoi(opt); size = atoi(opt); } opt = getKeyword("offset"); if(opt) pos = atoi(opt); if(maxsize < 0) { pos += maxsize; maxsize = -maxsize; size = -maxsize; } if(max > 1024) max = 1024; if(!id || (*id != '%' && *id != '@' && *id != '&')) { error("set-invalid-symbol"); return true; } buffer[0] = 0; while(NULL != (opt = getValue(NULL))) addString(buffer, max + 1, opt); if(!stricmp(line->cmd, "pset")) pset = true; opt = buffer; while(pset && stack) { --stack; if(frame[stack].local != frame[stack + 1].local) break; } sym = mapSymbol(id, size); stack = ss; if(!stricmp(line->cmd, "cat") || !stricmp(line->cmd, "add")) cat = true; else if(!strnicmp(line->cmd, "init", 4)) { if(sym && sym->type != symINITIAL && sym->type != symORIGINAL) { skip(); return true; } } if(!sym) { error("set-sym-missing"); return true; } if(sym->type == symINITIAL && prop) sym->type = symPROPERTY; else if(sym->type == symINITIAL) sym->type = symNORMAL; len = (unsigned)strlen(opt); if(pos < 0 && -pos > (int)len) pos = 0; else if(pos < 0) { opt = opt + len + pos; len = -pos; } else if(pos >= (int)len) len = 0; else { opt += pos; len -= pos; } if(!len) opt = ""; if(maxsize && (int)len > maxsize) { ep = (char *)opt + maxsize; *ep = 0; } if(cat) rtn = append(sym, opt); else rtn = commit(sym, opt); if(rtn) skip(); else error("set-type-invalid"); return true;}bool ScriptMethods::scrConst(void){ unsigned max = symlimit; char buffer[1024], pbuf[1024]; const char *id = getOption(NULL); const char *opt; ScriptProperty *prop = ScriptProperty::find(getMember()); if(max > 1024) max = 1024; if(!id || (*id != '%' && *id != '@' && *id != '&')) { error("const-invalid-symbol"); return true; } buffer[0] = 0; while(NULL != (opt = getValue(NULL))) addString(buffer, max + 1, opt); if(prop && !buffer[0]) { prop->clear(pbuf); opt = buffer; } else if(prop) { prop->set(pbuf, buffer, max); opt = pbuf; } else opt = buffer; if(setConst(id, opt)) skip(); else error("const-already-defined"); return true;}bool ScriptMethods::scrSequence(void){ Line *line = getLine(); const char *id = getOption(NULL); const char *opt; unsigned limit = line->argc; ScriptSymbols *syms; Symbol *sym; unsigned size = --limit * sizeof(opt); unsigned idx = 0; if(!id || (*id != '%' && *id != '@' && *id != '&')) { error("sequence-invalid-symbol"); return true; } syms = getSymbols(id); if(!syms) { error("sequence-symbol-invalid"); return true; } sym = syms->find(id, size); if(!sym) { error("sequence-symbol-invalid"); return true; } if(sym->type != symINITIAL || sym->size != size) { error("sequence-already-defined"); return true; } while(idx < limit) { opt = syms->cstring(getValue("")); memcpy(&sym->data[idx * sizeof(opt)], &opt, sizeof(opt)); ++idx; } sym->type = symSEQUENCE; sym->data[sym->size] = 0; skip(); return true;}bool ScriptMethods::scrDecimal(void){ frame[stack].decimal = atoi(getValue("0")); skip(); return true;}bool ScriptMethods::scrError(void){ char buffer[256]; const char *cp; buffer[0] = 0; while(NULL != (cp = getValue(NULL))) addString(buffer, sizeof(buffer), cp); error(buffer); return true;}bool ScriptMethods::scrExit(void){ while(stack) pull(); frame[stack].line = NULL; return true;}bool ScriptMethods::scrSignal(void){ const char *cp = getOption(NULL); if(!cp) { error("signal-target-missing"); return true; } if(*cp == '^') { if(!signal(++cp)) error("signal-trap-invalid"); return true; } error("signal-target-invalid"); return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -