Adding errormanager to toolkit api

This commit is contained in:
Michael Tryby
2018-07-13 11:47:47 -04:00
parent c8803a9f1b
commit 4723336726
7 changed files with 246 additions and 28 deletions

View File

@@ -69,8 +69,8 @@ ENDIF (MSVC)
# configure file groups
file(GLOB EPANET_SOURCES src/*.c)
file(GLOB EPANET_LIB_ALL src/*)
file(GLOB EPANET_SOURCES src/*.c src/util/*.c)
file(GLOB EPANET_LIB_ALL src/* src/util/*)
source_group("Library" FILES ${EPANET_LIB_ALL})

View File

@@ -294,8 +294,9 @@ typedef struct EN_Curve EN_Curve;
needed then the argument should be NULL.
*/
int DLLEXPORT ENepanet(const char *inpFile, const char *rptFile,
const char *binOutFile, void (*callback) (char *));
const char *binOutFile, void (*callback) (char *));
int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *inpFile,
const char *rptFile, const char *binOutFile, void(*callback) (char *));
// OPENING A CLOSING THE EPANET TOOLKIT SYSTEM
/**
@@ -1261,6 +1262,8 @@ int DLLEXPORT EN_deletelink(EN_ProjectHandle ph, int linkIndex);
int DLLEXPORT EN_alloc(EN_ProjectHandle *ph);
int DLLEXPORT EN_free(EN_ProjectHandle *ph);
void DLLEXPORT EN_clearError(EN_ProjectHandle ph);
int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char **msg_buffer);
int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode);

View File

@@ -133,6 +133,10 @@ execute function x and set the error code equal to its return value.
////////////////////////////////////////////#include "epanet2.h"
#include "vars.h"
// Local functions
void errorLookup(int errcode, char *errmsg, int len);
/****************************************************************
LEGACY (v <= 2.1) API: uses global project variable
@@ -159,24 +163,14 @@ execute function x and set the error code equal to its return value.
int DLLEXPORT ENepanet(const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *))
{
int errcode = 0;
EN_Project *_p;
ERRCODE(EN_alloc(&_defaultModel));
ERRCODE(EN_open(_defaultModel, f1, f2, f3));
_p = (EN_Project*)_defaultModel;
ERRCODE(EN_epanet(_defaultModel, f1, f2, f3, pviewprog));
_p->viewprog = pviewprog;
if (_p->out_files.Hydflag != USE) {
ERRCODE(EN_solveH(_defaultModel));
}
ERRCODE(EN_free(&_defaultModel));
ERRCODE(EN_solveQ(_defaultModel));
ERRCODE(EN_report(_defaultModel));
EN_close(_defaultModel);
EN_free(&_defaultModel);
return (errcode);
return errcode;
}
int DLLEXPORT ENopen(char *f1, char *f2, char *f3) {
@@ -548,21 +542,55 @@ int DLLEXPORT ENdeletenode(int index) {
/// allocate a project pointer
int DLLEXPORT EN_alloc(EN_ProjectHandle *ph)
{
int errorcode = 0;
EN_Project *project = calloc(1, sizeof(EN_Project));
*ph = project;
return 0;
if (project != NULL){
project->error_handle = new_errormanager(&errorLookup);
*ph = project;
}
else
errorcode = -1;
return errorcode;
}
int DLLEXPORT EN_free(EN_ProjectHandle *ph)
{
EN_Project *p = (EN_Project*)(*ph);
int errorcode = 0;
EN_Project *p = (EN_Project*)(*ph);
free(p);
if (p == NULL)
errorcode = -1;
else
{
dst_errormanager(p->error_handle);
free(p);
*ph = NULL;
*ph = NULL;
}
return 0;
return 0;
}
int DLLEXPORT EN_epanet(EN_ProjectHandle ph, const char *f1, const char *f2,
const char *f3, void(*pviewprog)(char *))
{
int errcode = 0;
EN_Project *_p = (EN_Project*)ph;
ERRCODE(EN_open(ph, f1, f2, f3));
_p->viewprog = pviewprog;
if (_p->out_files.Hydflag != USE) {
ERRCODE(EN_solveH(ph));
}
ERRCODE(EN_solveQ(ph));
ERRCODE(EN_report(ph));
EN_close(ph);
return set_error(_p->error_handle, errcode);
}
int DLLEXPORT EN_init(EN_ProjectHandle *ph, char *f2, char *f3,
@@ -1724,10 +1752,12 @@ int DLLEXPORT EN_getqualtype(EN_ProjectHandle ph, int *qualcode, int *tracenode)
}
int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname,
int DLLEXPORT EN_getqualinfo(EN_ProjectHandle ph, int *qualcode, char *chemname,
char *chemunits, int *tracenode) {
EN_getqualtype(p, qualcode, tracenode);
EN_Project *p = (EN_Project*)ph;
EN_getqualtype(ph, qualcode, tracenode);
if (p->quality.Qualflag == TRACE) {
strncpy(chemname, "", MAXID);
@@ -1739,6 +1769,63 @@ int DLLEXPORT EN_getqualinfo(EN_Project *p, int *qualcode, char *chemname,
return 0;
}
void errorLookup(int errcode, char *dest_msg, int dest_len)
// Purpose: takes error code returns error message
{
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:
msg = geterrmsg(errcode, msg);
}
strncpy(dest_msg, msg, MAXMSG);
}
void DLLEXPORT EN_clearError(EN_ProjectHandle ph)
{
EN_Project *p = (EN_Project*)ph;
clear_error(p->error_handle);
}
int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer)
//
// Purpose: Returns the error message or NULL.
//
// Note: Caller must free memory allocated by EN_check_error
//
{
int errorcode = 0;
char *temp = NULL;
EN_Project *p = (EN_Project*)ph;
if (p == NULL) return -1;
else
{
errorcode = p->error_handle->error_status;
if (errorcode)
temp = check_error(p->error_handle);
*msg_buffer = temp;
}
return errorcode;
}
int DLLEXPORT EN_geterror(int errcode, char *errmsg, int n) {
char newMsg[MAXMSG+1];
@@ -4247,11 +4334,11 @@ char *geterrmsg(int errcode, char *msg)
*/
{
switch (errcode) { /* Warnings */
#define DAT(code,enumer,string) case code: strcpy(msg, string); break;
#define DAT(code,enumer,string) case code: msg = string; break;
#include "errors.dat"
#undef DAT
default:
strcpy(msg, "");
msg = "";
}
return (msg);
}

