Files
EPANET/src/input2.c
Tom Taxon 3336c4119c All files in this commit: Added ifdef for Apple compilation - it does not have a malloc.h include file.
epanet.c
reset file variables to NULL so if the code is executed again without termination, the variables will be in a valid initial state.

Added retrieval of EN_STARTTIME to ENgettimeparam.
Added retrieval of EN_TANKVOLUME to ENgetnodevalue
Added retrieval of EN_LINKQUAL to ENgetlinkvalue
Fixed the check for identical filenames so it now allows for an empty (not generated) report file and outfile.
Added ENgetbasedemand and ENgetdemandpattern functions

input2.c
Fixed some compiler warnings


git-svn-id: https://epanet.svn.sourceforge.net/svnroot/epanet/BASE/trunk@424 c320cabd-cc23-0410-96d8-e60fbf53ed7f
2011-12-06 18:25:02 +00:00

969 lines
28 KiB
C
Executable File

/*
**********************************************************************
INPUT2.C -- Input data file interpreter for EPANET
VERSION: 2.00
DATE: 5/30/00
9/7/00
10/25/00
AUTHOR: L. Rossman
US EPA - NRMRL
This module reads and interprets the input data from file InFile.
The entry points for this module are:
netsize() -- called from ENopen() in EPANET.C
readdata() -- called from getdata() in INPUT1.C
The following utility functions are all called from INPUT3.C
addnodeID()
addlinkID()
findID()
getfloat()
**********************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifndef __APPLE__
#include <malloc.h>
#endif
#include <math.h>
#include "hash.h"
#include "text.h"
#include "types.h"
#include "funcs.h"
#define EXTERN extern
#include "vars.h"
#define MAXERRS 10 /* Max. input errors reported */
int Ntokens, /* Number of tokens in input line */
Ntitle; /* Number of title lines */
char *Tok[MAXTOKS]; /* Array of token strings */
/* Used in INPUT3.C: */
STmplist *PrevPat; /* Pointer to pattern list element */
STmplist *PrevCurve; /* Pointer to curve list element */
/* Defined in enumstxt.h in EPANET.C */
extern char *SectTxt[]; /* Input section keywords */
extern char *RptSectTxt[];
int netsize()
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: determines number of system components
**--------------------------------------------------------------
*/
{
char line[MAXLINE+1]; /* Line from input data file */
char *tok; /* First token of line */
int sect,newsect; /* Input data sections */
int errcode = 0; /* Error code */
/* Initialize network component counts */
MaxJuncs = 0;
MaxTanks = 0;
MaxPipes = 0;
MaxPumps = 0;
MaxValves = 0;
MaxControls = 0;
MaxRules = 0;
MaxCurves = 0;
sect = -1;
/* Add a default pattern 0 */
MaxPats = -1;
addpattern("");
/* Make pass through data file counting number of each component */
while (fgets(line,MAXLINE,InFile) != NULL)
{
/* Skip blank lines & those beginning with a comment */
tok = strtok(line,SEPSTR);
if (tok == NULL) continue;
if (*tok == ';') continue;
/* Check if line begins with a new section heading */
if (*tok == '[')
{
newsect = findmatch(tok,SectTxt);
if (newsect >= 0)
{
sect = newsect;
if (sect == _END) break;
continue;
}
else continue;
}
/* Add to count of current component */
switch(sect)
{
case _JUNCTIONS: MaxJuncs++; break;
case _RESERVOIRS:
case _TANKS: MaxTanks++; break;
case _PIPES: MaxPipes++; break;
case _PUMPS: MaxPumps++; break;
case _VALVES: MaxValves++; break;
case _CONTROLS: MaxControls++; break;
case _RULES: addrule(tok); break; /* See RULES.C */
case _PATTERNS: errcode = addpattern(tok);
break;
case _CURVES: errcode = addcurve(tok);
break;
}
if (errcode) break;
}
MaxNodes = MaxJuncs + MaxTanks;
MaxLinks = MaxPipes + MaxPumps + MaxValves;
if (MaxPats < 1) MaxPats = 1;
if (!errcode)
{
if (MaxJuncs < 1) errcode = 223; /* Not enough nodes */
else if (MaxTanks == 0) errcode = 224; /* No tanks */
}
return(errcode);
} /* End of netsize */
int readdata()
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: reads contents of input data file
**--------------------------------------------------------------
*/
{
char line[MAXLINE+1], /* Line from input data file */
wline[MAXLINE+1]; /* Working copy of input line */
int sect,newsect, /* Data sections */
errcode = 0, /* Error code */
inperr,errsum; /* Error code & total error count */
/* Allocate input buffer */
X = (double *) calloc(MAXTOKS, sizeof(double));
ERRCODE(MEMCHECK(X));
if (!errcode)
{
/* Initialize number of network components */
Ntitle = 0;
Nnodes = 0;
Njuncs = 0;
Ntanks = 0;
Nlinks = 0;
Npipes = 0;
Npumps = 0;
Nvalves = 0;
Ncontrols = 0;
Nrules = 0;
Ncurves = MaxCurves;
Npats = MaxPats;
PrevPat = NULL;
PrevCurve = NULL;
sect = -1;
errsum = 0;
/* Read each line from input file. */
while (fgets(line,MAXLINE,InFile) != NULL)
{
/* Make copy of line and scan for tokens */
strcpy(wline,line);
Ntokens = gettokens(wline);
/* Skip blank lines and comments */
if (Ntokens == 0) continue;
if (*Tok[0] == ';') continue;
/* Check if max. length exceeded */
if (strlen(line) >= MAXLINE)
{
sprintf(Msg,ERR214);
writeline(Msg);
writeline(line);
errsum++;
}
/* Check if at start of a new input section */
if (*Tok[0] == '[')
{
newsect = findmatch(Tok[0],SectTxt);
if (newsect >= 0)
{
sect = newsect;
if (sect == _END) break;
continue;
}
else
{
inperrmsg(201,sect,line);
errsum++;
break;
}
}
/* Otherwise process next line of input in current section */
else
{
inperr = newline(sect,line);
if (inperr > 0)
{
inperrmsg(inperr,sect,line);
errsum++;
}
}
/* Stop if reach end of file or max. error count */
if (errsum == MAXERRS) break;
} /* End of while */
/* Check for errors */
if (errsum > 0) errcode = 200;
}
/* Check for unlinked nodes */
if (!errcode) errcode = unlinked();
/* Get pattern & curve data from temp. lists */
if (!errcode) errcode = getpatterns();
if (!errcode) errcode = getcurves();
if (!errcode) errcode = getpumpparams();
/* Free input buffer */
free(X);
return(errcode);
} /* End of readdata */
int newline(int sect, char *line)
/*
**--------------------------------------------------------------
** Input: sect = current section of input file
** *line = line read from input file
** Output: returns error code or 0 if no error found
** Purpose: processes a new line of data from input file
**--------------------------------------------------------------
*/
{
int n;
switch (sect)
{
case _TITLE: if (Ntitle < 3)
{
n = (int)strlen(line);
if (line[n-1] == 10) line[n-1] = ' ';
strncpy(Title[Ntitle],line,MAXMSG);
Ntitle++;
}
return(0);
case _JUNCTIONS: return(juncdata());
case _RESERVOIRS:
case _TANKS: return(tankdata());
case _PIPES: return(pipedata());
case _PUMPS: return(pumpdata());
case _VALVES: return(valvedata());
case _PATTERNS: return(patterndata());
case _CURVES: return(curvedata());
case _DEMANDS: return(demanddata());
case _CONTROLS: return(controldata());
case _RULES: return(ruledata()); /* See RULES.C */
case _SOURCES: return(sourcedata());
case _EMITTERS: return(emitterdata());
case _QUALITY: return(qualdata());
case _STATUS: return(statusdata());
case _ROUGHNESS: return(0);
case _ENERGY: return(energydata());
case _REACTIONS: return(reactdata());
case _MIXING: return(mixingdata());
case _REPORT: return(reportdata());
case _TIMES: return(timedata());
case _OPTIONS: return(optiondata());
/* Data in these sections are not used for any computations */
case _COORDS: return(0);
case _LABELS: return(0);
case _TAGS: return(0);
case _VERTICES: return(0);
case _BACKDROP: return(0);
}
return(201);
} /* end of newline */
int getpumpparams(void)
/*
**-------------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: computes & checks pump curve parameters
**--------------------------------------------------------------
*/
{
int i, j = 0, k, m, n = 0;
double a,b,c,
h0 = 0.0, h1 = 0.0, h2 = 0.0, q1 = 0.0, q2 = 0.0;
for (i=1; i<=Npumps; i++)
{
k = Pump[i].Link;
if (Pump[i].Ptype == CONST_HP) /* Constant Hp pump */
{
Pump[i].H0 = 0.0;
Pump[i].R = -8.814*Link[k].Km;
Pump[i].N = -1.0;
Pump[i].Hmax = BIG; /* No head limit */
Pump[i].Qmax = BIG; /* No flow limit */
Pump[i].Q0 = 1.0; /* Init. flow = 1 cfs */
continue;
}
/* Set parameters for pump curves */
else if (Pump[i].Ptype == NOCURVE) /* Pump curve specified */
{
j = Pump[i].Hcurve; /* Get index of head curve */
if (j == 0)
{ /* Error: No head curve */
sprintf(Msg,ERR226,Link[k].ID);
writeline(Msg);
return(200);
}
n = Curve[j].Npts;
if (n == 1) /* Only a single h-q point */
{ /* supplied so use generic */
Pump[i].Ptype = POWER_FUNC; /* power function curve. */
q1 = Curve[j].X[0];
h1 = Curve[j].Y[0];
h0 = 1.33334*h1;
q2 = 2.0*q1;
h2 = 0.0;
}
else if (n == 3
&& Curve[j].X[0] == 0.0) /* 3 h-q points supplied with */
{ /* shutoff head so use fitted */
Pump[i].Ptype = POWER_FUNC; /* power function curve. */
h0 = Curve[j].Y[0];
q1 = Curve[j].X[1];
h1 = Curve[j].Y[1];
q2 = Curve[j].X[2];
h2 = Curve[j].Y[2];
}
else Pump[i].Ptype = CUSTOM; /* Else use custom pump curve.*/
/* Compute shape factors & limits of power function pump curves */
if (Pump[i].Ptype == POWER_FUNC)
{
if (!powercurve(h0,h1,h2,q1,q2,&a,&b,&c))
{ /* Error: Invalid curve */
sprintf(Msg,ERR227,Link[k].ID);
writeline(Msg);
return(200);
}
else
{
Pump[i].H0 = -a;
Pump[i].R = -b;
Pump[i].N = c;
Pump[i].Q0 = q1;
Pump[i].Qmax = pow((-a/b),(1.0/c));
Pump[i].Hmax = h0;
}
}
}
/* Assign limits to custom pump curves */
if (Pump[i].Ptype == CUSTOM)
{
for (m=1; m<n; m++)
{
if (Curve[j].Y[m] >= Curve[j].Y[m-1])
{ /* Error: Invalid curve */
sprintf(Msg,ERR227,Link[k].ID);
writeline(Msg);
return(200);
}
}
Pump[i].Qmax = Curve[j].X[n-1];
Pump[i].Q0 = (Curve[j].X[0] + Pump[i].Qmax)/2.0;
Pump[i].Hmax = Curve[j].Y[0];
}
} /* Next pump */
return(0);
}
int addnodeID(int n, char *id)
/*
**-------------------------------------------------------------
** Input: n = node index
** id = ID label
** Output: returns 0 if ID already in use, 1 if not
** Purpose: adds a node ID to the Node Hash Table
**--------------------------------------------------------------
*/
{
if (findnode(id)) return(0); /* see EPANET.C */
strncpy(Node[n].ID, id, MAXID);
HTinsert(Nht, Node[n].ID, n); /* see HASH.C */
return(1);
}
int addlinkID(int n, char *id)
/*
**-------------------------------------------------------------
** Input: n = link index
** id = ID label
** Output: returns 0 if ID already in use, 1 if not
** Purpose: adds a link ID to the Link Hash Table
**--------------------------------------------------------------
*/
{
if (findlink(id)) return(0); /* see EPANET.C */
strncpy(Link[n].ID, id, MAXID);
HTinsert(Lht, Link[n].ID, n); /* see HASH.C */
return(1);
}
int addpattern(char *id)
/*
**-------------------------------------------------------------
** Input: id = pattern ID label
** Output: returns error code
** Purpose: adds a new pattern to the database
**--------------------------------------------------------------
*/
{
STmplist *p;
/* Check if ID is same as last one processed */
if (Patlist != NULL && strcmp(id,Patlist->ID) == 0) return(0);
/* Check that pattern was not already created */
if (findID(id,Patlist) == NULL)
{
/* Update pattern count & create new list element */
(MaxPats)++;
p = (STmplist *) malloc(sizeof(STmplist));
if (p == NULL) return(101);
/* Initialize list element properties */
else
{
p->i = MaxPats;
strncpy(p->ID,id,MAXID);
p->x = NULL;
p->y = NULL;
p->next = Patlist;
Patlist = p;
}
}
return(0);
}
int addcurve(char *id)
/*
**-------------------------------------------------------------
** Input: id = curve ID label
** Output: returns error code
** Purpose: adds a new curve to the database
**--------------------------------------------------------------
*/
{
STmplist *c;
/* Check if ID is same as last one processed */
if (Curvelist != NULL && strcmp(id,Curvelist->ID) == 0) return(0);
/* Check that curve was not already created */
if (findID(id,Curvelist) == NULL)
{
/* Update curve count & create new list element */
(MaxCurves)++;
c = (STmplist *) malloc(sizeof(STmplist));
if (c == NULL) return(101);
/* Initialize list element properties */
else
{
c->i = MaxCurves;
strncpy(c->ID,id,MAXID);
c->x = NULL;
c->y = NULL;
c->next = Curvelist;
Curvelist = c;
}
}
return(0);
}
STmplist *findID(char *id, STmplist *list)
/*
**-------------------------------------------------------------
** Input: id = ID label
** list = pointer to head of a temporary list
** Output: returns list item with requested ID label
** Purpose: searches for item in temporary list
**-------------------------------------------------------------
*/
{
STmplist *item;
for (item = list; item != NULL; item = item->next)
{
if (strcmp(item->ID,id) == 0)
{
return(item);
}
}
return(NULL);
}
int unlinked()
/*
**--------------------------------------------------------------
** Input: none
** Output: returns error code if any unlinked junctions found
** Purpose: checks for unlinked junctions in network
**
** NOTE: unlinked tanks have no effect on computations.
**--------------------------------------------------------------
*/
{
char *marked;
int i,err, errcode;
errcode = 0;
err = 0;
marked = (char *) calloc(Nnodes+1,sizeof(char));
ERRCODE(MEMCHECK(marked));
if (!errcode)
{
memset(marked,0,(Nnodes+1)*sizeof(char));
for (i=1; i<=Nlinks; i++) /* Mark end nodes of each link */
{
marked[Link[i].N1]++;
marked[Link[i].N2]++;
}
for (i=1; i<=Njuncs; i++) /* Check each junction */
{
if (marked[i] == 0) /* If not marked then error */
{
err++;
sprintf(Msg,ERR233,Node[i].ID);
writeline(Msg);
}
if (err >= MAXERRS) break;
}
if (err > 0) errcode = 200;
}
free(marked);
return(errcode);
} /* End of unlinked */
int getpatterns(void)
/*
**-----------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: retrieves pattern data from temporary linked list
**-------------------------------------------------------------
*/
{
int i,j;
SFloatlist *f;
STmplist *pat;
/* Start at head of list */
pat = Patlist;
/* Traverse list of patterns */
while (pat != NULL)
{
/* Get index of current pattern in Pattern array */
i = pat->i;
/* Check if this is the default pattern */
if (strcmp(pat->ID, DefPatID) == 0) DefPat = i;
if (i >= 0 && i <= MaxPats)
{
/* Save pattern ID */
strcpy(Pattern[i].ID, pat->ID);
/* Give pattern a length of at least 1 */
if (Pattern[i].Length == 0) Pattern[i].Length = 1;
Pattern[i].F = (double *) calloc(Pattern[i].Length, sizeof(double));
if (Pattern[i].F == NULL) return(101);
/* Start at head of pattern multiplier list */
/* (which holds multipliers in reverse order)*/
f = pat->x;
j = Pattern[i].Length - 1;
/* Use at least one multiplier equal to 1.0 */
if (f == NULL) Pattern[i].F[0] = 1.0;
/* Traverse list, storing multipliers in Pattern array */
else while (f != NULL && j >= 0)
{
Pattern[i].F[j] = f->value;
f = f->next;
j--;
}
}
pat = pat->next;
}
return(0);
}
int getcurves(void)
/*
**-----------------------------------------------------------
** Input: none
** Output: returns error code
** Purpose: retrieves curve data from temporary linked list
**-----------------------------------------------------------
*/
{
int i,j;
double x;
SFloatlist *fx, *fy;
STmplist *c;
/* Start at head of curve list */
c = Curvelist;
/* Traverse list of curves */
while (c != NULL)
{
i = c->i;
if (i >= 1 && i <= MaxCurves)
{
/* Save curve ID */
strcpy(Curve[i].ID, c->ID);
/* Check that curve has data points */
if (Curve[i].Npts <= 0)
{
sprintf(Msg,ERR230,c->ID);
writeline(Msg);
return(200);
}
/* Allocate memory for curve data */
Curve[i].X = (double *) calloc(Curve[i].Npts, sizeof(double));
Curve[i].Y = (double *) calloc(Curve[i].Npts, sizeof(double));
if (Curve[i].X == NULL || Curve[i].Y == NULL) return(101);
/* Traverse list of x,y data */
x = BIG;
fx = c->x;
fy = c->y;
j = Curve[i].Npts - 1;
while (fx != NULL && fy != NULL && j >= 0)
{
/* Check that x data is in ascending order */
if (fx->value >= x)
{
sprintf(Msg,ERR230,c->ID);
writeline(Msg);
return(200);
}
x = fx->value;
/* Save x,y data in Curve structure */
Curve[i].X[j] = fx->value;
fx = fx->next;
Curve[i].Y[j] = fy->value;
fy = fy->next;
j--;
}
}
c = c->next;
}
return(0);
}
int findmatch(char *line, char *keyword[])
/*
**--------------------------------------------------------------
** Input: *line = line from input file
** *keyword[] = list of NULL terminated keywords
** Output: returns index of matching keyword or
** -1 if no match found
** Purpose: determines which keyword appears on input line
**--------------------------------------------------------------
*/
{
int i = 0;
while (keyword[i] != NULL)
{
if (match(line,keyword[i])) return(i);
i++;
}
return(-1);
} /* end of findmatch */
int match(char *str, char *substr)
/*
**--------------------------------------------------------------
** Input: *str = string being searched
** *substr = substring being searched for
** Output: returns 1 if substr found in str, 0 if not
** Purpose: sees if substr matches any part of str
**
** (Not case sensitive)
**--------------------------------------------------------------
*/
{
int i,j;
/*** Updated 9/7/00 ***/
/* Fail if substring is empty */
if (!substr[0]) return(0);
/* Skip leading blanks of str. */
for (i=0; str[i]; i++)
if (str[i] != ' ') break;
/* Check if substr matches remainder of str. */
for (i=i,j=0; substr[j]; i++,j++)
if (!str[i] || UCHAR(str[i]) != UCHAR(substr[j]))
return(0);
return(1);
} /* end of match */
/*** Updated 10/25/00 ***/
/* The gettokens function has been totally re-written. */
int gettokens(char *s)
/*
**--------------------------------------------------------------
** Input: *s = string to be tokenized
** Output: returns number of tokens in s
** Purpose: scans string for tokens, saving pointers to them
** in module global variable Tok[]
**
** Tokens can be separated by the characters listed in SEPSTR
** (spaces, tabs, newline, carriage return) which is defined
** in TYPES.H. Text between quotes is treated as a single token.
**--------------------------------------------------------------
*/
{
int len, m, n;
char *c;
/* Begin with no tokens */
for (n=0; n<MAXTOKS; n++) Tok[n] = NULL;
n = 0;
/* Truncate s at start of comment */
c = strchr(s,';');
if (c) *c = '\0';
len = (int)strlen(s);
/* Scan s for tokens until nothing left */
while (len > 0 && n < MAXTOKS)
{
m = (int)strcspn(s,SEPSTR); /* Find token length */
len -= m+1; /* Update length of s */
if (m == 0) s++; /* No token found */
else
{
if (*s == '"') /* Token begins with quote */
{
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 */
s += m+1; /* Begin next token */
}
}
return(n);
} /* End of gettokens */
double hour(char *time, char *units)
/*
**---------------------------------------------------------
** Input: *time = string containing a time value
** *units = string containing time units
** Output: returns numerical value of time in hours,
** or -1 if an error occurs
** Purpose: converts time from units to hours
**---------------------------------------------------------
*/
{
int n;
double y[3];
char *s;
/* Separate clock time into hrs, min, sec. */
for (n=0; n<3; n++) y[n] = 0.0;
n = 0;
s = strtok(time,":");
while (s != NULL && n <= 3)
{
if (!getfloat(s,&y[n])) return(-1.0);
s = strtok(NULL,":");
n++;
}
/* If decimal time with units attached then convert to hours. */
if (n == 1)
{
/*if (units[0] == '\0') return(y[0]);*/
if (strlen(units) == 0) return(y[0]);
if (match(units,w_SECONDS)) return(y[0]/3600.0);
if (match(units,w_MINUTES)) return(y[0]/60.0);
if (match(units,w_HOURS)) return(y[0]);
if (match(units,w_DAYS)) return(y[0]*24.0);
}
/* 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 */
/* (12 am is midnight, 12 pm is noon) */
if (units[0] == '\0') return(y[0]);
if (match(units,w_AM))
{
if (y[0] >= 13.0) return(-1.0);
if (y[0] >= 12.0) return(y[0]-12.0);
else return(y[0]);
}
if (match(units,w_PM))
{
if (y[0] >= 13.0) return(-1.0);
if (y[0] >= 12.0) return(y[0]);
else return(y[0]+12.0);
}
return(-1.0);
} /* end of hour */
int getfloat(char *s, double *y)
/*
**-----------------------------------------------------------
** Input: *s = character string
** Output: *y = floating point number
** returns 1 if conversion successful, 0 if not
** Purpose: converts string to floating point number
**-----------------------------------------------------------
*/
{
char *endptr;
*y = (double) strtod(s,&endptr);
if (*endptr > 0) return(0);
return(1);
}
int setreport(char *s)
/*
**-----------------------------------------------------------
** Input: *s = report format command
** Output: none
** Returns: error code
** Purpose: processes a report formatting command
** issued by the ENsetreport function
**-----------------------------------------------------------
*/
{
Ntokens = gettokens(s);
return(reportdata());
}
void inperrmsg(int err, int sect, char *line)
/*
**-------------------------------------------------------------
** Input: err = error code
** sect = input data section
** *line = line from input file
** Output: none
** Purpose: displays input error message
**-------------------------------------------------------------
*/
{
char fmt[MAXMSG+1];
char id[MAXMSG+1];
/* Retrieve ID label of object with input error */
/* (No ID used for CONTROLS or REPORT sections).*/
if (sect == _CONTROLS || sect == _REPORT) strcpy(id,"");
else if (sect == _ENERGY) strcpy(id,Tok[1]);
else strcpy(id,Tok[0]);
/* Copy error messge to string variable fmt */
switch (err)
{
case 201: strcpy(fmt,ERR201); break;
case 202: strcpy(fmt,ERR202); break;
case 203: strcpy(fmt,ERR203); break;
case 204: strcpy(fmt,ERR204); break;
case 205: strcpy(fmt,ERR205); break;
case 206: strcpy(fmt,ERR206); break;
case 207: strcpy(fmt,ERR207); break;
case 208: strcpy(fmt,ERR208); break;
case 209: strcpy(fmt,ERR209); break;
case 210: strcpy(fmt,ERR210); break;
case 211: strcpy(fmt,ERR211); break;
case 212: strcpy(fmt,ERR212); break;
case 213: strcpy(id,"");
strcpy(fmt,ERR213); break;
case 214: strcpy(id,"");
strcpy(fmt,ERR214); break;
case 215: strcpy(fmt,ERR215); break;
case 216: strcpy(fmt,ERR216); break;
case 217: strcpy(fmt,ERR217); break;
case 219: strcpy(fmt,ERR219); break;
case 220: strcpy(fmt,ERR220); break;
/*** Updated 10/25/00 ***/
case 222: strcpy(fmt,ERR222); break;
default: return;
}
/* Write error message to Report file */
sprintf(Msg,fmt,RptSectTxt[sect],id);
writeline(Msg);
/* Echo input line for syntax errors, and */
/* errors in CONTROLS and OPTIONS sections. */
if (sect == _CONTROLS || err == 201 || err == 213) writeline(line);
else writeline("");
}
/********************** END OF INPUT2.C ************************/