Merge branch 'dev-2.1' into doxy-trial

# Conflicts fixed:
#	include/epanet2.h
#	src/epanet.c
This commit is contained in:
sam hatchett
2015-11-28 13:22:45 -05:00
11 changed files with 274 additions and 90 deletions

View File

@@ -41,10 +41,13 @@ runcmdname = runepanet2.sh
epanetincludedir = ../../include
# Search path for sources
epanetsrcdir = ../../src
VPATH = $(epanetsrcdir):$(epanetincludedir)
epanetrundir = ../../run
VPATH = $(epanetsrcdir):$(epanetincludedir):$(epanetrundir)
# Install directories
prefix = ~
#prefix = /usr/local # GNU standard -- requires superuser rights
prefix =~
#
exec_prefix = $(prefix)
libdir = $(exec_prefix)/lib
bindir = $(exec_prefix)/bin
@@ -66,11 +69,11 @@ INSTALL_DATA = $(INSTALL) -m 644
# Files for the shared object library
epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \
input3.o mempool.o output.o quality.o report.o \
rules.o smatrix.o
rules.o smatrix.o epanet.o
# Epanet header files
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h types.h vars.h
# Epanet main program
epanet_main=epanet
epanet_main=main
# Epanet main program header files
epanet_main_heads=epanet2.h
@@ -78,11 +81,9 @@ epanet_main_heads=epanet2.h
all: $(libname) $(exename)
$(libname): $(epanet_objs)
$(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^
$(exename): $(libname) $(epanet_main_heads)
$(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c
$(exename): $(epanet_main).o $(epanet_main_heads)
$(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS)
$(epanet_objs): $(epanet_heads)
@@ -95,7 +96,7 @@ install:
$(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename)
$(INSTALL_PROGRAM) -D $(libname) $(libdir)/$(libname)
$(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h
$(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname)
$(INSTALL_PROGRAM) -D $(runcmdname) ~/$(runcmdname)
.PHONY: uninstall
uninstall:

View File

@@ -0,0 +1,3 @@
#!/bin/sh
export LD_LIBRARY_PATH=libdir:$LD_LIBRARY_PATH
exec exename $*

78
build/MinGW/Makefile Normal file
View File

@@ -0,0 +1,78 @@
# MINGW32 Makefile for EPANET
# This will build EPANET as DLL
# (epanet2.dll) under MINGW32 GCC, and a standalone
# executable (epanet2d.exe).
# The following targets are defined:
# make
# -Builds epanet2.dll, epanet2d.exe
# make install
# -Copy epanet2.dll, epanet2d.exe, epanet2.def to $(prefix)
# make clean
# -Removes object and library files, returning the build directory
# to its pristine state.
# You may wish to change the install path 'prefix',
# or the compiler flags, but these defaults should be fine.
# Target filenames
epanetrootname := epanet2
libname := $(epanetrootname).dll
exename := $(epanetrootname)d.exe
# Location of EPANET toolkit includes
epanetincludedir = ../../include
# Search path for sources
epanetsrcdir = ../../src
# Search path for sources
epanetmainsrcdir = ../../run
VPATH = $(epanetsrcdir):$(epanetincludedir):$(epanetmainsrcdir)
# Install directories
prefix = C:\discoD\EPA\EPAnet_util
execdir = $(prefix)
libdir = $(prefix)
# Compiler and flags
CC = gcc
CFLAGS = -g -O3 -std=c99 -Wno-implicit-function-declaration -D DLL
CPPFLAGS = -I $(epanetincludedir) -I $(epanetsrcdir)
LDFLAGS = -L . -Wl,--kill-at,--enable-stdcall-fixup,-rpath,$(libdir) -lm
# Files for the shared object library
epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \
input3.o mempool.o output.o quality.o report.o \
rules.o smatrix.o epanet.o
# Epanet header files
epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h types.h vars.h epanet2.h
# Epanet main program
epanet_main=main
# Epanet main program header files
epanet_main_heads=epanet2.h
.PHONY: all
all: $(libname) $(exename)
$(libname): $(epanet_objs)
$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $^ -Wl,--output-def,$(epanetrootname).def
$(exename): $(epanet_main_heads) $(libname) $(epanet_main).o
$(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS)
$(epanet_objs): $(epanet_heads)
.PHONY: clean
clean:
del $(epanet_main).o $(epanet_objs) $(exename) $(libname) $(epanetrootname).def
.PHONY: install
install:
copy $(exename) $(execdir)
copy $(libname) $(libdir)
copy $(epanetrootname).def $(libdir)

View File

@@ -66,7 +66,7 @@ EXPORTS
ENgetqualinfo = _ENgetqualinfo@16
ENsetbasedemand = _ENsetbasedemand@12
ENgetaveragepatternvalue = _ENgetaveragepatternvalue@8
ENgetheadcurve = _ENgetheadcurve@8
ENgetheadcurveindex = _ENgetheadcurveindex@8
ENgetpumptype = _ENgetpumptype@8
ENgetcurveindex = _ENgetcurveindex@8
ENgetcurveid = _ENgetcurveid@8

View File

@@ -59,6 +59,8 @@
2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; };
2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; };
2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; };
225762C51C068A3900484EC7 /* Net1.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 225762C31C068A2A00484EC7 /* Net1.inp */; };
225762C61C068A3B00484EC7 /* Net2.inp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 225762C41C068A2A00484EC7 /* Net2.inp */; };
226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; };
22CD9A5E1B27898E00B65E83 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 22CD9A5D1B27898E00B65E83 /* main.c */; };
22CD9A611B278BB900B65E83 /* libepanet-static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2255753B17551217009946B1 /* libepanet-static.a */; };
@@ -89,6 +91,8 @@
dstSubfolderSpec = 6;
files = (
223109E61BA865930030AAE8 /* Net3.inp in CopyFiles */,
225762C51C068A3900484EC7 /* Net1.inp in CopyFiles */,
225762C61C068A3B00484EC7 /* Net2.inp in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -106,8 +110,6 @@
/* Begin PBXFileReference section */
223109E31BA8658A0030AAE8 /* Net3.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net3.inp; path = "../../example-networks/Net3.inp"; sourceTree = "<group>"; };
223109E41BA8658A0030AAE8 /* sampletown.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = sampletown.inp; path = "../../example-networks/sampletown.inp"; sourceTree = "<group>"; };
223109E51BA8658A0030AAE8 /* simplenet.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = simplenet.inp; path = "../../example-networks/simplenet.inp"; sourceTree = "<group>"; };
223109F31BA869DA0030AAE8 /* runepanet copy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "runepanet copy"; sourceTree = BUILT_PRODUCTS_DIR; };
22310A091BA869F30030AAE8 /* libepanet-static copy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static copy.a"; sourceTree = BUILT_PRODUCTS_DIR; };
22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -133,6 +135,8 @@
22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../src/vars.h; sourceTree = SOURCE_ROOT; };
22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = epanet2.h; path = ../../include/epanet2.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
2255753B17551217009946B1 /* libepanet-static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static.a"; sourceTree = BUILT_PRODUCTS_DIR; };
225762C31C068A2A00484EC7 /* Net1.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net1.inp; path = "../../example-networks/Net1.inp"; sourceTree = "<group>"; };
225762C41C068A2A00484EC7 /* Net2.inp */ = {isa = PBXFileReference; lastKnownFileType = text; name = Net2.inp; path = "../../example-networks/Net2.inp"; sourceTree = "<group>"; };
22CD9A5D1B27898E00B65E83 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = main.c; path = ../../run/main.c; sourceTree = "<group>"; };
D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -233,8 +237,8 @@
isa = PBXGroup;
children = (
223109E31BA8658A0030AAE8 /* Net3.inp */,
223109E41BA8658A0030AAE8 /* sampletown.inp */,
223109E51BA8658A0030AAE8 /* simplenet.inp */,
225762C31C068A2A00484EC7 /* Net1.inp */,
225762C41C068A2A00484EC7 /* Net2.inp */,
);
name = "sample networks";
sourceTree = "<group>";