View File

@@ -23,6 +23,8 @@ AUTHOR: L. Rossman
#include "epanet2.h"
#include "hash.h"
#include "mempool.h"
#include "util/errormanager.h"
/*********************************************************/
/* All floats have been re-declared as doubles (7/3/07). */
@@ -870,6 +872,8 @@ typedef struct EN_Project {
Title[MAXTITLE][MAXMSG+1], /// Problem title
MapFname[MAXFNAME+1]; /// Map file name
error_handle_t* error_handle; //Simple error manager
void (* viewprog) (char *); /* Pointer to progress viewing function */
} EN_Project;

73
src/util/errormanager.c Normal file
View File

@@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
//
// errormanager.c
//
// Purpose: Provides a simple interface for managing runtime error messages.
//
// Date: 08/25/2017
//
// Author: Michael E. Tryby
// US EPA - ORD/NRMRL
//-----------------------------------------------------------------------------
#include "errormanager.h"
error_handle_t* new_errormanager(void (*p_error_message)(int, char*, int))
//
// Purpose: Constructs a new error handle.
//
{
error_handle_t* error_handle;
error_handle = (error_handle_t*)calloc(1, sizeof(error_handle_t));
if (error_handle != NULL)
error_handle->p_msg_lookup = p_error_message;
return error_handle;
}
void dst_errormanager(error_handle_t* error_handle)
//
// Purpose: Destroys the error handle.
//
{
free(error_handle);
}
int set_error(error_handle_t* error_handle, int errorcode)
//
// Purpose: Sets an error code in the handle.
//
{
// If the error code is 0 no action is taken and 0 is returned.
// This is a feature not a bug.
if (errorcode)
error_handle->error_status = errorcode;
return errorcode;
}
char* check_error(error_handle_t* error_handle)
//
// Purpose: Returns the error message or NULL.
//
// Note: Caller must free memory allocated by check_error
//
{
char* temp = NULL;
if (error_handle->error_status != 0) {
temp = (char*) calloc(ERR_MAXMSG, sizeof(char));
if (temp)
error_handle->p_msg_lookup(error_handle->error_status, temp, ERR_MAXMSG);
}
return temp;
}
void clear_error(error_handle_t* error_handle)
//
// Purpose: Clears the error from the handle.
//
{
error_handle->error_status = 0;
}

30
src/util/errormanager.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* errormanager.h
*
* Created on: Aug 25, 2017
*
* Author: Michael E. Tryby
* US EPA - ORD/NRMRL
*/
#ifndef ERRORMANAGER_H_
#define ERRORMANAGER_H_
#include <stdlib.h>
#include <string.h>
#define ERR_MAXMSG 256
typedef struct error_s {
int error_status;
void (*p_msg_lookup)(int, char*, int);
} error_handle_t;
error_handle_t* new_errormanager(void (*p_error_message)(int, char*, int));
void dst_errormanager(error_handle_t* error_handle);
int set_error(error_handle_t* error_handle, int errorcode);
char* check_error(error_handle_t* error_handle);
void clear_error(error_handle_t* error_handle);
#endif /* ERRORMANAGER_H_ */

View File

@@ -69,6 +69,27 @@ BOOST_AUTO_TEST_CASE(test_epanet)
BOOST_REQUIRE(error == 0);
}
BOOST_AUTO_TEST_CASE(test_errormanager)
{
char *error_msg;
EN_ProjectHandle ph = NULL;
std::string path_inp = std::string(DATA_PATH_INP);
std::string path_rpt = std::string(DATA_PATH_RPT);
std::string path_out = std::string(DATA_PATH_RPT);
EN_alloc(&ph);
EN_clearError(ph);
int error = EN_epanet(ph, path_inp.c_str(), path_rpt.c_str(), path_out.c_str(), NULL);
EN_checkError(ph, &error_msg);
EN_free(&ph);
free(error_msg);
}
BOOST_AUTO_TEST_SUITE_END()