- replaced locateSICSNode by FindHdbNode

This commit is contained in:
zolliker
2008-02-13 09:58:08 +00:00
parent 5ee27af961
commit 327f595fa6
3 changed files with 259 additions and 140 deletions

View File

@ -50,7 +50,7 @@ static pPollDriv makeHdbDriver(SConnection *pCon, char *objectIdentifier,
pHdb node = NULL;
pPollDriv pNew = NULL;
node = locateSICSNode(pServ->pSics,pCon,objectIdentifier);
node = FindHdbNode(NULL,objectIdentifier,pCon);
if(node == NULL){
SCWrite(pCon,"ERROR: object to poll not found",eError);
return 0;

View File

@ -27,6 +27,8 @@
#include <splitter.h>
#include "sicsobj.h"
#define MAX_HDB_PATH 1024
/*== there can be only one hipadaba in SICS, some globals to care for that == */
static pHdb root = NULL;
static pSicsPoll poller = NULL;
@ -648,7 +650,7 @@ static int MemGenReadCallback(void *userData, void *callData, pHdb node,
}
/*-------------------------------------------------------------------------*/
pHdbCallback MakeMemGenReadCallback(void *address){
return MakeHipadabaCallback(MemReadCallback, address,
return MakeHipadabaCallback(MemGenReadCallback, address,
NULL,-1,NULL);
}
/*-------------------------------------------------------------------------*/
@ -1052,7 +1054,174 @@ int AddSICSHdbMemPar(pHdb node, char *name, int priv,
return 1;
}
/*==================== access suport functions ==============================*/
/*==================== access support functions ==============================*/
pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr, SConnection *pCon) {
/* for namePtr == NULL, implements also "find node" */
char *element;
char buffer[MAX_HDB_PATH];
pHdb node = NULL;
pHdb parent = NULL;
char *name;
char *slash;
CommandList *pCom;
pDummy pDum;
int iret;
if (relpath[0] == '/' || rootpath == NULL) { /* absolute path */
iret = snprintf(buffer, sizeof buffer, "%s", relpath);
} else {
iret = snprintf(buffer, sizeof buffer, "%s/%s", rootpath, relpath);
}
if (iret < 0 || iret >= sizeof(buffer)) {
SCWrite(pCon,"ERROR: path too long",eError);
return NULL;
}
element = buffer;
if (strncmp(element, "/sics/", 6) == 0) {
/* sics object case */
slash = strchr(element+6, '/');
if (slash != NULL) *slash = '\0'; /* split off object name */
pCom = FindCommand(pServ->pSics, element);
if (pCom == NULL) {
SCPrintf(pCon, eError, "ERROR: object %s not found", element);
return NULL;
}
pDum = pCom->pData;
if (pDum == NULL) {
SCPrintf(pCon, eError, "ERROR: object %s has no data", element);
return NULL;
}
node = pDum->pDescriptor->parNode;
if (node == NULL) {
SCPrintf(pCon, eError, "ERROR: object %s does not use hipadaba", element);
return NULL;
}
if (slash == NULL) goto nodeFound;
*slash = '/';
element = slash+1;
parent = node;
/* parent is sics object, path is relative to it */
} else {
/* normal path */
parent = GetHipadabaRoot();
}
while (1) {
slash = strchr(element, '/');
if (slash != NULL) *slash = '\0'; /* split off next path element */
if (strcmp(element, "") == 0 || strcmp(element, ".") == 0) {
/* cases "//" and "/./" : do not move in tree */
if (slash == NULL) {
node = parent;
goto nodeFound;
}
*slash = '/';
element = slash + 1;
} else {
for (node = parent->child; node != NULL; node = node->next) {
if (strcasecmp(element, node->name) == 0) {
break;
}
}
if (node == NULL) {
if (namePtr) { /* "find parent" case */
if (slash != NULL) { /* element is not the last in path */
*slash = '/';
SCPrintf(pCon, eError, "ERROR: parent of %s not found", buffer);
return NULL;
}
/* the name must be taken from the end of relpath, as element is no longer valid */
*namePtr = relpath + (element - buffer);
return parent; /* parent found, and node does not yet exist */
}
/* "find node" case */
if (slash != NULL) *slash = '/';
SCPrintf(pCon, eError, "ERROR: node %s not found", buffer);
return NULL;
}
/* node found */
if (slash == NULL) goto nodeFound;
parent = node;
*slash = '/';
element = slash + 1;
}
}
nodeFound:
if (namePtr) { /* "find parent" case */
*namePtr = node->name;
SCPrintf(pCon, eError, "ERROR: node %s exists already", buffer);
return NULL;
}
return node; /* node found */
}
/*--------------------------------------------------------------------------*/
pHdb FindHdbNode(char *rootpath, char *relpath, SConnection *pCon) {
return FindHdbParent(rootpath, relpath, NULL, pCon);
}
/*--------------------------------------------------------------------------*/
int GetHdbPath(pHdb nodeArg, char *path, size_t pathlen) {
pHdb node, parent;
int len, pos, l;
static char *sics="/sics";
CommandList *pCom;
pDummy pDum;
path[0]='\0';
if (nodeArg == NULL) {
return 0;
}
/* determine path length and root node */
parent = nodeArg;
len = 0;
for (node = nodeArg; node != NULL && node != root; node = node->mama) {
len += strlen(node->name) + 1;
if (len >= pathlen) return 0; /* buffer overflow (recursive path?) */
parent = node;
}
/* check root and add prefix */
if (parent->mama != root) { /* not anchored in root */
pCom = FindCommand(pServ->pSics, parent->name);
if (!pCom) {
return 0; /* not a sics object */
}
pDum = pCom->pData;
if (pDum->pDescriptor->parNode != parent) {
/* node named as a sics object, but command is not related to node */
return 0;
}
l= strlen(sics);
len += l;
if (len > pathlen) return 0; /* buffer overflow */
strncpy(path, sics, l);
}
/* build the path backwards */
path[len]='\0';
pos = len;
for (node = nodeArg; node != NULL && node != root; node = node->mama) {
len = strlen(node->name);
pos -= len;
assert(pos>0);
strncpy(path+pos, node->name, len);
pos--;
path[pos]='/';
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int RemoveParNodeCallback(char *name, pDummy object, void *internalID) {
if (object->pDescriptor->parNode) {
InternalRemoveHipadabaCallback(object->pDescriptor->parNode, internalID);
}
return 1;
}
/*--------------------------------------------------------------------------*/
void RemoveSICSInternalCallback(void *internalID) {
InternalRemoveHipadabaCallback(GetHipadabaRoot(), internalID);
ForEachCommand(RemoveParNodeCallback, internalID);
}
/*--------------------------------------------------------------------------*/
int SICSHdbGetPar(void *obj, SConnection *pCon,
char *path, int dataType, void *data, int length){
pHdb par = NULL;
@ -1332,7 +1501,7 @@ pDynString formatValue(hdbValue v, pHdb node){
if (GetHdbProperty(node, "fmt", format, sizeof format -1)) {
snprintf(number,30,format, v.v.doubleValue);
} else {
snprintf(number,30,"%12.4f", v.v.doubleValue);
snprintf(number,30,"%.6g", v.v.doubleValue);
}
DynStringCopy(result,number);
break;
@ -1351,7 +1520,7 @@ pDynString formatValue(hdbValue v, pHdb node){
if (!GetHdbProperty(node, "fmt", format+1, sizeof format -2)) {
format[0]=' ';
} else {
strcpy(format, " %12.4f");
strcpy(format, " %.6g");
}
for(i = 0; i < v.arrayLength; i++){
snprintf(number,30,format, v.v.floatArray[i]);
@ -1552,7 +1721,7 @@ static char *hdbTypeToText(int type){
static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
int type = 0, i, length = 0, priv = -1;
char *pPtr = NULL;
char *name = NULL;
pHdb parent = NULL;
pHdb child = NULL;
char buffer[512], buffer2[512];
@ -1576,13 +1745,13 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
*/
strtolower(argv[3]);
type = convertHdbType(argv[3]);
if(type >= 7){
if(type > HIPFLOATVARAR){
SCWrite(pCon,
"ERROR: invalid type requested: none, int, float, text, intar, floatar, intvarar, floatvarar supported",
eError);
return 0;
}
if(type > 2){
if(type >= HIPINTAR){
if( argc < 5){
SCWrite(pCon,"ERROR: array length missing for array data type",
eError);
@ -1592,33 +1761,16 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
}
/* split off last path element */
strncpy(buffer,argv[1],511);
pPtr = strrchr(buffer,'/');
if(pPtr == NULL){
SCWrite(pCon,"ERROR: invalid path specification",
eError);
return 0;
}
*pPtr = '\0';
pPtr++;
if(strlen(pPtr) < 1) {
parent = root;
} else {
parent = locateSICSNode(pSics,pCon,buffer);
}
if(parent == NULL){
snprintf(buffer2,512,"ERROR: parent %s for new node does not exist",
buffer);
SCWrite(pCon,buffer2,eError);
return 0;
parent = FindHdbParent(NULL, argv[1], &name, pCon);
if (parent == NULL) {
return 0; /* error messages written inside FindHdbParent */
}
if(type != HIPNONE){
val = makeHdbValue(type,length);
child = MakeSICSHdbPar(pPtr, priv, val);
child = MakeSICSHdbPar(name, priv, val);
ReleaseHdbValue(&val);
} else {
child = MakeHipadabaNode(pPtr,type,length);
child = MakeHipadabaNode(name,type,length);
}
if(child == NULL){
SCWrite(pCon,"ERROR: out of memory creating node",eError);
@ -1633,7 +1785,7 @@ static int MakeHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
int type = 0, i, length = 0;
char *pPtr = NULL;
char *name = NULL;
pHdb parent = NULL;
pHdb child = NULL;
pHdb current = NULL;
@ -1672,28 +1824,11 @@ static int MakeHdbScriptNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
}
/* split off last path element */
strncpy(buffer,argv[1],511);
pPtr = strrchr(buffer,'/');
if(pPtr == NULL){
SCWrite(pCon,"ERROR: invalid path specification",
eError);
return 0;
parent = FindHdbParent(NULL, argv[1], &name, pCon);
if (parent == NULL) {
return 0; /* error messages written inside FindHdbParent */
}
*pPtr = '\0';
pPtr++;
if(strlen(pPtr) < 1) {
parent = root;
} else {
parent = locateSICSNode(pSics,pCon,buffer);
}
if(parent == NULL){
snprintf(buffer2,512,"ERROR: parent %s for new node does not exist",
buffer);
SCWrite(pCon,buffer2,eError);
return 0;
}
child = MakeSICSScriptPar(pPtr, argv[3], argv[2],
child = MakeSICSScriptPar(name, argv[3], argv[2],
makeHdbValue(type,length));
if(child == NULL){
SCWrite(pCon,"ERROR: out of memory creating node",eError);
@ -1755,45 +1890,6 @@ static int DeleteHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 1;
}
/*---------------------------------------------------------------------------*/
pHdb locateSICSNode(SicsInterp *pSics, SConnection *pCon, char *path){
pHdb result = NULL;
char *pPtr = NULL, sicsObj[128], error[256];
pDummy pDum = NULL;
CommandList *pCom = NULL;
if(strstr(path,"/sics/") != NULL){
pPtr = stptok(path,sicsObj,128,"/");
pPtr = stptok(pPtr,sicsObj,128,"/");
pPtr = stptok(pPtr,sicsObj,128,"/");
strtolower(sicsObj);
pCom = FindCommand(pSics,sicsObj);
if(pCom == NULL) {
snprintf(error,255,"ERROR: object %s not found",sicsObj);
SCWrite(pCon,error,eError);
return NULL;
}
pDum = (pDummy)pCom->pData;
if(pDum == NULL){
snprintf(error,255,"ERROR: object %s has no data",sicsObj);
SCWrite(pCon,error,eError);
return NULL;
}
if(pDum->pDescriptor->parNode == NULL){
snprintf(error,255,"ERROR: object %s does not use Hipadaba",sicsObj);
SCWrite(pCon,error,eError);
return NULL;
}
result = GetHipadabaNode(pDum->pDescriptor->parNode,pPtr);
} else {
result = GetHipadabaNode(root,path);
}
if(result == NULL){
snprintf(error,255,"ERROR: node %s NOT found",path);
SCWrite(pCon,error,eError);
}
return result;
}
/*---------------------------------------------------------------------------*/
static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pHdb targetNode = NULL;
@ -1812,7 +1908,7 @@ static int SetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -1865,7 +1961,7 @@ static int UpdateHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -1915,7 +2011,7 @@ static int ZipGetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -1939,7 +2035,7 @@ static int GetHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -1988,7 +2084,7 @@ static int GetHdbVal(SConnection *pCon, SicsInterp *pSics, void *pData,
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -2035,7 +2131,7 @@ static int HdbNodeInfo(SConnection *pCon, SicsInterp *pSics, void *pData,
}
strncpy(oriPath,argv[1], 511);
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -2063,7 +2159,7 @@ static int HdbNodeVal(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
return 0;
}
@ -2218,7 +2314,7 @@ static pDynString formatClientList(pHdb node){
DynStringConcat(result,number);
break;
case HIPFLOAT:
snprintf(number,50,"%lf",current->value.v.doubleValue);
snprintf(number,50,"%lg",current->value.v.doubleValue);
DynStringConcat(result,number);
break;
case HIPTEXT:
@ -2272,7 +2368,7 @@ static int ListHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
}
}
node = locateSICSNode(pSics,pCon,argv[pathArg]);
node = FindHdbNode(NULL,argv[pathArg],pCon);
if(node == NULL){
return 0;
}
@ -2318,7 +2414,7 @@ static int AutoNotifyHdbNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
node = locateSICSNode(pSics,pCon,argv[1]);
node = FindHdbNode(NULL,argv[1],pCon);
if(node == NULL){
return 0;
}
@ -2568,7 +2664,7 @@ static int CommandGetCallback(void *userData, void *callData, pHdb node,
/*--------------------------------------------------------------------------*/
static int SicsCommandNode(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
char buffer[512], buffer2[512], *pPtr = NULL;
char *name = NULL;
pHdbCallback kalle = NULL;
pHdb parent = NULL, node = NULL;
@ -2580,28 +2676,11 @@ static int SicsCommandNode(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
/* split off last path element */
strncpy(buffer,argv[1],511);
pPtr = strrchr(buffer,'/');
if(pPtr == NULL){
SCWrite(pCon,"ERROR: invalid path specification",
eError);
return 0;
}
*pPtr = '\0';
pPtr++;
if(strlen(pPtr) < 1) {
parent = root;
} else {
parent = locateSICSNode(pSics,pCon,buffer);
}
parent = FindHdbParent(NULL, argv[1], &name, pCon);
if(parent == NULL){
snprintf(buffer2,512,"ERROR: parent %s for new node does not exist",
buffer);
SCWrite(pCon,buffer2,eError);
return 0;
return 0; /* error message already written */
}
node = MakeHipadabaNode(pPtr, HIPTEXT, 1);
node = MakeHipadabaNode(name, HIPTEXT, 1);
if(node == NULL){
SCWrite(pCon,"ERROR: out of memory in hcommand",eError);
return 0;
@ -2639,7 +2718,7 @@ static int SetSICSHdbProperty(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: need path key value as parameters",eError);
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
SCWrite(pCon,"ERROR: node not found",eError);
return 0;
@ -2660,7 +2739,7 @@ static int GetSICSHdbProperty(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: need path key as parameters",eError);
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
SCWrite(pCon,"ERROR: node not found",eValue);
return 0;
@ -2684,7 +2763,7 @@ static int GetSICSHdbPropertyVal(SConnection *pCon, SicsInterp *pSics, void *pDa
SCWrite(pCon,"ERROR: need path key as parameters",eError);
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
SCWrite(pCon,"ERROR: node not found",eValue);
return 0;
@ -2709,7 +2788,7 @@ static int ListSICSHdbProperty(SConnection *pCon, SicsInterp *pSics, void *pData
SCWrite(pCon,"ERROR: need path as parameter",eError);
return 0;
}
targetNode = locateSICSNode(pSics,pCon,argv[1]);
targetNode = FindHdbNode(NULL,argv[1],pCon);
if(targetNode == NULL){
SCWrite(pCon,"ERROR: node not found",eError);
return 0;

View File

@ -1,4 +1,4 @@
/**
/** @file
* This is a set of helper functions for SICS to work with the hierarchical parameter
* database hipadaba. In SICS, the calldata associated with any callback will always
* be the connection object.
@ -115,7 +115,7 @@ pHdbCallback MakeMemSetCallback(float *address);
/**
* make a tree chnage callback
* @param pCon The connection to notfy on tree chnages
* @id The ID of this callback
* @param id The ID of this callback
* @return a suitable callback for notififications about tree changes.
*/
pHdbCallback MakeTreeChangeCallback(SConnection *pCon, int id);
@ -154,7 +154,7 @@ pHdb CreateSICSHdbPar(char *name, int priv, int dataType,
* @param name The name of the parameter
* @param priv The privilege required to change that parameter
* @param sicsObject The object corresponding to this parameter.
* @param dataType The datatype of this variable
* @param datatype The datatype of this variable
* @return A new suitably configured Hdb parameter or NULL when out of memory.
*/
pHdb MakeSICSHdbDriv(char *name, int priv,void *sicsObject, int datatype);
@ -187,6 +187,9 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v
* make a SICS scriptable parameter. I.e. when this parameter is set or read,
* appropriate scripts are invoked.
* @param name The name of the parameter
* @param setScript
* @param readScript
* @param name The name of the parameter
* @param dataType The datatype for the new parameter.
* @param length The length of any arrays
* @param data Data to initalise the parameter with. Can be NULL, then
@ -208,6 +211,7 @@ void RemoveSICSPar(pHdb node, void *callData);
/**
* add a new simple hdb parameter as child to node
* @param node The node to add the new node too.
* @param name The name of the new node
* @param priv The privilege required to change that parameter
* @param v The initial value and datatype of this parameter
* @return 1 on success, 0 else
@ -216,6 +220,7 @@ int AddSICSHdbPar(pHdb node, char *name, int priv, hdbValue v);
/**
* add a new read only hdb parameter as child to node
* @param node The node to add the new node too.
* @param name The name of the new node
* @param v The initial value and datatype of this parameter
* @return 1 on success, 0 else
*/
@ -226,6 +231,7 @@ int AddSICSHdbROPar(pHdb node, char *name, hdbValue v);
* arrays and fixed sized strings. This does not work for dynamically sized
* arrays or strings.
* @param node The node to add the new node too.
* @param name The name of the new node
* @param priv The privilege required to change that parameter
* @param data The pointer to map this parameter too. This must be in
* dynamically allocated memory.
@ -237,6 +243,48 @@ int AddSICSHdbROPar(pHdb node, char *name, hdbValue v);
int AddSICSHdbMemPar(pHdb node, char *name, int priv,
void *data, int datalength, int type, int length);
/*============== access support functions =================================*/
/** Find the parent of a node to be created
* @param rootpath the root path (where to start). May be NULL for absolute paths
* @param relpath an absolute or relative path
* @param namePtr (output) a pointer to a name. Will be the last element of
* the path if the parent was found. If namePtr is NULL, the routine does
* the same as FindHdbNode(root, relpath, pCon)
* @param pCon a connection for writing the error messages (may be NULL)
* @return the parent node or NULL on failure
*
* An abolute path starts with a slash, else it is a relative path.
* If the node exists already, an error message is emitted (node exists already)
* and NULL is returned.
*
* Nodes anchored in the sics object list are also found when
* the path starts with "/sics/"
*/
pHdb FindHdbParent(char *rootpath, char *relpath, char **namePtr, SConnection *pCon);
/** FindHdbNode finds a node
* @param rootpath the root path (where to start). May be NULL for absolute paths.
* @param relpath an absolute or relative path
* @param pCon a connection for writing the error messages (may be NULL)
* @return the found node or NULL on failure
*
* An abolute path starts with a slash, else it is a relative path.
* If relpath if a single dot ('.') root is returned.
*
* Nodes anchored in the sics object list are also found when
* the path starts with "/sics/"
*/
pHdb FindHdbNode(char *rootpath, char *relpath, SConnection *pCon);
/** Get the absolute path of a node anchored in the
* Hipadaba root or in a sics object
* @param nodeArg the input node
* @param path the result
* @param pathlen length of the result
* @return 1 on success, 0 on failure
*/
int GetHdbPath(pHdb nodeArg, char *path, size_t pathlen);
/** Remove all Callbacks rooted in the main root _and_ in sics objects
* @param internalID the internalID to be looked for
*/
void RemoveSICSInternalCallback(void *internalID);
/**
* SICSHdbGetPar returns the value of a parameter.
* @param obj The object for which to get a parameter.
@ -280,14 +328,6 @@ int SICSHdbSetPar(void *obj, SConnection *pCon,
*/
int isSICSHdbRO(pHdb node);
/*============= common SICS Interactions ===================================*/
/**
* locate a SICS Hdb node, thereby honouring the /sics/object/par syntax
* @param pSics, the SICS interpreter
* @param pCon A connection to report errors too
* @param path The path to locate
* @return The demanded node or NULL in case of failure
*/
pHdb locateSICSNode(SicsInterp *pSics, SConnection *pCon, char *path);
/**
* Install a SICS automatic notification callback on the node. This is
* a default callback using the current connection with its current
@ -317,9 +357,9 @@ int ProcessSICSHdbPar(pHdb root, SConnection *pCon, char *printPrefix,
/**
* print a listing of the parameters of node to pCon, using the
* specified prefix.
* @param The node to print
* @pCon The connection to print too
* @prefix The prefix to use for printing
* @param node The node to print
* @param pCon The connection to print too
* @param prefix The prefix to use for printing
*/
void PrintSICSParList(pHdb node, SConnection *pCon, char *prefix);
/**