diff --git a/polldriv.c b/polldriv.c index 5a852307..a5dc8fdc 100644 --- a/polldriv.c +++ b/polldriv.c @@ -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; diff --git a/sicshipadaba.c b/sicshipadaba.c index 49447530..358694ec 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -27,6 +27,8 @@ #include #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; diff --git a/sicshipadaba.h b/sicshipadaba.h index d60a6dd7..42c0c0bc 100644 --- a/sicshipadaba.h +++ b/sicshipadaba.h @@ -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); /**