Merge branch 'dev-list' of https://github.com/michaeltryby/EPANET into dev-list
This commit is contained in:
@@ -67,7 +67,7 @@ demand_data_t *create_demand_data(double base_demand, int pattern_index, const c
|
||||
|
||||
void delete_demand_data(void *data)
|
||||
{
|
||||
// TODO: This cast is a problem!
|
||||
// TODO: This cast is a problem!
|
||||
demand_data_t *demand_data = *(demand_data_t **)data;
|
||||
|
||||
if (demand_data->category_name)
|
||||
@@ -119,7 +119,12 @@ void set_pattern_index(list_node_t *lnode, int pattern_index)
|
||||
char *get_category_name(list_node_t *lnode)
|
||||
// Be advised: caller must free memory returned
|
||||
{
|
||||
return strdup(get_demand_data(lnode)->category_name);
|
||||
char *temp = get_demand_data(lnode)->category_name;
|
||||
|
||||
if (temp)
|
||||
return strdup(temp);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_category_name(list_node_t *lnode, const char *category_name)
|
||||
|
||||
292
src/epanet.c
292
src/epanet.c
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/03/2019
|
||||
Last Updated: 04/18/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "text.h"
|
||||
#include "enumstxt.h"
|
||||
|
||||
#include "util/cstr_helper.h"
|
||||
#include "demand.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -1708,11 +1707,11 @@ int DLLEXPORT EN_setqualtype(EN_Project p, int qualType, char *chemName,
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType, int *index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: id = node ID name
|
||||
** nodeType = type of node (see EN_NodeType)
|
||||
** Output: none
|
||||
** Output: index = index of newly added node
|
||||
** Returns: error code
|
||||
** Purpose: adds a new node to a project
|
||||
**----------------------------------------------------------------
|
||||
@@ -1723,26 +1722,22 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
Quality *qual = &p->quality;
|
||||
|
||||
int i, nIdx;
|
||||
int index;
|
||||
int size;
|
||||
// struct Sdemand *demand;
|
||||
Stank *tank;
|
||||
Snode *node;
|
||||
Scontrol *control;
|
||||
|
||||
// Cannot modify network structure while solvers are active
|
||||
*index = 0;
|
||||
if (!p->Openflag) return 102;
|
||||
if (hyd->OpenHflag || qual->OpenQflag) return 262;
|
||||
|
||||
// Check if id contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
// Check if a node with same id already exists
|
||||
if (EN_getnodeindex(p, id, &i) == 0) return 215;
|
||||
|
||||
// Check that id name is not too long
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
|
||||
// Grow node-related arrays to accomodate the new node
|
||||
size = (net->Nnodes + 2) * sizeof(Snode);
|
||||
net->Node = (Snode *)realloc(net->Node, size);
|
||||
@@ -1758,36 +1753,31 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
nIdx = net->Njuncs;
|
||||
node = &net->Node[nIdx];
|
||||
|
||||
//demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
|
||||
//demand->Base = 0.0;
|
||||
//demand->Pat = 0;
|
||||
//demand->Name = NULL;
|
||||
//demand->next = NULL;
|
||||
node->D = NULL;
|
||||
|
||||
// shift rest of Node array
|
||||
for (index = net->Nnodes; index >= net->Njuncs; index--)
|
||||
for (i = net->Nnodes; i >= net->Njuncs; i--)
|
||||
{
|
||||
hashtable_update(net->NodeHashTable, net->Node[index].ID, index + 1);
|
||||
net->Node[index + 1] = net->Node[index];
|
||||
hashtable_update(net->NodeHashTable, net->Node[i].ID, i + 1);
|
||||
net->Node[i + 1] = net->Node[i];
|
||||
}
|
||||
// shift indices of Tank array
|
||||
for (index = 1; index <= net->Ntanks; index++)
|
||||
for (i = 1; i <= net->Ntanks; i++)
|
||||
{
|
||||
net->Tank[index].Node += 1;
|
||||
net->Tank[i].Node += 1;
|
||||
}
|
||||
|
||||
// shift indices of Links, if necessary
|
||||
for (index = 1; index <= net->Nlinks; index++)
|
||||
for (i = 1; i <= net->Nlinks; i++)
|
||||
{
|
||||
if (net->Link[index].N1 > net->Njuncs - 1) net->Link[index].N1 += 1;
|
||||
if (net->Link[index].N2 > net->Njuncs - 1) net->Link[index].N2 += 1;
|
||||
if (net->Link[i].N1 > net->Njuncs - 1) net->Link[i].N1 += 1;
|
||||
if (net->Link[i].N2 > net->Njuncs - 1) net->Link[i].N2 += 1;
|
||||
}
|
||||
|
||||
// shift indices of tanks/reservoir nodes in controls
|
||||
for (index = 1; index <= net->Ncontrols; ++index)
|
||||
for (i = 1; i <= net->Ncontrols; ++i)
|
||||
{
|
||||
control = &net->Control[index];
|
||||
control = &net->Control[i];
|
||||
if (control->Node > net->Njuncs - 1) control->Node += 1;
|
||||
}
|
||||
|
||||
@@ -1842,6 +1832,7 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
|
||||
// Insert new node into hash table
|
||||
hashtable_insert(net->NodeHashTable, node->ID, nIdx);
|
||||
*index = nIdx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2018,13 +2009,10 @@ int DLLEXPORT EN_setnodeid(EN_Project p, int index, char *newid)
|
||||
*/
|
||||
{
|
||||
Network *net = &p->network;
|
||||
size_t n;
|
||||
|
||||
// Check for valid arguments
|
||||
if (index <= 0 || index > net->Nnodes) return 203;
|
||||
n = strlen(newid);
|
||||
if (n < 1 || n > MAXID) return 209;
|
||||
if (!cstr_isvalid(newid)) return 252;
|
||||
if (!namevalid(newid)) return 252;
|
||||
|
||||
// Check if another node with same name exists
|
||||
if (hashtable_find(net->NodeHashTable, newid) > 0) return 215;
|
||||
@@ -2312,10 +2300,6 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
set_base_demand(tail_list(demand), value / Ucf[FLOW]);
|
||||
// for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
// {
|
||||
// if (demand->next == NULL) demand->Base = value / Ucf[FLOW];
|
||||
// }
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2325,13 +2309,9 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
|
||||
if (j < 0 || j > nPats) return 205;
|
||||
if (index <= nJuncs)
|
||||
{
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
set_pattern_index(tail_list(demand), j);
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// if (demand->next == NULL) demand->Pat = j;
|
||||
//}
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
set_pattern_index(tail_list(demand), j);
|
||||
}
|
||||
else Tank[index - nJuncs].Pat = j;
|
||||
break;
|
||||
@@ -2551,24 +2531,16 @@ int DLLEXPORT EN_setjuncdata(EN_Project p, int index, double elev,
|
||||
// Assign values to junction's parameters
|
||||
Node[index].El = elev / p->Ucf[ELEV];
|
||||
|
||||
list_t *demand_list = Node[index].D;
|
||||
if (!demand_list) {
|
||||
demand_list = create_list(get_demand_data_size(), delete_demand_data);
|
||||
if (!demand_list) return 101;
|
||||
}
|
||||
demand_data_t *demand_data = create_demand_data(dmnd / p->Ucf[FLOW], patIndex, NULL);
|
||||
if (!demand_data) return 101;
|
||||
list_t *demand_list = Node[index].D;
|
||||
if (!demand_list) {
|
||||
demand_list = create_list(get_demand_data_size(), delete_demand_data);
|
||||
if (!demand_list) return 101;
|
||||
}
|
||||
demand_data_t *demand_data = create_demand_data(dmnd / p->Ucf[FLOW], patIndex, NULL);
|
||||
if (!demand_data) return 101;
|
||||
|
||||
append_list(demand_list, &demand_data);
|
||||
append_list(demand_list, &demand_data);
|
||||
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// if (demand->next == NULL)
|
||||
// {
|
||||
// demand->Base = dmnd / p->Ucf[FLOW];
|
||||
// demand->Pat = patIndex;
|
||||
// }
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2777,9 +2749,6 @@ int DLLEXPORT EN_getbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
//Pdemand d;
|
||||
//int n; //= 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return 203;
|
||||
@@ -2787,12 +2756,12 @@ int DLLEXPORT EN_getbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
// Retrieve demand for specified category
|
||||
if (nodeIndex <= p->network.Njuncs)
|
||||
{
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
*baseDemand = get_base_demand(lnode) * p->Ucf[FLOW];
|
||||
}
|
||||
else *baseDemand = (double)(0.0);
|
||||
@@ -2818,22 +2787,22 @@ int DLLEXPORT EN_setbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
// Set baseline demand for specified category
|
||||
if (nodeIndex <= p->network.Njuncs)
|
||||
{
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
// If demand list is null create one and set demand
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(baseDemand / p->Ucf[FLOW], 0, NULL);
|
||||
if (!dlist) return 101;
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
// If demand list is null create one and set demand
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(baseDemand / p->Ucf[FLOW], 0, NULL);
|
||||
if (!dlist) return 101;
|
||||
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
// else find the demand entry and set demand
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_base_demand(lnode, baseDemand / p->Ucf[FLOW]);
|
||||
}
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
// else find the demand entry and set demand
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_base_demand(lnode, baseDemand / p->Ucf[FLOW]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2849,9 +2818,7 @@ int DLLEXPORT EN_getdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
char *temp = NULL;
|
||||
char *temp = NULL;
|
||||
|
||||
strcpy(demandName, "");
|
||||
|
||||
@@ -2860,22 +2827,20 @@ int DLLEXPORT EN_getdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Njuncs) return 203;
|
||||
|
||||
// Locate demand category record and retrieve its name
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
temp = get_category_name(lnode);
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
if (dlist) {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
temp = get_category_name(lnode);
|
||||
|
||||
//for (d = p->network.Node[nodeIndex].D;
|
||||
// n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
//if (n != demandIndex) return 253;
|
||||
|
||||
if (temp) {
|
||||
strcpy(demandName, temp);
|
||||
//else demandName[0] = '\0';
|
||||
free(temp);
|
||||
}
|
||||
if (temp) {
|
||||
strcpy(demandName, temp);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
else return 253;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2892,31 +2857,29 @@ int DLLEXPORT EN_setdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Njuncs) return 203;
|
||||
|
||||
// Check that demandName is not too long
|
||||
if (strlen(demandName) > MAXID) return 250;
|
||||
// Check that demandName is not too long
|
||||
if (strlen(demandName) > MAXID) return 252;
|
||||
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(0, 0, demandName);
|
||||
if (!dlist) return 101;
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(0, 0, demandName);
|
||||
if (!dlist) return 101;
|
||||
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_category_name(lnode, demandName);
|
||||
}
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_category_name(lnode, demandName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2932,20 +2895,17 @@ int DLLEXPORT EN_getdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return 203;
|
||||
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
*patIndex = get_pattern_index(lnode);
|
||||
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
*patIndex = get_pattern_index(lnode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2964,9 +2924,6 @@ int DLLEXPORT EN_setdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
{
|
||||
Network *net = &p->network;
|
||||
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > net->Nnodes) return 203;
|
||||
@@ -2975,20 +2932,20 @@ int DLLEXPORT EN_setdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
// Locate demand category record and assign time pattern to it
|
||||
if (nodeIndex <= net->Njuncs) {
|
||||
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(0, patIndex, NULL);
|
||||
if (!dlist) return 101;
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
if (!dlist) {
|
||||
dlist = create_demand_list(0, patIndex, NULL);
|
||||
if (!dlist) return 101;
|
||||
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_pattern_index(lnode, patIndex);
|
||||
}
|
||||
p->network.Node[nodeIndex].D = dlist;
|
||||
}
|
||||
else {
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_pattern_index(lnode, patIndex);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3000,13 +2957,13 @@ int DLLEXPORT EN_setdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
char *fromNode, char *toNode)
|
||||
char *fromNode, char *toNode, int *index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: id = link ID name
|
||||
** type = link type (see EN_LinkType)
|
||||
** fromNode = name of link's starting node
|
||||
** toNode = name of link's ending node
|
||||
** Output: none
|
||||
** Output: index = position of new link in Link array
|
||||
** Returns: error code
|
||||
** Purpose: adds a new link to a project
|
||||
**----------------------------------------------------------------
|
||||
@@ -3021,11 +2978,12 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
Spump *pump;
|
||||
|
||||
// Cannot modify network structure while solvers are active
|
||||
*index = 0;
|
||||
if (!p->Openflag) return 102;
|
||||
if (p->hydraul.OpenHflag || p->quality.OpenQflag) return 262;
|
||||
|
||||
// Check if id contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
// Check if a link with same id already exists
|
||||
if (EN_getlinkindex(p, id, &i) == 0) return 215;
|
||||
@@ -3038,9 +2996,6 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
n2 = hashtable_find(net->NodeHashTable, toNode);
|
||||
if (n1 == 0 || n2 == 0) return 203;
|
||||
|
||||
// Check that id name is not too long
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
|
||||
// Check that valve link has legal connections
|
||||
if (linkType > PUMP)
|
||||
{
|
||||
@@ -3050,6 +3005,7 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
|
||||
// Grow link-related arrays to accomodate the new link
|
||||
net->Nlinks++;
|
||||
p->parser.MaxLinks = net->Nlinks;
|
||||
n = net->Nlinks;
|
||||
size = (n + 1) * sizeof(Slink);
|
||||
net->Link = (Slink *)realloc(net->Link, size);
|
||||
@@ -3129,6 +3085,7 @@ int DLLEXPORT EN_addlink(EN_Project p, char *id, int linkType,
|
||||
link->Comment = NULL;
|
||||
|
||||
hashtable_insert(net->LinkHashTable, link->ID, n);
|
||||
*index = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3282,13 +3239,10 @@ int DLLEXPORT EN_setlinkid(EN_Project p, int index, char *newid)
|
||||
*/
|
||||
{
|
||||
Network *net = &p->network;
|
||||
size_t n;
|
||||
|
||||
// Check for valid arguments
|
||||
if (index <= 0 || index > net->Nlinks) return 204;
|
||||
n = strlen(newid);
|
||||
if (n < 1 || n > MAXID) return 211;
|
||||
if (!cstr_isvalid(newid)) return 252;
|
||||
if (!namevalid(newid)) return 252;
|
||||
|
||||
// Check if another link with same name exists
|
||||
if (hashtable_find(net->LinkHashTable, newid) > 0) return 215;
|
||||
@@ -3386,10 +3340,7 @@ int DLLEXPORT EN_setlinktype(EN_Project p, int *index, int linkType, int actionC
|
||||
EN_deletelink(p, i, actionCode);
|
||||
|
||||
// Create a new link of new type and old id
|
||||
errcode = EN_addlink(p, id, linkType, id1, id2);
|
||||
|
||||
// Find the index of this new link
|
||||
EN_getlinkindex(p, id, index);
|
||||
errcode = EN_addlink(p, id, linkType, id1, id2, index);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
@@ -4039,11 +3990,8 @@ int DLLEXPORT EN_addpattern(EN_Project p, char *id)
|
||||
if (!p->Openflag) return 102;
|
||||
if (EN_getpatternindex(p, id, &i) == 0) return 215;
|
||||
|
||||
// Check is id name contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
|
||||
// Check that id name is not too long
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
// Expand the project's array of patterns
|
||||
n = net->Npats + 1;
|
||||
@@ -4166,10 +4114,8 @@ int DLLEXPORT EN_setpatternid(EN_Project p, int index, char *id)
|
||||
if (!p->Openflag) return 102;
|
||||
if (index < 1 || index > p->network.Npats) return 205;
|
||||
|
||||
// Check is id name contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
for (i = 1; i <= p->network.Npats; i++)
|
||||
{
|
||||
@@ -4315,11 +4261,8 @@ int DLLEXPORT EN_addcurve(EN_Project p, char *id)
|
||||
if (!p->Openflag) return 102;
|
||||
if (EN_getcurveindex(p, id, &i) == 0) return 215;
|
||||
|
||||
// Check is id name contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
|
||||
// Check that id name is not too long
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
// Expand the array of curves
|
||||
n = net->Ncurves + 1;
|
||||
@@ -4438,10 +4381,9 @@ int DLLEXPORT EN_setcurveid(EN_Project p, int index, char *id)
|
||||
if (!p->Openflag) return 102;
|
||||
if (index < 1 || index > p->network.Ncurves) return 205;
|
||||
|
||||
// Check is id name contains invalid characters
|
||||
if (!cstr_isvalid(id)) return 252;
|
||||
// Check if id name contains invalid characters
|
||||
if (!namevalid(id)) return 252;
|
||||
|
||||
if (strlen(id) > MAXID) return 250;
|
||||
for (i = 1; i <= p->network.Ncurves; i++)
|
||||
{
|
||||
if (i != index && strcmp(id, p->network.Curve[i].ID) == 0) return 215;
|
||||
|
||||
@@ -294,9 +294,9 @@ int DLLEXPORT ENsetqualtype(int qualType, char *chemName, char *chemUnits,
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddnode(char *id, int nodeType)
|
||||
int DLLEXPORT ENaddnode(char *id, int nodeType, int *index)
|
||||
{
|
||||
return EN_addnode(_defaultProject, id, nodeType);
|
||||
return EN_addnode(_defaultProject, id, nodeType, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletenode(int index, int actionCode)
|
||||
@@ -431,9 +431,9 @@ int DLLEXPORT ENsetdemandname(int nodeIndex, int demandIndex, char *demandName)
|
||||
|
||||
********************************************************************/
|
||||
|
||||
int DLLEXPORT ENaddlink(char *id, int linkType, char *fromNode, char *toNode)
|
||||
int DLLEXPORT ENaddlink(char *id, int linkType, char *fromNode, char *toNode, int *index)
|
||||
{
|
||||
return EN_addlink(_defaultProject, id, linkType, fromNode, toNode);
|
||||
return EN_addlink(_defaultProject, id, linkType, fromNode, toNode, index);
|
||||
}
|
||||
|
||||
int DLLEXPORT ENdeletelink(int index, int actionCode)
|
||||
|
||||
@@ -326,10 +326,10 @@ int EXPORT_PY_API anlys_setqualtype(Handle ph, EN_QualityType qualcode, char *ch
|
||||
|
||||
|
||||
|
||||
int EXPORT_PY_API node_add(Handle ph, char *id, EN_NodeType nodeType)
|
||||
int EXPORT_PY_API node_add(Handle ph, char *id, EN_NodeType nodeType, int *index)
|
||||
{
|
||||
handle_t *pr = (handle_t *)ph;
|
||||
return set_error(pr->error, EN_addnode(pr->project, id, nodeType));
|
||||
return set_error(pr->error, EN_addnode(pr->project, id, nodeType, index));
|
||||
}
|
||||
|
||||
int EXPORT_PY_API node_delete(Handle ph, int index, int actionCode)
|
||||
@@ -446,10 +446,10 @@ int EXPORT_PY_API dmnd_setname(Handle ph, int nodeIndex, int demandIdx, char *de
|
||||
|
||||
|
||||
|
||||
int EXPORT_PY_API link_add(Handle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode)
|
||||
int EXPORT_PY_API link_add(Handle ph, char *id, EN_LinkType linkType, char *fromNode, char *toNode, int *index)
|
||||
{
|
||||
handle_t *pr = (handle_t *)ph;
|
||||
return set_error(pr->error, EN_addlink(pr->project, id, linkType, fromNode, toNode));
|
||||
return set_error(pr->error, EN_addlink(pr->project, id, linkType, fromNode, toNode, index));
|
||||
}
|
||||
|
||||
int EXPORT_PY_API link_delete(Handle ph, int index, int actionCode)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/03/2019
|
||||
Last Updated: 04/18/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef FUNCS_H
|
||||
@@ -44,6 +44,7 @@ int resizecurve(Scurve *, int);
|
||||
int getcomment(Network *, int, int, char *);
|
||||
int setcomment(Network *, int, int, const char *);
|
||||
|
||||
int namevalid(const char *);
|
||||
char *getTmpName(char *);
|
||||
char *xstrcpy(char **, const char *, const size_t n);
|
||||
int strcomp(const char *, const char *);
|
||||
|
||||
@@ -122,42 +122,44 @@ void saveauxdata(Project *pr, FILE *f)
|
||||
}
|
||||
|
||||
|
||||
void write_demands(Project *pr, FILE *f) {
|
||||
int i, j;
|
||||
|
||||
Snode *node = NULL;
|
||||
list_node_t *lnode = NULL;
|
||||
char *temp = NULL;
|
||||
|
||||
char s[MAXLINE + 1],
|
||||
s1[MAXLINE + 1];
|
||||
void write_demands(Project *pr, FILE *f) {
|
||||
int i, j;
|
||||
|
||||
double ucf = pr->Ucf[DEMAND];
|
||||
Network *net = &pr->network;
|
||||
Snode *node = NULL;
|
||||
list_node_t *lnode = NULL;
|
||||
char *temp = NULL;
|
||||
|
||||
fprintf(f, "\n\n");
|
||||
fprintf(f, s_DEMANDS);
|
||||
char s[MAXLINE + 1],
|
||||
s1[MAXLINE + 1];
|
||||
|
||||
for (i = 1; i <= net->Njuncs; i++) {
|
||||
node = &net->Node[i];
|
||||
if (node->D) {
|
||||
for (lnode = first_list(node->D); done_list(lnode); lnode = next_list(lnode)) {
|
||||
sprintf(s, " %-31s %14.6f", node->ID, ucf * 100.0); // get_base_demand(lnode));
|
||||
double ucf = pr->Ucf[DEMAND];
|
||||
Network *net = &pr->network;
|
||||
|
||||
if
|
||||
((j = get_pattern_index(lnode)) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
else
|
||||
strcpy(s1, " ");
|
||||
fprintf(f, "\n\n");
|
||||
fprintf(f, s_DEMANDS);
|
||||
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
for (i = 1; i <= net->Njuncs; i++) {
|
||||
node = &net->Node[i];
|
||||
if (node->D) {
|
||||
for (lnode = first_list(node->D); done_list(lnode); lnode = next_list(lnode)) {
|
||||
if (lnode) {
|
||||
sprintf(s, " %-31s %14.6f", node->ID, ucf * get_base_demand(lnode));
|
||||
|
||||
if (temp = get_category_name(lnode)) {
|
||||
fprintf(f, " ;%s", temp);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if
|
||||
((j = get_pattern_index(lnode)) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
else
|
||||
strcpy(s1, " ");
|
||||
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
|
||||
if (temp = get_category_name(lnode)) {
|
||||
fprintf(f, " ;%s", temp);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,8 +371,8 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
|
||||
|
||||
// Write [DEMANDS] section
|
||||
write_demands(pr, f);
|
||||
|
||||
write_demands(pr, f);
|
||||
|
||||
|
||||
// Write [EMITTERS] section
|
||||
fprintf(f, "\n\n");
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
Last Updated: 04/03/2019
|
||||
Last Updated: 04/20/2019
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
@@ -819,7 +819,7 @@ void adjustpatterns(Network *network, int index)
|
||||
Psource source;
|
||||
|
||||
// Adjust patterns used by junctions
|
||||
for (j = 1; j <= network->Njuncs; j++)
|
||||
for (j = 1; j <= network->Nnodes; j++)
|
||||
{
|
||||
// Adjust demand patterns
|
||||
list_t *dlist = network->Node[j].D;
|
||||
@@ -1003,6 +1003,18 @@ int setcomment(Network *network, int object, int index, const char *newcomment)
|
||||
}
|
||||
}
|
||||
|
||||
int namevalid(const char *name)
|
||||
//----------------------------------------------------------------
|
||||
// Input: name = name used to ID an object
|
||||
// Output: returns TRUE if name is valid, FALSE if not
|
||||
// Purpose: checks that an object's ID name is valid.
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
size_t n = strlen(name);
|
||||
if (n < 1 || n > MAXID || strpbrk(name, " ;") || name[0] == '"') return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *getTmpName(char *fname)
|
||||
//----------------------------------------------------------------
|
||||
// Input: fname = file name string
|
||||
@@ -1042,33 +1054,37 @@ char *xstrcpy(char **s1, const char *s2, const size_t n)
|
||||
// n = maximum size of strings
|
||||
// Output: none
|
||||
// Purpose: like strcpy except for dynamic strings.
|
||||
// Note: The calling program is responsible for ensuring that
|
||||
// s1 points to a valid memory location or is NULL. E.g.,
|
||||
// the following code will likely cause a segment fault:
|
||||
// char *s;
|
||||
// s = xstrcpy(s, "Some text");
|
||||
// while this would work correctly:
|
||||
// char *s = NULL;
|
||||
// s = xstrcpy(s, "Some text");
|
||||
//----------------------------------------------------------------
|
||||
{
|
||||
size_t n1 = 0, n2;
|
||||
size_t n1 = 0, n2 = 0;
|
||||
|
||||
// Find size of source string
|
||||
if (s2) n2 = strlen(s2);
|
||||
if (n2 > n) n2 = n;
|
||||
|
||||
// Source string is empty -- free destination string
|
||||
if (s2 == NULL || strlen(s2) == 0)
|
||||
if (n2 == 0)
|
||||
{
|
||||
free(*s1);
|
||||
*s1 = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Source string not empty -- overwrite destination string
|
||||
else
|
||||
{
|
||||
// See if size of destination string needs to grow
|
||||
if (*s1) n1 = strlen(*s1);
|
||||
if ((n2 = strlen(s2)) > n) n2 = n;
|
||||
if (n2 > n1)
|
||||
{
|
||||
free(*s1);
|
||||
*s1 = (char *)malloc((n2 + 1) * sizeof(char));
|
||||
}
|
||||
// See if size of destination string needs to grow
|
||||
if (*s1) n1 = strlen(*s1);
|
||||
if (n2 > n1) *s1 = realloc(*s1, (n2 + 1) * sizeof(char));
|
||||
|
||||
// Copy the new comment string into the existing one
|
||||
if (*s1) strcpy(*s1, s2);
|
||||
return *s1;
|
||||
}
|
||||
// Copy the source string into the destination string
|
||||
strcpy(*s1, s2);
|
||||
return *s1;
|
||||
}
|
||||
|
||||
int strcomp(const char *s1, const char *s2)
|
||||
|
||||
@@ -237,7 +237,7 @@ void writesummary(Project *pr)
|
||||
Parser *parser = &pr->parser;
|
||||
Times *time = &pr->times;
|
||||
|
||||
char s[MAXFNAME + 1];
|
||||
char s[MAXLINE + 1];
|
||||
int i;
|
||||
int nres = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user