View File

@@ -140,6 +140,10 @@ Global Const EN_SAVE = 1
Global Const EN_INITFLOW = 10 ' Re-initialize flow flag
Global Const EN_CONST_HP = 0 ' constant horsepower
Global Const EN_POWER_FUNC = 1 ' power function
Global Const EN_CUSTOM = 2 ' user-defined custom curve
'These are the external functions that comprise the DLL
Declare Function ENepanet Lib "epanet2.dll" (ByVal F1 As String, ByVal F2 As String, ByVal F3 As String, ByVal F4 As Any) As Long
@@ -202,7 +206,7 @@ Global Const EN_INITFLOW = 10 ' Re-initialize flow flag
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal Index As Long, ByVal Code As Long, Value As Single) As Long
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal CurveIndex As Long, ByVal CurveID As String, nValues As Long, xValues As Any, yValues As Any) As Long
Declare Function ENgetheadcurve Lib "epanet2.dll" (ByVal Index As Long, ByVal ID As String) As Long
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal PumpIndex As Long, ByVal CurveIndex As Long) As Long
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal Index As Long, PumpType As Long) As Long
Declare Function ENgetversion Lib "epanet2.dll" (Value As Long) As Long

View File

@@ -60,6 +60,7 @@
#endif
#endif
// --- Define the EPANET toolkit constants
/// Node property codes
@@ -159,26 +160,33 @@ typedef enum {
} EN_LinkType;
#define EN_NONE 0 /* Quality analysis types. */
#define EN_CHEM 1 /* See QualType in TYPES.H */
#define EN_AGE 2
#define EN_TRACE 3
typedef enum {
EN_NONE = 0, /* Quality analysis types. */
EN_CHEM = 1, /* See QualType in TYPES.H */
EN_AGE = 2,
EN_TRACE = 3
} EN_QualityType;
#define EN_CONCEN 0 /* Source quality types. */
#define EN_MASS 1 /* See SourceType in TYPES.H. */
#define EN_SETPOINT 2
#define EN_FLOWPACED 3
typedef enum {
EN_CONCEN = 0, /* Source quality types. */
EN_MASS = 1, /* See SourceType in TYPES.H. */
EN_SETPOINT = 2,
EN_FLOWPACED = 3
} EN_SourceType;
typedef enum {
EN_CFS = 0, /* Flow units types. */
EN_GPM = 1, /* See FlowUnitsType */
EN_MGD = 2, /* in TYPES.H. */
EN_IMGD = 3,
EN_AFD = 4,
EN_LPS = 5,
EN_LPM = 6,
EN_MLD = 7,
EN_CMH = 8,
EN_CMD = 9
} EN_FlowUnits;
#define EN_CFS 0 /* Flow units types. */
#define EN_GPM 1 /* See FlowUnitsType */
#define EN_MGD 2 /* in TYPES.H. */
#define EN_IMGD 3
#define EN_AFD 4
#define EN_LPS 5
#define EN_LPM 6
#define EN_MLD 7
#define EN_CMH 8
#define EN_CMD 9
/// Simulation Option codes
typedef enum {
@@ -189,26 +197,47 @@ typedef enum {
EN_DEMANDMULT = 4
} EN_Option;
typedef enum {
EN_LOWLEVEL = 0, /* Control types. */
EN_HILEVEL = 1, /* See ControlType */
EN_TIMER = 2, /* in TYPES.H. */
EN_TIMEOFDAY = 3
} EN_ControlType;
#define EN_LOWLEVEL 0 /* Control types. */
#define EN_HILEVEL 1 /* See ControlType */
#define EN_TIMER 2 /* in TYPES.H. */
#define EN_TIMEOFDAY 3
#define EN_AVERAGE 1 /* Time statistic types. */
#define EN_MINIMUM 2 /* See TstatType in TYPES.H */
#define EN_MAXIMUM 3
#define EN_RANGE 4
#define EN_MIX1 0 /* Tank mixing models */
#define EN_MIX2 1
#define EN_FIFO 2
#define EN_LIFO 3
typedef enum {
EN_AVERAGE = 1, /* Time statistic types. */
EN_MINIMUM = 2, /* See TstatType in TYPES.H */
EN_MAXIMUM = 3,
EN_RANGE = 4
} EN_StatisticType;
#define EN_NOSAVE 0 /* Save-results-to-file flag */
#define EN_SAVE 1
#define EN_INITFLOW 10 /* Re-initialize flows flag */
typedef enum {
EN_MIX1 = 0, /* Tank mixing models */
EN_MIX2 = 1,
EN_FIFO = 2,
EN_LIFO = 3
} EN_MixingModel;
typedef enum {
EN_NOSAVE = 0,
EN_SAVE = 1,
EN_INITFLOW = 10,
EN_SAVE_AND_INIT = 11
} EN_SaveOption;
typedef enum {
EN_CONST_HP = 0, /* constant horsepower */
EN_POWER_FUNC = 1, /* power function */
EN_CUSTOM = 2 /* user-defined custom curve */
} EN_CurveType;
@@ -656,6 +685,8 @@ extern "C" {
@return Error code.
*/
int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues);
int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex);
int DLLEXPORT ENgetpumptype(int index, int *type);
/**
@brief Get the string ID of the head curve assigned to a pump.

View File

@@ -55,7 +55,7 @@ Public Const EN_STATUS = 11
Public Const EN_SETTING = 12
Public Const EN_ENERGY = 13
Public Const EN_LINKQUAL = 14 'ES
Public Const EN_LINKPATTERN 15
Public Const EN_LINKPATTERN = 15
Public Const EN_DURATION = 0 ' Time parameters
Public Const EN_HYDSTEP = 1
@@ -200,7 +200,7 @@ Public Const EN_CUSTOM = 2 ' user-defined custom curve
Declare Function ENgetlinkvalue Lib "epanet2.dll" (ByVal Index As Int32, ByVal Code As Int32, ByRef Value As Single) As Int32
Declare Function ENgetcurve Lib "epanet2.dll" (ByVal CurveIndex As Int32, ByRef nValues As Int32, ByRef xValues As Single, ByRef yValues As Single) As Int32 'ES
Declare Function ENgetheadcurve Lib "epanet2.dll" (ByVal Index As Int32, ByVal ID As StringBuilder) As Int32 'ES
Declare Function ENgetheadcurveindex Lib "epanet2.dll" (ByVal Index As Int32, ByVal CurveIndex As int32) As Int32 'ES
Declare Function ENgetpumptype Lib "epanet2.dll" (ByVal Index As Int32, ByRef PumpType As Int32) As Int32 'ES
Declare Function ENgetversion Lib "epanet2.dll" (ByRef Value As Int32) As Int32

View File

@@ -1,10 +1,19 @@
#include <stdio.h>
#include <string.h>
#include "epanet2.h"
#include "text.h"
#define MAXMSG 79 /* Max. # characters in message text */
#define MAXWARNCODE 99
/* text copied here, no more need of include "text.h" */
#define FMT01 "\nEPANET Version %d.%d.%d\n"
#define FMT03 "\n Correct syntax is:\n epanet <input file> <output file>\n"
#define FMT09 "\nEPANET completed.\n"
#define FMT10 "\nEPANET completed. There are warnings."
#define FMT11 "\nEPANET completed. There are errors."
void writeConsole(char *s);
extern char Warnflag;
/*
----------------------------------------------------------------
@@ -23,42 +32,89 @@ int main(int argc, char *argv[])
** Command line for stand-alone operation is:
** progname f1 f2 f3
** where progname = name of executable this code was compiled to,
** f1 = name of input file, f2 = name of report file, and
** f3 = name of binary output file (optional).
** f1 = name of input file,
** f2 = name of report file (optional, stdout if left blank)
** f3 = name of binary output file (optional, nullfile if left blank).
**--------------------------------------------------------------
*/
{
char *f1,*f2,*f3;
char blank[] = "";
char errmsg[MAXMSG+1]="";
int errcode;
int version;
char s[25];
int major;
int minor;
int patch;
/* get version from DLL and trasform in Major.Minor.Patch format
instead of hardcoded version */
ENgetversion(&version);
major= version/10000;
minor= (version%10000)/100;
patch= version%100;
sprintf(s,FMT01, major , minor, patch);
writeConsole(s);
/* Check for proper number of command line arguments */
if (argc < 3) {
if (argc < 2) {
writeConsole(FMT03);
return(1);
}
/* set inputfile name */
f1 = argv[1];
if (argc > 2) {
/* set rptfile name */
f2 = argv[2];
}
else {
/* Call the main control function */
f1 = argv[1];
f2 = argv[2];
if (argc > 3) {
f3 = argv[3];
}
else {
f3 = blank;
}
writeConsole(FMT01);
errcode = ENepanet(f1,f2,f3,NULL);
if (errcode > 0) {
writeConsole(FMT11);
}
else if (Warnflag > 0) {
writeConsole(FMT10);
}
else {
writeConsole(FMT09);
}
/* use stdout for rptfile */
f2 = blank;
}
return(0);
if (argc > 3) {
/* set binary output file name */
f3 = argv[3];
}
else {
/* NO binary output*/
f3 = blank;
}
/* Call the main control function */
if (strlen(f2)> 0) {
/* use stdout for progress messages */
errcode = ENepanet(f1,f2,f3,writeConsole);
}
else {
/* use stdout for reporting, no progress messages */
errcode = ENepanet(f1,f2,f3,NULL);
}
/* Error/Warning check */
if (errcode == 0) {
/* no errors */
writeConsole(FMT09);
return(0);
}
else {
ENgeterror(errcode, errmsg, MAXMSG);
writeConsole(errmsg);
if (errcode > MAXWARNCODE) {
/* error */
writeConsole(FMT11);
return(errcode);
}
else {
/* warning */
writeConsole(FMT10);
return(0);
}
}
} /* End of main */
@@ -70,6 +126,8 @@ void writeConsole(char *s)
**----------------------------------------------------------------
*/
{
fprintf(stdout,"%s",s);
fprintf(stdout,"%s\n",s);
fflush(stdout);
}

View File

@@ -180,7 +180,7 @@ int DLLEXPORT ENepanet(char *f1, char *f2, char *f3, void (*pviewprog) (char *))
ERRCODE(ENsolveQ());
ERRCODE(ENreport());
ENclose();
return(errcode);
return(MAX(errcode, Warnflag) );
}
@@ -290,7 +290,7 @@ int DLLEXPORT ENclose()
} //(2.00.12 - LR)
if (InFile != NULL) { fclose(InFile); InFile=NULL; }
if (RptFile != NULL) { fclose(RptFile); RptFile=NULL; }
if (RptFile != NULL && RptFile != stdout) { fclose(RptFile); RptFile=NULL; }
if (HydFile != NULL) { fclose(HydFile); HydFile=NULL; }
if (OutFile != NULL) { fclose(OutFile); OutFile=NULL; }
@@ -2397,25 +2397,31 @@ int DLLEXPORT ENsetqualtype(int qualcode, char *chemname,
return(0);
}
int DLLEXPORT ENgetheadcurve(int index, char *id)
int DLLEXPORT ENgetheadcurveindex(int index, int *curveindex)
/*----------------------------------------------------------------
** Input: index = index of pump in list of links
** Output: id = head curve ID
** Output: curveindex = head curve index
** Returns: error code
** Purpose: retrieves ID of a head curve for specific link index
** Purpose: retrieves index of a head curve for specific link index
**
** NOTE: 'id' must be able to hold MAXID characters
**----------------------------------------------------------------
*/
{
strcpy(id,"");
if (!Openflag) return(102);
if (index < 1 || index > Nlinks || PUMP != Link[index].Type) return(204);
strcpy(id,Curve[Pump[PUMPINDEX(index)].Hcurve].ID);
*curveindex = Pump[PUMPINDEX(index)].Hcurve;
return(0);
}
int DLLEXPORT ENgetpumptype(int index, int *type)
/*----------------------------------------------------------------
** Input: index = index of pump in list of links
** Output: type = Pump type
** Returns: error code
** Purpose: retrieves type of a pump for specific link index
**
**----------------------------------------------------------------
*/
{
*type=-1;
if (!Openflag) return(102);
@@ -3124,8 +3130,8 @@ void writecon(char *s)
*/
{
//(2.00.11 - LR)
fprintf(stdout,s);
fflush(stdout);
//fprintf(stdout,s);
//fflush(stdout);
}
@@ -3139,14 +3145,12 @@ void writewin(char *s)
**----------------------------------------------------------------
*/
{
#ifdef DLL
char progmsg[MAXMSG+1];
if (viewprog != NULL)
{
strncpy(progmsg,s,MAXMSG);
viewprog(progmsg);
}
#endif
}

View File

@@ -503,6 +503,7 @@ int savefinaloutput()
ERRCODE(savetimestat(x,LINKHDR));
if (!errcode) Nperiods = 1;
fclose(TmpOutFile);
TmpOutFile=NULL;
free(x);
}