// --------------------------------------------------------------------
// S c r i p t . c p p
//
// Layer for FICL.
// --------------------------------------------------------------------
// Copyright (c) 1998-2000 by Fyodor Ustinov
// FIDONet 2:5020/79
//
// All rights reserved.
// --------------------------------------------------------------------
//
// If you want to compile FTrack without script subsystem
//
// Check points 60*
#include "ficl.h"
#include "script.hpp"
#include "constant.hpp"
#include "vars.hpp"
#include "configure.hpp"
static cMSG *m = NULL;
void stackPushCStr(char *c) {
if (c == NULL) {
stackPushPtr(pVM->pStack,NULL);
stackPushUNS(pVM->pStack,0);
} else {
stackPushPtr(pVM->pStack,c);
stackPushUNS(pVM->pStack,strlen(c));
}
}
// --------------------------------------------------------------------
// Work with MSG
// --------------------------------------------------------------------
void CheckM(void) {
if (m == NULL) {
Log.Level(LOGE) << "Attempt of use of words like MSG.* in script before scandir." << EOL;
exit(-1);
}
}
static void fMsgFromAddr(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Point());
stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Node());
stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Net());
stackPushUNS(pVM->pStack, (UNS32)m->_FromAddr.Zone());
return;
}
static void fMsgFromAddrA(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack, (UNS32)&m->_FromAddr);
return;
}
static void fMsgToAddr(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Point());
stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Node());
stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Net());
stackPushUNS(pVM->pStack, (UNS32)m->_ToAddr.Zone());
return;
}
static void fMsgToAddrA(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack, (UNS32)&m->_ToAddr);
return;
}
static void fMsgFromName(FICL_VM *pVM) {
CheckM();
stackPushPtr(pVM->pStack,m->_FromName);
stackPushUNS(pVM->pStack,strlen(m->_FromName));
return;
}
static void fMsgToName(FICL_VM *pVM) {
CheckM();
stackPushPtr(pVM->pStack,m->_ToName);
stackPushUNS(pVM->pStack,strlen(m->_ToName));
return;
}
static void fMsgSubject(FICL_VM *pVM) {
CheckM();
stackPushPtr(pVM->pStack,m->_Subject);
stackPushUNS(pVM->pStack,strlen(m->_Subject));
return;
}
static void fMsgBody(FICL_VM *pVM) {
CheckM();
stackPushPtr(pVM->pStack,m->_Body);
stackPushUNS(pVM->pStack,strlen(m->_Body));
return;
}
static void fMsgLines(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack,m->Lines());
return;
}
static void fMsgBytes(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack,m->Bytes());
return;
}
static void fMsgKludgeBody(FICL_VM *pVM) {
IndBiList<Kludge>::ElemPtr Klu;
int KluNumber;
CheckM();
KluNumber = stackPopINT(pVM->pStack);
Klu = m->_Klu.GetFirst();
while (Klu != NULL && KluNumber != 0) {
Klu++;
KluNumber--;
}
if (Klu == NULL) {
stackPushPtr(pVM->pStack,NULL);
stackPushUNS(pVM->pStack,0);
} else {
stackPushCStr(Klu->Body());
}
return;
}
static void fMsgKludgeName(FICL_VM *pVM) {
IndBiList<Kludge>::ElemPtr Klu;
int KluNumber;
CheckM();
KluNumber = stackPopINT(pVM->pStack);
Klu = m->_Klu.GetFirst();
while (Klu != NULL && KluNumber != 0) {
Klu++;
KluNumber--;
}
if (Klu == NULL) {
stackPushPtr(pVM->pStack,NULL);
stackPushUNS(pVM->pStack,0);
} else {
stackPushCStr(Klu->Name());
}
return;
}
static void fMsgKludgeDelete(FICL_VM *pVM) {
IndBiList<Kludge>::ElemPtr Klu;
int KluNumber;
CheckM();
KluNumber = stackPopINT(pVM->pStack);
Klu = m->_Klu.GetFirst();
while (Klu != NULL && KluNumber != 0) {
Klu++;
KluNumber--;
}
if (Klu == NULL) {
vmThrow(pVM,FTR_OUTOFRANGE);
} else {
m->_Klu.Remove(Klu);
}
return;
}
static void fMsgKludges(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack,m->_Klu.ElemCount());
return;
}
static void fMsgLoopCount(FICL_VM *pVM) {
FICL_UNS count = stackPopUNS(pVM->pStack);
char *cp = (char *)stackPopPtr(pVM->pStack);
char *tmt;
CheckM();
if (count == 0) {
stackPushUNS(pVM->pStack,0);
return;
}
tmt = (char *) malloc(count+1);
CheckMem(tmt);
strncpy(tmt,cp,count);
tmt[count] = '\0';
stackPushUNS(pVM->pStack,m->LoopCount(tmt));
free(tmt);
return;
}
static void fMsgAttachSize(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack,m->AttachSize());
return;
}
static void fMsgWrite(FICL_VM *pVM) {
CheckM();
stackPushUNS(pVM->pStack,m->AttachSize());
return;
}
int ScriptWordExists(char *word) {
FICL_WORD *WordExec;
WordExec = ficlLookup(word);
if (WordExec != NULL) return TRUE;
else return FALSE;
}
// --------------------------------------------------------------------
// Scandirs...
// --------------------------------------------------------------------
ScrRet DoThisWordRc(char *word) {
return DoThisWord(word);
}
ScrRet DoThisWord(char *word) {
FICL_WORD *WordExec;
int i;
if (LogLevel >= 5) {
Log.Level(LOGD) << "DoThisWord(\"" << word << "\");" << EOL;
}
WordExec = ficlLookup(word);
if (WordExec != NULL) {
if ((i = ficlExecXT(pVM,WordExec)) != VM_INNEREXIT) {
Log.Level(LOGE) << "Error execution word '" << word << "' rc == " << i << EOL;
return SS_ERROR;
} else {
return SS_OK;
}
} else {
return SS_ERROR;
}
}
void PrepareMsgForScript(cMSG &sm) {
m = &sm;
}
void buildAddonsToFICL(void)
{
ficlBuild("MSG.FromAddr", fMsgFromAddr, FW_DEFAULT);
ficlBuild("MSG.FromAddrA", fMsgFromAddrA, FW_DEFAULT);
ficlBuild("MSG.ToAddr", fMsgToAddr, FW_DEFAULT);
ficlBuild("MSG.ToAddrA", fMsgToAddrA, FW_DEFAULT);
ficlBuild("MSG.FromName", fMsgFromName, FW_DEFAULT);
ficlBuild("MSG.ToName", fMsgToName, FW_DEFAULT);
ficlBuild("MSG.Subject", fMsgSubject, FW_DEFAULT);
ficlBuild("MSG.Body", fMsgBody, FW_DEFAULT);
ficlBuild("MSG.Lines", fMsgLines, FW_DEFAULT);
ficlBuild("MSG.Bytes", fMsgBytes, FW_DEFAULT);
ficlBuild("MSG.Kludge.Name", fMsgKludgeName, FW_DEFAULT);
ficlBuild("MSG.Kludge.Body", fMsgKludgeBody, FW_DEFAULT);
ficlBuild("MSG.Kludge.Delete", fMsgKludgeDelete, FW_DEFAULT);
ficlBuild("MSG.Kludges", fMsgKludges, FW_DEFAULT);
ficlBuild("MSG.LoopCount", fMsgLoopCount, FW_DEFAULT);
ficlBuild("MSG.AttachSize", fMsgAttachSize, FW_DEFAULT);
ficlBuild("MSG.Write", fMsgWrite, FW_DEFAULT);
return;
}
int InitScriptSystem(void) {
ficlInitSystem(FICL_SIZE);
pVM = ficlNewVM();
buildAddonsToFICL();
return TRUE;
}
int StopScriptSystem(void) {
ficlTermSystem();
return TRUE;
}
int InitScriptValues(void) {
return TRUE;
}
ScrRet DoSomeWord(char *word) {
if (ScriptWordExists(word)) {
return DoThisWord(word);
}
return SS_NOTDEF;
}
ScrRet DoSomeWordRc(char *word) {
if (ScriptWordExists(word)) {
return DoThisWordRc(word);
}
return SS_NOTDEF;
}
int _LoadScriptFile(char *fname) {
char Buff[MAXCFGLINE];
FILE *fh;
int LineNum;
char *tmt;
LineNum = 0;
Log.Level(LOGI) << "Load script file: '" << fname << "'." << EOL;
fh = fopen(fname,"r");
if (fh == NULL) {
yyerror("Unable to open script file.");
return (-1);
}
while(fgets(Buff,MAXCFGLINE,fh)) {
LineNum++;
while ((tmt = strrchr(Buff,'\n')) != NULL) *tmt = '\0';
while ((tmt = strrchr(Buff,'\r')) != NULL) *tmt = '\0';
if (strlen(Buff) == 0) continue;
if (ficlExec(pVM, Buff) != VM_OUTOFTEXT) {
sprintf(Buff,"Unable parsing script in line %d",LineNum);
yyerror(Buff);
fclose(fh);
return (-1);
}
}
ficlExec(pVM, "");
fclose(fh);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1