- First implementation of Hdbqueue
- First implementation of new object model for SICS
This commit is contained in:
17
conman.c
17
conman.c
@ -68,7 +68,7 @@
|
|||||||
#include "commandlog.h"
|
#include "commandlog.h"
|
||||||
#include "stptok.h"
|
#include "stptok.h"
|
||||||
#include "sicshipadaba.h"
|
#include "sicshipadaba.h"
|
||||||
|
#include "protocol.h"
|
||||||
/*
|
/*
|
||||||
#define UUDEB 1
|
#define UUDEB 1
|
||||||
define UUDEB , for buffer writing for checking encoding */
|
define UUDEB , for buffer writing for checking encoding */
|
||||||
@ -79,7 +79,7 @@ extern pServer pServ;
|
|||||||
|
|
||||||
|
|
||||||
/*------ Max Size of Command Stack */
|
/*------ Max Size of Command Stack */
|
||||||
#define MAXSTACK 100
|
#define MAXSTACK 1024
|
||||||
/*---------- Magic ID Header */
|
/*---------- Magic ID Header */
|
||||||
#define CONMAGIC 26051958
|
#define CONMAGIC 26051958
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
@ -1149,8 +1149,9 @@ pDynString SCEndBuffering(SConnection *pCon)
|
|||||||
int SCWriteZipped(SConnection *self, char *pName, void *pData, int iDataLen)
|
int SCWriteZipped(SConnection *self, char *pName, void *pData, int iDataLen)
|
||||||
{
|
{
|
||||||
char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL;
|
char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL;
|
||||||
int compressedLength, iRet, iRet2, iCount;
|
int compressedLength, iRet, iRet2, iCount, protocolID;
|
||||||
z_stream compStream;
|
z_stream compStream;
|
||||||
|
commandContext cc;
|
||||||
|
|
||||||
/* check for a valid connection */
|
/* check for a valid connection */
|
||||||
if(!VerifyConnection(self))
|
if(!VerifyConnection(self))
|
||||||
@ -1225,7 +1226,15 @@ pDynString SCEndBuffering(SConnection *pCon)
|
|||||||
|
|
||||||
/* write header line */
|
/* write header line */
|
||||||
memset(outBuf,0,65536);
|
memset(outBuf,0,65536);
|
||||||
sprintf(outBuf,"SICSBIN ZIP %s %d\r\n",pName,compressedLength);
|
|
||||||
|
protocolID = GetProtocolID(self);
|
||||||
|
if(protocolID == 5){
|
||||||
|
cc = SCGetContext(self);
|
||||||
|
sprintf(outBuf,"SICSBIN ZIP %s %d %d\r\n",pName,
|
||||||
|
compressedLength, cc.transID);
|
||||||
|
} else {
|
||||||
|
sprintf(outBuf,"SICSBIN ZIP %s %d \r\n",pName,compressedLength);
|
||||||
|
}
|
||||||
pHeader = strdup(outBuf);
|
pHeader = strdup(outBuf);
|
||||||
if(pHeader == NULL)
|
if(pHeader == NULL)
|
||||||
{
|
{
|
||||||
|
5
danu.c
5
danu.c
@ -363,8 +363,9 @@ int NewThousand(pDataNumber self)
|
|||||||
|
|
||||||
if(SCMatchRights(pCon,usMugger))
|
if(SCMatchRights(pCon,usMugger))
|
||||||
{
|
{
|
||||||
DecrementDataNumber(self);
|
iNum = DecrementDataNumber(self);
|
||||||
SCWrite(pCon,"Data file killed",eWarning);
|
snprintf(pBueffel,511,"Data file %d killed", iNum);
|
||||||
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
3
exe.w
3
exe.w
@ -174,6 +174,9 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
|
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
|
||||||
char *name);
|
char *name);
|
||||||
pDynString findBatchFile(SicsInterp *pSics, char *name);
|
pDynString findBatchFile(SicsInterp *pSics, char *name);
|
||||||
|
int exeHdbBuffer(SConnection *pCon,
|
||||||
|
SicsInterp *pSics, char *name);
|
||||||
|
int exeHdbNode(pHdb exeNode, SConnection *pCon);
|
||||||
@}
|
@}
|
||||||
|
|
||||||
@o exeman.i -d @{
|
@o exeman.i -d @{
|
||||||
|
12
exebuf.c
12
exebuf.c
@ -166,13 +166,17 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
|
|||||||
self->lineno = 0;
|
self->lineno = 0;
|
||||||
pTcl = InterpGetTcl(pSics);
|
pTcl = InterpGetTcl(pSics);
|
||||||
|
|
||||||
InvokeCallBack(pCall,BATCHSTART,self->name);
|
if(pCall != NULL){
|
||||||
|
InvokeCallBack(pCall,BATCHSTART,self->name);
|
||||||
|
}
|
||||||
|
|
||||||
if (echo) {
|
if (echo) {
|
||||||
SCsetMacro(pCon,0);
|
SCsetMacro(pCon,0);
|
||||||
}
|
}
|
||||||
while((command = findBlockEnd(self)) != NULL){
|
while((command = findBlockEnd(self)) != NULL){
|
||||||
InvokeCallBack(pCall,BATCHAREA,NULL);
|
if(pCall != NULL){
|
||||||
|
InvokeCallBack(pCall,BATCHAREA,NULL);
|
||||||
|
}
|
||||||
cmd = GetCharArray(command);
|
cmd = GetCharArray(command);
|
||||||
|
|
||||||
if (echo) {
|
if (echo) {
|
||||||
@ -223,7 +227,9 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
|
|||||||
SCSetInterrupt(pCon,eContinue);
|
SCSetInterrupt(pCon,eContinue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InvokeCallBack(pCall,BATCHEND,self->name);
|
if(pCall != NULL){
|
||||||
|
InvokeCallBack(pCall,BATCHEND,self->name);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
4
exebuf.h
4
exebuf.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 210 "exe.w"
|
#line 213 "exe.w"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Buffer handling code for the Exe Buffer batch file processing
|
* Buffer handling code for the Exe Buffer batch file processing
|
||||||
@ -89,7 +89,7 @@
|
|||||||
*/
|
*/
|
||||||
char *exeBufName(pExeBuf self);
|
char *exeBufName(pExeBuf self);
|
||||||
|
|
||||||
#line 223 "exe.w"
|
#line 226 "exe.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
exebuf.i
4
exebuf.i
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 201 "exe.w"
|
#line 204 "exe.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
/*--------------------------------------------------------------------
|
||||||
Internal header file for the exe buffer module. Do not edit. This is
|
Internal header file for the exe buffer module. Do not edit. This is
|
||||||
@ -16,6 +16,6 @@ typedef struct __EXEBUF{
|
|||||||
int lineno;
|
int lineno;
|
||||||
} ExeBuf;
|
} ExeBuf;
|
||||||
|
|
||||||
#line 206 "exe.w"
|
#line 209 "exe.w"
|
||||||
|
|
||||||
|
|
||||||
|
73
exeman.c
73
exeman.c
@ -297,12 +297,12 @@ static int SCHdbWrite(SConnection *self, char *message, int outCode){
|
|||||||
}
|
}
|
||||||
if(v.v.text != NULL){
|
if(v.v.text != NULL){
|
||||||
DynStringConcat(val,v.v.text);
|
DynStringConcat(val,v.v.text);
|
||||||
if(strrchr(v.v.text,(int)'\n') == NULL && strlen(v.v.text) > 2){
|
if(strrchr(v.v.text,(int)'\n') == NULL && strlen(v.v.text) > 1){
|
||||||
DynStringConcatChar(val,'\n');
|
DynStringConcatChar(val,'\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynStringConcat(val,message);
|
DynStringConcat(val,message);
|
||||||
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 2){
|
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 1){
|
||||||
DynStringConcatChar(val,'\n');
|
DynStringConcatChar(val,'\n');
|
||||||
}
|
}
|
||||||
if(v.v.text != NULL){
|
if(v.v.text != NULL){
|
||||||
@ -314,6 +314,66 @@ static int SCHdbWrite(SConnection *self, char *message, int outCode){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
int exeHdbNode(pHdb exeNode, SConnection *pCon){
|
||||||
|
char pBueffel[512], *name = NULL;
|
||||||
|
pHdb node = NULL;
|
||||||
|
pExeBuf buffer = NULL;
|
||||||
|
hdbValue v;
|
||||||
|
int status;
|
||||||
|
commandContext cc;
|
||||||
|
writeFunc oldWrite;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clear log buffer
|
||||||
|
*/
|
||||||
|
node = GetHipadabaNode(exeNode,"log");
|
||||||
|
if(node == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v = MakeHdbText(strdup(""));
|
||||||
|
UpdateHipadabaPar(node,v,pCon);
|
||||||
|
/*
|
||||||
|
* prepare context
|
||||||
|
*/
|
||||||
|
name = GetHipadabaPath(node);
|
||||||
|
cc = SCGetContext(pCon);
|
||||||
|
strncpy(cc.deviceID, name,255);
|
||||||
|
strncpy(bufferNode,name,511);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load commands into buffer
|
||||||
|
*/
|
||||||
|
node = GetHipadabaNode(exeNode,"commands");
|
||||||
|
if(node == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: Hdb node not found or in wrong format",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetHipadabaPar(node,&v,pCon);
|
||||||
|
if(v.dataType != HIPTEXT || v.v.text == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: Hdb node is of wrong type or contains no data",eError);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = exeBufCreate(name);
|
||||||
|
if(!buffer){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating batch buffer",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
exeBufAppend(buffer,v.v.text);
|
||||||
|
|
||||||
|
strncpy(bufferNode,name,511);
|
||||||
|
oldWrite = SCGetWriteFunc(pCon);
|
||||||
|
SCSetWriteFunc(pCon,SCHdbWrite);
|
||||||
|
SCPushContext2(pCon,cc);
|
||||||
|
status = exeBufProcess(buffer,pServ->pSics,pCon,NULL,0);
|
||||||
|
SCSetWriteFunc(pCon,oldWrite);
|
||||||
|
SCPopContext(pCon);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
static int runHdbBuffer(pExeMan self, SConnection *pCon,
|
static int runHdbBuffer(pExeMan self, SConnection *pCon,
|
||||||
SicsInterp *pSics, char *name){
|
SicsInterp *pSics, char *name){
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
@ -381,6 +441,15 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
|
|||||||
SCPopContext(pCon);
|
SCPopContext(pCon);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
int exeHdbBuffer(SConnection *pCon,
|
||||||
|
SicsInterp *pSics, char *name){
|
||||||
|
pExeMan self = (pExeMan)FindCommandData(pSics,"exe","ExeManager");
|
||||||
|
if(self != NULL){
|
||||||
|
return runHdbBuffer(self,pCon,pSics,name);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
int runExeBatchBuffer(void *pData, SConnection *pCon,
|
int runExeBatchBuffer(void *pData, SConnection *pCon,
|
||||||
SicsInterp *pSics, char *name){
|
SicsInterp *pSics, char *name){
|
||||||
|
3
exeman.h
3
exeman.h
@ -16,5 +16,8 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
|
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
|
||||||
char *name);
|
char *name);
|
||||||
pDynString findBatchFile(SicsInterp *pSics, char *name);
|
pDynString findBatchFile(SicsInterp *pSics, char *name);
|
||||||
|
int exeHdbBuffer(SConnection *pCon,
|
||||||
|
SicsInterp *pSics, char *name);
|
||||||
|
int exeHdbNode(pHdb exeNode, SConnection *pCon);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
exeman.i
4
exeman.i
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 179 "exe.w"
|
#line 182 "exe.w"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------
|
/*-------------------------------------------------------------------
|
||||||
Internal header file for the exe manager module. Do not edit. This
|
Internal header file for the exe manager module. Do not edit. This
|
||||||
@ -20,5 +20,5 @@ typedef struct __EXEMAN{
|
|||||||
int echo;
|
int echo;
|
||||||
}ExeMan, *pExeMan;
|
}ExeMan, *pExeMan;
|
||||||
|
|
||||||
#line 184 "exe.w"
|
#line 187 "exe.w"
|
||||||
|
|
||||||
|
12
fomerge.c
12
fomerge.c
@ -647,22 +647,12 @@ static int putElastic(SicsInterp *pSics, SConnection *pCon,
|
|||||||
}
|
}
|
||||||
status = CalculateFitFromData(fitter,(float *)fTimeBin,lSum,iTime);
|
status = CalculateFitFromData(fitter,(float *)fTimeBin,lSum,iTime);
|
||||||
free(lSum);
|
free(lSum);
|
||||||
if(status != 1)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"WARNING: problem locating elastic peak",eWarning);
|
|
||||||
}
|
|
||||||
GetFitResults(fitter,&fCenter,&fStdDev,&fFWHM,&fVal);
|
GetFitResults(fitter,&fCenter,&fStdDev,&fFWHM,&fVal);
|
||||||
fVal = fCenter - fElastic;
|
fVal = fCenter - fElastic;
|
||||||
if(fVal < 0.)
|
if(fVal < 0.)
|
||||||
fVal = - fVal;
|
fVal = - fVal;
|
||||||
/* bad value, leave at theoretical value */
|
/* bad value, leave at theoretical value */
|
||||||
if(fVal > 10.)
|
if(fVal < 10.)
|
||||||
{
|
|
||||||
SCWrite(pCon,
|
|
||||||
"WARNING: bad fit result, using theoretical elastic peak position",
|
|
||||||
eWarning);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
fElastic = fCenter;
|
fElastic = fCenter;
|
||||||
}
|
}
|
||||||
|
412
hdbqueue.c
Normal file
412
hdbqueue.c
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
/**
|
||||||
|
* This is the new Hipadaba based queuing system in support of the MountainGum
|
||||||
|
* user interface.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, July 2007
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include "sicsobj.h"
|
||||||
|
#include "hdbqueue.h"
|
||||||
|
#include "sicshipadaba.h"
|
||||||
|
#include "dynstring.h"
|
||||||
|
#include "exeman.h"
|
||||||
|
#include "macro.h"
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
int iStop;
|
||||||
|
SConnection *pCon;
|
||||||
|
}HdbQueue, *pHdbQueue;
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static pHdbCallback CopyCallbackChain(pHdbCallback source){
|
||||||
|
pHdbCallback current = NULL;
|
||||||
|
pHdbCallback result = NULL;
|
||||||
|
pHdbCallback head = NULL;
|
||||||
|
pHdbCallback tail = NULL;
|
||||||
|
|
||||||
|
current = source;
|
||||||
|
while(current != NULL){
|
||||||
|
result = MakeHipadabaCallback(current->userCallback,
|
||||||
|
current->userData,
|
||||||
|
NULL,
|
||||||
|
current->id,
|
||||||
|
current->internalID);
|
||||||
|
if(head == NULL){
|
||||||
|
head = result;
|
||||||
|
tail = result;
|
||||||
|
} else {
|
||||||
|
tail->next = result;
|
||||||
|
result->previous = tail;
|
||||||
|
tail = result;
|
||||||
|
}
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static pHdb MakeNewEntry(char *name, pHdbCallback update){
|
||||||
|
pHdb entry = NULL, child = NULL;
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
v = MakeHdbText("Undefined");
|
||||||
|
entry = MakeHipadabaNode(name,HIPNONE, 1);
|
||||||
|
entry->updateCallbacks = CopyCallbackChain(update);
|
||||||
|
child = MakeSICSHdbPar("description",usUser,v);
|
||||||
|
child->updateCallbacks = CopyCallbackChain(update);
|
||||||
|
AddHipadabaChild(entry,child,NULL);
|
||||||
|
child = MakeSICSHdbPar("commands",usUser,v);
|
||||||
|
child->updateCallbacks = CopyCallbackChain(update);
|
||||||
|
AddHipadabaChild(entry,child,NULL);
|
||||||
|
child = MakeSICSHdbPar("log",usUser,v);
|
||||||
|
child->updateCallbacks = CopyCallbackChain(update);
|
||||||
|
AddHipadabaChild(entry,child,NULL);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int EnqueFunc(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdb entry = NULL;
|
||||||
|
pHdb work = NULL;
|
||||||
|
char name[80];
|
||||||
|
hdbValue v;
|
||||||
|
|
||||||
|
if(nPar < 1){
|
||||||
|
SCWrite(pCon,"ERROR: internal: not enough parameters to EnqueFunc",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* new entry
|
||||||
|
*/
|
||||||
|
memset(&v,0,sizeof(hdbValue));
|
||||||
|
work = GetHipadabaNode(self->objectNode,"control/maxEntry");
|
||||||
|
assert(work != NULL);
|
||||||
|
snprintf(name,80,"%3.3d", work->value.v.intValue);
|
||||||
|
entry = MakeNewEntry(name, work->updateCallbacks);
|
||||||
|
if(entry == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory in EnqueFunc",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Update maxEntry
|
||||||
|
*/
|
||||||
|
cloneHdbValue(&work->value,&v);
|
||||||
|
v.v.intValue++;
|
||||||
|
UpdateHipadabaPar(work,v,pCon);
|
||||||
|
|
||||||
|
work = GetHipadabaNode(self->objectNode,"queue");
|
||||||
|
assert(work != NULL);
|
||||||
|
AddHipadabaChild(work, entry, pCon);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save description
|
||||||
|
*/
|
||||||
|
work = GetHipadabaNode(entry,"description");
|
||||||
|
assert(work != NULL);
|
||||||
|
UpdateHipadabaPar(work,par[0]->value,pCon);
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int AddCmdData(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdb work = NULL;
|
||||||
|
pHdb commandNode = NULL;
|
||||||
|
char name[80];
|
||||||
|
pDynString txt = NULL;
|
||||||
|
|
||||||
|
if(nPar < 1){
|
||||||
|
SCWrite(pCon,"ERROR: internal: not enough parameters to AddCmdData",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = GetHipadabaNode(self->objectNode,"control/maxEntry");
|
||||||
|
assert(work != NULL);
|
||||||
|
snprintf(name,80,"queue/%3.3d/commands", work->value.v.intValue-1);
|
||||||
|
commandNode = GetHipadabaNode(self->objectNode,name);
|
||||||
|
if(commandNode == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: Internal error in AddCommand",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
txt = CreateDynString(80,80);
|
||||||
|
if(strstr(commandNode->value.v.text,"Undefined") == NULL){
|
||||||
|
DynStringCopy(txt,commandNode->value.v.text);
|
||||||
|
}
|
||||||
|
DynStringConcat(txt,par[0]->value.v.text);
|
||||||
|
DynStringConcat(txt,"\n");
|
||||||
|
free(commandNode->value.v.text);
|
||||||
|
commandNode->value.v.text = strdup(GetCharArray(txt));
|
||||||
|
NotifyHipadabaPar(commandNode,pCon);
|
||||||
|
DeleteDynString(txt);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void sequentialNames(pHdb obj,SConnection *pCon){
|
||||||
|
pHdb work = NULL;
|
||||||
|
pHdb current = NULL;
|
||||||
|
int count = 0;
|
||||||
|
char name[80];
|
||||||
|
|
||||||
|
work = GetHipadabaNode(obj,"queue");
|
||||||
|
assert(work != NULL);
|
||||||
|
current = work->child;
|
||||||
|
while(current != NULL){
|
||||||
|
snprintf(name,80,"%3.3d",count);
|
||||||
|
if(current != NULL && current->name != NULL){
|
||||||
|
free(current->name);
|
||||||
|
}
|
||||||
|
current->name = strdup(name);
|
||||||
|
count++;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
InvokeCallbackChain(work->treeChangeCallbacks,work,pCon,work->value);
|
||||||
|
|
||||||
|
work = GetHipadabaNode(obj,"control/maxEntry");
|
||||||
|
assert(work != NULL);
|
||||||
|
work->value.v.intValue = count;
|
||||||
|
NotifyHipadabaPar(work,pCon);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int Dequeue(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdb work = NULL;
|
||||||
|
char name[80];
|
||||||
|
|
||||||
|
if(nPar < 1){
|
||||||
|
SCWrite(pCon,"ERROR: internal: not enough parameters to Dequeue",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(name,80,"queue/%3.3d", par[0]->value.v.intValue);
|
||||||
|
work = GetHipadabaNode(self->objectNode,name);
|
||||||
|
if(work != NULL){
|
||||||
|
DeleteHipadabaNode(work,pCon);
|
||||||
|
sequentialNames(self->objectNode, pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int Clean(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
int i;
|
||||||
|
pHdb current = NULL, queue = NULL;
|
||||||
|
pHdb currentEntry = NULL, tmp;
|
||||||
|
|
||||||
|
currentEntry = GetHipadabaNode(self->objectNode,"control/currentEntry");
|
||||||
|
queue = GetHipadabaNode(self->objectNode,"queue");
|
||||||
|
current = queue->child;
|
||||||
|
for(i = 0; i < currentEntry->value.v.intValue; i++){
|
||||||
|
if(current != NULL){
|
||||||
|
tmp = current->next;
|
||||||
|
DeleteNodeData(current);
|
||||||
|
current = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queue->child = tmp;
|
||||||
|
currentEntry->value.v.intValue = 0;
|
||||||
|
sequentialNames(self->objectNode, pCon);
|
||||||
|
NotifyHipadabaPar(currentEntry,pCon);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int QueueTask(void *pData){
|
||||||
|
pSICSOBJ self = (pSICSOBJ)pData;
|
||||||
|
int status, pos;
|
||||||
|
pHdb work = NULL;
|
||||||
|
pHdb exeNode = NULL;
|
||||||
|
pHdb max = NULL;
|
||||||
|
char name[80];
|
||||||
|
pHdbQueue priv = (pHdbQueue)self->pPrivate;
|
||||||
|
|
||||||
|
if(priv->iStop == 1){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
work = GetHipadabaNode(self->objectNode,"control/currentEntry");
|
||||||
|
max = GetHipadabaNode(self->objectNode,"control/maxEntry");
|
||||||
|
assert(work != NULL && max != NULL);
|
||||||
|
pos = work->value.v.intValue;
|
||||||
|
snprintf(name,80,"queue/%3.3d", pos);
|
||||||
|
|
||||||
|
exeNode = GetHipadabaNode(self->objectNode,name);
|
||||||
|
if(exeNode != NULL){
|
||||||
|
MacroPush(priv->pCon);
|
||||||
|
exeHdbNode(exeNode, priv->pCon);
|
||||||
|
MacroPop();
|
||||||
|
}
|
||||||
|
if(priv->iStop == 1 || SCGetInterrupt(priv->pCon) != eContinue){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
work->value.v.intValue = pos;
|
||||||
|
NotifyHipadabaPar(work,priv->pCon);
|
||||||
|
if(pos >= max->value.v.intValue){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int Start(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdbQueue priv = (pHdbQueue)self->pPrivate;
|
||||||
|
|
||||||
|
priv->iStop = 0;
|
||||||
|
priv->pCon = pCon;
|
||||||
|
|
||||||
|
TaskRegister(pServ->pTasker,
|
||||||
|
QueueTask,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
self,
|
||||||
|
10);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int Stop(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdbQueue priv = (pHdbQueue)self->pPrivate;
|
||||||
|
|
||||||
|
priv->iStop = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int Move(pSICSOBJ self, SConnection *pCon, pHdb par[], int nPar){
|
||||||
|
pHdb moveNode = NULL;
|
||||||
|
pHdb insertNode = NULL;
|
||||||
|
pHdb prevNode = NULL, queueNode = NULL;
|
||||||
|
pHdb tmp;
|
||||||
|
char name[80];
|
||||||
|
|
||||||
|
if(nPar < 2){
|
||||||
|
SCWrite(pCon,"ERROR: internal: not enough parameters to Move",eError);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(par[1]->value.v.intValue == par[0]->value.v.intValue + 1){
|
||||||
|
/*
|
||||||
|
* already in right sequence, nothing to do
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(name,80,"queue/%3.3d", par[1]->value.v.intValue);
|
||||||
|
moveNode = GetHipadabaNode(self->objectNode,name);
|
||||||
|
|
||||||
|
snprintf(name,80,"queue/%3.3d", par[0]->value.v.intValue);
|
||||||
|
insertNode = GetHipadabaNode(self->objectNode,name);
|
||||||
|
if(moveNode == NULL || insertNode == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: move not possible, participating nodes not found",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
queueNode = GetHipadabaNode(self->objectNode,"queue");
|
||||||
|
|
||||||
|
if(moveNode == queueNode->child){
|
||||||
|
queueNode->child = queueNode->child->next;
|
||||||
|
moveNode->next = insertNode->next;
|
||||||
|
insertNode->next = moveNode;
|
||||||
|
} else {
|
||||||
|
prevNode = queueNode->child;
|
||||||
|
while(prevNode != NULL && prevNode->next != moveNode){
|
||||||
|
prevNode = prevNode->next;
|
||||||
|
}
|
||||||
|
if(insertNode == queueNode->child ){
|
||||||
|
/*
|
||||||
|
* insert at top
|
||||||
|
*/
|
||||||
|
tmp = queueNode->child;
|
||||||
|
queueNode->child = moveNode;
|
||||||
|
prevNode->next = moveNode->next;
|
||||||
|
moveNode->next = tmp;
|
||||||
|
} else {
|
||||||
|
tmp = insertNode->next;
|
||||||
|
insertNode->next = moveNode;
|
||||||
|
prevNode->next = moveNode->next;
|
||||||
|
moveNode->next = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sequentialNames(self->objectNode, pCon);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static void Configure(pSICSOBJ self){
|
||||||
|
pHdb n = NULL, par = NULL;
|
||||||
|
hdbValue intValue, textValue, funcValue;
|
||||||
|
pHdb obj = self->objectNode;
|
||||||
|
|
||||||
|
intValue = MakeHdbInt(0);
|
||||||
|
textValue = MakeHdbText("Undefined");
|
||||||
|
|
||||||
|
n = MakeHipadabaNode("control",HIPNONE,1);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AddSICSHdbPar(n,"maxEntry",usInternal,intValue);
|
||||||
|
AddSICSHdbPar(n,"currentEntry",usInternal,intValue);
|
||||||
|
|
||||||
|
|
||||||
|
n = MakeHipadabaNode("queue",HIPNONE,1);
|
||||||
|
AddHipadabaChild(obj,n, NULL);
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,EnqueFunc);
|
||||||
|
n = MakeSICSHdbPar("enqueue",usUser, funcValue);
|
||||||
|
AddSICSHdbPar(n,"description",usUser,textValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,AddCmdData);
|
||||||
|
n = MakeSICSHdbPar("addcommand",usUser, funcValue);
|
||||||
|
AddSICSHdbPar(n,"command",usUser,textValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,Dequeue);
|
||||||
|
n = MakeSICSHdbPar("dequeue",usUser,funcValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AddSICSHdbPar(n,"index",usUser,intValue);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,Clean);
|
||||||
|
n = MakeSICSHdbPar("clean",usUser, funcValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,Start);
|
||||||
|
n = MakeSICSHdbPar("start",usUser, funcValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,Stop);
|
||||||
|
n = MakeSICSHdbPar("stop",usUser, funcValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
funcValue = makeHdbData(HIPFUNC,1,Move);
|
||||||
|
n = MakeSICSHdbPar("move",usUser,funcValue);
|
||||||
|
AddHipadabaChild(obj,n,NULL);
|
||||||
|
AddSICSHdbPar(n,"moveindex",usUser,intValue);
|
||||||
|
AddSICSHdbPar(n,"insertindex",usUser,intValue);
|
||||||
|
AppendHipadabaCallback(n,HCBSET,MakeSICSFuncCallback(self));
|
||||||
|
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int MakeHDBQueue(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pSICSOBJ self = NULL;
|
||||||
|
pHdbQueue priv = NULL;
|
||||||
|
|
||||||
|
priv = (pHdbQueue)malloc(sizeof(HdbQueue));
|
||||||
|
self = SetupSICSOBJ(pCon,pSics, pData,argc, argv);
|
||||||
|
if(self == NULL || priv == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Configure(self);
|
||||||
|
memset(priv,0,sizeof(HdbQueue));
|
||||||
|
self->pPrivate = priv;
|
||||||
|
self->KillPrivate = free;
|
||||||
|
return 1;
|
||||||
|
}
|
15
hdbqueue.h
Normal file
15
hdbqueue.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* This is the new Hipadab based queuing system in support of the MountainGum
|
||||||
|
* user interface.
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, July 2007
|
||||||
|
*/
|
||||||
|
#ifndef HDBQUEUE_H_
|
||||||
|
#define HDBQUEUE_H_
|
||||||
|
|
||||||
|
int MakeHDBQueue(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
#endif /*HDBQUEUE_H_*/
|
31
hipadaba.c
31
hipadaba.c
@ -29,7 +29,7 @@ void DeleteCallbackChain(pHdbCallback root){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static void DeleteNodeData(pHdb node){
|
void DeleteNodeData(pHdb node){
|
||||||
pHdb tmp = NULL;
|
pHdb tmp = NULL;
|
||||||
|
|
||||||
if(node == NULL){
|
if(node == NULL){
|
||||||
@ -57,7 +57,7 @@ static void DeleteNodeData(pHdb node){
|
|||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||||
void *callData, hdbValue v){
|
void *callData, hdbValue v){
|
||||||
pHdbCallback current = root;
|
pHdbCallback current = root;
|
||||||
int status;
|
int status;
|
||||||
@ -92,6 +92,17 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData){
|
|||||||
parent,callData,parent->value);
|
parent,callData,parent->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int CountHdbChildren(pHdb node){
|
||||||
|
int count = 0;
|
||||||
|
pHdb current = NULL;
|
||||||
|
current = node->child;
|
||||||
|
while(current != NULL){
|
||||||
|
current = current->next;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static void RemoveCallbackNode(pHdbCallback victim){
|
static void RemoveCallbackNode(pHdbCallback victim){
|
||||||
if(victim->previous != NULL) {
|
if(victim->previous != NULL) {
|
||||||
@ -347,6 +358,9 @@ hdbValue makeHdbData(int datatype, int length, void *data){
|
|||||||
case HIPOBJ:
|
case HIPOBJ:
|
||||||
val.v.obj = data;
|
val.v.obj = data;
|
||||||
break;
|
break;
|
||||||
|
case HIPFUNC:
|
||||||
|
val.v.obj = data;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -480,6 +494,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
|||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case HIPOBJ:
|
case HIPOBJ:
|
||||||
|
case HIPFUNC:
|
||||||
if(v2.v.obj == v1.v.obj) {
|
if(v2.v.obj == v1.v.obj) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -523,6 +538,7 @@ int getHdbValueLength(hdbValue v){
|
|||||||
length = strlen(v.v.text);
|
length = strlen(v.v.text);
|
||||||
break;
|
break;
|
||||||
case HIPOBJ:
|
case HIPOBJ:
|
||||||
|
case HIPFUNC:
|
||||||
length = sizeof(void *);
|
length = sizeof(void *);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -913,6 +929,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HIPOBJ:
|
case HIPOBJ:
|
||||||
|
case HIPFUNC:
|
||||||
target->v.obj = source->v.obj;
|
target->v.obj = source->v.obj;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -943,6 +960,16 @@ int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
int NotifyHipadabaPar(pHdb node,void *callData){
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = InvokeCallbackChain(node->updateCallbacks, node, callData, node->value);
|
||||||
|
if(status != 1 ){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------*/
|
||||||
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
|
int GetHipadabaPar(pHdb node, hdbValue *v, void *callData){
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
33
hipadaba.h
33
hipadaba.h
@ -39,6 +39,7 @@
|
|||||||
#define HIPINTVARAR 5
|
#define HIPINTVARAR 5
|
||||||
#define HIPFLOATVARAR 6
|
#define HIPFLOATVARAR 6
|
||||||
#define HIPOBJ 7
|
#define HIPOBJ 7
|
||||||
|
#define HIPFUNC 8
|
||||||
/* -------- callback types */
|
/* -------- callback types */
|
||||||
#define HCBSET 0
|
#define HCBSET 0
|
||||||
#define HCBUPDATE 1
|
#define HCBUPDATE 1
|
||||||
@ -192,7 +193,13 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length);
|
|||||||
*/
|
*/
|
||||||
void AddHipadabaChild(pHdb parent, pHdb child, void *callData);
|
void AddHipadabaChild(pHdb parent, pHdb child, void *callData);
|
||||||
/**
|
/**
|
||||||
* delete a hipadaba node and all its children
|
* Delete only the node data, without invoking any callbacks
|
||||||
|
* @param node The node to delete.
|
||||||
|
*/
|
||||||
|
void DeleteNodeData(pHdb node);
|
||||||
|
/**
|
||||||
|
* delete a hipadaba node and all its children. Then invoke the tree
|
||||||
|
* change callback to notify listeners.
|
||||||
* @parma node The node to delete
|
* @parma node The node to delete
|
||||||
* @param callData User data for the tree change callback
|
* @param callData User data for the tree change callback
|
||||||
*/
|
*/
|
||||||
@ -228,6 +235,12 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData);
|
|||||||
* @param root The callback chain to delete
|
* @param root The callback chain to delete
|
||||||
*/
|
*/
|
||||||
void DeleteCallbackChain(pHdbCallback root);
|
void DeleteCallbackChain(pHdbCallback root);
|
||||||
|
/**
|
||||||
|
* count the numbers of children in thie Hdb node
|
||||||
|
* @param node The node to count children for
|
||||||
|
* @return The number of children
|
||||||
|
*/
|
||||||
|
int CountHdbChildren(pHdb node);
|
||||||
/*===================== function protoypes: Callbacks ========================*/
|
/*===================== function protoypes: Callbacks ========================*/
|
||||||
/**
|
/**
|
||||||
* make a new hipdaba callback
|
* make a new hipdaba callback
|
||||||
@ -270,6 +283,16 @@ void RemoveHipadabaCallback(pHdb root, int id);
|
|||||||
* @param internalID The internal ID callbacks have to match in order to be removed.
|
* @param internalID The internal ID callbacks have to match in order to be removed.
|
||||||
*/
|
*/
|
||||||
void InternalRemoveHipadabaCallback(pHdb root, int internalID);
|
void InternalRemoveHipadabaCallback(pHdb root, int internalID);
|
||||||
|
/**
|
||||||
|
* invoke a callback chain.
|
||||||
|
* @param root The callback chain to invoke
|
||||||
|
* @param node The node reposnible for this callback chain
|
||||||
|
* @param callData Some data belonging to the callback
|
||||||
|
* @param v The new value for this callback
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||||
|
void *callData, hdbValue v);
|
||||||
|
|
||||||
/*============== Parameter Handling ===============================*/
|
/*============== Parameter Handling ===============================*/
|
||||||
/**
|
/**
|
||||||
@ -290,6 +313,14 @@ int SetHipadabaPar(pHdb node, hdbValue v, void *callData);
|
|||||||
* @return 0 on failure, 1 on success
|
* @return 0 on failure, 1 on success
|
||||||
*/
|
*/
|
||||||
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData);
|
int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData);
|
||||||
|
/**
|
||||||
|
* notify any update listeners that this node has been internally modidifed.
|
||||||
|
* @param node The node modified
|
||||||
|
* @param callData Addtional data for the callback
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int NotifyHipadabaPar(pHdb node,void *callData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a hipadaba parameter
|
* Read a hipadaba parameter
|
||||||
* @param node The node for which to read the parameter
|
* @param node The node for which to read the parameter
|
||||||
|
2
make_gen
2
make_gen
@ -33,7 +33,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
|
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \
|
||||||
moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \
|
moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \
|
||||||
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
|
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \
|
||||||
nwatch.o asyncqueue.o asyncprotocol.o
|
nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o hdbqueue.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o simdriv.o
|
MOTOROBJ = motor.o simdriv.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
6
ofac.c
6
ofac.c
@ -124,6 +124,8 @@
|
|||||||
#include "statemon.h"
|
#include "statemon.h"
|
||||||
#include "asyncqueue.h"
|
#include "asyncqueue.h"
|
||||||
#include "asyncprotocol.h"
|
#include "asyncprotocol.h"
|
||||||
|
#include "sicsobj.h"
|
||||||
|
#include "hdbqueue.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -341,6 +343,8 @@
|
|||||||
StateMonFactory,NULL,NULL);
|
StateMonFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
|
AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
|
AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeSicsObj",InstallSICSOBJ,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeHdbQueue",MakeHDBQueue,NULL,NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
install site specific commands
|
install site specific commands
|
||||||
@ -412,6 +416,8 @@
|
|||||||
RemoveCommand(pSics,"MakeStateMon");
|
RemoveCommand(pSics,"MakeStateMon");
|
||||||
RemoveCommand(pSics,"MakeAsyncQueue");
|
RemoveCommand(pSics,"MakeAsyncQueue");
|
||||||
RemoveCommand(pSics,"MakeAsyncProtocol");
|
RemoveCommand(pSics,"MakeAsyncProtocol");
|
||||||
|
RemoveCommand(pSics,"MakeSicsObject");
|
||||||
|
RemoveCommand(pSics,"MakeHdbQueue");
|
||||||
/*
|
/*
|
||||||
remove site specific installation commands
|
remove site specific installation commands
|
||||||
*/
|
*/
|
||||||
|
21
scan.c
21
scan.c
@ -547,10 +547,6 @@ CountEntry CollectCounterData(pScanData self)
|
|||||||
{
|
{
|
||||||
/*--------- drive */
|
/*--------- drive */
|
||||||
iRet = self->ScanDrive(self,i);
|
iRet = self->ScanDrive(self,i);
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* finished, check for interrupts. Whatever happened, user
|
/* finished, check for interrupts. Whatever happened, user
|
||||||
interrupt or HW interrupt, it will be on our connection
|
interrupt or HW interrupt, it will be on our connection
|
||||||
*/
|
*/
|
||||||
@ -579,13 +575,15 @@ CountEntry CollectCounterData(pScanData self)
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*-------------- count */
|
|
||||||
iRet = self->ScanCount(self, i);
|
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
return 0;
|
SCWrite(self->pCon,"WARNING: skipped scan point after drive failure",
|
||||||
|
eWarning);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*-------------- count */
|
||||||
|
iRet = self->ScanCount(self, i);
|
||||||
/* finished, check for interrupts. Whatever happened, user
|
/* finished, check for interrupts. Whatever happened, user
|
||||||
interrupt or HW interrupt, it will be on our connection
|
interrupt or HW interrupt, it will be on our connection
|
||||||
*/
|
*/
|
||||||
@ -610,6 +608,13 @@ CountEntry CollectCounterData(pScanData self)
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"WARNING: skipped scan point after count failure",
|
||||||
|
eWarning);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*-------- scan post processing */
|
/*-------- scan post processing */
|
||||||
self->CollectScanData(self,i);
|
self->CollectScanData(self,i);
|
||||||
InvokeCallBack(self->pCall,SCANPOINT,self);
|
InvokeCallBack(self->pCall,SCANPOINT,self);
|
||||||
|
257
sicshipadaba.c
257
sicshipadaba.c
@ -25,6 +25,7 @@
|
|||||||
#include <stptok.h>
|
#include <stptok.h>
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include <splitter.h>
|
#include <splitter.h>
|
||||||
|
#include "sicsobj.h"
|
||||||
|
|
||||||
/*== there can be only hipadaba in SICS, some globals to care for that == */
|
/*== there can be only hipadaba in SICS, some globals to care for that == */
|
||||||
static pHdb root = NULL;
|
static pHdb root = NULL;
|
||||||
@ -102,12 +103,18 @@ static int SICSDriveCallback(void *userData, void *callData, pHdb node,
|
|||||||
hdbValue v){
|
hdbValue v){
|
||||||
SConnection *pCon = NULL;
|
SConnection *pCon = NULL;
|
||||||
pDummy dum = NULL;
|
pDummy dum = NULL;
|
||||||
|
char pSicsdev[80];
|
||||||
|
|
||||||
pCon = (SConnection *)callData;
|
pCon = (SConnection *)callData;
|
||||||
dum = (pDummy)userData;
|
dum = (pDummy)userData;
|
||||||
assert(pCon != NULL && dum != NULL);
|
assert(pCon != NULL && dum != NULL);
|
||||||
return StartDevice(pServ->pExecutor,node->name,dum->pDescriptor,
|
if(GetHdbProperty(node,"sicsdev",pSicsdev,79)){
|
||||||
userData, pCon, (float)v.v.doubleValue);
|
return StartDevice(pServ->pExecutor,pSicsdev,dum->pDescriptor,
|
||||||
|
userData, pCon, (float)v.v.doubleValue);
|
||||||
|
} else {
|
||||||
|
return StartDevice(pServ->pExecutor,node->name,dum->pDescriptor,
|
||||||
|
userData, pCon, (float)v.v.doubleValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------*/
|
||||||
pHdbCallback MakeSICSDriveCallback(void *sicsObject){
|
pHdbCallback MakeSICSDriveCallback(void *sicsObject){
|
||||||
@ -145,6 +152,37 @@ static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int SICSFuncCallback(void *userData, void *callData, pHdb node,
|
||||||
|
hdbValue v){
|
||||||
|
pHdb par[64], current = NULL;
|
||||||
|
int nPar = 0;
|
||||||
|
SICSOBJFunc func = NULL;
|
||||||
|
|
||||||
|
assert(node->value.dataType == HIPFUNC);
|
||||||
|
if(userData == NULL || callData == NULL){
|
||||||
|
printf("Great Badness in calling SICSFuncCallback\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = node->child;
|
||||||
|
while(current != NULL){
|
||||||
|
par[nPar] = current;
|
||||||
|
nPar++;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
func = (SICSOBJFunc)node->value.v.obj;
|
||||||
|
if(func != NULL){
|
||||||
|
return func((pSICSOBJ)userData,(SConnection *)callData, par,nPar);
|
||||||
|
} else {
|
||||||
|
printf("Great Badness in calling SICSFuncCallback\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pHdbCallback MakeSICSFuncCallback(void *obj){
|
||||||
|
return MakeHipadabaCallback(SICSFuncCallback, obj,NULL,-1,-1);
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------------------*/
|
||||||
pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){
|
pHdbCallback MakeSICSReadDriveCallback(void *sicsObject){
|
||||||
return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1);
|
return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1);
|
||||||
@ -220,7 +258,50 @@ int formatNameValue(Protocol protocol, char *name, char *value, pDynString resul
|
|||||||
}
|
}
|
||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------------*/
|
||||||
|
static int sendZippedNodeData(pHdb node, SConnection *pCon){
|
||||||
|
hdbValue newValue;
|
||||||
|
int i, *iData = NULL;
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
memset(&newValue,0,sizeof(hdbValue));
|
||||||
|
GetHipadabaPar(node, &newValue, pCon);
|
||||||
|
path = GetHipadabaPath(node);
|
||||||
|
switch(newValue.dataType){
|
||||||
|
case HIPINTAR:
|
||||||
|
case HIPINTVARAR:
|
||||||
|
for(i = 0; i < newValue.arrayLength; i++){
|
||||||
|
newValue.v.intArray[i] = htonl(newValue.v.intArray[i]);
|
||||||
|
}
|
||||||
|
SCWriteZipped(pCon,path, newValue.v.intArray,
|
||||||
|
newValue.arrayLength*sizeof(int));
|
||||||
|
break;
|
||||||
|
case HIPFLOATAR:
|
||||||
|
case HIPFLOATVARAR:
|
||||||
|
iData = (int *)malloc(newValue.arrayLength*sizeof(int));
|
||||||
|
if(iData == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory in sendZippedData",eError);
|
||||||
|
free(path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(iData,0,newValue.arrayLength*sizeof(int));
|
||||||
|
for(i = 0; i < newValue.arrayLength; i++){
|
||||||
|
iData[i] = htonl((int)newValue.v.floatArray[i]*65536.);
|
||||||
|
}
|
||||||
|
SCWriteZipped(pCon,path, iData,
|
||||||
|
newValue.arrayLength*sizeof(int));
|
||||||
|
free(iData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SCWrite(pCon,"ERROR: zipped writing not supported for this datatype",
|
||||||
|
eError);
|
||||||
|
free(path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
free(path);
|
||||||
|
ReleaseHdbValue(&newValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*----------------------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------------------*/
|
||||||
static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
||||||
hdbValue v){
|
hdbValue v){
|
||||||
@ -229,7 +310,8 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
|||||||
pDynString result = NULL;
|
pDynString result = NULL;
|
||||||
char *pPath = NULL;
|
char *pPath = NULL;
|
||||||
Protocol protocol = normal_protocol;
|
Protocol protocol = normal_protocol;
|
||||||
int outCode, macro;
|
int outCode, macro, status;
|
||||||
|
char value[80];
|
||||||
|
|
||||||
cbInfo = (HdbCBInfo *)userData;
|
cbInfo = (HdbCBInfo *)userData;
|
||||||
pPath = GetHipadabaPath(node);
|
pPath = GetHipadabaPath(node);
|
||||||
@ -244,6 +326,19 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
|||||||
*/
|
*/
|
||||||
macro = SCinMacro(cbInfo->pCon);
|
macro = SCinMacro(cbInfo->pCon);
|
||||||
SCsetMacro(cbInfo->pCon,0);
|
SCsetMacro(cbInfo->pCon,0);
|
||||||
|
/**
|
||||||
|
* if transfer = zip always transfer data in zipped form
|
||||||
|
*/
|
||||||
|
if(GetHdbProperty(node,"transfer",value,80) == 1){
|
||||||
|
if(strstr(value,"zip") != NULL){
|
||||||
|
SCPushContext2(cbInfo->pCon,cbInfo->context);
|
||||||
|
status = sendZippedNodeData(node, cbInfo->pCon);
|
||||||
|
SCPopContext(cbInfo->pCon);
|
||||||
|
SCsetMacro(cbInfo->pCon,macro);
|
||||||
|
free(pPath);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
if(v.arrayLength < 100){
|
if(v.arrayLength < 100){
|
||||||
printedData = formatValue(v);
|
printedData = formatValue(v);
|
||||||
if(pPath == NULL || printedData == NULL || result == NULL){
|
if(pPath == NULL || printedData == NULL || result == NULL){
|
||||||
@ -1313,6 +1408,7 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
|||||||
double dValue;
|
double dValue;
|
||||||
char number[80];
|
char number[80];
|
||||||
char *pPtr = NULL;
|
char *pPtr = NULL;
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
|
||||||
switch(v->dataType){
|
switch(v->dataType){
|
||||||
case HIPNONE:
|
case HIPNONE:
|
||||||
@ -1385,6 +1481,16 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
|||||||
v->v.floatArray[i] = dValue;
|
v->v.floatArray[i] = dValue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case HIPOBJ:
|
||||||
|
pCom = FindCommand(pServ->pSics,data);
|
||||||
|
if(pCom == NULL && pCom->pData != NULL){
|
||||||
|
snprintf(error,errlen,"object %s NOT found", data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
v->v.obj = pCom->pData;
|
||||||
|
break;
|
||||||
|
case HIPFUNC:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
@ -1404,6 +1510,8 @@ static char *hdbTypes[] = {"none",
|
|||||||
"floatar",
|
"floatar",
|
||||||
"intvarar",
|
"intvarar",
|
||||||
"floatvarar",
|
"floatvarar",
|
||||||
|
"object",
|
||||||
|
"func",
|
||||||
NULL};
|
NULL};
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
static int convertHdbType(char *text){
|
static int convertHdbType(char *text){
|
||||||
@ -1689,7 +1797,7 @@ static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!cloneHdbValue(&targetNode->value,&newValue)){
|
if(!cloneHdbValue(&targetNode->value,&newValue)){
|
||||||
SCWrite(pCon,"ERROR: out of mmeory cloning node",
|
SCWrite(pCon,"ERROR: out of memory cloning node",
|
||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1761,6 +1869,7 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
memset(&newValue,0,sizeof(hdbValue));
|
||||||
GetHipadabaPar(targetNode,&newValue,pCon);
|
GetHipadabaPar(targetNode,&newValue,pCon);
|
||||||
}
|
}
|
||||||
status = UpdateHipadabaPar(targetNode,newValue,pCon);
|
status = UpdateHipadabaPar(targetNode,newValue,pCon);
|
||||||
@ -1771,6 +1880,25 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
static int ZipGetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pHdb targetNode = NULL;
|
||||||
|
char error[512], oriPath[512];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(argc < 2) {
|
||||||
|
SCWrite(pCon,"ERROR: need path to node",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(oriPath,argv[1], 511);
|
||||||
|
targetNode = locateSICSNode(pSics,pCon,argv[1]);
|
||||||
|
if(targetNode == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sendZippedNodeData(targetNode,pCon);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]){
|
int argc, char *argv[]){
|
||||||
pHdb targetNode = NULL;
|
pHdb targetNode = NULL;
|
||||||
@ -1780,6 +1908,7 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
int i, status;
|
int i, status;
|
||||||
Protocol protocol = normal_protocol;
|
Protocol protocol = normal_protocol;
|
||||||
int outCode;
|
int outCode;
|
||||||
|
char value[80];
|
||||||
|
|
||||||
if(argc < 2) {
|
if(argc < 2) {
|
||||||
SCWrite(pCon,"ERROR: need path to node to print",eError);
|
SCWrite(pCon,"ERROR: need path to node to print",eError);
|
||||||
@ -1791,6 +1920,14 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
if(targetNode == NULL){
|
if(targetNode == NULL){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if transfer = zip, redirect to zip
|
||||||
|
*/
|
||||||
|
if(GetHdbProperty(targetNode,"transfer", value,80) == 1){
|
||||||
|
if(strstr(value,"zip") != NULL){
|
||||||
|
return ZipGetHdbNode(pCon,pSics,pData,argc,argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
memset(&newValue,0,sizeof(hdbValue));
|
memset(&newValue,0,sizeof(hdbValue));
|
||||||
GetHipadabaPar(targetNode, &newValue, pCon);
|
GetHipadabaPar(targetNode, &newValue, pCon);
|
||||||
parData = formatValue(newValue);
|
parData = formatValue(newValue);
|
||||||
@ -1812,59 +1949,6 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
||||||
static int ZipGetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
||||||
int argc, char *argv[]){
|
|
||||||
pHdb targetNode = NULL;
|
|
||||||
hdbValue newValue;
|
|
||||||
char error[512], oriPath[512];
|
|
||||||
int i, status;
|
|
||||||
int *iData = NULL;
|
|
||||||
|
|
||||||
if(argc < 2) {
|
|
||||||
SCWrite(pCon,"ERROR: need path to node",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(oriPath,argv[1], 511);
|
|
||||||
targetNode = locateSICSNode(pSics,pCon,argv[1]);
|
|
||||||
if(targetNode == NULL){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset(&newValue,0,sizeof(hdbValue));
|
|
||||||
GetHipadabaPar(targetNode, &newValue, pCon);
|
|
||||||
switch(newValue.dataType){
|
|
||||||
case HIPINTAR:
|
|
||||||
case HIPINTVARAR:
|
|
||||||
for(i = 0; i < newValue.arrayLength; i++){
|
|
||||||
newValue.v.intArray[i] = htonl(newValue.v.intArray[i]);
|
|
||||||
}
|
|
||||||
SCWriteZipped(pCon,oriPath, newValue.v.intArray,
|
|
||||||
newValue.arrayLength*sizeof(int));
|
|
||||||
break;
|
|
||||||
case HIPFLOATAR:
|
|
||||||
case HIPFLOATVARAR:
|
|
||||||
iData = (int *)malloc(newValue.arrayLength*sizeof(int));
|
|
||||||
if(iData == NULL){
|
|
||||||
SCWrite(pCon,"ERROR: out of memory in ZipGetHdbNode",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset(iData,0,newValue.arrayLength*sizeof(int));
|
|
||||||
for(i = 0; i < newValue.arrayLength; i++){
|
|
||||||
iData[i] = htonl((int)newValue.v.floatArray[i]*65536.);
|
|
||||||
}
|
|
||||||
SCWriteZipped(pCon,oriPath, iData,
|
|
||||||
newValue.arrayLength*sizeof(int));
|
|
||||||
free(iData);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SCWrite(pCon,"ERROR: zipped writing not supported for this datatype",
|
|
||||||
eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ReleaseHdbValue(&newValue);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int countChildren(pHdb node){
|
static int countChildren(pHdb node){
|
||||||
pHdb current = NULL;
|
pHdb current = NULL;
|
||||||
@ -2316,6 +2400,63 @@ static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/* --------------------------------------------------------------------------
|
||||||
|
* This is actually SCInvoke but without advancing the context. I think this
|
||||||
|
* is only of local use. It makes sure that commands executed as Hipadaba
|
||||||
|
* commands get logged properly.
|
||||||
|
*/
|
||||||
|
static int HDBInvoke(SConnection *self, SicsInterp *pInter, char *pCommand)
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
long lLen;
|
||||||
|
const char *pResult = NULL;
|
||||||
|
char *pBuffer = NULL, *pFile = NULL;
|
||||||
|
char pBueffel[80];
|
||||||
|
int i, iSpace;
|
||||||
|
|
||||||
|
assert(pInter);
|
||||||
|
|
||||||
|
/* print command to log files */
|
||||||
|
for( i = 0; i < self->iFiles; i++)
|
||||||
|
{
|
||||||
|
if(self->pFiles[i])
|
||||||
|
{
|
||||||
|
fprintf(self->pFiles[i],"SICS>> %s\n",pCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print to command log if user or manager */
|
||||||
|
if(SCGetRights(self) <= usUser)
|
||||||
|
{
|
||||||
|
if(self->pSock != NULL)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"sock %d>>",self->pSock->sockid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* invoke */
|
||||||
|
self->inUse++;
|
||||||
|
self->eInterrupt = eContinue;
|
||||||
|
self->parameterChange = 0;
|
||||||
|
/*
|
||||||
|
get first word of command
|
||||||
|
*/
|
||||||
|
iRet = InterpExecute(pInter,self,pCommand);
|
||||||
|
if(self->parameterChange == 1)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
automatically save changed parameters
|
||||||
|
*/
|
||||||
|
pFile = IFindOption(pSICSOptions,"statusfile");
|
||||||
|
if(pFile != NULL)
|
||||||
|
{
|
||||||
|
WriteSicsStatus(pInter,pFile,0);
|
||||||
|
self->parameterChange = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self->inUse--;
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int CommandSetCallback(void *userData, void *callData, pHdb node,
|
static int CommandSetCallback(void *userData, void *callData, pHdb node,
|
||||||
hdbValue v){
|
hdbValue v){
|
||||||
@ -2348,7 +2489,7 @@ static int CommandSetCallback(void *userData, void *callData, pHdb node,
|
|||||||
}
|
}
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
status = SCInvoke(pCon, pServ->pSics,GetCharArray(cmd));
|
status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
|
||||||
DeleteDynString(cmd);
|
DeleteDynString(cmd);
|
||||||
return status;
|
return status;
|
||||||
} else {
|
} else {
|
||||||
|
@ -119,6 +119,11 @@ pHdbCallback MakeMemSetCallback(float *address);
|
|||||||
* @return a suitable callback for notififications about tree changes.
|
* @return a suitable callback for notififications about tree changes.
|
||||||
*/
|
*/
|
||||||
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id);
|
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id);
|
||||||
|
/**
|
||||||
|
* make a clalback to invoke a function node
|
||||||
|
*/
|
||||||
|
pHdbCallback MakeSICSFuncCallback(void *obj);
|
||||||
|
|
||||||
/*======================== parameter creation ===================================*/
|
/*======================== parameter creation ===================================*/
|
||||||
/**
|
/**
|
||||||
* make a simple SICS hdb parameter. Setting it will call update immediately. Use
|
* make a simple SICS hdb parameter. Setting it will call update immediately. Use
|
||||||
|
167
sicsobj.c
Normal file
167
sicsobj.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/**
|
||||||
|
* This is the header file for the new (as of 2007) style SICS objects
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, July 2007
|
||||||
|
*/
|
||||||
|
#include <sics.h>
|
||||||
|
#include "assert.h"
|
||||||
|
#include "ifile.h"
|
||||||
|
#include "sicsobj.h"
|
||||||
|
#include "sicshipadaba.h"
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void DefaultKill(void *data){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pSICSOBJ MakeSICSOBJ(char *name, char *class){
|
||||||
|
pSICSOBJ pNew = NULL;
|
||||||
|
|
||||||
|
pNew = (pSICSOBJ)malloc(sizeof(SICSOBJ));
|
||||||
|
if(pNew == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(pNew,0,sizeof(SICSOBJ));
|
||||||
|
pNew->pDes = CreateDescriptor(class);
|
||||||
|
pNew->objectNode = MakeHipadabaNode(name, HIPNONE, 1);
|
||||||
|
if(pNew->pDes == NULL || pNew->objectNode == NULL){
|
||||||
|
free(pNew);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
pNew->pDes->parNode = pNew->objectNode;
|
||||||
|
pNew->KillPrivate = DefaultKill;
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void KillSICSOBJ(void *data){
|
||||||
|
pSICSOBJ self = (pSICSOBJ)data;
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(self->pDes != NULL){
|
||||||
|
DeleteDescriptor(self->pDes);
|
||||||
|
}
|
||||||
|
if(self->KillPrivate != NULL && self->pPrivate != NULL){
|
||||||
|
self->KillPrivate(self->pPrivate);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*===========================================================================*/
|
||||||
|
static int assignPar(pHdb node, SConnection *pCon, char *data){
|
||||||
|
char error[132], buffer[256];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = readHdbValue(&node->value,data, error, 132);
|
||||||
|
if(status != 1){
|
||||||
|
snprintf(buffer,255,"ERROR: error parsing %s: %s",
|
||||||
|
node->name, error);
|
||||||
|
SCWrite(pCon,buffer,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection *pCon,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
int status, i, count = 0;
|
||||||
|
pHdb currentPar = NULL;
|
||||||
|
SICSOBJFunc pFunc = NULL;
|
||||||
|
pHdb parArray[64];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assign parameters and fill parameter array for function at the same
|
||||||
|
* time. Be lenient about missing parameters: Then the old values will
|
||||||
|
* be used.
|
||||||
|
*/
|
||||||
|
for(i = 0, currentPar = commandNode->child;
|
||||||
|
i < argc && currentPar != NULL;
|
||||||
|
i++, currentPar = currentPar->next){
|
||||||
|
if(argv[i] != NULL){
|
||||||
|
status = assignPar(currentPar,pCon, argv[i]);
|
||||||
|
}
|
||||||
|
if(status != 1){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
parArray[i] = currentPar;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pFunc = (SICSOBJFunc)commandNode->value.v.obj;
|
||||||
|
if(pFunc == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: internal error, function not found",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = pFunc(object, pCon, parArray,count);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pSICSOBJ self = NULL;
|
||||||
|
int status;
|
||||||
|
pHdb parNode;
|
||||||
|
char buffer[132];
|
||||||
|
|
||||||
|
self = (pSICSOBJ)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
if(argc < 1){
|
||||||
|
SCWrite(pCon,"ERROR: Nothing to process",eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
parNode = GetHipadabaNode(self->objectNode,argv[1]);
|
||||||
|
if(parNode != NULL && parNode->value.dataType == HIPFUNC){
|
||||||
|
status = invokeOBJFunction(self, parNode, pCon, argc-2, &argv[2]);
|
||||||
|
} else {
|
||||||
|
status = ProcessSICSHdbPar(self->objectNode,pCon, argv[0],
|
||||||
|
argc-1,&argv[1]);
|
||||||
|
}
|
||||||
|
if(status == -1){
|
||||||
|
snprintf(buffer,131,"ERROR: no command or parameter found for key: %s",
|
||||||
|
argv[1]);
|
||||||
|
SCWrite(pCon,buffer,eError);
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pSICSOBJ pNew = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(argc < 3){
|
||||||
|
SCWrite(pCon,"ERROR: not enough arguments to InstallSICSOBJ",eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pNew = MakeSICSOBJ(argv[1], argv[2]);
|
||||||
|
if(pNew == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating new SICS object",eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,
|
||||||
|
argv[1],
|
||||||
|
InvokeSICSOBJ,
|
||||||
|
KillSICSOBJ,
|
||||||
|
pNew);
|
||||||
|
if(status != 1){
|
||||||
|
KillSICSOBJ(pNew);
|
||||||
|
SCPrintf(pCon,eError,"ERROR: failed create duplicate command %s", argv[1]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pNew;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int InstallSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pSICSOBJ pNew = NULL;
|
||||||
|
|
||||||
|
pNew = SetupSICSOBJ(pCon, pSics, pData, argc, argv);
|
||||||
|
if(pNew == NULL){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
44
sicsobj.h
Normal file
44
sicsobj.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* This is the header file for the new (as of 2007) style SICS objects
|
||||||
|
*
|
||||||
|
* copyright: see file COPYRIGHT
|
||||||
|
*
|
||||||
|
* Mark Koennecke, July 2007
|
||||||
|
*/
|
||||||
|
#ifndef SICSOBJ2_H_
|
||||||
|
#define SICSOBJ2_H_
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <hipadaba.h>
|
||||||
|
/*======================================================================
|
||||||
|
* Be careful when changing this data structure. It has to be compatible
|
||||||
|
* in its first fields with the SICS object descriptor as defined in
|
||||||
|
* obdes.h in order to achieve backwards compatibility with old style
|
||||||
|
* SICS objects.
|
||||||
|
* =====================================================================*/
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pHdb objectNode;
|
||||||
|
void *pPrivate;
|
||||||
|
void (*KillPrivate)(void *pPrivate);
|
||||||
|
}SICSOBJ, *pSICSOBJ;
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
typedef int (*SICSOBJFunc)(pSICSOBJ self, SConnection *pCon,
|
||||||
|
pHdb par[], int nPar);
|
||||||
|
/*======================= Live & Death =================================*/
|
||||||
|
pSICSOBJ MakeSICSOBJ(char *name, char *class);
|
||||||
|
void KillSICSOBJ(void *data);
|
||||||
|
/**
|
||||||
|
* This creates a new SICS object and installs it in the interpreter. It returns
|
||||||
|
* the newly created SICS object such that the caller can continue
|
||||||
|
* configuring it.
|
||||||
|
*/
|
||||||
|
pSICSOBJ SetupSICSOBJ(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
/*====================== Interpreter Interface ===========================*/
|
||||||
|
int InvokeSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int InstallSICSOBJ(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*SICSOBJ2_H_*/
|
Reference in New Issue
Block a user