Merge branch 'dev' of https://github.com/OpenWaterAnalytics/EPANET into dev
This commit is contained in:
@@ -5,7 +5,7 @@ Attribute VB_Name = "Module1"
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL)
|
||||
|
||||
'Last updated on 02/28/2019
|
||||
'Last updated on 03/17/2019
|
||||
|
||||
' These are codes used by the DLL functions
|
||||
Public Const EN_ELEVATION = 0 ' Node parameters
|
||||
@@ -83,6 +83,13 @@ Public Const EN_MAXHEADERROR = 2
|
||||
Public Const EN_MAXFLOWCHANGE = 3
|
||||
Public Const EN_MASSBALANCE = 4
|
||||
|
||||
Public Const EN_NODE = 0 ' Component types
|
||||
Public Const EN_LINK = 1
|
||||
Public Const EN_TIMEPAT = 2
|
||||
Public Const EN_CURVE = 3
|
||||
Public Const EN_CONTROL = 4
|
||||
Public Const EN_RULE = 5
|
||||
|
||||
Public Const EN_NODECOUNT = 0 ' Component counts
|
||||
Public Const EN_TANKCOUNT = 1
|
||||
Public Const EN_LINKCOUNT = 2
|
||||
|
||||
@@ -21,6 +21,7 @@ EXPORTS
|
||||
ENepanet = _ENepanet@16
|
||||
ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8
|
||||
ENgetbasedemand = _ENgetbasedemand@12
|
||||
ENgetcomment = _ENgetcomment@12
|
||||
ENgetcontrol = _ENgetcontrol@24
|
||||
ENgetcoord = _ENgetcoord@12
|
||||
ENgetcount = _ENgetcount@8
|
||||
@@ -80,6 +81,7 @@ EXPORTS
|
||||
ENsavehydfile = _ENsavehydfile@4
|
||||
ENsaveinpfile = _ENsaveinpfile@4
|
||||
ENsetbasedemand = _ENsetbasedemand@12
|
||||
ENsetcomment = _ENsetcomment@12
|
||||
ENsetcontrol = _ENsetcontrol@24
|
||||
ENsetcoord = _ENsetcoord@20
|
||||
ENsetcurve = _ENsetcurve@16
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/28/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -77,6 +77,10 @@ extern "C" {
|
||||
|
||||
int DLLEXPORT ENsettitle(char *line1, char *line2, char *line3);
|
||||
|
||||
int DLLEXPORT ENgetcomment(int object, int index, char *comment);
|
||||
|
||||
int DLLEXPORT ENsetcomment(int object, int index, char *comment);
|
||||
|
||||
int DLLEXPORT ENgetcount(int object, int *count);
|
||||
|
||||
int DLLEXPORT ENsaveinpfile(const char *filename);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
'Declarations of functions in the EPANET PROGRAMMERs TOOLKIT
|
||||
'(EPANET2.DLL) for use with VB.Net.
|
||||
|
||||
'Last updated on 02/28/2019
|
||||
'Last updated on 03/17/2019
|
||||
|
||||
Imports System.Runtime.InteropServices
|
||||
Imports System.Text
|
||||
@@ -88,6 +88,13 @@ Public Const EN_MAXHEADERROR = 2
|
||||
Public Const EN_MAXFLOWCHANGE = 3
|
||||
Public Const EN_MASSBALANCE = 4
|
||||
|
||||
Public Const EN_NODE = 0 ' Component types
|
||||
Public Const EN_LINK = 1
|
||||
Public Const EN_TIMEPAT = 2
|
||||
Public Const EN_CURVE = 3
|
||||
Public Const EN_CONTROL = 4
|
||||
Public Const EN_RULE = 5
|
||||
|
||||
Public Const EN_NODECOUNT = 0 'Component counts
|
||||
Public Const EN_TANKCOUNT = 1
|
||||
Public Const EN_LINKCOUNT = 2
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/08/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -146,6 +146,26 @@ typedef struct Project *EN_Project;
|
||||
*/
|
||||
int DLLEXPORT EN_settitle(EN_Project ph, char *line1, char *line2, char *line3);
|
||||
|
||||
/**
|
||||
@brief Retrieves a descriptive comment assigned to a Node, Link, Pattern or Curve.
|
||||
@param ph an EPANET project handle.
|
||||
@param object a type of object (either EN_NODE, EN_LINK, EN_TIMEPAT or EN_CURVE)
|
||||
@param index the object's index starting from 1
|
||||
@param[out] comment the comment string assigned to the object
|
||||
@return an error code
|
||||
*/
|
||||
int DLLEXPORT EN_getcomment(EN_Project ph, int object, int index, char *comment);
|
||||
|
||||
/**
|
||||
@brief Assigns a descriptive comment to a Node, Link, Pattern or Curve.
|
||||
@param ph an EPANET project handle.
|
||||
@param object a type of object (either EN_NODE, EN_LINK, EN_TIMEPAT or EN_CURVE)
|
||||
@param index the object's index starting from 1
|
||||
@param[out] comment the comment string assigned to the object
|
||||
@return an error code
|
||||
*/
|
||||
int DLLEXPORT EN_setcomment(EN_Project ph, int object, int index, char *comment);
|
||||
|
||||
/**
|
||||
@brief Retrieves the number of objects of a given type in a project.
|
||||
@param ph an EPANET project handle.
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 01/14/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -128,6 +128,19 @@ typedef enum {
|
||||
EN_MASSBALANCE = 4 //!< Cumulative water quality mass balance ratio
|
||||
} EN_AnalysisStatistic;
|
||||
|
||||
/// Types of network objects
|
||||
/**
|
||||
A network model is composed of these types of objects.
|
||||
*/
|
||||
typedef enum {
|
||||
EN_NODE = 0, //!< Nodes
|
||||
EN_LINK = 1, //!< Links
|
||||
EN_TIMEPAT = 2, //!< Time patterns
|
||||
EN_CURVE = 3, //!< Data curves
|
||||
EN_CONTROL = 4, //!< Simple controls
|
||||
EN_RULE = 5 //!< Control rules
|
||||
} EN_ObjectType;
|
||||
|
||||
/// Types of objects to count
|
||||
/**
|
||||
These options tell @ref EN_getcount which type of object to count.
|
||||
|
||||
57
src/epanet.c
57
src/epanet.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/08/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -275,6 +275,32 @@ int DLLEXPORT EN_settitle(EN_Project p, char *line1, char *line2, char *line3)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_getcomment(EN_Project p, int object, int index, char *comment)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: object = a type of object (see EN_ObjectType)
|
||||
** index = the object's index
|
||||
** Output: comment = the object's descriptive comment
|
||||
** Returns: error code
|
||||
** Purpose: Retrieves an object's descriptive comment
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return getcomment(&p->network, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_setcomment(EN_Project p, int object, int index, char *comment)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: object = a type of object (see EN_ObjectType)
|
||||
** index = the object's index
|
||||
** comment = a descriptive comment to assign
|
||||
** Returns: error code
|
||||
** Purpose: Assigns a descriptive comment to an object
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
return setcomment(&p->network, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT EN_getcount(EN_Project p, int object, int *count)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: object = type of object to count (see EN_CountType)
|
||||
@@ -1208,7 +1234,7 @@ int DLLEXPORT EN_setoption(EN_Project p, int option, double value)
|
||||
if (demand->Pat == tmpPat)
|
||||
{
|
||||
demand->Pat = pat;
|
||||
strcpy(demand->Name, "");
|
||||
demand->Name = xstrcpy(&demand->Name, "", MAXMSG);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1668,7 +1694,7 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
|
||||
demand->Base = 0.0;
|
||||
demand->Pat = hyd->DefPat; // Use default pattern
|
||||
strcpy(demand->Name, "");
|
||||
demand->Name = NULL;
|
||||
demand->next = NULL;
|
||||
node->D = demand;
|
||||
|
||||
@@ -1743,7 +1769,7 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
node->Rpt = 0;
|
||||
node->X = MISSING;
|
||||
node->Y = MISSING;
|
||||
strcpy(node->Comment, "");
|
||||
node->Comment = NULL;
|
||||
|
||||
// Insert new node into hash table
|
||||
hashtable_insert(net->NodeHashTable, node->ID, nIdx);
|
||||
@@ -1769,7 +1795,6 @@ int DLLEXPORT EN_deletenode(EN_Project p, int index, int actionCode)
|
||||
int i, nodeType, tankindex;
|
||||
Snode *node;
|
||||
Pdemand demand, nextdemand;
|
||||
Psource source;
|
||||
|
||||
// Cannot modify network structure while solvers are active
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -1801,16 +1826,17 @@ int DLLEXPORT EN_deletenode(EN_Project p, int index, int actionCode)
|
||||
// Remove node from its hash table
|
||||
hashtable_delete(net->NodeHashTable, node->ID);
|
||||
|
||||
// Free memory allocated to node's demands & WQ source
|
||||
// Free memory allocated to node's demands, WQ source & comment
|
||||
demand = node->D;
|
||||
while (demand != NULL)
|
||||
{
|
||||
nextdemand = demand->next;
|
||||
free(demand->Name);
|
||||
free(demand);
|
||||
demand = nextdemand;
|
||||
}
|
||||
source = node->S;
|
||||
if (source != NULL) free(source);
|
||||
free(node->S);
|
||||
free(node->Comment);
|
||||
|
||||
// Shift position of higher entries in Node & Coord arrays down one
|
||||
for (i = index; i <= net->Nnodes - 1; i++)
|
||||
@@ -1823,6 +1849,7 @@ int DLLEXPORT EN_deletenode(EN_Project p, int index, int actionCode)
|
||||
// Remove references to demands & source in last (inactive) Node array entry
|
||||
net->Node[net->Nnodes].D = NULL;
|
||||
net->Node[net->Nnodes].S = NULL;
|
||||
net->Node[net->Nnodes].Comment = NULL;
|
||||
|
||||
// If deleted node is a tank, remove it from the Tank array
|
||||
if (nodeType != EN_JUNCTION)
|
||||
@@ -2522,7 +2549,6 @@ int DLLEXPORT EN_settankdata(EN_Project p, int index, double elev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int DLLEXPORT EN_getcoord(EN_Project p, int index, double *x, double *y)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: index = node index
|
||||
@@ -2752,7 +2778,7 @@ int DLLEXPORT EN_setdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
for (d = p->network.Node[nodeIndex].D;
|
||||
n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
strncpy(d->Name, demandName, MAXMSG);
|
||||
d->Name = xstrcpy(&d->Name, demandName, MAXMSG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2944,7 +2970,7 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
link->R = 0;
|
||||
link->Rc = 0;
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, "");
|
||||
link->Comment = NULL;
|
||||
|
||||
hashtable_insert(net->LinkHashTable, link->ID, n);
|
||||
return 0;
|
||||
@@ -2993,6 +3019,10 @@ int DLLEXPORT EN_deletelink(EN_Project p, int index, int actionCode)
|
||||
// Remove link from its hash table
|
||||
hashtable_delete(net->LinkHashTable, link->ID);
|
||||
|
||||
// Remove link's comment
|
||||
free(net->Link[index].Comment);
|
||||
net->Link[net->Nlinks].Comment = NULL;
|
||||
|
||||
// Shift position of higher entries in Link array down one
|
||||
for (i = index; i <= net->Nlinks - 1; i++)
|
||||
{
|
||||
@@ -3864,6 +3894,7 @@ int DLLEXPORT EN_addpattern(EN_Project p, char *id)
|
||||
// Assign properties to the new pattern
|
||||
pat = &net->Pattern[n];
|
||||
strcpy(pat->ID, id);
|
||||
pat->Comment = NULL;
|
||||
pat->Length = 1;
|
||||
pat->F = (double *)calloc(1, sizeof(double));
|
||||
if (pat->F == NULL) err = 1;
|
||||
@@ -3924,6 +3955,7 @@ int DLLEXPORT EN_deletepattern(EN_Project p, int index)
|
||||
|
||||
// Free the pattern's factor array
|
||||
FREE(net->Pattern[index].F);
|
||||
FREE(net->Pattern[index].Comment);
|
||||
|
||||
// Shift the entries in the network's Pattern array
|
||||
for (i = index; i < net->Npats; i++) net->Pattern[i] = net->Pattern[i+1];
|
||||
@@ -4141,6 +4173,7 @@ int DLLEXPORT EN_addcurve(EN_Project p, char *id)
|
||||
// Set the properties of the new curve
|
||||
curve = &net->Curve[n];
|
||||
strcpy(curve->ID, id);
|
||||
curve->Comment = NULL;
|
||||
curve->Npts = 1;
|
||||
curve->Type = GENERIC_CURVE;
|
||||
curve->X = (double *)calloc(1, sizeof(double));
|
||||
@@ -4194,6 +4227,7 @@ int DLLEXPORT EN_deletecurve(EN_Project p, int index)
|
||||
// Free the curve's data arrays
|
||||
FREE(net->Curve[index].X);
|
||||
FREE(net->Curve[index].Y);
|
||||
FREE(net->Curve[index].Comment);
|
||||
|
||||
// Shift the entries in the network's Curve array
|
||||
for (i = index; i < net->Ncurves; i++) net->Curve[i] = net->Curve[i + 1];
|
||||
@@ -5092,7 +5126,6 @@ int DLLEXPORT EN_getelseaction(EN_Project p, int ruleIndex, int actionIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
|
||||
Saction *actions;
|
||||
Saction *action;
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/08/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __APPLE__
|
||||
@@ -112,6 +112,16 @@ int DLLEXPORT ENsettitle(char *line1, char *line2, char *line3)
|
||||
return EN_settitle(_defaultProject, line1, line2, line3) ;
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcomment(int object, int index, char *comment)
|
||||
{
|
||||
return EN_getcomment(_defaultProject, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENsetcomment(int object, int index, char *comment)
|
||||
{
|
||||
return EN_setcomment(_defaultProject, object, index, comment);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENgetcount(int object, int *count)
|
||||
{
|
||||
return EN_getcount(_defaultProject, object, count);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 02/08/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef FUNCS_H
|
||||
@@ -39,7 +39,11 @@ int findpump(Network *, int);
|
||||
void adjustpatterns(Network *, int);
|
||||
void adjustcurves(Network *, int);
|
||||
|
||||
int getcomment(Network *, int, int, char *);
|
||||
int setcomment(Network *, int, int, const char *);
|
||||
|
||||
char *getTmpName(char *);
|
||||
char *xstrcpy(char **, const char *, const size_t n);
|
||||
int strcomp(const char *, const char *);
|
||||
double interp(int, double [], double [], double);
|
||||
char *geterrmsg(int, char *);
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: saves network data to an EPANET formatted text file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/09/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -84,7 +84,7 @@ void saveauxdata(Project *pr, FILE *f)
|
||||
case _LABELS:
|
||||
case _BACKDROP:
|
||||
case _TAGS:
|
||||
fprintf(f, "%s", line);
|
||||
fprintf(f, "\n%s", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,8 +161,8 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
node = &net->Node[i];
|
||||
fprintf(f, "\n %-31s %12.4f ;%s", node->ID, node->El * pr->Ucf[ELEV],
|
||||
node->Comment);
|
||||
fprintf(f, "\n %-31s %12.4f", node->ID, node->El * pr->Ucf[ELEV]);
|
||||
if (node->Comment) fprintf(f, " ;%s", node->Comment);
|
||||
}
|
||||
|
||||
// Write [RESERVOIRS] section
|
||||
@@ -175,9 +175,10 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
{
|
||||
node = &net->Node[tank->Node];
|
||||
sprintf(s, " %-31s %12.4f", node->ID, node->El * pr->Ucf[ELEV]);
|
||||
if ((j = tank->Pat) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
if ((j = tank->Pat) > 0) sprintf(s1, " %s", net->Pattern[j].ID);
|
||||
else strcpy(s1, " ");
|
||||
fprintf(f, "\n%s %s ;%s", s, s1, node->Comment);
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
if (node->Comment) fprintf(f, " ;%s", node->Comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,9 +198,10 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
(tank->Hmax - node->El) * pr->Ucf[ELEV],
|
||||
sqrt(4.0 * tank->A / PI) * pr->Ucf[ELEV],
|
||||
tank->Vmin * SQR(pr->Ucf[ELEV]) * pr->Ucf[ELEV]);
|
||||
if ((j = tank->Vcurve) > 0) sprintf(s1, "%-31s", net->Curve[j].ID);
|
||||
if ((j = tank->Vcurve) > 0) sprintf(s1, "%s", net->Curve[j].ID);
|
||||
else strcpy(s1, " ");
|
||||
fprintf(f, "\n%s %s ;%s", s, s1, node->Comment);
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
if (node->Comment) fprintf(f, " ;%s", node->Comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,17 +218,15 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
if (hyd->Formflag == DW) kc = kc * pr->Ucf[ELEV] * 1000.0;
|
||||
km = link->Km * SQR(d) * SQR(d) / 0.02517;
|
||||
|
||||
sprintf(s, " %-31s %-31s %-31s %12.4f %12.4f", link->ID,
|
||||
net->Node[link->N1].ID, net->Node[link->N2].ID,
|
||||
link->Len * pr->Ucf[LENGTH], d * pr->Ucf[DIAM]);
|
||||
|
||||
if (hyd->Formflag == DW) sprintf(s1, "%12.4f %12.4f", kc, km);
|
||||
else sprintf(s1, "%12.4f %12.4f", kc, km);
|
||||
sprintf(s, " %-31s %-31s %-31s %12.4f %12.4f %12.4f %12.4f",
|
||||
link->ID, net->Node[link->N1].ID, net->Node[link->N2].ID,
|
||||
link->Len * pr->Ucf[LENGTH], d * pr->Ucf[DIAM], kc, km);
|
||||
|
||||
if (link->Type == CVPIPE) sprintf(s2, "CV");
|
||||
else if (link->Status == CLOSED) sprintf(s2, "CLOSED");
|
||||
else strcpy(s2, " ");
|
||||
fprintf(f, "\n%s %s %s ;%s", s, s1, s2, link->Comment);
|
||||
fprintf(f, "\n%s %-6s", s, s2);
|
||||
if (link->Comment) fprintf(f, " ;%s", link->Comment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,9 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
strcat(s, s1);
|
||||
}
|
||||
|
||||
fprintf(f, "\n%s ;%s", s, link->Comment);
|
||||
fprintf(f, "\n%s", s);
|
||||
if (link->Comment) fprintf(f, " ;%s", link->Comment);
|
||||
|
||||
}
|
||||
|
||||
// Write [VALVES] section
|
||||
@@ -316,7 +318,8 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
sprintf(s1, "%-31s %12.4f", net->Curve[j].ID, km);
|
||||
}
|
||||
else sprintf(s1, "%12.4f %12.4f", kc, km);
|
||||
fprintf(f, "\n%s %s ;%s", s, s1, link->Comment);
|
||||
fprintf(f, "\n%s %s", s, s1);
|
||||
if (link->Comment) fprintf(f, " ;%s", link->Comment);
|
||||
}
|
||||
|
||||
// Write [DEMANDS] section
|
||||
@@ -329,9 +332,10 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
for (demand = node->D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
sprintf(s, " %-31s %14.6f", node->ID, ucf * demand->Base);
|
||||
if ((j = demand->Pat) > 0) sprintf(s1, " %s", net->Pattern[j].ID);
|
||||
if ((j = demand->Pat) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
else strcpy(s1, " ");
|
||||
fprintf(f, "\n%s %s ;%s", s, s1, demand->Name);
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
if (demand->Name) fprintf(f, " ;%s", demand->Name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,6 +396,7 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
fprintf(f, s_PATTERNS);
|
||||
for (i = 1; i <= net->Npats; i++)
|
||||
{
|
||||
if (net->Pattern[i].Comment) fprintf(f, "\n;%s", net->Pattern[i].Comment);
|
||||
for (j = 0; j < net->Pattern[i].Length; j++)
|
||||
{
|
||||
if (j % 6 == 0) fprintf(f, "\n %-31s", net->Pattern[i].ID);
|
||||
@@ -404,11 +409,11 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
fprintf(f, s_CURVES);
|
||||
for (i = 1; i <= net->Ncurves; i++)
|
||||
{
|
||||
if (net->Curve[i].Comment) fprintf(f, "\n;%s", net->Curve[i].Comment);
|
||||
for (j = 0; j < net->Curve[i].Npts; j++)
|
||||
{
|
||||
curve = &net->Curve[i];
|
||||
fprintf(f, "\n %-31s %12.4f %12.4f", curve->ID, curve->X[j],
|
||||
curve->Y[j]);
|
||||
fprintf(f, "\n %-31s %12.4f %12.4f", curve->ID, curve->X[j], curve->Y[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -776,7 +781,6 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
}
|
||||
else fprintf(f, "\n %-20sNO",field->Name);
|
||||
}
|
||||
fprintf(f, "\n\n");
|
||||
|
||||
// Write [COORDINATES] section
|
||||
fprintf(f, "\n\n");
|
||||
@@ -787,9 +791,9 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
if (node->X == MISSING || node->Y == MISSING) continue;
|
||||
fprintf(f, "\n %-31s %14.6f %14.6f", node->ID, node->X, node->Y);
|
||||
}
|
||||
fprintf(f, "\n\n");
|
||||
|
||||
// Save auxilary data to new input file
|
||||
fprintf(f, "\n");
|
||||
saveauxdata(pr, f);
|
||||
|
||||
// Close the new input file
|
||||
|
||||
@@ -7,7 +7,7 @@ Description: retrieves network data from an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 12/15/2018
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -334,7 +334,7 @@ void adjustdata(Project *pr)
|
||||
if (demand->Pat == 0)
|
||||
{
|
||||
demand->Pat = hyd->DefPat;
|
||||
strcpy(demand->Name, "");
|
||||
xstrcpy(&demand->Name, "", MAXMSG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
src/input2.c
29
src/input2.c
@@ -7,7 +7,7 @@ Description: reads and interprets network data from an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 01/01/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -166,6 +166,7 @@ int readdata(Project *pr)
|
||||
net->Npats = parser->MaxPats;
|
||||
parser->PrevPat = NULL;
|
||||
parser->PrevCurve = NULL;
|
||||
parser->LineComment[0] = '\0';
|
||||
|
||||
sect = -1;
|
||||
errsum = 0;
|
||||
@@ -175,19 +176,31 @@ int readdata(Project *pr)
|
||||
{
|
||||
// Make copy of line and scan for tokens
|
||||
strcpy(wline, line);
|
||||
parser->Ntokens = gettokens(wline, parser->Tok, MAXTOKS,
|
||||
parser->Comment);
|
||||
parser->Ntokens = gettokens(wline, parser->Tok, MAXTOKS, parser->Comment);
|
||||
|
||||
// Skip blank lines and comments
|
||||
// Skip blank lines and those filled with a comment
|
||||
parser->ErrTok = -1;
|
||||
if (parser->Ntokens == 0) continue;
|
||||
if (*parser->Tok[0] == ';') continue;
|
||||
if (parser->Ntokens == 0)
|
||||
{
|
||||
// Store full line comment for Patterns and Curves
|
||||
if (sect == _PATTERNS || sect == _CURVES)
|
||||
{
|
||||
strncpy(parser->LineComment, parser->Comment, MAXMSG);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Apply full line comment for Patterns and Curves
|
||||
if (sect == _PATTERNS || sect == _CURVES)
|
||||
{
|
||||
strcpy(parser->Comment, parser->LineComment);
|
||||
}
|
||||
parser->LineComment[0] = '\0';
|
||||
|
||||
// Check if max. line length exceeded
|
||||
if (strlen(line) >= MAXLINE)
|
||||
{
|
||||
sprintf(pr->Msg, "%s section: %s", geterrmsg(214, pr->Msg),
|
||||
SectTxt[sect]);
|
||||
sprintf(pr->Msg, "%s section: %s", geterrmsg(214, pr->Msg), SectTxt[sect]);
|
||||
writeline(pr, pr->Msg);
|
||||
writeline(pr, line);
|
||||
errsum++;
|
||||
|
||||
35
src/input3.c
35
src/input3.c
@@ -7,7 +7,7 @@ Description: parses network data from a line of an EPANET input file
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 01/01/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -115,15 +115,14 @@ int juncdata(Project *pr)
|
||||
node->Ke = 0.0;
|
||||
node->Rpt = 0;
|
||||
node->Type = JUNCTION;
|
||||
strcpy(node->Comment, parser->Comment);
|
||||
|
||||
node->Comment = xstrcpy(&node->Comment, parser->Comment, MAXMSG);
|
||||
|
||||
// create a demand record, even if no demand is specified here.
|
||||
demand = (struct Sdemand *) malloc(sizeof(struct Sdemand));
|
||||
if (demand == NULL) return 101;
|
||||
demand->Base = y;
|
||||
demand->Pat = p;
|
||||
strncpy(demand->Name, "", MAXMSG);
|
||||
demand->Name = NULL;
|
||||
demand->next = NULL;
|
||||
node->D = demand;
|
||||
hyd->NodeDemand[njuncs] = y;
|
||||
@@ -224,7 +223,7 @@ int tankdata(Project *pr)
|
||||
node->S = NULL;
|
||||
node->Ke = 0.0;
|
||||
node->Type = (diam == 0) ? RESERVOIR : TANK;
|
||||
strcpy(node->Comment, parser->Comment);
|
||||
node->Comment = xstrcpy(&node->Comment, parser->Comment, MAXMSG);
|
||||
tank->Node = i;
|
||||
tank->H0 = initlevel;
|
||||
tank->Hmin = minlevel;
|
||||
@@ -329,7 +328,7 @@ int pipedata(Project *pr)
|
||||
link->Type = type;
|
||||
link->Status = status;
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, parser->Comment);
|
||||
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -392,7 +391,7 @@ int pumpdata(Project *pr)
|
||||
link->Type = PUMP;
|
||||
link->Status = OPEN;
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, parser->Comment);
|
||||
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
||||
pump->Link = net->Nlinks;
|
||||
pump->Ptype = NOCURVE; // NOCURVE is a placeholder
|
||||
pump->Hcurve = 0;
|
||||
@@ -535,7 +534,7 @@ int valvedata(Project *pr)
|
||||
link->Type = type;
|
||||
link->Status = status;
|
||||
link->Rpt = 0;
|
||||
strcpy(link->Comment, parser->Comment);
|
||||
link->Comment = xstrcpy(&link->Comment, parser->Comment, MAXMSG);
|
||||
net->Valve[net->Nvalves].Link = net->Nlinks;
|
||||
return 0;
|
||||
}
|
||||
@@ -559,6 +558,7 @@ int patterndata(Project *pr)
|
||||
double x;
|
||||
SFloatlist *f;
|
||||
STmplist *p;
|
||||
Spattern *pattern;
|
||||
|
||||
n = parser->Ntokens - 1;
|
||||
if (n < 1) return 201;
|
||||
@@ -566,8 +566,13 @@ int patterndata(Project *pr)
|
||||
// Check for a new pattern
|
||||
if (parser->PrevPat != NULL &&
|
||||
strcmp(parser->Tok[0], parser->PrevPat->ID) == 0) p = parser->PrevPat;
|
||||
else p = getlistitem(parser->Tok[0], parser->Patlist);
|
||||
else
|
||||
{
|
||||
p = getlistitem(parser->Tok[0], parser->Patlist);
|
||||
if (p == NULL) return setError(parser, 0, 205);
|
||||
pattern = &(net->Pattern[p->i]);
|
||||
pattern->Comment = xstrcpy(&pattern->Comment, parser->Comment, MAXMSG);
|
||||
}
|
||||
|
||||
// Add parsed multipliers to the pattern
|
||||
for (i = 1; i <= n; i++)
|
||||
@@ -606,13 +611,19 @@ int curvedata(Project *pr)
|
||||
double x, y;
|
||||
SFloatlist *fx, *fy;
|
||||
STmplist *c;
|
||||
Scurve *curve;
|
||||
|
||||
// Check for valid curve ID
|
||||
if (parser->Ntokens < 3) return 201;
|
||||
if (parser->PrevCurve != NULL &&
|
||||
strcmp(parser->Tok[0], parser->PrevCurve->ID) == 0) c = parser->PrevCurve;
|
||||
else c = getlistitem(parser->Tok[0], parser->Curvelist);
|
||||
else
|
||||
{
|
||||
c = getlistitem(parser->Tok[0], parser->Curvelist);
|
||||
if (c == NULL) return setError(parser, 0, 206);
|
||||
curve = &(net->Curve[c->i]);
|
||||
curve->Comment = xstrcpy(&curve->Comment, parser->Comment, MAXMSG);
|
||||
}
|
||||
|
||||
// Check for valid data
|
||||
if (!getfloat(parser->Tok[1], &x)) return setError(parser, 1, 202);
|
||||
@@ -731,7 +742,7 @@ int demanddata(Project *pr)
|
||||
// with what is specified in this section
|
||||
demand->Base = y;
|
||||
demand->Pat = p;
|
||||
strncpy(demand->Name, parser->Comment, MAXMSG);
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXMSG);
|
||||
hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category.
|
||||
}
|
||||
|
||||
@@ -744,7 +755,7 @@ int demanddata(Project *pr)
|
||||
if (demand == NULL) return 101;
|
||||
demand->Base = y;
|
||||
demand->Pat = p;
|
||||
strncpy(demand->Name, parser->Comment, MAXMSG);
|
||||
demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXMSG);
|
||||
demand->next = NULL;
|
||||
cur_demand->next = demand;
|
||||
}
|
||||
|
||||
149
src/project.c
149
src/project.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 03/05/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -370,6 +370,7 @@ int allocdata(Project *pr)
|
||||
{
|
||||
pr->network.Pattern[n].Length = 0;
|
||||
pr->network.Pattern[n].F = NULL;
|
||||
pr->network.Pattern[n].Comment = NULL;
|
||||
}
|
||||
for (n = 0; n <= pr->parser.MaxCurves; n++)
|
||||
{
|
||||
@@ -377,10 +378,17 @@ int allocdata(Project *pr)
|
||||
pr->network.Curve[n].Type = GENERIC_CURVE;
|
||||
pr->network.Curve[n].X = NULL;
|
||||
pr->network.Curve[n].Y = NULL;
|
||||
pr->network.Curve[n].Comment = NULL;
|
||||
}
|
||||
for (n = 0; n <= pr->parser.MaxNodes; n++)
|
||||
{
|
||||
pr->network.Node[n].D = NULL; // node demand
|
||||
pr->network.Node[n].S = NULL; // node source
|
||||
pr->network.Node[n].Comment = NULL;
|
||||
}
|
||||
for (n = 0; n <= pr->parser.MaxLinks; n++)
|
||||
{
|
||||
pr->network.Link[n].Comment = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,18 +467,29 @@ void freedata(Project *pr)
|
||||
while (demand != NULL)
|
||||
{
|
||||
nextdemand = demand->next;
|
||||
free(demand->Name);
|
||||
free(demand);
|
||||
demand = nextdemand;
|
||||
}
|
||||
// Free memory used for WQ source data
|
||||
source = pr->network.Node[j].S;
|
||||
if (source != NULL) free(source);
|
||||
free(source);
|
||||
free(pr->network.Node[j].Comment);
|
||||
}
|
||||
free(pr->network.Node);
|
||||
}
|
||||
|
||||
// Free memory for other network objects
|
||||
// Free memory for link data
|
||||
if (pr->network.Link != NULL)
|
||||
{
|
||||
for (j = 0; j <= pr->parser.MaxLinks; j++)
|
||||
{
|
||||
free(pr->network.Link[j].Comment);
|
||||
}
|
||||
}
|
||||
free(pr->network.Link);
|
||||
|
||||
// Free memory for other network objects
|
||||
free(pr->network.Tank);
|
||||
free(pr->network.Pump);
|
||||
free(pr->network.Valve);
|
||||
@@ -479,7 +498,11 @@ void freedata(Project *pr)
|
||||
// Free memory for time patterns
|
||||
if (pr->network.Pattern != NULL)
|
||||
{
|
||||
for (j = 0; j <= pr->parser.MaxPats; j++) free(pr->network.Pattern[j].F);
|
||||
for (j = 0; j <= pr->parser.MaxPats; j++)
|
||||
{
|
||||
free(pr->network.Pattern[j].F);
|
||||
free(pr->network.Pattern[j].Comment);
|
||||
}
|
||||
free(pr->network.Pattern);
|
||||
}
|
||||
|
||||
@@ -490,6 +513,7 @@ void freedata(Project *pr)
|
||||
{
|
||||
free(pr->network.Curve[j].X);
|
||||
free(pr->network.Curve[j].Y);
|
||||
free(pr->network.Curve[j].Comment);
|
||||
}
|
||||
free(pr->network.Curve);
|
||||
}
|
||||
@@ -878,6 +902,87 @@ void adjustcurves(Network *network, int index)
|
||||
}
|
||||
}
|
||||
|
||||
int getcomment(Network *network, int object, int index, char *comment)
|
||||
//----------------------------------------------------------------
|
||||
// Input: object = a type of network object
|
||||
// index = index of the specified object
|
||||
// comment = the object's comment string
|
||||
// Output: error code
|
||||
// Purpose: gets the comment string assigned to an object.
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
char *currentcomment;
|
||||
|
||||
// Get pointer to specified object's comment
|
||||
switch (object)
|
||||
{
|
||||
case NODE:
|
||||
if (index < 1 || index > network->Nnodes) return 251;
|
||||
currentcomment = network->Node[index].Comment;
|
||||
break;
|
||||
case LINK:
|
||||
if (index < 1 || index > network->Nlinks) return 251;
|
||||
currentcomment = network->Link[index].Comment;
|
||||
break;
|
||||
case TIMEPAT:
|
||||
if (index < 1 || index > network->Npats) return 251;
|
||||
currentcomment = network->Pattern[index].Comment;
|
||||
break;
|
||||
case CURVE:
|
||||
if (index < 1 || index > network->Ncurves) return 251;
|
||||
currentcomment = network->Curve[index].Comment;
|
||||
break;
|
||||
default:
|
||||
strcpy(comment, "");
|
||||
return 251;
|
||||
}
|
||||
|
||||
// Copy the object's comment to the returned string
|
||||
if (currentcomment) strcpy(comment, currentcomment);
|
||||
else comment[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setcomment(Network *network, int object, int index, const char *newcomment)
|
||||
//----------------------------------------------------------------
|
||||
// Input: object = a type of network object
|
||||
// index = index of the specified object
|
||||
// newcomment = new comment string
|
||||
// Output: error code
|
||||
// Purpose: sets the comment string of an object.
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
char *comment;
|
||||
|
||||
switch (object)
|
||||
{
|
||||
case NODE:
|
||||
if (index < 1 || index > network->Nnodes) return 251;
|
||||
comment = network->Node[index].Comment;
|
||||
network->Node[index].Comment = xstrcpy(&comment, newcomment, MAXMSG);
|
||||
return 0;
|
||||
|
||||
case LINK:
|
||||
if (index < 1 || index > network->Nlinks) return 251;
|
||||
comment = network->Link[index].Comment;
|
||||
network->Link[index].Comment = xstrcpy(&comment, newcomment, MAXMSG);
|
||||
return 0;
|
||||
|
||||
case TIMEPAT:
|
||||
if (index < 1 || index > network->Npats) return 251;
|
||||
comment = network->Pattern[index].Comment;
|
||||
network->Pattern[index].Comment = xstrcpy(&comment, newcomment, MAXMSG);
|
||||
return 0;
|
||||
|
||||
case CURVE:
|
||||
if (index < 1 || index > network->Ncurves) return 251;
|
||||
comment = network->Curve[index].Comment;
|
||||
network->Curve[index].Comment = xstrcpy(&comment, newcomment, MAXMSG);
|
||||
return 0;
|
||||
|
||||
default: return 251;
|
||||
}
|
||||
}
|
||||
|
||||
char *getTmpName(char *fname)
|
||||
//----------------------------------------------------------------
|
||||
@@ -911,6 +1016,42 @@ char *getTmpName(char *fname)
|
||||
return fname;
|
||||
}
|
||||
|
||||
char *xstrcpy(char **s1, const char *s2, const size_t n)
|
||||
//----------------------------------------------------------------
|
||||
// Input: s1 = destination string
|
||||
// s2 = source string
|
||||
// n = maximum size of strings
|
||||
// Output: none
|
||||
// Purpose: like strcpy except for dynamic strings.
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
size_t n1 = 0, n2;
|
||||
|
||||
// Source string is empty -- free destination string
|
||||
if (s2 == NULL || strlen(s2) == 0)
|
||||
{
|
||||
free(*s1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Source string not empty -- overwrite destination string
|
||||
else
|
||||
{
|
||||
// See if size of destination string needs to grow
|
||||
if (*s1) n1 = strlen(*s1);
|
||||
if ((n2 = strlen(s2)) > n) n2 = n;
|
||||
if (n2 > n1)
|
||||
{
|
||||
free(*s1);
|
||||
*s1 = (char *)malloc((n2 + 1) * sizeof(char));
|
||||
}
|
||||
|
||||
// Copy the new comment string into the existing one
|
||||
if (*s1) strcpy(*s1, s2);
|
||||
return *s1;
|
||||
}
|
||||
}
|
||||
|
||||
int strcomp(const char *s1, const char *s2)
|
||||
/*---------------------------------------------------------------
|
||||
** Input: s1 = character string
|
||||
|
||||
19
src/types.h
19
src/types.h
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 01/01/2019
|
||||
Last Updated: 03/17/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -122,7 +122,11 @@ typedef int INT4;
|
||||
|
||||
typedef enum {
|
||||
NODE,
|
||||
LINK
|
||||
LINK,
|
||||
TIMEPAT,
|
||||
CURVE,
|
||||
CONTROL,
|
||||
RULE
|
||||
} ObjectType;
|
||||
|
||||
typedef enum {
|
||||
@@ -333,6 +337,7 @@ typedef struct Tmplist STmplist; // Pointer to temporary list of objects
|
||||
typedef struct // Time Pattern Object
|
||||
{
|
||||
char ID[MAXID+1]; // pattern ID
|
||||
char *Comment; // pattern comment
|
||||
int Length; // pattern length
|
||||
double *F; // pattern factors
|
||||
} Spattern;
|
||||
@@ -340,6 +345,7 @@ typedef struct // Time Pattern Object
|
||||
typedef struct // Curve Object
|
||||
{
|
||||
char ID[MAXID+1]; // curve ID
|
||||
char *Comment; // curve comment
|
||||
CurveType Type; // curve type
|
||||
int Npts; // number of points
|
||||
double *X; // x-values
|
||||
@@ -350,7 +356,7 @@ struct Sdemand // Demand List Item
|
||||
{
|
||||
double Base; // baseline demand
|
||||
int Pat; // pattern index
|
||||
char Name[MAXMSG+1]; // demand category name
|
||||
char *Name; // demand category name
|
||||
struct Sdemand *next; // next demand list item
|
||||
};
|
||||
typedef struct Sdemand *Pdemand; // Pointer to demand list
|
||||
@@ -386,7 +392,7 @@ typedef struct // Node Object
|
||||
double Ke; // emitter coeff.
|
||||
int Rpt; // reporting flag
|
||||
NodeType Type; // node type
|
||||
char Comment[MAXMSG+1]; // node comment
|
||||
char *Comment; // node comment
|
||||
} Snode;
|
||||
|
||||
typedef struct // Link Object
|
||||
@@ -406,7 +412,7 @@ typedef struct // Link Object
|
||||
LinkType Type; // link type
|
||||
StatusType Status; // initial status
|
||||
int Rpt; // reporting flag
|
||||
char Comment[MAXMSG+1]; // link Comment
|
||||
char *Comment; // link comment
|
||||
} Slink;
|
||||
|
||||
typedef struct // Tank Object
|
||||
@@ -547,7 +553,8 @@ typedef struct {
|
||||
DefPatID[MAXID + 1], // Default demand pattern ID
|
||||
InpFname[MAXFNAME + 1], // Input file name
|
||||
*Tok[MAXTOKS], // Array of token strings
|
||||
Comment[MAXMSG+1]; // Comment text
|
||||
Comment[MAXMSG + 1], // Comment text
|
||||
LineComment[MAXMSG + 1]; // Full line comment
|
||||
|
||||
int
|
||||
MaxNodes, // Node count from input file */
|
||||
|
||||
131
tests/test_comments.cpp
Normal file
131
tests/test_comments.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
// Test of EPANET's Comment Handling Functions
|
||||
//
|
||||
// This is a test of the API functions EN_getcomment and EN_setcomment
|
||||
//
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
//#define NO_BOOST
|
||||
|
||||
#ifndef NO_BOOST
|
||||
#define BOOST_TEST_MODULE "toolkit"
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "epanet2_2.h"
|
||||
|
||||
#define DATA_PATH_INP "./net1.inp"
|
||||
#define DATA_PATH_RPT "./test.rpt"
|
||||
#define DATA_PATH_OUT "./test.out"
|
||||
#define DATA_PATH_TMP "./tmp.inp"
|
||||
|
||||
#ifdef NO_BOOST
|
||||
#define BOOST_REQUIRE(x) (((x)) ? cout << "\nPassed at line " << __LINE__ : cout << "\nFailed at line " << __LINE__ )
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
int checkComments(EN_Project ph)
|
||||
{
|
||||
int index;
|
||||
char comment[EN_MAXMSG + 1];
|
||||
EN_getnodeindex(ph, (char *)"11", &index);
|
||||
EN_getcomment(ph, EN_NODE, index, comment);
|
||||
if (strcmp(comment, (char *)"J11") != 0) return 0;
|
||||
|
||||
EN_getnodeindex(ph, (char *)"23", &index);
|
||||
EN_getcomment(ph, EN_NODE, index, comment);
|
||||
if (strcmp(comment, (char *)"Junc23") != 0) return 0;
|
||||
|
||||
EN_getlinkindex(ph, (char *)"11", &index);
|
||||
EN_getcomment(ph, EN_LINK, index, comment);
|
||||
if (strcmp(comment, (char *)"P11") != 0) return 0;
|
||||
|
||||
EN_getlinkindex(ph, (char *)"9", &index);
|
||||
EN_getcomment(ph, EN_LINK, index, comment);
|
||||
if (strcmp(comment, (char *)"Pump9") != 0) return 0;
|
||||
|
||||
EN_getpatternindex(ph, (char *)"1", &index);
|
||||
EN_getcomment(ph, EN_TIMEPAT, index, comment);
|
||||
if (strcmp(comment, (char *)"Time Pattern 1") != 0) return 0;
|
||||
|
||||
EN_getcurveindex(ph, (char *)"1", &index);
|
||||
EN_getcomment(ph, EN_CURVE, index, comment);
|
||||
if (strcmp(comment, (char *)"Curve 1") != 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef NO_BOOST
|
||||
BOOST_AUTO_TEST_SUITE (test_toolkit)
|
||||
BOOST_AUTO_TEST_CASE(test_setlinktype)
|
||||
{
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#endif
|
||||
|
||||
int error = 0;
|
||||
int index;
|
||||
char comment[EN_MAXMSG+1];
|
||||
|
||||
// Create & load a project
|
||||
EN_Project ph = NULL;
|
||||
EN_createproject(&ph);
|
||||
std::string path_inp = string(DATA_PATH_INP);
|
||||
std::string path_rpt = string(DATA_PATH_RPT);
|
||||
std::string path_out = string(DATA_PATH_OUT);
|
||||
error = EN_open(ph, path_inp.c_str(), path_rpt.c_str(), "");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Add comments to selected objects
|
||||
EN_getnodeindex(ph, (char *)"11", &index);
|
||||
EN_setcomment(ph, EN_NODE, index, (char *)"J11");
|
||||
EN_getnodeindex(ph, (char *)"23", &index);
|
||||
EN_setcomment(ph, EN_NODE, index, (char *)"Junc23");
|
||||
EN_getlinkindex(ph, (char *)"11", &index);
|
||||
|
||||
EN_setcomment(ph, EN_LINK, index, (char *)"P11");
|
||||
EN_getlinkindex(ph, (char *)"9", &index);
|
||||
EN_setcomment(ph, EN_LINK, index, (char *)"Pump9");
|
||||
|
||||
EN_getpatternindex(ph, (char *)"1", &index);
|
||||
EN_setcomment(ph, EN_TIMEPAT, index, (char *)"Time Pattern 1");
|
||||
|
||||
EN_getcurveindex(ph, (char *)"1", &index);
|
||||
EN_setcomment(ph, EN_CURVE, index, (char *)"Curve 1");
|
||||
|
||||
// Retrieve comments and test their values
|
||||
BOOST_REQUIRE(checkComments(ph) == 1);
|
||||
|
||||
// Replace short comment with longer one and vice versa
|
||||
EN_getnodeindex(ph, (char *)"11", &index);
|
||||
EN_setcomment(ph, EN_NODE, index, (char *)"Junction11");
|
||||
EN_getcomment(ph, EN_NODE, index, comment);
|
||||
BOOST_REQUIRE(strcmp(comment, (char *)"Junction11") == 0);
|
||||
EN_setcomment(ph, EN_NODE, index, (char *)"J11");
|
||||
EN_getcomment(ph, EN_NODE, index, comment);
|
||||
BOOST_REQUIRE(strcmp(comment, (char *)"J11") == 0);
|
||||
|
||||
// Save & re-open project
|
||||
string path_tmp = string(DATA_PATH_TMP);
|
||||
EN_saveinpfile(ph, path_tmp.c_str());
|
||||
EN_close(ph);
|
||||
error = EN_open(ph, path_tmp.c_str(), path_rpt.c_str(), "");
|
||||
BOOST_REQUIRE(error == 0);
|
||||
|
||||
// Check that comments were saved & read correctly
|
||||
BOOST_REQUIRE(checkComments(ph) == 1);
|
||||
remove(path_tmp.c_str());
|
||||
|
||||
// Close project
|
||||
EN_close(ph);
|
||||
EN_deleteproject(&ph);
|
||||
|
||||
#ifdef NO_BOOST
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#ifndef NO_BOOST
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
#endif
|
||||
@@ -21,6 +21,7 @@ EXPORTS
|
||||
ENepanet = _ENepanet@16
|
||||
ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8
|
||||
ENgetbasedemand = _ENgetbasedemand@12
|
||||
ENgetcomment = _ENgetcomment@12
|
||||
ENgetcontrol = _ENgetcontrol@24
|
||||
ENgetcoord = _ENgetcoord@12
|
||||
ENgetcount = _ENgetcount@8
|
||||
@@ -80,6 +81,7 @@ EXPORTS
|
||||
ENsavehydfile = _ENsavehydfile@4
|
||||
ENsaveinpfile = _ENsaveinpfile@4
|
||||
ENsetbasedemand = _ENsetbasedemand@12
|
||||
ENsetcomment = _ENsetcomment@12
|
||||
ENsetcontrol = _ENsetcontrol@24
|
||||
ENsetcoord = _ENsetcoord@20
|
||||
ENsetcurve = _ENsetcurve@16
|
||||
|
||||
Reference in New Issue
Block a user