/*------------------------------------------------------------------*/ pNXVcontext NXVinit(const char *nxdlDir) { pNXVcontext self = NULL; self = malloc(sizeof(struct __NXVContext)); if(self == NULL){ return NULL; } memset(self, 0, sizeof(struct __NXVContext)); self->logger = NXVdefaultLogger; self->nxdlRetriever = NXVdefaultRetriever; self->retrieverUserData = (char *)nxdlDir; hash_construct_table(&self->logData,50); hash_construct_table(&self->dimSymbols,20); return self; }
/*--------------------------------------------------------------*/ void NXVprepareContext(pNXVcontext self, char *dataFile, char *appDef) { if(self->dataFile != NULL){ free(self->dataFile); } self->dataFile = strdup(dataFile); if(self->nxdlFile){ free(self->nxdlFile); } if(appDef != NULL){ self->nxdlFile = strdup(appDef); } else { self->nxdlFile = NULL; } hash_free_table(&self->logData,free); hash_construct_table(&self->logData,50); hash_insert("dataFile",strdup(dataFile),&self->logData); hash_free_table(&self->dimSymbols,free); hash_construct_table(&self->dimSymbols,20); self->errCount = 0; self->warnCount = 0; }
int main(void) { hash_table table; char *strings[] = { "The first string", "The second string", "The third string", "The fourth string", "A much longer string than the rest in this example.", "The last string", NULL }; char *junk[] = { "The first data", "The second data", "The third data", "The fourth data", "The fifth datum", "The sixth piece of data" }; int i; void *j; hash_construct_table(&table, 211); /* I know, no checking on strdup ;-)), but using strdup to demonstrate hash_table_free with a functionpointer */ for (i = 0; NULL != strings[i]; i++) hash_insert(strings[i], strdup(junk[i]), &table); /* enumerating to a file */ if (NULL != (o = fopen("HASH.HSH", "wb"))) { fprintf(o, "%d strings in the table:\n\n", table.count); hash_enumerate(&table, fprinter); fprintf(o, "\nsorted by key:\n"); hash_sorted_enum(&table, fprinter); fclose(o); } /* enumerating to screen */ hash_sorted_enum(&table, printer); printf("\n"); /* delete 3 strings, should be 3 left */ for (i = 0; i < 3; i++) { /* hash_del returns a pointer to the data */ strfree(hash_del(strings[i], &table)); } hash_enumerate(&table, printer); for (i = 0; NULL != strings[i]; i++) { j = hash_lookup(strings[i], &table); if (NULL == j) printf("\n'%s' is not in the table", strings[i]); else printf("\n%s is still in the table.", strings[i]); } hash_free_table(&table, strfree); return 0; }
/*--------------------------------------------------------------*/ int NXVvalidateGroup(pNXVcontext self, hid_t groupID, xmlNodePtr groupNode) { hash_table namesSeen, baseNames; xmlNodePtr cur = NULL; xmlChar *name = NULL, *myClass = NULL; xmlChar *target = NULL; hid_t childID; char fName[256], childName[512], nxdlChildPath[512], childPath[512]; char mynxdlPath[512]; char *savedNXDLPath, *pPtr; SecondPassData spd; hsize_t idx = 0; /* manage nxdlPath, xmlGetNodePath does not work */ savedNXDLPath = self->nxdlPath; myClass = xmlGetProp(groupNode,(xmlChar *)"type"); if(self->nxdlPath == NULL) { snprintf(mynxdlPath,sizeof(mynxdlPath),"/%s", (char *) myClass); } else { snprintf(mynxdlPath,sizeof(mynxdlPath),"%s/%s", self->nxdlPath, (char *) myClass); } self->nxdlPath = mynxdlPath; /* tell what we are doing */ H5Iget_name(groupID,fName,sizeof(fName)); NXVsetLog(self,"sev","debug"); NXVsetLog(self,"message","Validating group"); NXVsetLog(self,"nxdlPath",self->nxdlPath); NXVsetLog(self,"dataPath",fName); NXVlog(self); validateGroupAttributes(self, groupID, groupNode); hash_construct_table(&namesSeen,100); /* first pass */ cur = groupNode->xmlChildrenNode; while(cur != NULL){ if(xmlStrcmp(cur->name,(xmlChar *) "group") == 0){ childID = findGroup(self, groupID, cur); if(childID >= 0){ H5Iget_name(childID, childName,sizeof(childName)); /* we have to get at the HDF5 name. There may be no name in the NXDL, but a suitable group has been found by NXclass. */ pPtr = strrchr(childName,'/'); if(pPtr != NULL){ hash_insert(pPtr+1,strdup(""),&namesSeen); } else { hash_insert(childName,strdup(""),&namesSeen); } NXVvalidateGroup(self,childID,cur); } else { name = xmlGetProp(cur,(xmlChar *)"type"); snprintf(nxdlChildPath,sizeof(nxdlChildPath),"%s/%s", self->nxdlPath, (char *)name); xmlFree(name); NXVsetLog(self,"dataPath",fName); NXVsetLog(self,"nxdlPath", nxdlChildPath); if(!isOptional(cur)){ NXVsetLog(self,"sev","error"); NXVsetLog(self,"message","Required group missing"); NXVlog(self); self->errCount++; } else { NXVsetLog(self,"sev","warnopt"); NXVsetLog(self,"message","Optional group missing"); NXVlog(self); } } } if(xmlStrcmp(cur->name,(xmlChar *) "field") == 0){ name = xmlGetProp(cur,(xmlChar *)"name"); if(H5LTfind_dataset(groupID,(char *)name) ) { childID = H5Dopen(groupID,(char *)name,H5P_DEFAULT); } else { childID = -1; } snprintf(childPath,sizeof(childPath),"%s/%s", fName,name); if(childID < 0){ NXVsetLog(self,"dataPath",childPath); snprintf(nxdlChildPath,sizeof(nxdlChildPath), "%s/%s", self->nxdlPath, name); NXVsetLog(self,"nxdlPath", nxdlChildPath); if(!isOptional(cur)){ NXVsetLog(self,"sev","error"); NXVsetLog(self,"message","Required field missing"); NXVlog(self); self->errCount++; } else { NXVsetLog(self,"sev","warnopt"); NXVsetLog(self,"message","Optional field missing"); NXVlog(self); } } else { if(xmlStrcmp(name,(xmlChar *)"depends_on") == 0){ /* This must b validated from the field level. As it might point to fields which are not in the application definition */ validateDependsOn(self,groupID,childID); } else { NXVvalidateField(self,childID, cur); } hash_insert((char *)name,strdup(""),&namesSeen); } xmlFree(name); } if(xmlStrcmp(cur->name,(xmlChar *) "link") == 0){ name = xmlGetProp(cur,(xmlChar *)"name"); target = xmlGetProp(cur,(xmlChar *)"target"); hash_insert((char *)name,strdup(""),&namesSeen); validateLink(self,groupID,name, target); xmlFree(name); xmlFree(target); } cur = cur->next; } /* Second pass: search the HDF5 group for additional stuff which have not checked yet. Most of the hard work is in the SecondPassIterator. */ hash_construct_table(&baseNames,100); NXVloadBaseClass(self,&baseNames,(char *)myClass); spd.baseNames = &baseNames; spd.namesSeen = &namesSeen; spd.self = self; NXVsetLog(self,"nxdlPath", mynxdlPath); H5Literate(groupID, H5_INDEX_NAME, H5_ITER_INC, &idx, SecondPassIterator, &spd); /* clean up */ hash_free_table(&namesSeen,free); hash_free_table(&baseNames,free); xmlFree(myClass); /* restore my paths... */ self->nxdlPath = savedNXDLPath; return 0; }