Fixed bug in hash.c
A bug in the delete function in hash.c was preventing the unit test of the new set ID API functions from running properly. In fixing this bug the entire hash table code was refactored to make it look more like the mempool service routines. Also the need to copy the string passed into the table's insert function was eliminated.
This commit is contained in:
@@ -129,8 +129,6 @@ Both network files are available [here](https://doi.org/10.23719/1375314).
|
||||
## New API functions
|
||||
|Function|Description|
|
||||
|--|--|
|
||||
|`ENaddlink`| |
|
||||
|`ENaddnode`| |
|
||||
|`ENgetcurvetype`| |
|
||||
|`ENgetdemandmodel`||
|
||||
|`ENsetdemandmodel`||
|
||||
@@ -156,6 +154,8 @@ Both network files are available [here](https://doi.org/10.23719/1375314).
|
||||
|`ENaddlink`||
|
||||
|`ENdeletelink`||
|
||||
|`ENdeletenode`||
|
||||
| `ENsetnodeid` ||
|
||||
| `ENsetlinkid` ||
|
||||
|`ENgetdemandname`||
|
||||
|`ENsetdemandname`||
|
||||
|
||||
|
||||
53
src/epanet.c
53
src/epanet.c
@@ -89,9 +89,9 @@ This module calls the following functions that reside in other modules:
|
||||
writelogo()
|
||||
writereport()
|
||||
HASH.C
|
||||
ENHashTablecreate()
|
||||
ENHashTableFind()
|
||||
ENHashTableFree()
|
||||
hashtable_create()
|
||||
hashtable_find()
|
||||
hashtable_free()
|
||||
|
||||
The macro ERRCODE(x) is defined in TYPES.H. It says if the current
|
||||
value of the error code variable (errcode) is not fatal (< 100) then
|
||||
@@ -857,7 +857,6 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph)
|
||||
freedata(p);
|
||||
|
||||
out = &p->out_files;
|
||||
|
||||
if (out->TmpOutFile != out->OutFile) {
|
||||
if (out->TmpOutFile != NULL) {
|
||||
fclose(out->TmpOutFile);
|
||||
@@ -2916,15 +2915,15 @@ int DLLEXPORT EN_setnodeid(EN_ProjectHandle ph, int index, char *newid)
|
||||
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 209);
|
||||
|
||||
// Check if another node with same name exists
|
||||
if (ENHashTableFind(net->NodeHashTable, newid) > 0)
|
||||
if (hashtable_find(net->NodeHashTable, newid) > 0)
|
||||
{
|
||||
return set_error(p->error_handle, 215);
|
||||
}
|
||||
|
||||
// Replace the existing node ID with the new value
|
||||
ENHashTableDelete(net->NodeHashTable, net->Node[index].ID);
|
||||
hashtable_delete(net->NodeHashTable, net->Node[index].ID);
|
||||
strncpy(net->Node[index].ID, newid, MAXID);
|
||||
ENHashTableInsert(net->NodeHashTable, net->Node[index].ID, index);
|
||||
hashtable_insert(net->NodeHashTable, net->Node[index].ID, index);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -3210,15 +3209,15 @@ int DLLEXPORT EN_setlinkid(EN_ProjectHandle ph, int index, char *newid)
|
||||
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 211);
|
||||
|
||||
// Check if another link with same name exists
|
||||
if (ENHashTableFind(net->LinkHashTable, newid) > 0)
|
||||
if (hashtable_find(net->LinkHashTable, newid) > 0)
|
||||
{
|
||||
return set_error(p->error_handle, 215);
|
||||
}
|
||||
|
||||
// Replace the existing link ID with the new value
|
||||
ENHashTableDelete(net->LinkHashTable, net->Link[index].ID);
|
||||
hashtable_delete(net->LinkHashTable, net->Link[index].ID);
|
||||
strncpy(net->Link[index].ID, newid, MAXID);
|
||||
ENHashTableInsert(net->LinkHashTable, net->Link[index].ID, index);
|
||||
hashtable_insert(net->LinkHashTable, net->Link[index].ID, index);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -4325,8 +4324,8 @@ int allocdata(EN_Project *p)
|
||||
parser_data_t *par;
|
||||
|
||||
/* Allocate node & link ID hash tables */
|
||||
p->network.NodeHashTable = ENHashTableCreate();
|
||||
p->network.LinkHashTable = ENHashTableCreate();
|
||||
p->network.NodeHashTable = hashtable_create();
|
||||
p->network.LinkHashTable = hashtable_create();
|
||||
ERRCODE(MEMCHECK(p->network.NodeHashTable));
|
||||
ERRCODE(MEMCHECK(p->network.LinkHashTable));
|
||||
|
||||
@@ -4531,10 +4530,9 @@ void freedata(EN_Project *p)
|
||||
freerules(p);
|
||||
|
||||
/* Free hash table memory */
|
||||
if (net->NodeHashTable != NULL)
|
||||
ENHashTableFree(net->NodeHashTable);
|
||||
if (net->LinkHashTable != NULL)
|
||||
ENHashTableFree(net->LinkHashTable);
|
||||
if (net->NodeHashTable != NULL) hashtable_free(net->NodeHashTable);
|
||||
|
||||
if (net->LinkHashTable != NULL) hashtable_free(net->LinkHashTable);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4637,7 +4635,7 @@ int findnode(EN_Network *n, char *id)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return (ENHashTableFind(n->NodeHashTable, id));
|
||||
return (hashtable_find(n->NodeHashTable, id));
|
||||
}
|
||||
|
||||
int findlink(EN_Network *n, char *id)
|
||||
@@ -4649,7 +4647,7 @@ int findlink(EN_Network *n, char *id)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return (ENHashTableFind(n->LinkHashTable, id));
|
||||
return (hashtable_find(n->LinkHashTable, id));
|
||||
}
|
||||
|
||||
int findtank(EN_Network *n, int index)
|
||||
@@ -5055,7 +5053,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
|
||||
|
||||
// shift rest of Node array
|
||||
for (index = net->Nnodes; index >= net->Njuncs; index--) {
|
||||
ENHashTableUpdate(net->NodeHashTable, net->Node[index].ID, index + 1);
|
||||
hashtable_update(net->NodeHashTable, net->Node[index].ID, index + 1);
|
||||
net->Node[index + 1] = net->Node[index];
|
||||
net->Coord[index + 1] = net->Coord[index];
|
||||
}
|
||||
@@ -5171,7 +5169,7 @@ int DLLEXPORT EN_addnode(EN_ProjectHandle ph, char *id, EN_NodeType nodeType) {
|
||||
coord->Y = 0;
|
||||
|
||||
/* Insert new node into hash table */
|
||||
ENHashTableInsert(net->NodeHashTable, node->ID, nIdx); /* see HASH.C */
|
||||
hashtable_insert(net->NodeHashTable, node->ID, nIdx); /* see HASH.C */
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -5194,8 +5192,8 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch
|
||||
return set_error(p->error_handle, 215);
|
||||
|
||||
/* Lookup the from and to nodes */
|
||||
N1 = ENHashTableFind(net->NodeHashTable, fromNode);
|
||||
N2 = ENHashTableFind(net->NodeHashTable, toNode);
|
||||
N1 = hashtable_find(net->NodeHashTable, fromNode);
|
||||
N2 = hashtable_find(net->NodeHashTable, toNode);
|
||||
|
||||
if (N1 == 0 || N2 == 0) {
|
||||
return set_error(p->error_handle, 203);
|
||||
@@ -5277,7 +5275,7 @@ int DLLEXPORT EN_addlink(EN_ProjectHandle ph, char *id, EN_LinkType linkType, ch
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, "");
|
||||
|
||||
ENHashTableInsert(net->LinkHashTable, link->ID, n);
|
||||
hashtable_insert(net->LinkHashTable, link->ID, n);
|
||||
return set_error(p->error_handle, 0);
|
||||
}
|
||||
|
||||
@@ -5300,15 +5298,14 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int index) {
|
||||
link = &net->Link[index];
|
||||
|
||||
// remove from hash table
|
||||
ENHashTableDelete(net->LinkHashTable, link->ID);
|
||||
ENHashTableFind(net->LinkHashTable, link->ID);
|
||||
hashtable_delete(net->LinkHashTable, link->ID);
|
||||
|
||||
// shift link and pump arrays to re-sort link indices
|
||||
net->Nlinks--;
|
||||
for (i = index; i <= net->Nlinks - 1; i++) {
|
||||
net->Link[i] = net->Link[i + 1];
|
||||
// update hashtable
|
||||
ENHashTableUpdate(net->LinkHashTable, net->Link[i].ID, i);
|
||||
hashtable_update(net->LinkHashTable, net->Link[i].ID, i);
|
||||
}
|
||||
for (i = 1; i <= net->Npumps; i++) {
|
||||
if (net->Pump[i].Link > index) {
|
||||
@@ -5361,14 +5358,14 @@ int DLLEXPORT EN_deletenode(EN_ProjectHandle ph, int index) {
|
||||
// TODO: check for existing controls/rules that reference this node?
|
||||
|
||||
// remove from hash table
|
||||
ENHashTableDelete(net->NodeHashTable, net->Node[index].ID);
|
||||
hashtable_delete(net->NodeHashTable, net->Node[index].ID);
|
||||
|
||||
// shift node and coord array to remove node
|
||||
for (i = index; i <= net->Nnodes - 1; i++) {
|
||||
net->Node[i] = net->Node[i + 1];
|
||||
net->Coord[i] = net->Coord[i + 1];
|
||||
// update hashtable
|
||||
ENHashTableUpdate(net->NodeHashTable, net->Node[i].ID, i);
|
||||
hashtable_update(net->NodeHashTable, net->Node[i].ID, i);
|
||||
}
|
||||
|
||||
// update tank array
|
||||
|
||||
269
src/hash.c
269
src/hash.c
@@ -1,21 +1,20 @@
|
||||
/*-----------------------------------------------------------------------------
|
||||
** hash.c
|
||||
**
|
||||
** Implementation of a simple Hash Table for string storage & retrieval
|
||||
** Implementation of a simple Hash Table that uses a string pointer
|
||||
** as a key and an associated integer as data.
|
||||
**
|
||||
** Written by L. Rossman
|
||||
** Last Updated on 6/19/03
|
||||
** Last Updated on 10/17/18
|
||||
**
|
||||
** The hash table data structure (HTable) is defined in "hash.h".
|
||||
** Interface Functions:
|
||||
** HTcreate() - creates a hash table
|
||||
** HTinsert() - inserts a string & its index value into a hash table
|
||||
** HTfind() - retrieves the index value of a string from a table
|
||||
** HTfree() - frees a hash table
|
||||
** hashtable_create - creates a hash table
|
||||
** hashtable_insert - inserts a string & its data value into a table
|
||||
** hashtable_find - retrieves the data value associated with a string
|
||||
** hashtable_findkey - retrieves the key associated with a data value
|
||||
** hashtable_delete - deletes an entry from a table
|
||||
** hashtable_free - frees a hash table
|
||||
**
|
||||
*********************************************************************
|
||||
** NOTE: This is a modified version of the original HASH.C module.
|
||||
*********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __APPLE__
|
||||
@@ -26,144 +25,148 @@
|
||||
#include <string.h>
|
||||
#include "hash.h"
|
||||
|
||||
unsigned int _enHash(char *str);
|
||||
unsigned int _enHash(char *str)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
unsigned int retHash;
|
||||
int c;
|
||||
while ((c = *str++)) {
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
}
|
||||
retHash = hash % ENHASHTABLEMAXSIZE;
|
||||
#define HASHTABLEMAXSIZE 128000
|
||||
|
||||
return retHash;
|
||||
}
|
||||
|
||||
ENHashTable *ENHashTableCreate()
|
||||
typedef struct DataEntryStruct
|
||||
{
|
||||
int i;
|
||||
ENHashTable *ht = (ENHashTable *) calloc(ENHASHTABLEMAXSIZE, sizeof(ENHashTable));
|
||||
if (ht != NULL) {
|
||||
for (i=0; i<ENHASHTABLEMAXSIZE; i++) {
|
||||
ht[i] = NULL;
|
||||
char *key;
|
||||
int data;
|
||||
struct DataEntryStruct *next;
|
||||
} DataEntry;
|
||||
|
||||
unsigned int gethash(char *str)
|
||||
{
|
||||
unsigned int hash = 5381;
|
||||
unsigned int retHash;
|
||||
int c;
|
||||
while ((c = *str++))
|
||||
{
|
||||
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
||||
}
|
||||
}
|
||||
return(ht);
|
||||
retHash = hash % HASHTABLEMAXSIZE;
|
||||
return retHash;
|
||||
}
|
||||
|
||||
int ENHashTableInsert(ENHashTable *ht, char *key, int data)
|
||||
HashTable *hashtable_create()
|
||||
{
|
||||
size_t len;
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(0);
|
||||
}
|
||||
entry = (ENHashEntry *) malloc(sizeof(ENHashEntry));
|
||||
if (entry == NULL) {
|
||||
return(0);
|
||||
}
|
||||
len = strlen(key) + 1;
|
||||
entry->key = calloc(len, sizeof(char));
|
||||
strncpy(entry->key, key, len);
|
||||
entry->data = data;
|
||||
entry->next = ht[i];
|
||||
ht[i] = entry;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Abel Heinsbroek: Added function to update the hash table value for a given key */
|
||||
int ENHashTableUpdate(ENHashTable *ht, char *key, int new_data)
|
||||
{
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NOTFOUND);
|
||||
}
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key,key) == 0 ) {
|
||||
entry->data = new_data;
|
||||
return(1);
|
||||
int i;
|
||||
HashTable *ht = (HashTable *) calloc(HASHTABLEMAXSIZE, sizeof(HashTable));
|
||||
if (ht != NULL)
|
||||
{
|
||||
for (i = 0; i < HASHTABLEMAXSIZE; i++) ht[i] = NULL;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return(NOTFOUND);
|
||||
return ht;
|
||||
}
|
||||
|
||||
int ENHashTableDelete(ENHashTable *ht, char *key) {
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NOTFOUND);
|
||||
}
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if (strcmp(entry->key, key) == 0) {
|
||||
entry->key = "";
|
||||
return(1);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
return(NOTFOUND);
|
||||
}
|
||||
|
||||
int ENHashTableFind(ENHashTable *ht, char *key)
|
||||
int hashtable_insert(HashTable *ht, char *key, int data)
|
||||
{
|
||||
unsigned int i = _enHash(key);
|
||||
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NOTFOUND);
|
||||
}
|
||||
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key,key) == 0 ) {
|
||||
return(entry->data);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return(NOTFOUND);
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return 0;
|
||||
entry = (DataEntry *) malloc(sizeof(DataEntry));
|
||||
if (entry == NULL) return(0);
|
||||
entry->key = key;
|
||||
entry->data = data;
|
||||
entry->next = ht[i];
|
||||
ht[i] = entry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char *ENHashTableFindKey(ENHashTable *ht, char *key)
|
||||
int hashtable_update(HashTable *ht, char *key, int new_data)
|
||||
{
|
||||
unsigned int i = _enHash(key);
|
||||
ENHashEntry *entry;
|
||||
if ( i >= ENHASHTABLEMAXSIZE ) {
|
||||
return(NULL);
|
||||
}
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key,key) == 0 ) {
|
||||
return(entry->key);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void ENHashTableFree(ENHashTable *ht)
|
||||
{
|
||||
ENHashEntry *entry, *nextentry;
|
||||
int i;
|
||||
for (i=0; i<ENHASHTABLEMAXSIZE; i++)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
nextentry = entry->next;
|
||||
free(entry->key);
|
||||
free(entry);
|
||||
entry = nextentry;
|
||||
if ( strcmp(entry->key, key) == 0 )
|
||||
{
|
||||
entry->data = new_data;
|
||||
return 1;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
free(ht);
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
int hashtable_delete(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry, *preventry;
|
||||
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
|
||||
// Check if first entry in bucket i to be deleted
|
||||
entry = ht[i];
|
||||
if (strcmp(entry->key, key) == 0)
|
||||
{
|
||||
ht[i] = entry->next;
|
||||
free(entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check remaining entries in bucket i
|
||||
preventry = ht[i];
|
||||
entry = ht[i]->next;
|
||||
while (entry != NULL)
|
||||
{
|
||||
if (strcmp(entry->key, key) == 0)
|
||||
{
|
||||
preventry->next = entry->next;
|
||||
free(entry);
|
||||
return 1;
|
||||
}
|
||||
preventry = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
int hashtable_find(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NOTFOUND;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key, key) == 0 )
|
||||
{
|
||||
return entry->data;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
return NOTFOUND;
|
||||
}
|
||||
|
||||
char *hashtable_findkey(HashTable *ht, char *key)
|
||||
{
|
||||
unsigned int i = gethash(key);
|
||||
DataEntry *entry;
|
||||
if ( i >= HASHTABLEMAXSIZE ) return NULL;
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
if ( strcmp(entry->key, key) == 0 ) return entry->key;
|
||||
entry = entry->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hashtable_free(HashTable *ht)
|
||||
{
|
||||
DataEntry *entry, *nextentry;
|
||||
int i;
|
||||
for (i = 0; i < HASHTABLEMAXSIZE; i++)
|
||||
{
|
||||
entry = ht[i];
|
||||
while (entry != NULL)
|
||||
{
|
||||
nextentry = entry->next;
|
||||
free(entry);
|
||||
entry = nextentry;
|
||||
}
|
||||
}
|
||||
free(ht);
|
||||
}
|
||||
|
||||
24
src/hash.h
24
src/hash.h
@@ -7,24 +7,16 @@
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#define ENHASHTABLEMAXSIZE 128000
|
||||
#define NOTFOUND 0
|
||||
|
||||
typedef struct HTentryStruct
|
||||
{
|
||||
char *key;
|
||||
int data;
|
||||
struct HTentryStruct *next;
|
||||
} ENHashEntry;
|
||||
typedef struct DataEntryStruct *HashTable;
|
||||
|
||||
typedef ENHashEntry *ENHashTable;
|
||||
|
||||
ENHashTable *ENHashTableCreate(void);
|
||||
int ENHashTableInsert(ENHashTable *, char *, int);
|
||||
int ENHashTableFind(ENHashTable *, char *);
|
||||
char *ENHashTableFindKey(ENHashTable *, char *);
|
||||
void ENHashTableFree(ENHashTable *);
|
||||
int ENHashTableUpdate(ENHashTable *ht, char *key, int new_data);
|
||||
int ENHashTableDelete(ENHashTable *ht, char *key);
|
||||
HashTable *hashtable_create(void);
|
||||
int hashtable_insert(HashTable *, char *, int);
|
||||
int hashtable_find(HashTable *, char *);
|
||||
char *hashtable_findkey(HashTable *, char *);
|
||||
void hashtable_free(HashTable *);
|
||||
int hashtable_update(HashTable *ht, char *key, int new_data);
|
||||
int hashtable_delete(HashTable *ht, char *key);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -472,7 +472,7 @@ int addnodeID(EN_Network *net, int n, char *id)
|
||||
return (0); /* see EPANET.C */
|
||||
}
|
||||
strncpy(net->Node[n].ID, id, MAXID);
|
||||
ENHashTableInsert(net->NodeHashTable, net->Node[n].ID, n); /* see HASH.C */
|
||||
hashtable_insert(net->NodeHashTable, net->Node[n].ID, n); /* see HASH.C */
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -490,7 +490,7 @@ int addlinkID(EN_Network *net, int n, char *id)
|
||||
return (0); /* see EPANET.C */
|
||||
}
|
||||
strncpy(net->Link[n].ID, id, MAXID);
|
||||
ENHashTableInsert(net->LinkHashTable, net->Link[n].ID, n); /* see HASH.C */
|
||||
hashtable_insert(net->LinkHashTable, net->Link[n].ID, n); /* see HASH.C */
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
@@ -874,9 +874,10 @@ typedef struct {
|
||||
Scurve *Curve; /* Curve data */
|
||||
Scoord *Coord; /* Coordinate data */
|
||||
Scontrol *Control; /* Control data */
|
||||
ENHashTable *NodeHashTable,
|
||||
*LinkHashTable; /* Hash tables for ID labels */
|
||||
Padjlist *Adjlist; /* Node adjacency lists */
|
||||
HashTable
|
||||
*NodeHashTable,
|
||||
*LinkHashTable; /* Hash tables for ID labels */
|
||||
Padjlist *Adjlist; /* Node adjacency lists */
|
||||
|
||||
} EN_Network;
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
//
|
||||
// test_setid.cpp
|
||||
//
|
||||
// Test of ENsetid EPANET API Function
|
||||
|
||||
/*
|
||||
This is a test for the API functions that change a node or link ID name.
|
||||
@@ -10,77 +8,76 @@ A node and link name are changed, the network is saved, reopened and the new nam
|
||||
#define BOOST_TEST_MODULE "toolkit"
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "epanet2.h"
|
||||
|
||||
// NOTE: Project Home needs to be updated to run unit test
|
||||
#define DATA_PATH_INP "./net1.inp"
|
||||
#define DATA_PATH_RPT "./test.rpt"
|
||||
#define DATA_PATH_OUT "./test.out"
|
||||
#define DATA_PATH_INP "net1.inp"
|
||||
#define DATA_PATH_RPT "test.rpt"
|
||||
#define DATA_PATH_OUT ""
|
||||
|
||||
using namespace std;
|
||||
|
||||
BOOST_AUTO_TEST_SUITE (test_toolkit)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_setid)
|
||||
{
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int error = 0;
|
||||
int index;
|
||||
char errmsg[256];
|
||||
char id[80];
|
||||
char newid[80];
|
||||
string newid;
|
||||
|
||||
std::string path_inp = std::string(DATA_PATH_INP);
|
||||
std::string path_rpt = std::string(DATA_PATH_RPT);
|
||||
std::string path_out = std::string(DATA_PATH_OUT);
|
||||
|
||||
error = ENopen(path_inp.c_str(), path_rpt.c_str(), path_out.c_str());
|
||||
error = ENopen(path_inp.c_str(), path_rpt.c_str(), "");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Test of illegal node name change
|
||||
error = ENgetnodeid(3, id);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
strncpy(newid, "Illegal; node name", 79);
|
||||
error = ENsetnodeid(3, newid);
|
||||
newid = "Illegal; node name";
|
||||
error = ENsetnodeid(3, (char *)newid.c_str());
|
||||
BOOST_REQUIRE(error > 0);
|
||||
|
||||
// Test of legal node name change
|
||||
strncpy(newid, "Node3", 79);
|
||||
error = ENsetnodeid(3, newid);
|
||||
newid = "Node3";
|
||||
error = ENsetnodeid(3, (char *)newid.c_str());
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Test of illegal link name change
|
||||
error = ENgetlinkid(3, id);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
strncpy(newid, "Illegal; link name", 79);
|
||||
error = ENsetlinkid(3, newid);
|
||||
newid = "Illegal; link name";
|
||||
error = ENsetlinkid(3, (char *)newid.c_str());
|
||||
BOOST_REQUIRE(error > 0);
|
||||
|
||||
// Test of legal link name change
|
||||
strncpy(newid, "Link3", 79);
|
||||
error = ENsetlinkid(3, newid);
|
||||
newid = "Link3";
|
||||
error = ENsetlinkid(3, (char *)newid.c_str());
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Save the project
|
||||
error = ENsaveinpfile("net1_setid.inp");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
error = ENclose();
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Re-open the saved project
|
||||
error = ENopen("net1_setid.inp", path_rpt.c_str(), path_out.c_str());
|
||||
error = ENopen("net1_setid.inp", path_rpt.c_str(), "");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Check that 3rd node has its new name
|
||||
error = ENgetnodeindex((char *)"Node3", &index);
|
||||
error = ENgetnodeindex("Node3", &index);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
BOOST_REQUIRE(index == 3);
|
||||
|
||||
// Check that 3rd link has its new name
|
||||
error = ENgetlinkindex((char *)"Link3", &index);
|
||||
error = ENgetlinkindex("Link3", &index);
|
||||
BOOST_REQUIRE(error == 0);
|
||||
BOOST_REQUIRE(index == 3);
|
||||
ENclose();
|
||||
|
||||
error = ENclose();
|
||||
BOOST_REQUIRE(error == 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Reference in New Issue
Block a user