- 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 "stptok.h"
|
||||
#include "sicshipadaba.h"
|
||||
|
||||
#include "protocol.h"
|
||||
/*
|
||||
#define UUDEB 1
|
||||
define UUDEB , for buffer writing for checking encoding */
|
||||
@ -79,7 +79,7 @@ extern pServer pServ;
|
||||
|
||||
|
||||
/*------ Max Size of Command Stack */
|
||||
#define MAXSTACK 100
|
||||
#define MAXSTACK 1024
|
||||
/*---------- Magic ID Header */
|
||||
#define CONMAGIC 26051958
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1149,8 +1149,9 @@ pDynString SCEndBuffering(SConnection *pCon)
|
||||
int SCWriteZipped(SConnection *self, char *pName, void *pData, int iDataLen)
|
||||
{
|
||||
char outBuf[65546], *pBuf = NULL, noutBuf[ZIPBUF], *pHeader = NULL;
|
||||
int compressedLength, iRet, iRet2, iCount;
|
||||
int compressedLength, iRet, iRet2, iCount, protocolID;
|
||||
z_stream compStream;
|
||||
commandContext cc;
|
||||
|
||||
/* check for a valid connection */
|
||||
if(!VerifyConnection(self))
|
||||
@ -1225,7 +1226,15 @@ pDynString SCEndBuffering(SConnection *pCon)
|
||||
|
||||
/* write header line */
|
||||
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);
|
||||
if(pHeader == NULL)
|
||||
{
|
||||
|
5
danu.c
5
danu.c
@ -363,8 +363,9 @@ int NewThousand(pDataNumber self)
|
||||
|
||||
if(SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
DecrementDataNumber(self);
|
||||
SCWrite(pCon,"Data file killed",eWarning);
|
||||
iNum = DecrementDataNumber(self);
|
||||
snprintf(pBueffel,511,"Data file %d killed", iNum);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
return 1;
|
||||
}
|
||||
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,
|
||||
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 @{
|
||||
|
6
exebuf.c
6
exebuf.c
@ -166,13 +166,17 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
|
||||
self->lineno = 0;
|
||||
pTcl = InterpGetTcl(pSics);
|
||||
|
||||
if(pCall != NULL){
|
||||
InvokeCallBack(pCall,BATCHSTART,self->name);
|
||||
}
|
||||
|
||||
if (echo) {
|
||||
SCsetMacro(pCon,0);
|
||||
}
|
||||
while((command = findBlockEnd(self)) != NULL){
|
||||
if(pCall != NULL){
|
||||
InvokeCallBack(pCall,BATCHAREA,NULL);
|
||||
}
|
||||
cmd = GetCharArray(command);
|
||||
|
||||
if (echo) {
|
||||
@ -223,7 +227,9 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
|
||||
SCSetInterrupt(pCon,eContinue);
|
||||
}
|
||||
}
|
||||
if(pCall != NULL){
|
||||
InvokeCallBack(pCall,BATCHEND,self->name);
|
||||
}
|
||||
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
|
||||
@ -89,7 +89,7 @@
|
||||
*/
|
||||
char *exeBufName(pExeBuf self);
|
||||
|
||||
#line 223 "exe.w"
|
||||
#line 226 "exe.w"
|
||||
|
||||
|
||||
#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
|
||||
@ -16,6 +16,6 @@ typedef struct __EXEBUF{
|
||||
int lineno;
|
||||
} 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){
|
||||
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');
|
||||
}
|
||||
}
|
||||
DynStringConcat(val,message);
|
||||
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 2){
|
||||
if(strrchr(message,(int)'\n') == NULL && strlen(message) > 1){
|
||||
DynStringConcatChar(val,'\n');
|
||||
}
|
||||
if(v.v.text != NULL){
|
||||
@ -314,6 +314,66 @@ static int SCHdbWrite(SConnection *self, char *message, int outCode){
|
||||
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,
|
||||
SicsInterp *pSics, char *name){
|
||||
char pBueffel[512];
|
||||
@ -381,6 +441,15 @@ static int runHdbBuffer(pExeMan self, SConnection *pCon,
|
||||
SCPopContext(pCon);
|
||||
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,
|
||||
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,
|
||||
char *name);
|
||||
pDynString findBatchFile(SicsInterp *pSics, char *name);
|
||||
int exeHdbBuffer(SConnection *pCon,
|
||||
SicsInterp *pSics, char *name);
|
||||
int exeHdbNode(pHdb exeNode, SConnection *pCon);
|
||||
|
||||
#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
|
||||
@ -20,5 +20,5 @@ typedef struct __EXEMAN{
|
||||
int echo;
|
||||
}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);
|
||||
free(lSum);
|
||||
if(status != 1)
|
||||
{
|
||||
SCWrite(pCon,"WARNING: problem locating elastic peak",eWarning);
|
||||
}
|
||||
GetFitResults(fitter,&fCenter,&fStdDev,&fFWHM,&fVal);
|
||||
fVal = fCenter - fElastic;
|
||||
if(fVal < 0.)
|
||||
fVal = - fVal;
|
||||
/* bad value, leave at theoretical value */
|
||||
if(fVal > 10.)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"WARNING: bad fit result, using theoretical elastic peak position",
|
||||
eWarning);
|
||||
}
|
||||
else
|
||||
if(fVal < 10.)
|
||||
{
|
||||
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;
|
||||
|
||||
if(node == NULL){
|
||||
@ -57,7 +57,7 @@ static void DeleteNodeData(pHdb node){
|
||||
free(node);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||
int InvokeCallbackChain(pHdbCallback root, pHdb node,
|
||||
void *callData, hdbValue v){
|
||||
pHdbCallback current = root;
|
||||
int status;
|
||||
@ -92,6 +92,17 @@ void RemoveHdbNodeFromParent(pHdb node, void *callData){
|
||||
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){
|
||||
if(victim->previous != NULL) {
|
||||
@ -347,6 +358,9 @@ hdbValue makeHdbData(int datatype, int length, void *data){
|
||||
case HIPOBJ:
|
||||
val.v.obj = data;
|
||||
break;
|
||||
case HIPFUNC:
|
||||
val.v.obj = data;
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@ -480,6 +494,7 @@ int compareHdbValue(hdbValue v1, hdbValue v2){
|
||||
return 1;
|
||||
break;
|
||||
case HIPOBJ:
|
||||
case HIPFUNC:
|
||||
if(v2.v.obj == v1.v.obj) {
|
||||
return 1;
|
||||
} else {
|
||||
@ -523,6 +538,7 @@ int getHdbValueLength(hdbValue v){
|
||||
length = strlen(v.v.text);
|
||||
break;
|
||||
case HIPOBJ:
|
||||
case HIPFUNC:
|
||||
length = sizeof(void *);
|
||||
break;
|
||||
}
|
||||
@ -913,6 +929,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){
|
||||
}
|
||||
break;
|
||||
case HIPOBJ:
|
||||
case HIPFUNC:
|
||||
target->v.obj = source->v.obj;
|
||||
break;
|
||||
default:
|
||||
@ -943,6 +960,16 @@ int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData){
|
||||
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 status;
|
||||
|
||||
|
33
hipadaba.h
33
hipadaba.h
@ -39,6 +39,7 @@
|
||||
#define HIPINTVARAR 5
|
||||
#define HIPFLOATVARAR 6
|
||||
#define HIPOBJ 7
|
||||
#define HIPFUNC 8
|
||||
/* -------- callback types */
|
||||
#define HCBSET 0
|
||||
#define HCBUPDATE 1
|
||||
@ -192,7 +193,13 @@ pHdb MakeHipadabaNode(char *name, int datatype, int length);
|
||||
*/
|
||||
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
|
||||
* @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
|
||||
*/
|
||||
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 ========================*/
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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 ===============================*/
|
||||
/**
|
||||
@ -290,6 +313,14 @@ int SetHipadabaPar(pHdb node, hdbValue v, void *callData);
|
||||
* @return 0 on failure, 1 on success
|
||||
*/
|
||||
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
|
||||
* @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 \
|
||||
moregress.o hdbcommand.o multicounter.o regresscter.o histregress.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
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
|
6
ofac.c
6
ofac.c
@ -124,6 +124,8 @@
|
||||
#include "statemon.h"
|
||||
#include "asyncqueue.h"
|
||||
#include "asyncprotocol.h"
|
||||
#include "sicsobj.h"
|
||||
#include "hdbqueue.h"
|
||||
/*----------------------- Server options creation -------------------------*/
|
||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -341,6 +343,8 @@
|
||||
StateMonFactory,NULL,NULL);
|
||||
AddCommand(pInter,"MakeAsyncProtocol",AsyncProtocolFactory,NULL,NULL);
|
||||
AddCommand(pInter,"MakeAsyncQueue",AsyncQueueFactory,NULL,NULL);
|
||||
AddCommand(pInter,"MakeSicsObj",InstallSICSOBJ,NULL,NULL);
|
||||
AddCommand(pInter,"MakeHdbQueue",MakeHDBQueue,NULL,NULL);
|
||||
|
||||
/*
|
||||
install site specific commands
|
||||
@ -412,6 +416,8 @@
|
||||
RemoveCommand(pSics,"MakeStateMon");
|
||||
RemoveCommand(pSics,"MakeAsyncQueue");
|
||||
RemoveCommand(pSics,"MakeAsyncProtocol");
|
||||
RemoveCommand(pSics,"MakeSicsObject");
|
||||
RemoveCommand(pSics,"MakeHdbQueue");
|
||||
/*
|
||||
remove site specific installation commands
|
||||
*/
|
||||
|
19
scan.c
19
scan.c
@ -547,10 +547,6 @@ CountEntry CollectCounterData(pScanData self)
|
||||
{
|
||||
/*--------- drive */
|
||||
iRet = self->ScanDrive(self,i);
|
||||
if(!iRet)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* finished, check for interrupts. Whatever happened, user
|
||||
interrupt or HW interrupt, it will be on our connection
|
||||
*/
|
||||
@ -579,13 +575,15 @@ CountEntry CollectCounterData(pScanData self)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
/*-------------- count */
|
||||
iRet = self->ScanCount(self, i);
|
||||
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
|
||||
interrupt or HW interrupt, it will be on our connection
|
||||
*/
|
||||
@ -610,6 +608,13 @@ CountEntry CollectCounterData(pScanData self)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(self->pCon,"WARNING: skipped scan point after count failure",
|
||||
eWarning);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-------- scan post processing */
|
||||
self->CollectScanData(self,i);
|
||||
InvokeCallBack(self->pCall,SCANPOINT,self);
|
||||
|
253
sicshipadaba.c
253
sicshipadaba.c
@ -25,6 +25,7 @@
|
||||
#include <stptok.h>
|
||||
#include "protocol.h"
|
||||
#include <splitter.h>
|
||||
#include "sicsobj.h"
|
||||
|
||||
/*== there can be only hipadaba in SICS, some globals to care for that == */
|
||||
static pHdb root = NULL;
|
||||
@ -102,12 +103,18 @@ static int SICSDriveCallback(void *userData, void *callData, pHdb node,
|
||||
hdbValue v){
|
||||
SConnection *pCon = NULL;
|
||||
pDummy dum = NULL;
|
||||
char pSicsdev[80];
|
||||
|
||||
pCon = (SConnection *)callData;
|
||||
dum = (pDummy)userData;
|
||||
assert(pCon != NULL && dum != NULL);
|
||||
if(GetHdbProperty(node,"sicsdev",pSicsdev,79)){
|
||||
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){
|
||||
@ -145,6 +152,37 @@ static int SICSReadDriveCallback(void *userData, void *callData, pHdb node,
|
||||
}
|
||||
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){
|
||||
return MakeHipadabaCallback(SICSReadDriveCallback, sicsObject,NULL,-1,-1);
|
||||
@ -220,7 +258,50 @@ int formatNameValue(Protocol protocol, char *name, char *value, pDynString resul
|
||||
}
|
||||
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,
|
||||
hdbValue v){
|
||||
@ -229,7 +310,8 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
||||
pDynString result = NULL;
|
||||
char *pPath = NULL;
|
||||
Protocol protocol = normal_protocol;
|
||||
int outCode, macro;
|
||||
int outCode, macro, status;
|
||||
char value[80];
|
||||
|
||||
cbInfo = (HdbCBInfo *)userData;
|
||||
pPath = GetHipadabaPath(node);
|
||||
@ -244,6 +326,19 @@ static int SICSNotifyCallback(void *userData, void *callData, pHdb node,
|
||||
*/
|
||||
macro = SCinMacro(cbInfo->pCon);
|
||||
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){
|
||||
printedData = formatValue(v);
|
||||
if(pPath == NULL || printedData == NULL || result == NULL){
|
||||
@ -1313,6 +1408,7 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
||||
double dValue;
|
||||
char number[80];
|
||||
char *pPtr = NULL;
|
||||
CommandList *pCom = NULL;
|
||||
|
||||
switch(v->dataType){
|
||||
case HIPNONE:
|
||||
@ -1385,6 +1481,16 @@ int readHdbValue(hdbValue *v, char *data, char *error, int errlen){
|
||||
v->v.floatArray[i] = dValue;
|
||||
}
|
||||
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:
|
||||
assert(0);
|
||||
break;
|
||||
@ -1404,6 +1510,8 @@ static char *hdbTypes[] = {"none",
|
||||
"floatar",
|
||||
"intvarar",
|
||||
"floatvarar",
|
||||
"object",
|
||||
"func",
|
||||
NULL};
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int convertHdbType(char *text){
|
||||
@ -1689,7 +1797,7 @@ static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
if(!cloneHdbValue(&targetNode->value,&newValue)){
|
||||
SCWrite(pCon,"ERROR: out of mmeory cloning node",
|
||||
SCWrite(pCon,"ERROR: out of memory cloning node",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
@ -1761,6 +1869,7 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
memset(&newValue,0,sizeof(hdbValue));
|
||||
GetHipadabaPar(targetNode,&newValue,pCon);
|
||||
}
|
||||
status = UpdateHipadabaPar(targetNode,newValue,pCon);
|
||||
@ -1771,6 +1880,25 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
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,
|
||||
int argc, char *argv[]){
|
||||
pHdb targetNode = NULL;
|
||||
@ -1780,6 +1908,7 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int i, status;
|
||||
Protocol protocol = normal_protocol;
|
||||
int outCode;
|
||||
char value[80];
|
||||
|
||||
if(argc < 2) {
|
||||
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){
|
||||
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));
|
||||
GetHipadabaPar(targetNode, &newValue, pCon);
|
||||
parData = formatValue(newValue);
|
||||
@ -1812,59 +1949,6 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
|
||||
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){
|
||||
pHdb current = NULL;
|
||||
@ -2316,6 +2400,63 @@ static int ChainHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
SCSendOK(pCon);
|
||||
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,
|
||||
hdbValue v){
|
||||
@ -2348,7 +2489,7 @@ static int CommandSetCallback(void *userData, void *callData, pHdb node,
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
status = SCInvoke(pCon, pServ->pSics,GetCharArray(cmd));
|
||||
status = HDBInvoke(pCon,pServ->pSics, GetCharArray(cmd));
|
||||
DeleteDynString(cmd);
|
||||
return status;
|
||||
} else {
|
||||
|
@ -119,6 +119,11 @@ pHdbCallback MakeMemSetCallback(float *address);
|
||||
* @return a suitable callback for notififications about tree changes.
|
||||
*/
|
||||
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id);
|
||||
/**
|
||||
* make a clalback to invoke a function node
|
||||
*/
|
||||
pHdbCallback MakeSICSFuncCallback(void *obj);
|
||||
|
||||
/*======================== parameter creation ===================================*/
|
||||
/**
|
||||
* 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