Merge pull request #303 from LRossman/dev-lrossman

Fix #211 for EN_setreport
This commit is contained in:
Lew Rossman
2018-10-23 09:21:02 -04:00
committed by GitHub
12 changed files with 365 additions and 193 deletions

View File

@@ -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`||

View File

@@ -250,7 +250,9 @@ Public Const EN_G_CURVE = 4 ' General\default curve
Declare Function ENsetflowunits Lib "epanet2.dll" (ByVal code As Long) As Long
Declare Function ENaddcontrol Lib "epanet2.dll" (Cindex As Long, ByVal Ctype As Long, ByVal Lindex As Long, ByVal setting As Single, ByVal Nindex As Long, ByVal Level As Single) As Long
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Long, ByVal Ctype As Long, ByVal Lindex As Long, ByVal setting As Single, ByVal Nindex As Long, ByVal Level As Single) As Long
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, ByVal value As Single) As Long
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Long, ByVal newid As String) As Long
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal index As Long, ByVal code As Long, ByVal value As Single) As Long
Declare Function ENaddpattern Lib "epanet2.dll" (ByVal id As String) As Long
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal index As Long, F As Any, ByVal N As Long) As Long

View File

@@ -842,6 +842,14 @@ extern "C" {
@return Error code.
*/
int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level);
/**
@brief Change the ID name for a node.
@param index The index of a node. First node is index 1.
@param newid A string containing the node's new ID name.
@return Error code.
*/
int DLLEXPORT ENsetnodeid(int index, char *newid);
/**
@brief Set a property value for a node.
@@ -852,6 +860,14 @@ extern "C" {
@see EN_NodeProperty
*/
int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v);
/**
@brief Change the ID name for a link.
@param index The index of a link. First link is index 1.
@param newid A string containing the link's new ID name.
@return Error code.
*/
int DLLEXPORT ENsetlinkid(int index, char *newid);
/**
@brief Set a property value for a link.
@@ -1297,7 +1313,9 @@ extern "C" {
int DLLEXPORT EN_addcontrol(EN_ProjectHandle ph, int *cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level);
int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level);
int DLLEXPORT EN_setnodeid(EN_ProjectHandle ph, int index, char *newid);
int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v);
int DLLEXPORT EN_setlinkid(EN_ProjectHandle ph, int index, char *newid);
int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v);
int DLLEXPORT EN_addpattern(EN_ProjectHandle ph, char *id);
int DLLEXPORT EN_setpattern(EN_ProjectHandle ph, int index, EN_API_FLOAT_TYPE *f, int len);

View File

@@ -227,7 +227,9 @@ Public Const EN_CUSTOM = 2 ' user-defined custom curve
Declare Function ENgetversion Lib "epanet2.dll" (ByRef Value As Int32) As Int32
Declare Function ENsetcontrol Lib "epanet2.dll" (ByVal Cindex As Int32, ByVal CtlType As Int32, ByVal Lindex As Int32, ByVal Setting As Single, ByVal Nindex As Int32, ByVal Level As Single) As Int32
Declare Function ENsetnodeid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
Declare Function ENsetnodevalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
Declare Function ENsetlinkid Lib "epanet2.dll" (ByVal index As Int32, ByVal newid As String) As Int32
Declare Function ENsetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByVal Value As Single) As Int32
Declare Function ENsetpattern Lib "epanet2.dll" (ByVal Index as Int32, ByRef F as Single, ByVal N as Int32) as Int32
Declare Function ENsetpatternvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Period As Int32, ByVal Value As Single) As Int32

View File

@@ -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
@@ -437,10 +437,18 @@ int DLLEXPORT ENaddcontrol(int *cindex, int ctype, int lindex,
level);
}
int DLLEXPORT ENsetnodeid(int index, char *newid) {
return EN_setnodeid(_defaultModel, index, newid);
}
int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) {
return EN_setnodevalue(_defaultModel, index, code, v);
}
int DLLEXPORT ENsetlinkid(int index, char *newid) {
return EN_setlinkid(_defaultModel, index, newid);
}
int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) {
return EN_setlinkvalue(_defaultModel, index, code, v);
}
@@ -842,14 +850,12 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph)
out_file_t *out;
EN_Project *p = (EN_Project*)ph;
if (p->Openflag) {
writetime(p, FMT105);
}
freedata(p);
out = &p->out_files;
if (out->TmpOutFile != out->OutFile) {
if (out->TmpOutFile != NULL) {
fclose(out->TmpOutFile);
@@ -879,7 +885,7 @@ int DLLEXPORT EN_close(EN_ProjectHandle ph)
remove(out->HydFname);
if (out->Outflag == SCRATCH)
remove(out->OutFname);
p->Openflag = FALSE;
p->hydraulics.OpenHflag = FALSE;
p->save_options.SaveHflag = FALSE;
@@ -1377,9 +1383,10 @@ int DLLEXPORT EN_setreport(EN_ProjectHandle ph, char *s) {
if (!p->Openflag)
return set_error(p->error_handle, 102);
if (strlen(s) > MAXLINE)
if (strlen(s) >= MAXLINE)
return set_error(p->error_handle, 250);
strcpy(s1, s);
strcat(s1, "\n");
if (setreport(p, s1) > 0)
return set_error(p->error_handle, 250);
else
@@ -2891,6 +2898,34 @@ int DLLEXPORT EN_setcontrol(EN_ProjectHandle ph, int cindex, int ctype, int lind
return set_error(p->error_handle, 0);
}
int DLLEXPORT EN_setnodeid(EN_ProjectHandle ph, int index, char *newid)
{
EN_Project *p = (EN_Project*)ph;
EN_Network *net = &p->network;
size_t n;
// Check for valid arguments
if (index <= 0 || index > net->Nnodes)
{
return set_error(p->error_handle, 203);
}
n = strlen(newid);
if (n < 1 || n > MAXID) return set_error(p->error_handle, 209);
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 209);
// Check if another node with same name exists
if (hashtable_find(net->NodeHashTable, newid) > 0)
{
return set_error(p->error_handle, 215);
}
// Replace the existing node ID with the new value
hashtable_delete(net->NodeHashTable, net->Node[index].ID);
strncpy(net->Node[index].ID, newid, MAXID);
hashtable_insert(net->NodeHashTable, net->Node[index].ID, index);
return set_error(p->error_handle, 0);
}
int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_FLOAT_TYPE v)
/*----------------------------------------------------------------
** Input: index = node index
@@ -3157,6 +3192,34 @@ int DLLEXPORT EN_setnodevalue(EN_ProjectHandle ph, int index, int code, EN_API_F
return set_error(p->error_handle, 0);
}
int DLLEXPORT EN_setlinkid(EN_ProjectHandle ph, int index, char *newid)
{
EN_Project *p = (EN_Project*)ph;
EN_Network *net = &p->network;
size_t n;
// Check for valid arguments
if (index <= 0 || index > net->Nlinks)
{
return set_error(p->error_handle, 204);
}
n = strlen(newid);
if (n < 1 || n > MAXID) return set_error(p->error_handle, 211);
if (strcspn(newid, " ;") < n) return set_error(p->error_handle, 211);
// Check if another link with same name exists
if (hashtable_find(net->LinkHashTable, newid) > 0)
{
return set_error(p->error_handle, 215);
}
// Replace the existing link ID with the new value
hashtable_delete(net->LinkHashTable, net->Link[index].ID);
strncpy(net->Link[index].ID, newid, MAXID);
hashtable_insert(net->LinkHashTable, net->Link[index].ID, index);
return set_error(p->error_handle, 0);
}
int DLLEXPORT EN_setlinkvalue(EN_ProjectHandle ph, int index, int code,
EN_API_FLOAT_TYPE v)
@@ -4260,8 +4323,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));
@@ -4433,14 +4496,14 @@ void freedata(EN_Project *p)
}
free(net->Node);
}
/* Free memory for other network objects */
free(net->Link);
free(net->Tank);
free(net->Pump);
free(net->Valve);
free(net->Control);
/* Free memory for time patterns */
if (net->Pattern != NULL) {
for (j = 0; j <= par->MaxPats; j++)
@@ -4456,20 +4519,19 @@ void freedata(EN_Project *p)
}
free(net->Curve);
}
/* Free memory for node coordinates */
if (p->parser.Coordflag == TRUE) {
free(net->Coord);
}
/* Free memory for rule base (see RULES.C) */
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);
}
/*
@@ -4572,7 +4634,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)
@@ -4584,7 +4646,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)
@@ -4990,7 +5052,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];
}
@@ -5106,7 +5168,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);
}
@@ -5129,8 +5191,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);
@@ -5212,7 +5274,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);
}
@@ -5235,15 +5297,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) {
@@ -5296,14 +5357,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

View File

@@ -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 as a key
** and an associated integer as data.
**
** Written by L. Rossman
** Last Updated on 6/19/03
** Last Updated on 10/19/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,153 @@
#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;
return retHash;
}
#define HASHTABLEMAXSIZE 128000
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)
char *dupstr(const char *s)
{
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);
size_t size = strlen(s) + 1;
char *p = malloc(size);
if (p) memcpy(p, s, size);
return p;
}
/* Abel Heinsbroek: Added function to update the hash table value for a given key */
int ENHashTableUpdate(ENHashTable *ht, char *key, int new_data)
HashTable *hashtable_create()
{
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 = dupstr(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;
preventry = NULL;
entry = ht[i];
while (entry != NULL)
{
if (strcmp(entry->key, key) == 0)
{
if (preventry == NULL) ht[i] = entry->next;
else preventry->next = entry->next;
free(entry->key);
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->key);
free(entry);
entry = nextentry;
}
ht[i] = NULL;
}
free(ht);
}

View File

@@ -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;
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);
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);
#endif

View File

@@ -104,9 +104,9 @@ void setdefaults(EN_Project *pr)
time_options_t *time = &pr->time_options;
out_file_t *out = &pr->out_files;
strncpy(pr->Title[0], "", MAXMSG);
strncpy(pr->Title[1], "", MAXMSG);
strncpy(pr->Title[2], "", MAXMSG);
strncpy(pr->Title[0], "", TITLELEN);
strncpy(pr->Title[1], "", TITLELEN);
strncpy(pr->Title[2], "", TITLELEN);
strncpy(out->TmpDir, "", MAXFNAME);
strncpy(out->TmpFname, "", MAXFNAME);
strncpy(out->HydFname, "", MAXFNAME);

View File

@@ -292,7 +292,7 @@ int newline(EN_Project *pr, int sect, char *line)
n = (int)strlen(line);
if (line[n - 1] == 10)
line[n - 1] = ' ';
strncpy(pr->Title[par->Ntitle], line, MAXMSG);
strncpy(pr->Title[par->Ntitle], line, TITLELEN);
par->Ntitle++;
}
return (0);
@@ -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);
}

View File

@@ -87,9 +87,9 @@ int savenetdata(EN_Project *pr)
fwrite(ibuf, sizeof(INT4), 15, outFile);
/* Write string variables to outFile */
fwrite(pr->Title[0], sizeof(char), MAXMSG + 1, outFile);
fwrite(pr->Title[1], sizeof(char), MAXMSG + 1, outFile);
fwrite(pr->Title[2], sizeof(char), MAXMSG + 1, outFile);
fwrite(pr->Title[0], sizeof(char), TITLELEN + 1, outFile);
fwrite(pr->Title[1], sizeof(char), TITLELEN + 1, outFile);
fwrite(pr->Title[2], sizeof(char), TITLELEN + 1, outFile);
fwrite(par->InpFname, sizeof(char), MAXFNAME + 1, outFile);
fwrite(rep->Rpt2Fname, sizeof(char), MAXFNAME + 1, outFile);
fwrite(qu->ChemName, sizeof(char), MAXID + 1, outFile);

View File

@@ -48,8 +48,9 @@ typedef int INT4;
#define ENGINE_VERSION 201
#define EOFMARK 0x1A /* Use 0x04 for UNIX systems */
#define MAXTITLE 3 /* Max. # title lines */
#define TITLELEN 79 // Max. # characters in a title line
#define MAXID 31 /* Max. # characters in ID name */
#define MAXMSG 79 /* Max. # characters in message text */
#define MAXMSG 255 /* Max. # characters in message text */
#define MAXLINE 255 /* Max. # characters read from input line */
#define MAXFNAME 259 /* Max. # characters in file name */
#define MAXTOKS 40 /* Max. items per line of input */
@@ -873,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;
@@ -900,7 +902,7 @@ typedef struct EN_Project {
Openflag, /// Toolkit open flag
Warnflag, /// Warning flag
Msg[MAXMSG+1], /// General-purpose string: errors, messages
Title[MAXTITLE][MAXMSG+1], /// Problem title
Title[MAXTITLE][TITLELEN+1],/// Project title
MapFname[MAXFNAME+1]; /// Map file name
error_handle_t* error_handle; //Simple error manager

87
tests/test_setid.cpp Normal file
View File

@@ -0,0 +1,87 @@
// Test of ENsetid EPANET API Function
#define _CRT_SECURE_NO_DEPRECATE
/*
This is a test for the API functions that change a node or link ID name.
A node and link name are changed, the network is saved, reopened and the new names are checked.
*/
#define BOOST_TEST_MODULE "toolkit"
#include <boost/test/included/unit_test.hpp>
#include <string>
#include "epanet2.h"
#define DATA_PATH_INP "./net1.inp"
#define DATA_PATH_RPT "./test.rpt"
#define DATA_PATH_OUT "./test.out"
using namespace std;
BOOST_AUTO_TEST_SUITE (test_toolkit)
BOOST_AUTO_TEST_CASE(test_setid)
{
int error = 0;
int index;
string newid;
EN_ProjectHandle ph = NULL;
EN_createproject(&ph);
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 = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), "");
BOOST_REQUIRE(error == 0);
// Test of illegal node name change
newid = "Illegal; node name";
error = EN_setnodeid(ph, 3, (char *)newid.c_str());
BOOST_REQUIRE(error > 0);
// Test of legal node name change
newid = "Node3";
error = EN_setnodeid(ph, 3, (char *)newid.c_str());
BOOST_REQUIRE(error == 0);
// Test of illegal link name change
newid = "Illegal; link name";
error = EN_setlinkid(ph, 3, (char *)newid.c_str());
BOOST_REQUIRE(error > 0);
// Test of legal link name change
newid = "Link3";
error = EN_setlinkid(ph, 3, (char *)newid.c_str());
BOOST_REQUIRE(error == 0);
// Save the project
error = EN_saveinpfile(ph, "net1_setid.inp");
BOOST_REQUIRE(error == 0);
error = EN_close(ph);
BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph);
// Re-open the saved project
EN_createproject(&ph);
error = EN_open(ph, "net1_setid.inp", path_rpt.c_str(), "");
BOOST_REQUIRE(error == 0);
// Check that 3rd node has its new name
error = EN_getnodeindex(ph, "Node3", &index);
BOOST_REQUIRE(error == 0);
BOOST_REQUIRE(index == 3);
// Check that 3rd link has its new name
error = EN_getlinkindex(ph, "Link3", &index);
BOOST_REQUIRE(error == 0);
BOOST_REQUIRE(index == 3);
error = EN_close(ph);
BOOST_REQUIRE(error == 0);
EN_deleteproject(&ph);
}
BOOST_AUTO_TEST_SUITE_END()