From 1a01b46187dea607e51b86c27e1dd81c6a1a3902 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 26 Mar 2019 14:57:41 -0400 Subject: [PATCH 01/26] Adding build configuration Setting up debug build so we can better monitor memory leaks --- appveyor.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1d3f5ae..99b2d8d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,14 +20,23 @@ environment: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 GENERATOR: "Visual Studio 15 2017" GROUP: "SUPPORTED" + BUILD_CONFIG: "Release" BOOST_ROOT: "C:/Libraries/boost_1_67_0" - PLATFORM: "win32" REF_BUILD_ID: "220dev5" # New build on Visual Studio 15 2017 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 GENERATOR: "Visual Studio 15 2017 Win64" GROUP: "EXPERIMENTAL" + BUILD_CONFIG: "Release" + BOOST_ROOT: "C:/Libraries/boost_1_67_0" + PLATFORM: "win64" + REF_BUILD_ID: "381_2" + # adding debug configuration so we can monitor memory leaks + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + GENERATOR: "Visual Studio 15 2017 Win64" + GROUP: "EXPERIMENTAL" + BUILD_CONFIG: "Debug" BOOST_ROOT: "C:/Libraries/boost_1_67_0" PLATFORM: "win64" REF_BUILD_ID: "381_2" @@ -60,7 +69,7 @@ before_build: # run custom build script build_script: - - cmake --build . --config Release + - cmake --build . --config %BUILD_CONFIG% before_test: - cd %EPANET_HOME% @@ -70,11 +79,12 @@ before_test: test_script: # run unit tests - cd %BUILD_HOME%\tests - - ctest -C Release --output-on-failure + - ctest -C %BUILD_CONFIG% --output-on-failure # run regression tests - - cd %EPANET_HOME% - - tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% - + - IF "%BUILD_CONFIG%" == "Release" ( + cd %EPANET_HOME% + tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% + ) on_success: - cd %TEST_HOME%\benchmark - appveyor PushArtifact receipt.json From 44bea587c09fed996b66eb334e47275a16925be0 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 26 Mar 2019 15:18:54 -0400 Subject: [PATCH 02/26] Fixing bug in appveyor.yml --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 99b2d8d..1ba3beb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -82,8 +82,7 @@ test_script: - ctest -C %BUILD_CONFIG% --output-on-failure # run regression tests - IF "%BUILD_CONFIG%" == "Release" ( - cd %EPANET_HOME% - tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% + cd %EPANET_HOME% & tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% ) on_success: - cd %TEST_HOME%\benchmark From d4d876da718fa35d43658279f3ca0d506254ae58 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 26 Mar 2019 15:51:09 -0400 Subject: [PATCH 03/26] Update appveyor.yml Adding conditions to post test tasks --- appveyor.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 1ba3beb..dc80e1c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -81,15 +81,21 @@ test_script: - cd %BUILD_HOME%\tests - ctest -C %BUILD_CONFIG% --output-on-failure # run regression tests + - cd %EPANET_HOME% - IF "%BUILD_CONFIG%" == "Release" ( - cd %EPANET_HOME% & tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% + tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% ) on_success: - cd %TEST_HOME%\benchmark - - appveyor PushArtifact receipt.json + - IF "%BUILD_CONFIG%" == "Release" ( + appveyor PushArtifact receipt.json + ) on_failure: - cd %TEST_HOME%\benchmark # zip up the SUT benchmarks - - 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% - - appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip + - IF "%BUILD_CONFIG%" == "Release" ( + 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & + appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip + ) + From 8574f522563632264fee5164cd00668eff8268ba Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 26 Mar 2019 16:48:08 -0400 Subject: [PATCH 04/26] Fixing indentation --- appveyor.yml | 1 - src/epanet_py.c | 42 +++++++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dc80e1c..22c1acf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -98,4 +98,3 @@ on_failure: 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip ) - diff --git a/src/epanet_py.c b/src/epanet_py.c index fb681aa..4c16cbf 100644 --- a/src/epanet_py.c +++ b/src/epanet_py.c @@ -786,25 +786,29 @@ void error_lookup(int errcode, char *dest_msg, int dest_len) { char *msg = NULL; - switch (errcode) - { - case 1: msg = WARN1; - break; - case 2: msg = WARN2; - break; - case 3: msg = WARN3; - break; - case 4: msg = WARN4; - break; - case 5: msg = WARN5; - break; - case 6: msg = WARN6; - break; - default: - { - char new_msg[MAXMSG + 1]; - msg = geterrmsg(errcode, new_msg); - } + switch (errcode) { + case 1: + msg = WARN1; + break; + case 2: + msg = WARN2; + break; + case 3: + msg = WARN3; + break; + case 4: + msg = WARN4; + break; + case 5: + msg = WARN5; + break; + case 6: + msg = WARN6; + break; + default: { + char new_msg[MAXMSG + 1]; + msg = geterrmsg(errcode, new_msg); + } } strncpy(dest_msg, msg, dest_len); } From 1b167b5caf01ba4563fa1cc71bc355a0bf664a1e Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 28 Mar 2019 09:26:26 -0400 Subject: [PATCH 05/26] Cleaning up include statements Removing inclusion of malloc.h. Adding crtdbg.h --- run/main.c | 1 + src/epanet.c | 45 +++++++++++++++-------------- src/epanet2.c | 10 +++++-- src/epanet_py.c | 1 + src/hash.c | 5 +--- src/hydcoeffs.c | 6 +--- src/hydraul.c | 6 +--- src/hydsolver.c | 6 +--- src/hydstatus.c | 1 + src/inpfile.c | 4 --- src/input1.c | 28 ++++++++++-------- src/input2.c | 63 +++++++++++++++++++++-------------------- src/input3.c | 11 ++++--- src/mempool.c | 4 +-- src/output.c | 6 +--- src/project.c | 12 +++++--- src/quality.c | 6 +--- src/qualreact.c | 1 + src/qualroute.c | 7 ++--- src/report.c | 7 ++--- src/rules.c | 6 +--- src/smatrix.c | 7 +---- src/types.h | 4 ++- src/util/errormanager.c | 6 ---- tests/CMakeLists.txt | 23 ++++++++------- tests/test_analysis.cpp | 1 - tests/test_project.cpp | 50 +++++++++++++++++++------------- tests/test_toolkit.hpp | 6 ++++ 28 files changed, 164 insertions(+), 169 deletions(-) diff --git a/run/main.c b/run/main.c index 793fffa..ea0a91c 100644 --- a/run/main.c +++ b/run/main.c @@ -12,6 +12,7 @@ */ #include + #include "epanet2.h" void writeConsole(char *s) diff --git a/src/epanet.c b/src/epanet.c index 29462bc..a6df228 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -11,12 +11,17 @@ ****************************************************************************** */ -#include -#include -#include -#ifndef __APPLE__ -#include +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#else + #include #endif + +#include +#include + #include #include @@ -216,26 +221,24 @@ int DLLEXPORT EN_open(EN_Project p, const char *inpFile, const char *rptFile, ERRCODE(netsize(p)); ERRCODE(allocdata(p)); - // Read input data - ERRCODE(getdata(p)); + if (!errcode) { + // Read input data + ERRCODE(getdata(p)); - // Close input file - if (p->parser.InFile != NULL) - { + // Close input file + if (p->parser.InFile != NULL) { fclose(p->parser.InFile); p->parser.InFile = NULL; - } + } - // Free temporary linked lists used for Patterns & Curves - freeTmplist(p->parser.Patlist); - freeTmplist(p->parser.Curvelist); + // Free temporary linked lists used for Patterns & Curves + freeTmplist(p->parser.Patlist); + freeTmplist(p->parser.Curvelist); - // If using previously saved hydraulics file then open it - if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p)); + // If using previously saved hydraulics file then open it + if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p)); - // Write input summary to report file - if (!errcode) - { + // Write input summary to report file if (p->report.Summaryflag) writesummary(p); writetime(p, FMT104); p->Openflag = TRUE; @@ -279,7 +282,7 @@ 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 +** Output: comment = the object's descriptive comment ** Returns: error code ** Purpose: Retrieves an object's descriptive comment **---------------------------------------------------------------- @@ -840,7 +843,7 @@ int DLLEXPORT EN_closeQ(EN_Project p) if (!p->Openflag) return 102; closequal(p); p->quality.OpenQflag = FALSE; - closeoutfile(p); + closeoutfile(p); return 0; } diff --git a/src/epanet2.c b/src/epanet2.c index 935d6c4..3d11608 100644 --- a/src/epanet2.c +++ b/src/epanet2.c @@ -10,11 +10,15 @@ Last Updated: 03/17/2019 ****************************************************************************** */ -#ifndef __APPLE__ -#include + +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include #else -#include + #include #endif + #include #include "types.h" diff --git a/src/epanet_py.c b/src/epanet_py.c index 4c16cbf..e84fdc9 100644 --- a/src/epanet_py.c +++ b/src/epanet_py.c @@ -26,6 +26,7 @@ typedef struct { Project *project; error_handle_t *error; }handle_t; + // Extern functions extern char *geterrmsg(int, char *); // Local functions diff --git a/src/hash.c b/src/hash.c index 95ac8dd..c3f91e2 100755 --- a/src/hash.c +++ b/src/hash.c @@ -11,12 +11,9 @@ ****************************************************************************** */ -#ifndef __APPLE__ -#include -#else #include -#endif #include + #include "hash.h" #define HASHTABLEMAXSIZE 128000 diff --git a/src/hydcoeffs.c b/src/hydcoeffs.c index b6c002c..4b3583d 100644 --- a/src/hydcoeffs.c +++ b/src/hydcoeffs.c @@ -11,13 +11,9 @@ ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include "types.h" diff --git a/src/hydraul.c b/src/hydraul.c index 703f7b7..c442ac6 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -11,13 +11,9 @@ ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include "types.h" diff --git a/src/hydsolver.c b/src/hydsolver.c index 3c0694a..90c93e1 100644 --- a/src/hydsolver.c +++ b/src/hydsolver.c @@ -12,13 +12,9 @@ ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include "types.h" diff --git a/src/hydstatus.c b/src/hydstatus.c index f7edb6b..5905337 100644 --- a/src/hydstatus.c +++ b/src/hydstatus.c @@ -12,6 +12,7 @@ Last Updated: 11/27/2018 */ #include + #include "types.h" #include "funcs.h" diff --git a/src/inpfile.c b/src/inpfile.c index 45b5aab..994830a 100644 --- a/src/inpfile.c +++ b/src/inpfile.c @@ -13,11 +13,7 @@ Last Updated: 03/17/2019 #include #include -#ifndef __APPLE__ -#include -#else #include -#endif #include #include "types.h" diff --git a/src/input1.c b/src/input1.c index fe606d9..4cafa13 100644 --- a/src/input1.c +++ b/src/input1.c @@ -3,26 +3,30 @@ Project: OWA EPANET Version: 2.2 Module: input1.c -Description: retrieves network data from an EPANET input file +Description: retrieves network data from an EPANET input file Authors: see AUTHORS Copyright: see AUTHORS License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#else + #include +#endif #include -#include #include -#ifndef __APPLE__ -#include -#endif +#include #include "types.h" #include "funcs.h" #include "hash.h" #include "text.h" -#include + // Default values #define MAXITER 200 // Default max. # hydraulic iterations @@ -56,7 +60,7 @@ int getdata(Project *pr) int errcode = 0; // Assign default data values & reporting options - setdefaults(pr); + setdefaults(pr); initreport(&pr->report); // Read in network data @@ -102,7 +106,7 @@ void setdefaults(Project *pr) parser->Pressflag = PSI; // Pressure units are psi out->Hydflag = SCRATCH; // No external hydraulics file rpt->Tstatflag = SERIES; // Generate time series output - + hyd->Formflag = HW; // Use Hazen-Williams formula hyd->Htol = HTOL; // Default head tolerance hyd->Qtol = QTOL; // Default flow tolerance @@ -353,7 +357,7 @@ int inittanks(Project *pr) */ { Network *net = &pr->network; - + int i, j, n = 0; double a; int errcode = 0, levelerr; @@ -546,7 +550,7 @@ void convertunits(Project *pr) Slink *link; Spump *pump; Scontrol *control; - + // Convert nodal elevations & initial WQ // (WQ source units are converted in QUALITY.C for (i = 1; i <= net->Nnodes; i++) @@ -644,7 +648,7 @@ void convertunits(Project *pr) pump->H0 /= pr->Ucf[HEAD]; pump->R *= (pow(pr->Ucf[FLOW], pump->N) / pr->Ucf[HEAD]); } - + // Convert flow range & max. head units pump->Q0 /= pr->Ucf[FLOW]; pump->Qmax /= pr->Ucf[FLOW]; @@ -653,7 +657,7 @@ void convertunits(Project *pr) } else { - // For flow control valves, convert flow setting + // For flow control valves, convert flow setting // while for other valves convert pressure setting link->Diam /= pr->Ucf[DIAM]; link->Km = 0.02517 * link->Km / SQR(link->Diam) / SQR(link->Diam); diff --git a/src/input2.c b/src/input2.c index 2820e35..e4d2d85 100644 --- a/src/input2.c +++ b/src/input2.c @@ -10,13 +10,16 @@ License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#else + #include +#endif #include -#include #include -#ifndef __APPLE__ -#include -#endif #include #include "types.h" @@ -56,7 +59,7 @@ int netsize(Project *pr) */ { Parser *parser = &pr->parser; - + char line[MAXLINE + 1]; // Line from input data file char *tok; // First token of line int sect, newsect; // Input data sections @@ -147,7 +150,7 @@ int readdata(Project *pr) inperr, errsum; // Error code & total error count // Allocate input buffer - parser->X = (double *)calloc(MAXTOKS, sizeof(double)); + parser->X = (double *)calloc(MAXTOKS + 1, sizeof(double)); ERRCODE(MEMCHECK(parser->X)); if (errcode) return errcode; @@ -175,7 +178,7 @@ int readdata(Project *pr) while (fgets(line, MAXLINE, parser->InFile) != NULL) { // Make copy of line and scan for tokens - strcpy(wline, line); + strncpy(wline, line, MAXLINE); parser->Ntokens = gettokens(wline, parser->Tok, MAXTOKS, parser->Comment); // Skip blank lines and those filled with a comment @@ -246,10 +249,10 @@ int readdata(Project *pr) // Stop if reach end of file or max. error count if (errsum == MAXERRS) break; } - + // Check for errors if (errsum > 0) errcode = 200; - + // Check for unlinked nodes if (!errcode) errcode = unlinked(pr); @@ -397,7 +400,7 @@ int updatepumpparams(Project *pr, int pumpindex) curve->Type = PUMP_CURVE; npts = curve->Npts; - // Generic power function curve + // Generic power function curve if (npts == 1) { pump->Ptype = POWER_FUNC; @@ -407,7 +410,7 @@ int updatepumpparams(Project *pr, int pumpindex) q2 = 2.0 * q1; h2 = 0.0; } - + // 3 point curve with shutoff head else if (npts == 3 && curve->X[0] == 0.0) { @@ -418,7 +421,7 @@ int updatepumpparams(Project *pr, int pumpindex) q2 = curve->X[2]; h2 = curve->Y[2]; } - + // Custom pump curve else { @@ -431,7 +434,7 @@ int updatepumpparams(Project *pr, int pumpindex) pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0; pump->Hmax = curve->Y[0]; } - + // Compute shape factors & limits of power function curves if (pump->Ptype == POWER_FUNC) { @@ -461,7 +464,7 @@ int addnodeID(Network *net, int n, char *id) **-------------------------------------------------------------- */ { - if (findnode(net,id)) return 0; + if (findnode(net,id)) return 0; strncpy(net->Node[n].ID, id, MAXID); hashtable_insert(net->NodeHashTable, net->Node[n].ID, n); return 1; @@ -587,7 +590,7 @@ int unlinked(Project *pr) Network *net = &pr->network; int *marked; int i, err, errcode; - + errcode = 0; err = 0; @@ -596,19 +599,19 @@ int unlinked(Project *pr) ERRCODE(MEMCHECK(marked)); if (errcode) return errcode; memset(marked, 0, (net->Nnodes + 1) * sizeof(int)); - + // Mark end nodes of each link for (i = 1; i <= net->Nlinks; i++) { marked[net->Link[i].N1]++; marked[net->Link[i].N2]++; } - + // Check each junction for (i = 1; i <= net->Njuncs; i++) { // If not marked then error - if (marked[i] == 0) + if (marked[i] == 0) { err++; sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID); @@ -638,7 +641,7 @@ int getpatterns(Project *pr) SFloatlist *f; STmplist *tmppattern; Spattern *pattern; - + // Start at head of the list of patterns tmppattern = parser->Patlist; @@ -696,7 +699,7 @@ int getcurves(Project *pr) { Network *net = &pr->network; Parser *parser = &pr->parser; - + int i, j; double x; char errmsg[MAXMSG+1]; @@ -827,14 +830,14 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) int m, n; size_t len; char *c, *c2; - + // clear comment comment[0] = '\0'; - + // Begin with no tokens for (n=0; n 0 && n < MAXTOKS) { @@ -868,7 +871,7 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) { s++; // Start token after quote m = (int)strcspn(s,"\"\n\r"); // Find end quote (or EOL) - } + } s[m] = '\0'; // Null-terminate the token Tok[n] = s; // Save pointer to token n++; // Update token count @@ -876,7 +879,7 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) } } return n; -} +} double hour(char *time, char *units) /* @@ -914,7 +917,7 @@ double hour(char *time, char *units) if (match(units, w_DAYS)) return (y[0] * 24.0); } - // Convert hh:mm:ss format to decimal hours + // Convert hh:mm:ss format to decimal hours if (n > 1) y[0] = y[0] + y[1] / 60.0 + y[2] / 3600.0; // If am/pm attached then adjust hour accordingly @@ -933,7 +936,7 @@ double hour(char *time, char *units) else return (y[0] + 12.0); } return -1.0; -} +} int getfloat(char *s, double *y) /* @@ -979,14 +982,14 @@ void inperrmsg(Project *pr, int err, int sect, char *line) */ { Parser *parser = &pr->parser; - + char errStr[MAXMSG + 1] = ""; char tok[MAXMSG + 1]; // Get token associated with input error if (parser->ErrTok >= 0) strcpy(tok, parser->Tok[parser->ErrTok]); else strcpy(tok, ""); - + // write error message to report file sprintf(pr->Msg, "Error %d: %s %s in %s section:", err, geterrmsg(err, errStr), tok, SectTxt[sect]); diff --git a/src/input3.c b/src/input3.c index fb35da2..d00a6e9 100644 --- a/src/input3.c +++ b/src/input3.c @@ -10,13 +10,16 @@ License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#else + #include +#endif #include -#include #include -#ifndef __APPLE__ -#include -#endif #include #include "types.h" diff --git a/src/mempool.c b/src/mempool.c index 55552ed..871b4c8 100755 --- a/src/mempool.c +++ b/src/mempool.c @@ -15,9 +15,7 @@ */ #include -#ifndef __APPLE__ -#include -#endif + #include "mempool.h" /* diff --git a/src/output.c b/src/output.c index fd92077..d86fe50 100644 --- a/src/output.c +++ b/src/output.c @@ -11,13 +11,9 @@ Last Updated: 11/27/2018 ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include "types.h" diff --git a/src/project.c b/src/project.c index fd4cb8d..8355588 100644 --- a/src/project.c +++ b/src/project.c @@ -11,14 +11,18 @@ ****************************************************************************** */ -#include -#include -#ifndef __APPLE__ -#include +#ifdef _DEBUG +#define _CRTDBG_MAP_ALLOC +#include +#include #else #include #endif +#include +#include + + //*** For the Windows SDK _tempnam function ***// #ifdef _WIN32 #include diff --git a/src/quality.c b/src/quality.c index de27f63..06e1997 100644 --- a/src/quality.c +++ b/src/quality.c @@ -11,13 +11,9 @@ Last Updated: 11/27/2018 ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include "mempool.h" diff --git a/src/qualreact.c b/src/qualreact.c index 0805a21..0afac47 100644 --- a/src/qualreact.c +++ b/src/qualreact.c @@ -13,6 +13,7 @@ Last Updated: 11/27/2018 #include #include + #include "types.h" // Exported functions diff --git a/src/qualroute.c b/src/qualroute.c index 72bb66f..03e3545 100644 --- a/src/qualroute.c +++ b/src/qualroute.c @@ -11,13 +11,10 @@ Last Updated: 11/27/2018 ****************************************************************************** */ -#include -#ifndef __APPLE__ -#include -#else #include -#endif +#include #include + #include "mempool.h" #include "types.h" diff --git a/src/report.c b/src/report.c index 5605ffb..dd4ff3d 100644 --- a/src/report.c +++ b/src/report.c @@ -11,13 +11,10 @@ ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif + #ifdef _WIN32 #define snprintf _snprintf diff --git a/src/rules.c b/src/rules.c index 7e9945f..eee5568 100644 --- a/src/rules.c +++ b/src/rules.c @@ -11,13 +11,9 @@ ****************************************************************************** */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include "types.h" #include "funcs.h" diff --git a/src/smatrix.c b/src/smatrix.c index 510bb3e..3446384 100755 --- a/src/smatrix.c +++ b/src/smatrix.c @@ -18,16 +18,11 @@ linsolve() -- called from netsolve() in HYDRAUL.C */ +#include #include #include -#ifndef __APPLE__ -#include -#else -#include -#endif #include #include - #include //For optional timer macros #include "text.h" diff --git a/src/types.h b/src/types.h index 4329414..38d6607 100755 --- a/src/types.h +++ b/src/types.h @@ -14,9 +14,11 @@ #ifndef TYPES_H #define TYPES_H -#include "hash.h" #include +#include "hash.h" + + /* ------------------------------------------- Definition of 4-byte integers & reals diff --git a/src/util/errormanager.c b/src/util/errormanager.c index 5a9876c..b674fe6 100644 --- a/src/util/errormanager.c +++ b/src/util/errormanager.c @@ -10,13 +10,7 @@ // US EPA - ORD/NRMRL //----------------------------------------------------------------------------- -//#ifdef _WIN32 -//#define _CRTDBG_MAP_ALLOC -//#include -//#include -//#else #include -//#endif #include #include "errormanager.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d16c376..ffb73b4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,18 +19,19 @@ endif(UNIX) set(toolkit_test_srcs test_toolkit.cpp test_project.cpp - test_hydraulics.cpp - test_quality.cpp - test_report.cpp - test_analysis.cpp - test_node.cpp - test_demand.cpp - test_link.cpp +# test_hydraulics.cpp +# test_quality.cpp +# test_report.cpp +# test_analysis.cpp +# test_node.cpp +# test_demand.cpp +# test_link.cpp # test_pump.cpp - test_pattern.cpp - test_curve.cpp - test_control.cpp - test_net_builder.cpp) +# test_pattern.cpp +# test_curve.cpp +# test_control.cpp +# test_net_builder.cpp +) add_executable(test_toolkit ${toolkit_test_srcs}) diff --git a/tests/test_analysis.cpp b/tests/test_analysis.cpp index f7120f1..917b523 100644 --- a/tests/test_analysis.cpp +++ b/tests/test_analysis.cpp @@ -11,7 +11,6 @@ ****************************************************************************** */ -//#define BOOST_ALL_DYN_LINK #include #include "test_toolkit.hpp" diff --git a/tests/test_project.cpp b/tests/test_project.cpp index 6f0b68c..6ae1143 100644 --- a/tests/test_project.cpp +++ b/tests/test_project.cpp @@ -56,35 +56,47 @@ BOOST_AUTO_TEST_CASE(test_save) { int error; - EN_Project ph_save; + EN_Project ph = NULL; - EN_createproject(&ph_save); - error = EN_open(ph_save, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT); - BOOST_REQUIRE(error == 0); - - error = EN_saveinpfile(ph_save, "test_reopen.inp"); - BOOST_REQUIRE(error == 0); - - BOOST_CHECK(boost::filesystem::exists("test_reopen.inp") == true); - - error = EN_close(ph_save); + error = EN_createproject(&ph); BOOST_REQUIRE(error == 0); - EN_deleteproject(&ph_save); + + error = EN_open(ph, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT); + BOOST_REQUIRE(error == 0); + + error = EN_saveinpfile(ph, DATA_PATH_TMP); + BOOST_REQUIRE(error == 0); + + BOOST_CHECK(boost::filesystem::exists(DATA_PATH_TMP) == true); + + error = EN_close(ph); + BOOST_REQUIRE(error == 0); + + error = EN_deleteproject(&ph); + BOOST_REQUIRE(error == 0); + + BOOST_CHECK(ph == NULL); } BOOST_AUTO_TEST_CASE(test_reopen, * boost::unit_test::depends_on("test_project/test_save")) { int error; - EN_Project ph_reopen; + EN_Project ph = NULL; - EN_createproject(&ph_reopen); - error = EN_open(ph_reopen, "test_reopen.inp", DATA_PATH_RPT, DATA_PATH_OUT); - BOOST_REQUIRE(error == 0); + error = EN_createproject(&ph); + BOOST_REQUIRE(error == 0); - error = EN_close(ph_reopen); - BOOST_REQUIRE(error == 0); - EN_deleteproject(&ph_reopen); + error = EN_open(ph, DATA_PATH_TMP, DATA_PATH_RPT, DATA_PATH_OUT); + BOOST_REQUIRE(error == 0); + + error = EN_close(ph); + BOOST_REQUIRE(error == 0); + + EN_deleteproject(&ph); + BOOST_REQUIRE(error == 0); + + BOOST_CHECK(ph == NULL); } BOOST_AUTO_TEST_CASE(test_run) diff --git a/tests/test_toolkit.hpp b/tests/test_toolkit.hpp index 03ac664..f0da4e7 100644 --- a/tests/test_toolkit.hpp +++ b/tests/test_toolkit.hpp @@ -14,6 +14,12 @@ #ifndef TEST_TOOLKIT_HPP #define TEST_TOOLKIT_HPP +// MSVC ONLY +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#endif #include "epanet2_2.h" From 727ede3aba8ce7831d649043ef1360d5d718b2d0 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 28 Mar 2019 17:28:02 -0400 Subject: [PATCH 06/26] Initial commit filemanager --- src/util/filemanager.c | 89 ++++++++++++++++++++++++++++++++++++++++++ src/util/filemanager.h | 44 +++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/util/filemanager.c create mode 100644 src/util/filemanager.h diff --git a/src/util/filemanager.c b/src/util/filemanager.c new file mode 100644 index 0000000..f2fcc8f --- /dev/null +++ b/src/util/filemanager.c @@ -0,0 +1,89 @@ + + +#include +#include + +#include "filemanager.h" + + +// local (private) functions +int _get_temp_filename(char *tempname); + + +file_handle_t *create_file_manager(const char *filename, const char *file_mode) { + + file_handle_t *file_handle; + file_handle = (file_handle_t*)calloc(1, sizeof(file_handle_t)); + + if (filename == NULL) + _get_temp_filename(file_handle->filename); + else + strncpy(file_handle->filename, filename, FILE_MAXNAME); + + file_handle->file = NULL; + strncpy(file_handle->mode, file_mode, FILE_MAXMODE); + + return file_handle; +} + +int delete_file_manager(file_handle_t *file_handle) { + free(file_handle); +} + + +int open_file(file_handle_t *file_handle) { + int error = 0; + + if ((file_handle->file = fopen(file_handle->filename, file_handle->mode)) == NULL) + error = -1; + + return error; +} + +FILE *get_file(file_handle_t *file_handle) { + return file_handle->file; +} + +int close_file(file_handle_t *file_handle) { + int error = 0; + + if (file_handle->file != NULL) { + error = fclose(file_handle->file); + file_handle->file = NULL; + } + return error; +} + +int remove_file(file_handle_t *file_handle) { + return remove(file_handle->filename); +} + + +int _get_temp_filename(char *tempname) { + int error = 0 +#ifdef _WIN32 + char* name = NULL; + + // --- use Windows _tempnam function to get a pointer to an + // unused file name that begins with "en" + if ((name = _tempnam(NULL, "en") == NULL) { + error = -1; + return error; + } + else if (strlen(name) < FILE_MAXNAME) + strncpy(tempname, name, FILE_MAXNAME); + else + tempname = NULL; + + // --- free the pointer returned by _tempnam + if (name) + free(name); + + // --- for non-Windows systems: +#else + // --- use system function mkstemp() to create a temporary file name + strncpy(tempname, "enXXXXXX", 8); + error = mkstemp(tempname); +#endif + return error; +} diff --git a/src/util/filemanager.h b/src/util/filemanager.h new file mode 100644 index 0000000..24c8b55 --- /dev/null +++ b/src/util/filemanager.h @@ -0,0 +1,44 @@ + + + + +#ifndef FILEMANAGER_H_ +#define FILEMANAGER_H_ + + +#include + +#define FILE_MAXNAME 259 +#define FILE_MAXMODE 3 + + +#if defined(__cplusplus) +extern "C" { +#endif + + +typedef struct file_s { + char filename[FILE_MAXNAME + 1], + FILE *file; + char mode[FILE_MAXMODE + 1]; +} file_handle_t; + + +file_handle_t *create_file_manager(const char *filename, const char *file_mode); + +int delete_file_manager(file_handle_t *file_handle); + + +int open_file(file_handle_t *file_handle); + +FILE *get_file(file_handle_t *file_handle); + +int close_file(file_handle_t *file_handle); + + + +#if defined(__cplusplus) +} +#endif + +#endif /* FILEMANAGER_H_ */ From d1df792c779d29dedc01d799205c7baa7dc033ea Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Thu, 28 Mar 2019 17:39:05 -0400 Subject: [PATCH 07/26] Adding remove_file() --- src/util/filemanager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/filemanager.h b/src/util/filemanager.h index 24c8b55..4daf04e 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -35,6 +35,7 @@ FILE *get_file(file_handle_t *file_handle); int close_file(file_handle_t *file_handle); +int remove_file(file_handle_t *file_handle); #if defined(__cplusplus) From 69da9a4997dd86e35ae6c4295c7e28b40493b17b Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Fri, 29 Mar 2019 17:04:55 -0400 Subject: [PATCH 08/26] Work in progress --- src/util/filemanager.h | 2 +- tests/util/test_filemanager.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/util/test_filemanager.cpp diff --git a/src/util/filemanager.h b/src/util/filemanager.h index 4daf04e..c9961b8 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -20,7 +20,7 @@ extern "C" { typedef struct file_s { char filename[FILE_MAXNAME + 1], FILE *file; - char mode[FILE_MAXMODE + 1]; + char mode[FILE_MAXMODE + 1]; } file_handle_t; diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp new file mode 100644 index 0000000..b9d830e --- /dev/null +++ b/tests/util/test_filemanager.cpp @@ -0,0 +1,7 @@ + + +#define BOOST_TEST_MODULE filemanager + +#include + +#include "util/filemanager.h" From 23ac179ec120653f7b26ba9118805124a11f8fc9 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 1 Apr 2019 15:03:02 -0400 Subject: [PATCH 09/26] Implementing filemanager Implementing and testing filemanager and upgrading epanet_output library to use it. --- src/outfile/CMakeLists.txt | 3 +- src/outfile/src/epanet_output.c | 180 +++++++++++-------------------- src/util/filemanager.c | 104 ++++++++++++++---- src/util/filemanager.h | 27 +++-- tests/util/CMakeLists.txt | 6 ++ tests/util/test_errormanager.cpp | 2 +- tests/util/test_filemanager.cpp | 59 ++++++++++ 7 files changed, 231 insertions(+), 150 deletions(-) diff --git a/src/outfile/CMakeLists.txt b/src/outfile/CMakeLists.txt index cdd2f0f..79a8ae1 100644 --- a/src/outfile/CMakeLists.txt +++ b/src/outfile/CMakeLists.txt @@ -21,7 +21,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # configure file groups set(EPANET_OUT_SOURCES src/epanet_output.c - ../util/errormanager.c) + ../util/errormanager.c + ../util/filemanager.c) # the binary output file API diff --git a/src/outfile/src/epanet_output.c b/src/outfile/src/epanet_output.c index dcbcd75..6e0c63d 100644 --- a/src/outfile/src/epanet_output.c +++ b/src/outfile/src/epanet_output.c @@ -40,18 +40,13 @@ #include #include "util/errormanager.h" +#include "util/filemanager.h" #include "epanet_output.h" #include "messages.h" // NOTE: These depend on machine data model and may change when porting -// F_OFF Must be a 8 byte / 64 bit integer for large file support -#ifdef _WIN32 // Windows (32-bit and 64-bit) -#define F_OFF __int64 -#else // Other platforms -#define F_OFF off_t -#endif #define INT4 int // Must be a 4 byte / 32 bit integer type #define REAL4 float // Must be a 4 byte / 32 bit real type #define WORDSIZE 4 // Memory alignment 4 byte word size for both int and real @@ -71,33 +66,28 @@ // Typedefs for opaque pointer typedef struct data_s { - char name[MAXFNAME+1]; // file path/name - FILE* file; // FILE structure pointer INT4 nodeCount, tankCount, linkCount, pumpCount, valveCount, nPeriods; F_OFF outputStartPos; // starting file position of output data F_OFF bytesPerPeriod; // bytes saved per simulation time period - error_handle_t* error_handle; + error_handle_t *error_handle; + file_handle_t *file_handle; } data_t; //----------------------------------------------------------------------------- // Local functions //----------------------------------------------------------------------------- -void errorLookup(int errcode, char* errmsg, int length); -int validateFile(ENR_Handle); -float getNodeValue(ENR_Handle, int, int, int); -float getLinkValue(ENR_Handle, int, int, int); +void errorLookup(int errcode, char* errmsg, int length); +int validateFile(ENR_Handle); +float getNodeValue(ENR_Handle, int, int, int); +float getLinkValue(ENR_Handle, int, int, int); -int _fopen(FILE **f, const char *name, const char *mode); -int _fseek(FILE* stream, F_OFF offset, int whence); -F_OFF _ftell(FILE* stream); - -float* newFloatArray(int n); -int* newIntArray(int n); -char* newCharArray(int n); +float *newFloatArray(int n); +int *newIntArray(int n); +char *newCharArray(int n); -int EXPORT_OUT_API ENR_init(ENR_Handle* dp_handle) +int EXPORT_OUT_API ENR_init(ENR_Handle *dp_handle) // Purpose: Initialized pointer for the opaque ENR_Handle. // // Returns: Error code 0 on success, -1 on failure @@ -114,6 +104,7 @@ int EXPORT_OUT_API ENR_init(ENR_Handle* dp_handle) if (p_data != NULL){ p_data->error_handle = create_error_manager(&errorLookup); + p_data->file_handle = create_file_manager(); *dp_handle = p_data; } else @@ -123,7 +114,7 @@ int EXPORT_OUT_API ENR_init(ENR_Handle* dp_handle) return errorcode; } -int EXPORT_OUT_API ENR_close(ENR_Handle* p_handle) +int EXPORT_OUT_API ENR_close(ENR_Handle *p_handle) /*------------------------------------------------------------------------ ** Input: *p_handle = pointer to ENR_Handle struct ** @@ -143,13 +134,16 @@ int EXPORT_OUT_API ENR_close(ENR_Handle* p_handle) p_data = (data_t*)(*p_handle); - if (p_data == NULL || p_data->file == NULL) + if (p_data == NULL || p_data->file_handle == NULL) errorcode = -1; else { + close_file(p_data->file_handle); + delete_error_manager(p_data->error_handle); - fclose(p_data->file); + delete_file_manager(p_data->file_handle); + free(p_data); *p_handle = NULL; @@ -178,23 +172,22 @@ int EXPORT_OUT_API ENR_open(ENR_Handle p_handle, const char* path) if (p_data == NULL) return -1; else { - strncpy(p_data->name, path, MAXFNAME); // Attempt to open binary output file for reading only - if ((_fopen(&(p_data->file), path, "rb")) != 0) errorcode = 434; + if ((open_file(p_data->file_handle, path, "rb")) != 0) + errorcode = 434; // Perform checks to insure the file is valid else if ((err = validateFile(p_data)) != 0) errorcode = err; // If a warning is encountered read file header if (errorcode < 400 ) { - // read network size - fseek(p_data->file, 2*WORDSIZE, SEEK_SET); - fread(&(p_data->nodeCount), WORDSIZE, 1, p_data->file); - fread(&(p_data->tankCount), WORDSIZE, 1, p_data->file); - fread(&(p_data->linkCount), WORDSIZE, 1, p_data->file); - fread(&(p_data->pumpCount), WORDSIZE, 1, p_data->file); - fread(&(p_data->valveCount), WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 2*WORDSIZE, SEEK_SET); + read_file(&(p_data->nodeCount), WORDSIZE, 1, p_data->file_handle); + read_file(&(p_data->tankCount), WORDSIZE, 1, p_data->file_handle); + read_file(&(p_data->linkCount), WORDSIZE, 1, p_data->file_handle); + read_file(&(p_data->pumpCount), WORDSIZE, 1, p_data->file_handle); + read_file(&(p_data->valveCount), WORDSIZE, 1, p_data->file_handle); // Compute positions and offsets for retrieving data // fixed portion of header + title section + filenames + chem names @@ -240,8 +233,8 @@ int EXPORT_OUT_API ENR_getVersion(ENR_Handle p_handle, int* version) if (p_data == NULL) return -1; else { - fseek(p_data->file, 1*WORDSIZE, SEEK_SET); - if (fread(version, WORDSIZE, 1, p_data->file) != 1) + seek_file(p_data->file_handle, 1*WORDSIZE, SEEK_SET); + if (read_file(version, WORDSIZE, 1, p_data->file_handle) != 1) errorcode = 436; } @@ -319,26 +312,26 @@ int EXPORT_OUT_API ENR_getUnits(ENR_Handle p_handle, ENR_Units code, int* unitFl switch (code) { case ENR_flowUnits: - _fseek(p_data->file, 9*WORDSIZE, SEEK_SET); - fread(unitFlag, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 9*WORDSIZE, SEEK_SET); + read_file(unitFlag, WORDSIZE, 1, p_data->file_handle); break; case ENR_pressUnits: - _fseek(p_data->file, 10*WORDSIZE, SEEK_SET); - fread(unitFlag, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 10*WORDSIZE, SEEK_SET); + read_file(unitFlag, WORDSIZE, 1, p_data->file_handle); break; case ENR_qualUnits: offset = 7*WORDSIZE; - _fseek(p_data->file, offset, SEEK_SET); - fread(unitFlag, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(unitFlag, WORDSIZE, 1, p_data->file_handle); if (*unitFlag == 0) *unitFlag = ENR_NONE; else if (*unitFlag == 1) { offset = 15*WORDSIZE + 3*MAXMSG_P1 + 2*(MAXFNAME+1) + MAXID_P1; - _fseek(p_data->file, offset, SEEK_SET); - fread(temp, MAXID_P1, 1, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(temp, MAXID_P1, 1, p_data->file_handle); if (!strcmp(temp, "mg/L")) *unitFlag = ENR_MGL; else *unitFlag = ENR_UGL; @@ -379,18 +372,18 @@ int EXPORT_OUT_API ENR_getTimes(ENR_Handle p_handle, ENR_Time code, int* time) switch (code) { case ENR_reportStart: - fseek(p_data->file, 12*WORDSIZE, SEEK_SET); - fread(time, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 12*WORDSIZE, SEEK_SET); + read_file(time, WORDSIZE, 1, p_data->file_handle); break; case ENR_reportStep: - fseek(p_data->file, 13*WORDSIZE, SEEK_SET); - fread(time, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 13*WORDSIZE, SEEK_SET); + read_file(time, WORDSIZE, 1, p_data->file_handle); break; case ENR_simDuration: - fseek(p_data->file, 14*WORDSIZE, SEEK_SET); - fread(time, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 14*WORDSIZE, SEEK_SET); + read_file(time, WORDSIZE, 1, p_data->file_handle); break; case ENR_numPeriods: @@ -405,7 +398,6 @@ int EXPORT_OUT_API ENR_getTimes(ENR_Handle p_handle, ENR_Time code, int* time) } int EXPORT_OUT_API ENR_getChemData(ENR_Handle p_handle, char** name, int* length) - { return 0; } @@ -459,8 +451,8 @@ int EXPORT_OUT_API ENR_getElementName(ENR_Handle p_handle, ENR_ElementType type, if (!errorcode) { - _fseek(p_data->file, offset, SEEK_SET); - fread(temp, 1, MAXID_P1, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(temp, 1, MAXID_P1, p_data->file_handle); *name = temp; *length = MAXID_P1; @@ -505,9 +497,9 @@ int EXPORT_OUT_API ENR_getEnergyUsage(ENR_Handle p_handle, int pumpIndex, offset += (pumpIndex - 1)*(WORDSIZE + 6*WORDSIZE); // Power summary is 1 int and 6 floats for each pump - _fseek(p_data->file, offset, SEEK_SET); - fread(linkIndex, WORDSIZE, 1, p_data->file); - fread(temp, WORDSIZE, 6, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(linkIndex, WORDSIZE, 1, p_data->file_handle); + read_file(temp, WORDSIZE, 6, p_data->file_handle); *outValues = temp; *length = NENERGYRESULTS; @@ -541,8 +533,8 @@ int EXPORT_OUT_API ENR_getNetReacts(ENR_Handle p_handle, float** outValues, int* // Reaction summary is 4 floats located right before epilogue. // This offset is relative to the end of the file. offset = - 3*WORDSIZE - 4*WORDSIZE; - _fseek(p_data->file, offset, SEEK_END); - fread(temp, WORDSIZE, 4, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_END); + read_file(temp, WORDSIZE, 4, p_data->file_handle); *outValues = temp; *length = NREACTRESULTS; @@ -670,8 +662,8 @@ int EXPORT_OUT_API ENR_getNodeAttribute(ENR_Handle p_handle, int periodIndex, // add offset for node and attribute offset += ((attr - 1)*p_data->nodeCount)*WORDSIZE; - _fseek(p_data->file, offset, SEEK_SET); - fread(temp, WORDSIZE, p_data->nodeCount, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(temp, WORDSIZE, p_data->nodeCount, p_data->file_handle); *outValueArray = temp; *length = p_data->nodeCount; @@ -720,8 +712,8 @@ int EXPORT_OUT_API ENR_getLinkAttribute(ENR_Handle p_handle, int periodIndex, // add offset for link and attribute offset += ((attr - 1)*p_data->linkCount)*WORDSIZE; - _fseek(p_data->file, offset, SEEK_SET); - fread(temp, WORDSIZE, p_data->linkCount, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(temp, WORDSIZE, p_data->linkCount, p_data->file_handle); *outValueArray = temp; *length = p_data->linkCount; @@ -852,16 +844,16 @@ int validateFile(ENR_Handle p_handle) p_data = (data_t*)p_handle; // Read magic number from beginning of file - fseek(p_data->file, 0L, SEEK_SET); - fread(&magic1, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, 0L, SEEK_SET); + read_file(&magic1, WORDSIZE, 1, p_data->file_handle); // Fast forward to end and read file epilogue - fseek(p_data->file, -3*WORDSIZE, SEEK_END); - fread(&(p_data->nPeriods), WORDSIZE, 1, p_data->file); - fread(&hydcode, WORDSIZE, 1, p_data->file); - fread(&magic2, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, -3*WORDSIZE, SEEK_END); + read_file(&(p_data->nPeriods), WORDSIZE, 1, p_data->file_handle); + read_file(&hydcode, WORDSIZE, 1, p_data->file_handle); + read_file(&magic2, WORDSIZE, 1, p_data->file_handle); - filepos = _ftell(p_data->file); + filepos = tell_file(p_data->file_handle); // Is the file an EPANET binary file? if (magic1 != magic2) errorcode = 435; @@ -891,8 +883,8 @@ float getNodeValue(ENR_Handle p_handle, int periodIndex, int nodeIndex, // add byte position for attribute and node offset += ((attr - 1)*p_data->nodeCount + (nodeIndex - 1))*WORDSIZE; - _fseek(p_data->file, offset, SEEK_SET); - fread(&y, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(&y, WORDSIZE, 1, p_data->file_handle); return y; } @@ -915,56 +907,12 @@ float getLinkValue(ENR_Handle p_handle, int periodIndex, int linkIndex, // add byte position for attribute and link offset += ((attr - 1)*p_data->linkCount + (linkIndex - 1))*WORDSIZE; - _fseek(p_data->file, offset, SEEK_SET); - fread(&y, WORDSIZE, 1, p_data->file); + seek_file(p_data->file_handle, offset, SEEK_SET); + read_file(&y, WORDSIZE, 1, p_data->file_handle); return y; } -int _fopen(FILE **f, const char *name, const char *mode) { - // - // Purpose: Substitute for fopen_s on platforms where it doesn't exist - // Note: fopen_s is part of C++11 standard - // - int ret = 0; -#ifdef _WIN32 - ret = (int)fopen_s(f, name, mode); -#else - *f = fopen(name, mode); - if (!*f) - ret = -1; -#endif - return ret; -} - -int _fseek(FILE* stream, F_OFF offset, int whence) -// -// Purpose: Selects platform fseek() for large file support -// -{ -#ifdef _WIN32 // Windows (32-bit and 64-bit) -#define FSEEK64 _fseeki64 -#else // Other platforms -#define FSEEK64 fseeko -#endif - - return FSEEK64(stream, offset, whence); -} - -F_OFF _ftell(FILE* stream) -// -// Purpose: Selects platform ftell() for large file support -// -{ -#ifdef _WIN32 // Windows (32-bit and 64-bit) -#define FTELL64 _ftelli64 -#else // Other platforms -#define FTELL64 ftello -#endif - - return FTELL64(stream); -} - float* newFloatArray(int n) // // Warning: Caller must free memory allocated by this function. diff --git a/src/util/filemanager.c b/src/util/filemanager.c index f2fcc8f..f2bdca3 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -1,49 +1,91 @@ -#include + +// MSVC ONLY +#ifdef _DEBUG + #define _CRTDBG_MAP_ALLOC + #include + #include +#else + #include +#endif + #include #include "filemanager.h" +typedef struct file_s { + char filename[FILE_MAXNAME + 1]; + FILE *file; + char mode[FILE_MAXMODE + 1]; +} file_handle_t; + + // local (private) functions +int _fopen(FILE **f, const char *name, const char *mode); int _get_temp_filename(char *tempname); -file_handle_t *create_file_manager(const char *filename, const char *file_mode) { +file_handle_t *create_file_manager() { file_handle_t *file_handle; file_handle = (file_handle_t*)calloc(1, sizeof(file_handle_t)); + return file_handle; +} + +void delete_file_manager(file_handle_t *file_handle) { + free(file_handle); +} + + +int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode) { + int error = 0; + if (filename == NULL) _get_temp_filename(file_handle->filename); else strncpy(file_handle->filename, filename, FILE_MAXNAME); - file_handle->file = NULL; - strncpy(file_handle->mode, file_mode, FILE_MAXMODE); - - return file_handle; -} - -int delete_file_manager(file_handle_t *file_handle) { - free(file_handle); -} - - -int open_file(file_handle_t *file_handle) { - int error = 0; - - if ((file_handle->file = fopen(file_handle->filename, file_handle->mode)) == NULL) + if (file_mode == NULL) error = -1; + else { + strncpy(file_handle->mode, file_mode, FILE_MAXMODE); + error = _fopen(&(file_handle->file), file_handle->filename, file_handle->mode); + } return error; } -FILE *get_file(file_handle_t *file_handle) { - return file_handle->file; +int seek_file(file_handle_t *file_handle, F_OFF offset, int whence) +{ +#ifdef _WIN32 // Windows (32-bit and 64-bit) +#define FSEEK64 _fseeki64 +#else // Other platforms +#define FSEEK64 fseeko +#endif + + return FSEEK64(file_handle->file, offset, whence); } +F_OFF tell_file(file_handle_t *file_handle) +{ +#ifdef _WIN32 // Windows (32-bit and 64-bit) +#define FTELL64 _ftelli64 +#else // Other platforms +#define FTELL64 ftello +#endif + + return FTELL64(file_handle->file); +} + +size_t read_file(void *ptr, size_t size, size_t nmemb, file_handle_t *file_handle) +{ + return fread(ptr, size, nmemb, file_handle->file); +} + + int close_file(file_handle_t *file_handle) { int error = 0; @@ -59,14 +101,30 @@ int remove_file(file_handle_t *file_handle) { } -int _get_temp_filename(char *tempname) { - int error = 0 +int _fopen(FILE **f, const char *name, const char *mode) { +// +// Purpose: Substitute for fopen_s on platforms where it doesn't exist +// Note: fopen_s is part of C++11 standard +// + int ret = 0; #ifdef _WIN32 - char* name = NULL; + ret = (int)fopen_s(f, name, mode); +#else + *f = fopen(name, mode); + if (!*f) + ret = -1; +#endif + return ret; +} + +int _get_temp_filename(char *tempname) { + int error = 0; +#ifdef _WIN32 + char *name = NULL; // --- use Windows _tempnam function to get a pointer to an // unused file name that begins with "en" - if ((name = _tempnam(NULL, "en") == NULL) { + if ((name = _tempnam(name, "en")) == NULL) { error = -1; return error; } diff --git a/src/util/filemanager.h b/src/util/filemanager.h index c9961b8..a69c68f 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -8,6 +8,14 @@ #include + +// F_OFF Must be a 8 byte / 64 bit integer for large file support +#ifdef _WIN32 // Windows (32-bit and 64-bit) +#define F_OFF __int64 +#else // Other platforms +#define F_OFF off_t +#endif + #define FILE_MAXNAME 259 #define FILE_MAXMODE 3 @@ -17,21 +25,22 @@ extern "C" { #endif -typedef struct file_s { - char filename[FILE_MAXNAME + 1], - FILE *file; - char mode[FILE_MAXMODE + 1]; -} file_handle_t; +typedef struct file_s file_handle_t; -file_handle_t *create_file_manager(const char *filename, const char *file_mode); +file_handle_t *create_file_manager(); -int delete_file_manager(file_handle_t *file_handle); +void delete_file_manager(file_handle_t *file_handle); -int open_file(file_handle_t *file_handle); +int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode); + +int seek_file(file_handle_t *file_handle, F_OFF offset, int whence); + +F_OFF tell_file(file_handle_t *file_handle); + +size_t read_file(void *ptr, size_t size, size_t nmemb, file_handle_t *file_handle); -FILE *get_file(file_handle_t *file_handle); int close_file(file_handle_t *file_handle); diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index 6173a07..a349b4a 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -15,3 +15,9 @@ set (test_source add_executable(test_errormanager ${test_source}) target_include_directories(test_errormanager PUBLIC ../../src/) target_link_libraries(test_errormanager ${Boost_LIBRARIES}) + + + +add_executable(test_filemanager ./test_filemanager.cpp ../../src/util/filemanager.c) +target_include_directories(test_filemanager PUBLIC ../../src/) +target_link_libraries(test_filemanager ${Boost_LIBRARIES}) diff --git a/tests/util/test_errormanager.cpp b/tests/util/test_errormanager.cpp index 0003ee2..f9a88b6 100644 --- a/tests/util/test_errormanager.cpp +++ b/tests/util/test_errormanager.cpp @@ -1,7 +1,7 @@ #define BOOST_TEST_MODULE errormanager -//#define BOOST_TEST_DYN_LINK + #include #include "util/errormanager.h" diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index b9d830e..b81d9d3 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -5,3 +5,62 @@ #include #include "util/filemanager.h" + + +#define DATA_PATH_OUTPUT "./example1.out" + + +BOOST_AUTO_TEST_SUITE(test_filemanager) + +BOOST_AUTO_TEST_CASE (test_create_destroy) +{ + file_handle_t *file_handle = NULL; + + file_handle = create_file_manager(); + BOOST_CHECK(file_handle != NULL); + + delete_file_manager(file_handle); +} + +BOOST_AUTO_TEST_CASE(test_open_close) +{ + int error = 0; + file_handle_t *file_handle = NULL; + + file_handle = create_file_manager(); + BOOST_CHECK(file_handle != NULL); + + error = open_file(file_handle, DATA_PATH_OUTPUT, "rb"); + BOOST_REQUIRE(error == 0); + + error = close_file(file_handle); + BOOST_REQUIRE(error == 0); + + delete_file_manager(file_handle); +} + +struct Fixture{ + Fixture() { + error = 0; + file_handle = NULL; + + file_handle = create_file_manager(); + open_file(file_handle, DATA_PATH_OUTPUT, "rb"); + } + ~Fixture() { + close_file(file_handle); + delete_file_manager(file_handle); + } + int error; + file_handle_t *file_handle; +}; + +BOOST_FIXTURE_TEST_CASE(test_get_file, Fixture) +{ + FILE *file; + + //file = get_file(file_handle); + //BOOST_CHECK(file != NULL); +} + +BOOST_AUTO_TEST_SUITE_END() From b9f00421ddeaf507e505698dea950932ac968dc5 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 1 Apr 2019 15:16:58 -0400 Subject: [PATCH 10/26] Adding header info --- src/util/filemanager.c | 17 +++++++++++++---- src/util/filemanager.h | 18 +++++++++++++----- tests/util/test_filemanager.cpp | 21 +++++++++++++-------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/util/filemanager.c b/src/util/filemanager.c index f2bdca3..ddeee4b 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -1,4 +1,15 @@ - +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/filemanager.c + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/01/2019 + ****************************************************************************** +*/ // MSVC ONLY @@ -18,7 +29,6 @@ typedef struct file_s { char filename[FILE_MAXNAME + 1]; FILE *file; - char mode[FILE_MAXMODE + 1]; } file_handle_t; @@ -51,8 +61,7 @@ int open_file(file_handle_t *file_handle, const char *filename, const char *file if (file_mode == NULL) error = -1; else { - strncpy(file_handle->mode, file_mode, FILE_MAXMODE); - error = _fopen(&(file_handle->file), file_handle->filename, file_handle->mode); + error = _fopen(&(file_handle->file), file_handle->filename, file_mode); } return error; diff --git a/src/util/filemanager.h b/src/util/filemanager.h index a69c68f..63cabd6 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -1,6 +1,15 @@ - - - +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/filemanager.h + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/01/2019 + ****************************************************************************** +*/ #ifndef FILEMANAGER_H_ #define FILEMANAGER_H_ @@ -17,14 +26,13 @@ #endif #define FILE_MAXNAME 259 -#define FILE_MAXMODE 3 #if defined(__cplusplus) extern "C" { #endif - +// Forward declariation of file_handle_t typedef struct file_s file_handle_t; diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index b81d9d3..b73d139 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -1,4 +1,15 @@ - +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/test_filemanager.cpp + Description: Tests filemanager + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/01/2019 + ****************************************************************************** +*/ #define BOOST_TEST_MODULE filemanager @@ -12,6 +23,7 @@ BOOST_AUTO_TEST_SUITE(test_filemanager) + BOOST_AUTO_TEST_CASE (test_create_destroy) { file_handle_t *file_handle = NULL; @@ -55,12 +67,5 @@ struct Fixture{ file_handle_t *file_handle; }; -BOOST_FIXTURE_TEST_CASE(test_get_file, Fixture) -{ - FILE *file; - - //file = get_file(file_handle); - //BOOST_CHECK(file != NULL); -} BOOST_AUTO_TEST_SUITE_END() From 36a12cd4b689ccd9e7da54c775b20967d01b0bc8 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 1 Apr 2019 15:23:13 -0400 Subject: [PATCH 11/26] Adding test_filemanager to ctest --- tests/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ffb73b4..fd9a8d8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,6 +60,10 @@ add_test(NAME test_reent add_test(NAME test_errormanager COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_errormanager) +add_test(NAME test_filemanager + COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_filemanager + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/outfile/data) + add_test(NAME test_output COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_output WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/outfile/data) From a0b08921fc3856acf9b376f85f5f69727eccf41d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 1 Apr 2019 15:24:52 -0400 Subject: [PATCH 12/26] Tweaking header doc --- tests/util/test_filemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index b73d139..0b35293 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -3,7 +3,7 @@ Project: OWA EPANET Version: 2.2 Module: util/test_filemanager.cpp - Description: Tests filemanager + Description: Tests for util/filemanager.c Authors: see AUTHORS Copyright: see AUTHORS License: see LICENSE From 2c6d4ca74d72540d3a6f0c88d4bef2b08c24da5e Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 1 Apr 2019 18:05:02 -0400 Subject: [PATCH 13/26] Work in progress Added test for temp files, getter for filename, and wrappers for fwrite, fprintf, and fgets --- src/util/filemanager.c | 36 +++++++++++++++++++++++++++++++++ src/util/filemanager.h | 14 +++++++++++++ tests/util/CMakeLists.txt | 8 +------- tests/util/test_filemanager.cpp | 25 ++++++++++++++++++++++- 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/src/util/filemanager.c b/src/util/filemanager.c index ddeee4b..a5f5c43 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -21,6 +21,7 @@ #include #endif +#include #include #include "filemanager.h" @@ -50,6 +51,15 @@ void delete_file_manager(file_handle_t *file_handle) { } +void get_filename(file_handle_t *file_handle, char **filename) +{ + char *temp = (char*) malloc((FILE_MAXNAME)*sizeof(char)); + + strncpy(temp, file_handle->filename, FILE_MAXNAME); + *filename = temp; +} + + int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode) { int error = 0; @@ -89,11 +99,37 @@ F_OFF tell_file(file_handle_t *file_handle) return FTELL64(file_handle->file); } +// Read and write to a binary file size_t read_file(void *ptr, size_t size, size_t nmemb, file_handle_t *file_handle) { return fread(ptr, size, nmemb, file_handle->file); } +size_t write_file(const void * ptr, size_t size, size_t count, file_handle_t *file_handle) +{ + return fwrite(ptr, size, count, file_handle->file); +} + + +// print and get from a text file +int printf_file(file_handle_t *file_handle, const char *format, ... ) +{ + int error = 0; + va_list args; + + va_start(args, format); + error = vfprintf(file_handle->file, format, args); + va_end(args); + + return error; +} + +int gets_file(char *str, int num, file_handle_t *file_handle) +{ + fgets(str, num, file_handle->file); + return 0; +} + int close_file(file_handle_t *file_handle) { int error = 0; diff --git a/src/util/filemanager.h b/src/util/filemanager.h index 63cabd6..1e313b8 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -16,6 +16,7 @@ #include +#include // F_OFF Must be a 8 byte / 64 bit integer for large file support @@ -41,14 +42,27 @@ file_handle_t *create_file_manager(); void delete_file_manager(file_handle_t *file_handle); +void get_filename(file_handle_t *file_handle, char **filename); + + int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode); int seek_file(file_handle_t *file_handle, F_OFF offset, int whence); F_OFF tell_file(file_handle_t *file_handle); + +// Functions for working with binary files size_t read_file(void *ptr, size_t size, size_t nmemb, file_handle_t *file_handle); +size_t write_file(const void *ptr, size_t size, size_t count, file_handle_t *file_handle); + + +// Functions for working with text files +int printf_file(file_handle_t *file_handle, const char *format, ... ); + +int gets_file(char *str, int num, file_handle_t *file_handle); + int close_file(file_handle_t *file_handle); diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index a349b4a..e126ceb 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -7,17 +7,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -set (test_source -./test_errormanager.cpp -../../src/util/errormanager.c -) - -add_executable(test_errormanager ${test_source}) +add_executable(test_errormanager ./test_errormanager.cpp ../../src/util/errormanager.c) target_include_directories(test_errormanager PUBLIC ../../src/) target_link_libraries(test_errormanager ${Boost_LIBRARIES}) - add_executable(test_filemanager ./test_filemanager.cpp ../../src/util/filemanager.c) target_include_directories(test_filemanager PUBLIC ../../src/) target_link_libraries(test_filemanager ${Boost_LIBRARIES}) diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index 0b35293..79fcec7 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -14,6 +14,7 @@ #define BOOST_TEST_MODULE filemanager #include +#include #include "util/filemanager.h" @@ -21,6 +22,15 @@ #define DATA_PATH_OUTPUT "./example1.out" +boost::test_tools::predicate_result check_string(std::string test, std::string ref) +{ + if (ref.compare(test) == 0) + return true; + else + return false; +} + + BOOST_AUTO_TEST_SUITE(test_filemanager) @@ -57,7 +67,7 @@ struct Fixture{ file_handle = NULL; file_handle = create_file_manager(); - open_file(file_handle, DATA_PATH_OUTPUT, "rb"); + open_file(file_handle, NULL, "wt"); } ~Fixture() { close_file(file_handle); @@ -67,5 +77,18 @@ struct Fixture{ file_handle_t *file_handle; }; +BOOST_FIXTURE_TEST_CASE(test_temp_file, Fixture) +{ + char *filename; + + printf_file(file_handle, "%s", "This is a test."); + + get_filename(file_handle, &filename); + //BOOST_CHECK(check_string(filename, "./test_file.txt")); + + BOOST_CHECK(boost::filesystem::exists(filename) == true); + + free(filename); +} BOOST_AUTO_TEST_SUITE_END() From c98d13de803ffeec5280dd7ba3305720b586e659 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 11:05:56 -0400 Subject: [PATCH 14/26] Updated filemanager to use dynamically allocated strings converted filename to dynamically allocated string created cstr_helper --- src/outfile/CMakeLists.txt | 3 +- src/util/cstr_helper.c | 22 +++++++++++++++ src/util/cstr_helper.h | 9 ++++++ src/util/filemanager.c | 49 ++++++++++++++++++++------------- src/util/filemanager.h | 4 ++- tests/util/CMakeLists.txt | 7 +++-- tests/util/test_filemanager.cpp | 3 +- 7 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 src/util/cstr_helper.c create mode 100644 src/util/cstr_helper.h diff --git a/src/outfile/CMakeLists.txt b/src/outfile/CMakeLists.txt index 79a8ae1..c129221 100644 --- a/src/outfile/CMakeLists.txt +++ b/src/outfile/CMakeLists.txt @@ -22,7 +22,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # configure file groups set(EPANET_OUT_SOURCES src/epanet_output.c ../util/errormanager.c - ../util/filemanager.c) + ../util/filemanager.c + ../util/cstr_helper.c) # the binary output file API diff --git a/src/util/cstr_helper.c b/src/util/cstr_helper.c new file mode 100644 index 0000000..9266551 --- /dev/null +++ b/src/util/cstr_helper.c @@ -0,0 +1,22 @@ + +#include +#include + + +int copy_cstr(const char *source, char **destination, size_t *size) +// Determines length, allocates memory, and returns a null terminated copy +// Be Aware: caller is responsible for freeing memory +{ + size_t len; + + len = strlen(source); + *destination = (char *) calloc(len + 1, sizeof(char)); + + if (*destination == NULL) + return -1; + else { + strncpy(*destination, source, len); + *size = len + 1; + } + return 0; +} diff --git a/src/util/cstr_helper.h b/src/util/cstr_helper.h new file mode 100644 index 0000000..1b435c1 --- /dev/null +++ b/src/util/cstr_helper.h @@ -0,0 +1,9 @@ + +#ifndef CSTR_HELPER_H_ +#define CSTR_HELPER_H_ + + +int copy_cstr(const char *source, char **destination, size_t *size); + + +#endif /* CSTR_HELPER_H_ */ diff --git a/src/util/filemanager.c b/src/util/filemanager.c index a5f5c43..98d775c 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -22,41 +22,50 @@ #endif #include -#include #include "filemanager.h" typedef struct file_s { - char filename[FILE_MAXNAME + 1]; + char *filename; + size_t size; FILE *file; } file_handle_t; // local (private) functions int _fopen(FILE **f, const char *name, const char *mode); -int _get_temp_filename(char *tempname); +int _get_temp_filename(char **tempname, size_t *size); file_handle_t *create_file_manager() { file_handle_t *file_handle; - file_handle = (file_handle_t*)calloc(1, sizeof(file_handle_t)); + file_handle = (file_handle_t *)calloc(1, sizeof(file_handle_t)); + + file_handle->filename = NULL; + file_handle->size = 0; + file_handle->file = NULL; return file_handle; } void delete_file_manager(file_handle_t *file_handle) { - free(file_handle); + + if (file_handle->file != NULL) + close_file(file_handle); + + free(file_handle->filename); + free(file_handle); } -void get_filename(file_handle_t *file_handle, char **filename) +void get_filename(file_handle_t *file_handle, char **filename, size_t *size) +// +// BE AWARE: The memory allocated here must be freed by the caller +// { - char *temp = (char*) malloc((FILE_MAXNAME)*sizeof(char)); - - strncpy(temp, file_handle->filename, FILE_MAXNAME); - *filename = temp; + copy_cstr(file_handle->filename, filename, size); } @@ -64,9 +73,9 @@ int open_file(file_handle_t *file_handle, const char *filename, const char *file int error = 0; if (filename == NULL) - _get_temp_filename(file_handle->filename); + _get_temp_filename(&(file_handle->filename), &(file_handle->size)); else - strncpy(file_handle->filename, filename, FILE_MAXNAME); + copy_cstr(filename, &(file_handle->filename), &(file_handle->size)); if (file_mode == NULL) error = -1; @@ -146,12 +155,14 @@ int remove_file(file_handle_t *file_handle) { } -int _fopen(FILE **f, const char *name, const char *mode) { +int _fopen(FILE **f, const char *name, const char *mode) // // Purpose: Substitute for fopen_s on platforms where it doesn't exist // Note: fopen_s is part of C++11 standard // +{ int ret = 0; + #ifdef _WIN32 ret = (int)fopen_s(f, name, mode); #else @@ -162,8 +173,10 @@ int _fopen(FILE **f, const char *name, const char *mode) { return ret; } -int _get_temp_filename(char *tempname) { +int _get_temp_filename(char **tempname, size_t *size) +{ int error = 0; + #ifdef _WIN32 char *name = NULL; @@ -173,10 +186,8 @@ int _get_temp_filename(char *tempname) { error = -1; return error; } - else if (strlen(name) < FILE_MAXNAME) - strncpy(tempname, name, FILE_MAXNAME); else - tempname = NULL; + copy_cstr(name, tempname, size); // --- free the pointer returned by _tempnam if (name) @@ -185,8 +196,8 @@ int _get_temp_filename(char *tempname) { // --- for non-Windows systems: #else // --- use system function mkstemp() to create a temporary file name - strncpy(tempname, "enXXXXXX", 8); - error = mkstemp(tempname); + copy_cstr("enXXXXXX", tempname, size) + error = mkstemp(*tempname); #endif return error; } diff --git a/src/util/filemanager.h b/src/util/filemanager.h index 1e313b8..f0b00d2 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -18,6 +18,8 @@ #include #include +#include "cstr_helper.h" + // F_OFF Must be a 8 byte / 64 bit integer for large file support #ifdef _WIN32 // Windows (32-bit and 64-bit) @@ -42,7 +44,7 @@ file_handle_t *create_file_manager(); void delete_file_manager(file_handle_t *file_handle); -void get_filename(file_handle_t *file_handle, char **filename); +void get_filename(file_handle_t *file_handle, char **filename, size_t *size); int open_file(file_handle_t *file_handle, const char *filename, const char *file_mode); diff --git a/tests/util/CMakeLists.txt b/tests/util/CMakeLists.txt index e126ceb..0bd4a43 100644 --- a/tests/util/CMakeLists.txt +++ b/tests/util/CMakeLists.txt @@ -7,11 +7,14 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) -add_executable(test_errormanager ./test_errormanager.cpp ../../src/util/errormanager.c) +add_executable(test_errormanager ./test_errormanager.cpp + ../../src/util/errormanager.c) target_include_directories(test_errormanager PUBLIC ../../src/) target_link_libraries(test_errormanager ${Boost_LIBRARIES}) -add_executable(test_filemanager ./test_filemanager.cpp ../../src/util/filemanager.c) +add_executable(test_filemanager ./test_filemanager.cpp + ../../src/util/filemanager.c + ../../src/util/cstr_helper.c) target_include_directories(test_filemanager PUBLIC ../../src/) target_link_libraries(test_filemanager ${Boost_LIBRARIES}) diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index 79fcec7..310c620 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -80,10 +80,11 @@ struct Fixture{ BOOST_FIXTURE_TEST_CASE(test_temp_file, Fixture) { char *filename; + size_t size; printf_file(file_handle, "%s", "This is a test."); - get_filename(file_handle, &filename); + get_filename(file_handle, &filename, &size); //BOOST_CHECK(check_string(filename, "./test_file.txt")); BOOST_CHECK(boost::filesystem::exists(filename) == true); From a89f3c90053f2c2c40c99d39d8de38c8e9e6626d Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 12:31:05 -0400 Subject: [PATCH 15/26] Making sure filename is null terminated string Added file_handle validation --- src/util/cstr_helper.c | 22 +++++++++++++++++----- src/util/cstr_helper.h | 6 +++++- src/util/filemanager.c | 27 +++++++++++++++++---------- src/util/filemanager.h | 3 +++ tests/util/test_filemanager.cpp | 4 +++- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/util/cstr_helper.c b/src/util/cstr_helper.c index 9266551..2e33d50 100644 --- a/src/util/cstr_helper.c +++ b/src/util/cstr_helper.c @@ -2,21 +2,33 @@ #include #include +#include "cstr_helper.h" -int copy_cstr(const char *source, char **destination, size_t *size) + +int copy_cstr(const char *source, char **dest) // Determines length, allocates memory, and returns a null terminated copy // Be Aware: caller is responsible for freeing memory { size_t len; len = strlen(source); - *destination = (char *) calloc(len + 1, sizeof(char)); + *dest = (char *) calloc((len + 1), sizeof(char)); - if (*destination == NULL) + if (*dest == NULL) return -1; else { - strncpy(*destination, source, len); - *size = len + 1; + strncpy(*dest, source, (len + 1)); + strncat(*dest, "\0", 1); } return 0; } + + +bool isnullterm_cstr(const char *source) +{ + if (strchr(source, '\0')) + return true; + else + return false; + +} diff --git a/src/util/cstr_helper.h b/src/util/cstr_helper.h index 1b435c1..55f71d0 100644 --- a/src/util/cstr_helper.h +++ b/src/util/cstr_helper.h @@ -3,7 +3,11 @@ #define CSTR_HELPER_H_ -int copy_cstr(const char *source, char **destination, size_t *size); +#include + + +int copy_cstr(const char *source, char **destination); +bool isnullterm_cstr(const char *source); #endif /* CSTR_HELPER_H_ */ diff --git a/src/util/filemanager.c b/src/util/filemanager.c index 98d775c..49ca4a3 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -27,15 +27,14 @@ typedef struct file_s { - char *filename; - size_t size; + char *filename; // Assumes this is a null terminated string FILE *file; } file_handle_t; // local (private) functions int _fopen(FILE **f, const char *name, const char *mode); -int _get_temp_filename(char **tempname, size_t *size); +int _get_temp_filename(char **tempname); file_handle_t *create_file_manager() { @@ -44,14 +43,13 @@ file_handle_t *create_file_manager() { file_handle = (file_handle_t *)calloc(1, sizeof(file_handle_t)); file_handle->filename = NULL; - file_handle->size = 0; file_handle->file = NULL; return file_handle; } void delete_file_manager(file_handle_t *file_handle) { - + if (file_handle->file != NULL) close_file(file_handle); @@ -65,7 +63,7 @@ void get_filename(file_handle_t *file_handle, char **filename, size_t *size) // BE AWARE: The memory allocated here must be freed by the caller // { - copy_cstr(file_handle->filename, filename, size); + copy_cstr(file_handle->filename, filename); } @@ -73,9 +71,9 @@ int open_file(file_handle_t *file_handle, const char *filename, const char *file int error = 0; if (filename == NULL) - _get_temp_filename(&(file_handle->filename), &(file_handle->size)); + _get_temp_filename(&(file_handle->filename)); else - copy_cstr(filename, &(file_handle->filename), &(file_handle->size)); + copy_cstr(filename, &(file_handle->filename)); if (file_mode == NULL) error = -1; @@ -173,7 +171,7 @@ int _fopen(FILE **f, const char *name, const char *mode) return ret; } -int _get_temp_filename(char **tempname, size_t *size) +int _get_temp_filename(char **tempname) { int error = 0; @@ -187,7 +185,7 @@ int _get_temp_filename(char **tempname, size_t *size) return error; } else - copy_cstr(name, tempname, size); + copy_cstr(name, tempname); // --- free the pointer returned by _tempnam if (name) @@ -201,3 +199,12 @@ int _get_temp_filename(char **tempname, size_t *size) #endif return error; } + +bool is_valid(file_handle_t *file_handle) +{ + if ((file_handle->filename == NULL && file_handle->file == NULL) || + (isnullterm_cstr(file_handle->filename) && file_handle != NULL)) + return true; + else + return false; +} diff --git a/src/util/filemanager.h b/src/util/filemanager.h index f0b00d2..93ee8d9 100644 --- a/src/util/filemanager.h +++ b/src/util/filemanager.h @@ -71,6 +71,9 @@ int close_file(file_handle_t *file_handle); int remove_file(file_handle_t *file_handle); +bool is_valid(file_handle_t *file_handle); + + #if defined(__cplusplus) } #endif diff --git a/tests/util/test_filemanager.cpp b/tests/util/test_filemanager.cpp index 310c620..70ff6c6 100644 --- a/tests/util/test_filemanager.cpp +++ b/tests/util/test_filemanager.cpp @@ -40,6 +40,7 @@ BOOST_AUTO_TEST_CASE (test_create_destroy) file_handle = create_file_manager(); BOOST_CHECK(file_handle != NULL); + BOOST_CHECK(is_valid(file_handle) == true); delete_file_manager(file_handle); } @@ -54,6 +55,7 @@ BOOST_AUTO_TEST_CASE(test_open_close) error = open_file(file_handle, DATA_PATH_OUTPUT, "rb"); BOOST_REQUIRE(error == 0); + BOOST_CHECK(is_valid(file_handle) == true); error = close_file(file_handle); BOOST_REQUIRE(error == 0); @@ -85,7 +87,7 @@ BOOST_FIXTURE_TEST_CASE(test_temp_file, Fixture) printf_file(file_handle, "%s", "This is a test."); get_filename(file_handle, &filename, &size); - //BOOST_CHECK(check_string(filename, "./test_file.txt")); + BOOST_CHECK(is_valid(file_handle) == true); BOOST_CHECK(boost::filesystem::exists(filename) == true); From 3828ebb1cd4af7600dc0462b875d66ada24641d3 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 13:48:38 -0400 Subject: [PATCH 16/26] updating cstr_helper to use secure string functions --- src/util/cstr_helper.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/util/cstr_helper.c b/src/util/cstr_helper.c index 2e33d50..13ca1c4 100644 --- a/src/util/cstr_helper.c +++ b/src/util/cstr_helper.c @@ -9,16 +9,19 @@ int copy_cstr(const char *source, char **dest) // Determines length, allocates memory, and returns a null terminated copy // Be Aware: caller is responsible for freeing memory { - size_t len; + size_t size; - len = strlen(source); - *dest = (char *) calloc((len + 1), sizeof(char)); + size = 1 + strlen(source); + *dest = (char *) calloc(size, sizeof(char)); if (*dest == NULL) return -1; else { - strncpy(*dest, source, (len + 1)); - strncat(*dest, "\0", 1); +#ifdef _MSC_VER + strncpy_s(*dest, size, source, size); +#else + strncpy(*dest, source, size); +#endif } return 0; } @@ -30,5 +33,4 @@ bool isnullterm_cstr(const char *source) return true; else return false; - } From 44fc73cf41c3f10af99e001f3daab68ef67f3360 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 14:37:32 -0400 Subject: [PATCH 17/26] Fixing bug --- src/util/filemanager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/filemanager.c b/src/util/filemanager.c index 49ca4a3..9603ce4 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -194,7 +194,7 @@ int _get_temp_filename(char **tempname) // --- for non-Windows systems: #else // --- use system function mkstemp() to create a temporary file name - copy_cstr("enXXXXXX", tempname, size) + copy_cstr("enXXXXXX", tempname); error = mkstemp(*tempname); #endif return error; From ecf0e5173c159f414481af8506d430a56e3f6628 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 15:27:05 -0400 Subject: [PATCH 18/26] revert 1a01b46 to 1b167b5 --- run/main.c | 1 - src/epanet.c | 43 +++++++++++++--------------- src/epanet2.c | 10 ++----- src/epanet_py.c | 1 - src/hash.c | 5 +++- src/hydcoeffs.c | 6 +++- src/hydraul.c | 6 +++- src/hydsolver.c | 6 +++- src/hydstatus.c | 1 - src/inpfile.c | 4 +++ src/input1.c | 28 ++++++++---------- src/input2.c | 63 ++++++++++++++++++++--------------------- src/input3.c | 11 +++---- src/mempool.c | 4 ++- src/output.c | 6 +++- src/project.c | 12 +++----- src/quality.c | 6 +++- src/qualreact.c | 1 - src/qualroute.c | 7 +++-- src/report.c | 7 +++-- src/rules.c | 6 +++- src/smatrix.c | 7 ++++- src/types.h | 4 +-- src/util/errormanager.c | 6 ++++ tests/CMakeLists.txt | 23 +++++++-------- tests/test_analysis.cpp | 1 + tests/test_project.cpp | 40 +++++++++----------------- tests/test_toolkit.hpp | 6 ---- 28 files changed, 163 insertions(+), 158 deletions(-) diff --git a/run/main.c b/run/main.c index ea0a91c..793fffa 100644 --- a/run/main.c +++ b/run/main.c @@ -12,7 +12,6 @@ */ #include - #include "epanet2.h" void writeConsole(char *s) diff --git a/src/epanet.c b/src/epanet.c index a6df228..29462bc 100644 --- a/src/epanet.c +++ b/src/epanet.c @@ -11,17 +11,12 @@ ****************************************************************************** */ -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include -#else - #include -#endif - #include +#include #include - +#ifndef __APPLE__ +#include +#endif #include #include @@ -221,24 +216,26 @@ int DLLEXPORT EN_open(EN_Project p, const char *inpFile, const char *rptFile, ERRCODE(netsize(p)); ERRCODE(allocdata(p)); - if (!errcode) { - // Read input data - ERRCODE(getdata(p)); + // Read input data + ERRCODE(getdata(p)); - // Close input file - if (p->parser.InFile != NULL) { + // Close input file + if (p->parser.InFile != NULL) + { fclose(p->parser.InFile); p->parser.InFile = NULL; - } + } - // Free temporary linked lists used for Patterns & Curves - freeTmplist(p->parser.Patlist); - freeTmplist(p->parser.Curvelist); + // Free temporary linked lists used for Patterns & Curves + freeTmplist(p->parser.Patlist); + freeTmplist(p->parser.Curvelist); - // If using previously saved hydraulics file then open it - if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p)); + // If using previously saved hydraulics file then open it + if (p->outfile.Hydflag == USE) ERRCODE(openhydfile(p)); - // Write input summary to report file + // Write input summary to report file + if (!errcode) + { if (p->report.Summaryflag) writesummary(p); writetime(p, FMT104); p->Openflag = TRUE; @@ -282,7 +279,7 @@ 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 +** Output: comment = the object's descriptive comment ** Returns: error code ** Purpose: Retrieves an object's descriptive comment **---------------------------------------------------------------- @@ -843,7 +840,7 @@ int DLLEXPORT EN_closeQ(EN_Project p) if (!p->Openflag) return 102; closequal(p); p->quality.OpenQflag = FALSE; - closeoutfile(p); + closeoutfile(p); return 0; } diff --git a/src/epanet2.c b/src/epanet2.c index 3d11608..935d6c4 100644 --- a/src/epanet2.c +++ b/src/epanet2.c @@ -10,15 +10,11 @@ Last Updated: 03/17/2019 ****************************************************************************** */ - -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include +#ifndef __APPLE__ +#include #else - #include +#include #endif - #include #include "types.h" diff --git a/src/epanet_py.c b/src/epanet_py.c index e84fdc9..4c16cbf 100644 --- a/src/epanet_py.c +++ b/src/epanet_py.c @@ -26,7 +26,6 @@ typedef struct { Project *project; error_handle_t *error; }handle_t; - // Extern functions extern char *geterrmsg(int, char *); // Local functions diff --git a/src/hash.c b/src/hash.c index c3f91e2..95ac8dd 100755 --- a/src/hash.c +++ b/src/hash.c @@ -11,9 +11,12 @@ ****************************************************************************** */ +#ifndef __APPLE__ +#include +#else #include +#endif #include - #include "hash.h" #define HASHTABLEMAXSIZE 128000 diff --git a/src/hydcoeffs.c b/src/hydcoeffs.c index 4b3583d..b6c002c 100644 --- a/src/hydcoeffs.c +++ b/src/hydcoeffs.c @@ -11,9 +11,13 @@ ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include "types.h" diff --git a/src/hydraul.c b/src/hydraul.c index c442ac6..703f7b7 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -11,9 +11,13 @@ ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include "types.h" diff --git a/src/hydsolver.c b/src/hydsolver.c index 90c93e1..3c0694a 100644 --- a/src/hydsolver.c +++ b/src/hydsolver.c @@ -12,9 +12,13 @@ ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include "types.h" diff --git a/src/hydstatus.c b/src/hydstatus.c index 5905337..f7edb6b 100644 --- a/src/hydstatus.c +++ b/src/hydstatus.c @@ -12,7 +12,6 @@ Last Updated: 11/27/2018 */ #include - #include "types.h" #include "funcs.h" diff --git a/src/inpfile.c b/src/inpfile.c index 994830a..45b5aab 100644 --- a/src/inpfile.c +++ b/src/inpfile.c @@ -13,7 +13,11 @@ Last Updated: 03/17/2019 #include #include +#ifndef __APPLE__ +#include +#else #include +#endif #include #include "types.h" diff --git a/src/input1.c b/src/input1.c index 4cafa13..fe606d9 100644 --- a/src/input1.c +++ b/src/input1.c @@ -3,30 +3,26 @@ Project: OWA EPANET Version: 2.2 Module: input1.c -Description: retrieves network data from an EPANET input file +Description: retrieves network data from an EPANET input file Authors: see AUTHORS Copyright: see AUTHORS License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include -#else - #include -#endif #include +#include #include -#include +#ifndef __APPLE__ +#include +#endif #include "types.h" #include "funcs.h" #include "hash.h" #include "text.h" - +#include // Default values #define MAXITER 200 // Default max. # hydraulic iterations @@ -60,7 +56,7 @@ int getdata(Project *pr) int errcode = 0; // Assign default data values & reporting options - setdefaults(pr); + setdefaults(pr); initreport(&pr->report); // Read in network data @@ -106,7 +102,7 @@ void setdefaults(Project *pr) parser->Pressflag = PSI; // Pressure units are psi out->Hydflag = SCRATCH; // No external hydraulics file rpt->Tstatflag = SERIES; // Generate time series output - + hyd->Formflag = HW; // Use Hazen-Williams formula hyd->Htol = HTOL; // Default head tolerance hyd->Qtol = QTOL; // Default flow tolerance @@ -357,7 +353,7 @@ int inittanks(Project *pr) */ { Network *net = &pr->network; - + int i, j, n = 0; double a; int errcode = 0, levelerr; @@ -550,7 +546,7 @@ void convertunits(Project *pr) Slink *link; Spump *pump; Scontrol *control; - + // Convert nodal elevations & initial WQ // (WQ source units are converted in QUALITY.C for (i = 1; i <= net->Nnodes; i++) @@ -648,7 +644,7 @@ void convertunits(Project *pr) pump->H0 /= pr->Ucf[HEAD]; pump->R *= (pow(pr->Ucf[FLOW], pump->N) / pr->Ucf[HEAD]); } - + // Convert flow range & max. head units pump->Q0 /= pr->Ucf[FLOW]; pump->Qmax /= pr->Ucf[FLOW]; @@ -657,7 +653,7 @@ void convertunits(Project *pr) } else { - // For flow control valves, convert flow setting + // For flow control valves, convert flow setting // while for other valves convert pressure setting link->Diam /= pr->Ucf[DIAM]; link->Km = 0.02517 * link->Km / SQR(link->Diam) / SQR(link->Diam); diff --git a/src/input2.c b/src/input2.c index e4d2d85..2820e35 100644 --- a/src/input2.c +++ b/src/input2.c @@ -10,16 +10,13 @@ License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include -#else - #include -#endif #include +#include #include +#ifndef __APPLE__ +#include +#endif #include #include "types.h" @@ -59,7 +56,7 @@ int netsize(Project *pr) */ { Parser *parser = &pr->parser; - + char line[MAXLINE + 1]; // Line from input data file char *tok; // First token of line int sect, newsect; // Input data sections @@ -150,7 +147,7 @@ int readdata(Project *pr) inperr, errsum; // Error code & total error count // Allocate input buffer - parser->X = (double *)calloc(MAXTOKS + 1, sizeof(double)); + parser->X = (double *)calloc(MAXTOKS, sizeof(double)); ERRCODE(MEMCHECK(parser->X)); if (errcode) return errcode; @@ -178,7 +175,7 @@ int readdata(Project *pr) while (fgets(line, MAXLINE, parser->InFile) != NULL) { // Make copy of line and scan for tokens - strncpy(wline, line, MAXLINE); + strcpy(wline, line); parser->Ntokens = gettokens(wline, parser->Tok, MAXTOKS, parser->Comment); // Skip blank lines and those filled with a comment @@ -249,10 +246,10 @@ int readdata(Project *pr) // Stop if reach end of file or max. error count if (errsum == MAXERRS) break; } - + // Check for errors if (errsum > 0) errcode = 200; - + // Check for unlinked nodes if (!errcode) errcode = unlinked(pr); @@ -400,7 +397,7 @@ int updatepumpparams(Project *pr, int pumpindex) curve->Type = PUMP_CURVE; npts = curve->Npts; - // Generic power function curve + // Generic power function curve if (npts == 1) { pump->Ptype = POWER_FUNC; @@ -410,7 +407,7 @@ int updatepumpparams(Project *pr, int pumpindex) q2 = 2.0 * q1; h2 = 0.0; } - + // 3 point curve with shutoff head else if (npts == 3 && curve->X[0] == 0.0) { @@ -421,7 +418,7 @@ int updatepumpparams(Project *pr, int pumpindex) q2 = curve->X[2]; h2 = curve->Y[2]; } - + // Custom pump curve else { @@ -434,7 +431,7 @@ int updatepumpparams(Project *pr, int pumpindex) pump->Q0 = (curve->X[0] + pump->Qmax) / 2.0; pump->Hmax = curve->Y[0]; } - + // Compute shape factors & limits of power function curves if (pump->Ptype == POWER_FUNC) { @@ -464,7 +461,7 @@ int addnodeID(Network *net, int n, char *id) **-------------------------------------------------------------- */ { - if (findnode(net,id)) return 0; + if (findnode(net,id)) return 0; strncpy(net->Node[n].ID, id, MAXID); hashtable_insert(net->NodeHashTable, net->Node[n].ID, n); return 1; @@ -590,7 +587,7 @@ int unlinked(Project *pr) Network *net = &pr->network; int *marked; int i, err, errcode; - + errcode = 0; err = 0; @@ -599,19 +596,19 @@ int unlinked(Project *pr) ERRCODE(MEMCHECK(marked)); if (errcode) return errcode; memset(marked, 0, (net->Nnodes + 1) * sizeof(int)); - + // Mark end nodes of each link for (i = 1; i <= net->Nlinks; i++) { marked[net->Link[i].N1]++; marked[net->Link[i].N2]++; } - + // Check each junction for (i = 1; i <= net->Njuncs; i++) { // If not marked then error - if (marked[i] == 0) + if (marked[i] == 0) { err++; sprintf(pr->Msg, "Error 233: %s %s", geterrmsg(233, pr->Msg), net->Node[i].ID); @@ -641,7 +638,7 @@ int getpatterns(Project *pr) SFloatlist *f; STmplist *tmppattern; Spattern *pattern; - + // Start at head of the list of patterns tmppattern = parser->Patlist; @@ -699,7 +696,7 @@ int getcurves(Project *pr) { Network *net = &pr->network; Parser *parser = &pr->parser; - + int i, j; double x; char errmsg[MAXMSG+1]; @@ -830,14 +827,14 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) int m, n; size_t len; char *c, *c2; - + // clear comment comment[0] = '\0'; - + // Begin with no tokens for (n=0; n 0 && n < MAXTOKS) { @@ -871,7 +868,7 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) { s++; // Start token after quote m = (int)strcspn(s,"\"\n\r"); // Find end quote (or EOL) - } + } s[m] = '\0'; // Null-terminate the token Tok[n] = s; // Save pointer to token n++; // Update token count @@ -879,7 +876,7 @@ int gettokens(char *s, char** Tok, int maxToks, char *comment) } } return n; -} +} double hour(char *time, char *units) /* @@ -917,7 +914,7 @@ double hour(char *time, char *units) if (match(units, w_DAYS)) return (y[0] * 24.0); } - // Convert hh:mm:ss format to decimal hours + // Convert hh:mm:ss format to decimal hours if (n > 1) y[0] = y[0] + y[1] / 60.0 + y[2] / 3600.0; // If am/pm attached then adjust hour accordingly @@ -936,7 +933,7 @@ double hour(char *time, char *units) else return (y[0] + 12.0); } return -1.0; -} +} int getfloat(char *s, double *y) /* @@ -982,14 +979,14 @@ void inperrmsg(Project *pr, int err, int sect, char *line) */ { Parser *parser = &pr->parser; - + char errStr[MAXMSG + 1] = ""; char tok[MAXMSG + 1]; // Get token associated with input error if (parser->ErrTok >= 0) strcpy(tok, parser->Tok[parser->ErrTok]); else strcpy(tok, ""); - + // write error message to report file sprintf(pr->Msg, "Error %d: %s %s in %s section:", err, geterrmsg(err, errStr), tok, SectTxt[sect]); diff --git a/src/input3.c b/src/input3.c index d00a6e9..fb35da2 100644 --- a/src/input3.c +++ b/src/input3.c @@ -10,16 +10,13 @@ License: see LICENSE Last Updated: 03/17/2019 ****************************************************************************** */ -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include -#else - #include -#endif #include +#include #include +#ifndef __APPLE__ +#include +#endif #include #include "types.h" diff --git a/src/mempool.c b/src/mempool.c index 871b4c8..55552ed 100755 --- a/src/mempool.c +++ b/src/mempool.c @@ -15,7 +15,9 @@ */ #include - +#ifndef __APPLE__ +#include +#endif #include "mempool.h" /* diff --git a/src/output.c b/src/output.c index d86fe50..fd92077 100644 --- a/src/output.c +++ b/src/output.c @@ -11,9 +11,13 @@ Last Updated: 11/27/2018 ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include "types.h" diff --git a/src/project.c b/src/project.c index 8355588..fd4cb8d 100644 --- a/src/project.c +++ b/src/project.c @@ -11,18 +11,14 @@ ****************************************************************************** */ -#ifdef _DEBUG -#define _CRTDBG_MAP_ALLOC -#include -#include +#include +#include +#ifndef __APPLE__ +#include #else #include #endif -#include -#include - - //*** For the Windows SDK _tempnam function ***// #ifdef _WIN32 #include diff --git a/src/quality.c b/src/quality.c index 06e1997..de27f63 100644 --- a/src/quality.c +++ b/src/quality.c @@ -11,9 +11,13 @@ Last Updated: 11/27/2018 ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include "mempool.h" diff --git a/src/qualreact.c b/src/qualreact.c index 0afac47..0805a21 100644 --- a/src/qualreact.c +++ b/src/qualreact.c @@ -13,7 +13,6 @@ Last Updated: 11/27/2018 #include #include - #include "types.h" // Exported functions diff --git a/src/qualroute.c b/src/qualroute.c index 03e3545..72bb66f 100644 --- a/src/qualroute.c +++ b/src/qualroute.c @@ -11,10 +11,13 @@ Last Updated: 11/27/2018 ****************************************************************************** */ -#include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include - #include "mempool.h" #include "types.h" diff --git a/src/report.c b/src/report.c index dd4ff3d..5605ffb 100644 --- a/src/report.c +++ b/src/report.c @@ -11,10 +11,13 @@ ****************************************************************************** */ -#include #include #include - +#ifndef __APPLE__ +#include +#else +#include +#endif #ifdef _WIN32 #define snprintf _snprintf diff --git a/src/rules.c b/src/rules.c index eee5568..7e9945f 100644 --- a/src/rules.c +++ b/src/rules.c @@ -11,9 +11,13 @@ ****************************************************************************** */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include "types.h" #include "funcs.h" diff --git a/src/smatrix.c b/src/smatrix.c index 3446384..510bb3e 100755 --- a/src/smatrix.c +++ b/src/smatrix.c @@ -18,11 +18,16 @@ linsolve() -- called from netsolve() in HYDRAUL.C */ -#include #include #include +#ifndef __APPLE__ +#include +#else +#include +#endif #include #include + #include //For optional timer macros #include "text.h" diff --git a/src/types.h b/src/types.h index 38d6607..4329414 100755 --- a/src/types.h +++ b/src/types.h @@ -14,10 +14,8 @@ #ifndef TYPES_H #define TYPES_H -#include - #include "hash.h" - +#include /* ------------------------------------------- diff --git a/src/util/errormanager.c b/src/util/errormanager.c index b674fe6..5a9876c 100644 --- a/src/util/errormanager.c +++ b/src/util/errormanager.c @@ -10,7 +10,13 @@ // US EPA - ORD/NRMRL //----------------------------------------------------------------------------- +//#ifdef _WIN32 +//#define _CRTDBG_MAP_ALLOC +//#include +//#include +//#else #include +//#endif #include #include "errormanager.h" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fd9a8d8..64c7c23 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,19 +19,18 @@ endif(UNIX) set(toolkit_test_srcs test_toolkit.cpp test_project.cpp -# test_hydraulics.cpp -# test_quality.cpp -# test_report.cpp -# test_analysis.cpp -# test_node.cpp -# test_demand.cpp -# test_link.cpp + test_hydraulics.cpp + test_quality.cpp + test_report.cpp + test_analysis.cpp + test_node.cpp + test_demand.cpp + test_link.cpp # test_pump.cpp -# test_pattern.cpp -# test_curve.cpp -# test_control.cpp -# test_net_builder.cpp -) + test_pattern.cpp + test_curve.cpp + test_control.cpp + test_net_builder.cpp) add_executable(test_toolkit ${toolkit_test_srcs}) diff --git a/tests/test_analysis.cpp b/tests/test_analysis.cpp index 917b523..f7120f1 100644 --- a/tests/test_analysis.cpp +++ b/tests/test_analysis.cpp @@ -11,6 +11,7 @@ ****************************************************************************** */ +//#define BOOST_ALL_DYN_LINK #include #include "test_toolkit.hpp" diff --git a/tests/test_project.cpp b/tests/test_project.cpp index 6ae1143..6f0b68c 100644 --- a/tests/test_project.cpp +++ b/tests/test_project.cpp @@ -56,47 +56,35 @@ BOOST_AUTO_TEST_CASE(test_save) { int error; - EN_Project ph = NULL; + EN_Project ph_save; - error = EN_createproject(&ph); - BOOST_REQUIRE(error == 0); - - error = EN_open(ph, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT); + EN_createproject(&ph_save); + error = EN_open(ph_save, DATA_PATH_NET1, DATA_PATH_RPT, DATA_PATH_OUT); BOOST_REQUIRE(error == 0); - error = EN_saveinpfile(ph, DATA_PATH_TMP); + error = EN_saveinpfile(ph_save, "test_reopen.inp"); BOOST_REQUIRE(error == 0); - BOOST_CHECK(boost::filesystem::exists(DATA_PATH_TMP) == true); + BOOST_CHECK(boost::filesystem::exists("test_reopen.inp") == true); - error = EN_close(ph); + error = EN_close(ph_save); BOOST_REQUIRE(error == 0); - - error = EN_deleteproject(&ph); - BOOST_REQUIRE(error == 0); - - BOOST_CHECK(ph == NULL); + EN_deleteproject(&ph_save); } BOOST_AUTO_TEST_CASE(test_reopen, * boost::unit_test::depends_on("test_project/test_save")) { int error; - EN_Project ph = NULL; + EN_Project ph_reopen; - error = EN_createproject(&ph); - BOOST_REQUIRE(error == 0); + EN_createproject(&ph_reopen); + error = EN_open(ph_reopen, "test_reopen.inp", DATA_PATH_RPT, DATA_PATH_OUT); + BOOST_REQUIRE(error == 0); - error = EN_open(ph, DATA_PATH_TMP, DATA_PATH_RPT, DATA_PATH_OUT); - BOOST_REQUIRE(error == 0); - - error = EN_close(ph); - BOOST_REQUIRE(error == 0); - - EN_deleteproject(&ph); - BOOST_REQUIRE(error == 0); - - BOOST_CHECK(ph == NULL); + error = EN_close(ph_reopen); + BOOST_REQUIRE(error == 0); + EN_deleteproject(&ph_reopen); } BOOST_AUTO_TEST_CASE(test_run) diff --git a/tests/test_toolkit.hpp b/tests/test_toolkit.hpp index f0da4e7..03ac664 100644 --- a/tests/test_toolkit.hpp +++ b/tests/test_toolkit.hpp @@ -14,12 +14,6 @@ #ifndef TEST_TOOLKIT_HPP #define TEST_TOOLKIT_HPP -// MSVC ONLY -#ifdef _DEBUG - #define _CRTDBG_MAP_ALLOC - #include - #include -#endif #include "epanet2_2.h" From 907760540e40c68d06a0d80c8a30ad94f6687ba9 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 15:34:21 -0400 Subject: [PATCH 19/26] Reorganizing public functions --- src/util/filemanager.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/util/filemanager.c b/src/util/filemanager.c index 9603ce4..7a4469f 100644 --- a/src/util/filemanager.c +++ b/src/util/filemanager.c @@ -153,6 +153,16 @@ int remove_file(file_handle_t *file_handle) { } +bool is_valid(file_handle_t *file_handle) +{ + if ((file_handle->filename == NULL && file_handle->file == NULL) || + (isnullterm_cstr(file_handle->filename) && file_handle != NULL)) + return true; + else + return false; +} + + int _fopen(FILE **f, const char *name, const char *mode) // // Purpose: Substitute for fopen_s on platforms where it doesn't exist @@ -199,12 +209,3 @@ int _get_temp_filename(char **tempname) #endif return error; } - -bool is_valid(file_handle_t *file_handle) -{ - if ((file_handle->filename == NULL && file_handle->file == NULL) || - (isnullterm_cstr(file_handle->filename) && file_handle != NULL)) - return true; - else - return false; -} From 3ba40015b2c4577f1b84bb426fd9dd51464c002a Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 15:41:24 -0400 Subject: [PATCH 20/26] revert 8574f52 --- appveyor.yml | 1 + src/epanet_py.c | 42 +++++++++++++++++++----------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 22c1acf..dc80e1c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -98,3 +98,4 @@ on_failure: 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip ) + diff --git a/src/epanet_py.c b/src/epanet_py.c index 4c16cbf..fb681aa 100644 --- a/src/epanet_py.c +++ b/src/epanet_py.c @@ -786,29 +786,25 @@ void error_lookup(int errcode, char *dest_msg, int dest_len) { char *msg = NULL; - switch (errcode) { - case 1: - msg = WARN1; - break; - case 2: - msg = WARN2; - break; - case 3: - msg = WARN3; - break; - case 4: - msg = WARN4; - break; - case 5: - msg = WARN5; - break; - case 6: - msg = WARN6; - break; - default: { - char new_msg[MAXMSG + 1]; - msg = geterrmsg(errcode, new_msg); - } + switch (errcode) + { + case 1: msg = WARN1; + break; + case 2: msg = WARN2; + break; + case 3: msg = WARN3; + break; + case 4: msg = WARN4; + break; + case 5: msg = WARN5; + break; + case 6: msg = WARN6; + break; + default: + { + char new_msg[MAXMSG + 1]; + msg = geterrmsg(errcode, new_msg); + } } strncpy(dest_msg, msg, dest_len); } From ddf0a088db598edc3b3af1341f9997b0b466bd57 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 15:47:06 -0400 Subject: [PATCH 21/26] revert 1a01b46 --- appveyor.yml | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index dc80e1c..5972e3c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,23 +20,14 @@ environment: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 GENERATOR: "Visual Studio 15 2017" GROUP: "SUPPORTED" - BUILD_CONFIG: "Release" BOOST_ROOT: "C:/Libraries/boost_1_67_0" + PLATFORM: "win32" REF_BUILD_ID: "220dev5" # New build on Visual Studio 15 2017 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 GENERATOR: "Visual Studio 15 2017 Win64" GROUP: "EXPERIMENTAL" - BUILD_CONFIG: "Release" - BOOST_ROOT: "C:/Libraries/boost_1_67_0" - PLATFORM: "win64" - REF_BUILD_ID: "381_2" - # adding debug configuration so we can monitor memory leaks - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - GENERATOR: "Visual Studio 15 2017 Win64" - GROUP: "EXPERIMENTAL" - BUILD_CONFIG: "Debug" BOOST_ROOT: "C:/Libraries/boost_1_67_0" PLATFORM: "win64" REF_BUILD_ID: "381_2" @@ -69,7 +60,7 @@ before_build: # run custom build script build_script: - - cmake --build . --config %BUILD_CONFIG% + - cmake --build . --config Release before_test: - cd %EPANET_HOME% @@ -79,12 +70,11 @@ before_test: test_script: # run unit tests - cd %BUILD_HOME%\tests - - ctest -C %BUILD_CONFIG% --output-on-failure + - ctest -C Release --output-on-failure # run regression tests - cd %EPANET_HOME% - - IF "%BUILD_CONFIG%" == "Release" ( - tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% - ) + - tools\run-nrtest.cmd %REF_BUILD_ID% %SUT_BUILD_ID% + on_success: - cd %TEST_HOME%\benchmark - IF "%BUILD_CONFIG%" == "Release" ( @@ -98,4 +88,3 @@ on_failure: 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip ) - From 611afbafd2c8399380fae0904f4a4142806901a1 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 15:58:16 -0400 Subject: [PATCH 22/26] Update .travis.yml No apt-get update --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3349562..308cb2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,7 @@ env: - TEST_HOME=nrtestsuite before_install: - - sudo apt-get -qq update +# - sudo apt-get -qq update - eval "${MATRIX_EVAL}" #install: From 90325d7a65748a35f760afee8b5f7265fcee9194 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 16:14:28 -0400 Subject: [PATCH 23/26] Update appveyor.yml Rolling back changes to match dev HEAD --- appveyor.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5972e3c..4eda106 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,7 +21,6 @@ environment: GENERATOR: "Visual Studio 15 2017" GROUP: "SUPPORTED" BOOST_ROOT: "C:/Libraries/boost_1_67_0" - PLATFORM: "win32" REF_BUILD_ID: "220dev5" # New build on Visual Studio 15 2017 @@ -77,14 +76,10 @@ test_script: on_success: - cd %TEST_HOME%\benchmark - - IF "%BUILD_CONFIG%" == "Release" ( - appveyor PushArtifact receipt.json - ) + - appveyor PushArtifact receipt.json on_failure: - cd %TEST_HOME%\benchmark # zip up the SUT benchmarks - - IF "%BUILD_CONFIG%" == "Release" ( - 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & - appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip - ) + - 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & + - appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip From 525c861d4b51bebff5f6e9a04223cbe30b369226 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 16:16:53 -0400 Subject: [PATCH 24/26] Update appveyor.yml Fixing bug --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4eda106..d8e6ce9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -81,5 +81,5 @@ on_success: on_failure: - cd %TEST_HOME%\benchmark # zip up the SUT benchmarks - - 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% & + - 7z a benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip .\epanet-%SUT_BUILD_ID% - appveyor PushArtifact benchmark-%PLATFORM%-%SUT_BUILD_ID%.zip From ea5d2894b1603ff6cdfd02bd4fa1277cf3002d18 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 16:51:55 -0400 Subject: [PATCH 25/26] Bumping version, updating headers --- src/outfile/src/epanet_output.c | 5 +++-- src/util/cstr_helper.c | 12 ++++++++++++ src/util/cstr_helper.h | 12 ++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/outfile/src/epanet_output.c b/src/outfile/src/epanet_output.c index 6e0c63d..7d46e03 100644 --- a/src/outfile/src/epanet_output.c +++ b/src/outfile/src/epanet_output.c @@ -2,8 +2,9 @@ // // epanet_output.c -- API for reading results from EPANET binary output file // -// Version: 0.30 -// Date 09/06/2017 +// Version: 0.40 +// Date 04/02/2019 +// 09/06/2017 // 06/17/2016 // 08/05/2014 // 05/21/2014 diff --git a/src/util/cstr_helper.c b/src/util/cstr_helper.c index 13ca1c4..9106446 100644 --- a/src/util/cstr_helper.c +++ b/src/util/cstr_helper.c @@ -1,3 +1,15 @@ +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/cstr_helper.c + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/02/2019 + ****************************************************************************** +*/ #include #include diff --git a/src/util/cstr_helper.h b/src/util/cstr_helper.h index 55f71d0..ba4aac9 100644 --- a/src/util/cstr_helper.h +++ b/src/util/cstr_helper.h @@ -1,3 +1,15 @@ +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/cstr_helper.h + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/02/2019 + ****************************************************************************** +*/ #ifndef CSTR_HELPER_H_ #define CSTR_HELPER_H_ From 0e30d57d4e96ee9a9efd48a3ff7f3a5361f89a06 Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Tue, 2 Apr 2019 17:01:35 -0400 Subject: [PATCH 26/26] Update errormanager Make error_handle_t "private". Update headers. --- src/util/errormanager.c | 29 ++++++++++++++++++----------- src/util/errormanager.h | 25 +++++++++++++------------ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/util/errormanager.c b/src/util/errormanager.c index 5a9876c..96a40bd 100644 --- a/src/util/errormanager.c +++ b/src/util/errormanager.c @@ -1,14 +1,15 @@ -//----------------------------------------------------------------------------- -// -// errormanager.c -// -// Purpose: Provides a simple interface for managing runtime error messages. -// -// Date: 08/25/2017 -// -// Author: Michael E. Tryby -// US EPA - ORD/NRMRL -//----------------------------------------------------------------------------- +/* + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/errormanager.c + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/02/2019 + ****************************************************************************** +*/ //#ifdef _WIN32 //#define _CRTDBG_MAP_ALLOC @@ -22,6 +23,12 @@ #include "errormanager.h" +typedef struct error_s { + int error_status; + void (*p_msg_lookup)(int, char*, int); +} error_handle_t; + + error_handle_t *create_error_manager(void (*p_error_message)(int, char*, int)) // // Purpose: Constructs a new error handle. diff --git a/src/util/errormanager.h b/src/util/errormanager.h index 6939f35..450eb88 100644 --- a/src/util/errormanager.h +++ b/src/util/errormanager.h @@ -1,11 +1,15 @@ /* - * errormanager.h - * - * Created on: Aug 25, 2017 - * - * Author: Michael E. Tryby - * US EPA - ORD/NRMRL - */ + ****************************************************************************** + Project: OWA EPANET + Version: 2.2 + Module: util/errormanager.h + Description: Provides a simple interface for managing files + Authors: see AUTHORS + Copyright: see AUTHORS + License: see LICENSE + Last Updated: 04/02/2019 + ****************************************************************************** +*/ #ifndef ERRORMANAGER_H_ #define ERRORMANAGER_H_ @@ -17,11 +21,8 @@ extern "C" { #endif - -typedef struct error_s { - int error_status; - void (*p_msg_lookup)(int, char*, int); -} error_handle_t; +// Forward declaration +typedef struct error_s error_handle_t; error_handle_t* create_error_manager(void (*p_error_message)(int, char*, int)); void delete_error_manager(error_handle_t* error_handle);