GCC Code Coverage Report


Directory: src/solver/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 87.5% 386 / 0 / 441
Functions: 93.8% 15 / 0 / 16
Branches: 75.7% 215 / 0 / 284

input.c
Line Branch Exec Source
1 //-----------------------------------------------------------------------------
2 // input.c
3 //
4 // Project: EPA SWMM5
5 // Version: 5.2
6 // Date: 06/01/22 (Build 5.2.1)
7 // Author: L. Rossman
8 //
9 // Input data processing functions.
10 //
11 // Update History
12 // ==============
13 // Build 5.1.007:
14 // - Support added for climate adjustment input data.
15 // Build 5.1.011:
16 // - Support added for reading hydraulic event dates.
17 // Build 5.1.015:
18 // - Support added for multiple infiltration methods within a project.
19 // Build 5.2.0:
20 // - Support added for Streets and Inlets.
21 // - Support added for named variables & math expressions in control rules.
22 // Build 5.2.1:
23 // - Possible integer underflow avoided in getTokens() function.
24 //-----------------------------------------------------------------------------
25 #define _CRT_SECURE_NO_DEPRECATE
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <math.h>
30 #include "headers.h"
31 #include "lid.h"
32
33 //-----------------------------------------------------------------------------
34 // Constants
35 //-----------------------------------------------------------------------------
36 static const int MAXERRS = 100; // Max. input errors reported
37
38 //-----------------------------------------------------------------------------
39 // Shared variables
40 //-----------------------------------------------------------------------------
41 static char *Tok[MAXTOKS]; // String tokens from line of input
42 static int Ntokens; // Number of tokens in line of input
43 static int Mobjects[MAX_OBJ_TYPES]; // Working number of objects of each type
44 static int Mnodes[MAX_NODE_TYPES]; // Working number of node objects
45 static int Mlinks[MAX_LINK_TYPES]; // Working number of link objects
46 static int Mevents; // Working number of event periods
47
48 //-----------------------------------------------------------------------------
49 // External Functions (declared in funcs.h)
50 //-----------------------------------------------------------------------------
51 // input_countObjects (called by swmm_open in swmm5.c)
52 // input_readData (called by swmm_open in swmm5.c)
53
54 //-----------------------------------------------------------------------------
55 // Local functions
56 //-----------------------------------------------------------------------------
57 static int addObject(int objType, char* id);
58 static int getTokens(char *s);
59 static int parseLine(int sect, char* line);
60 static int readOption(char* line);
61 static int readTitle(char* line);
62 static int readControl(char* tok[], int ntoks);
63 static int readNode(int type);
64 static int readLink(int type);
65 static int readEvent(char* tok[], int ntoks);
66
67 //=============================================================================
68
69 58 int input_countObjects()
70 //
71 // Input: none
72 // Output: returns error code
73 // Purpose: reads input file to determine number of system objects.
74 //
75 {
76 char line[MAXLINE+1]; // line from input data file
77 char wLine[MAXLINE+1]; // working copy of input line
78 char *tok; // first string token of line
79 58 int sect = -1, newsect; // input data sections
80 58 int errcode = 0; // error code
81 58 int errsum = 0; // number of errors found
82 int i;
83 58 long lineCount = 0;
84
85 // --- initialize number of objects & set default values
86
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if ( ErrorCode ) return ErrorCode;
87 58 error_setInpError(0, "");
88
2/2
✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 58 times.
1102 for (i = 0; i < MAX_OBJ_TYPES; i++) Nobjects[i] = 0;
89
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 58 times.
348 for (i = 0; i < MAX_NODE_TYPES; i++) Nnodes[i] = 0;
90
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 58 times.
348 for (i = 0; i < MAX_LINK_TYPES; i++) Nlinks[i] = 0;
91 58 controls_init();
92
93 // --- make pass through data file counting number of each object
94
2/2
✓ Branch 1 taken 110389 times.
✓ Branch 2 taken 58 times.
110447 while ( fgets(line, MAXLINE, Finp.file) != NULL )
95 {
96 // --- skip blank lines & those beginning with a comment
97 110389 lineCount++;
98 110389 sstrncpy(wLine, line, MAXLINE); // make working copy of line
99 110389 tok = strtok(wLine, SEPSTR); // get first text token on line
100
2/2
✓ Branch 0 taken 1731 times.
✓ Branch 1 taken 108658 times.
110389 if ( tok == NULL ) continue;
101
2/2
✓ Branch 0 taken 787 times.
✓ Branch 1 taken 107871 times.
108658 if ( *tok == ';' ) continue;
102
103 // --- check if line begins with a new section heading
104
2/2
✓ Branch 0 taken 1226 times.
✓ Branch 1 taken 106645 times.
107871 if ( *tok == '[' )
105 {
106 // --- look for heading in list of section keywords
107 1226 newsect = findmatch(tok, SectWords);
108
1/2
✓ Branch 0 taken 1226 times.
✗ Branch 1 not taken.
1226 if ( newsect >= 0 )
109 {
110 1226 sect = newsect;
111 1226 continue;
112 }
113 else
114 {
115 sect = -1;
116 errcode = ERR_KEYWORD;
117 }
118 }
119
120 // --- if in OPTIONS section then read the option setting
121 // otherwise add object and its ID name (tok) to project
122
2/2
✓ Branch 0 taken 1588 times.
✓ Branch 1 taken 105057 times.
106645 if ( sect == s_OPTION ) errcode = readOption(line);
123
1/2
✓ Branch 0 taken 105057 times.
✗ Branch 1 not taken.
105057 else if ( sect >= 0 ) errcode = addObject(sect, tok);
124
125 // --- report any error found
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106645 times.
106645 if ( errcode )
127 {
128 report_writeInputErrorMsg(errcode, sect, line, lineCount);
129 errsum++;
130 if (errsum >= MAXERRS ) break;
131 }
132 }
133
134 // --- set global error code if input errors were found
135
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if ( errsum > 0 ) ErrorCode = ERR_INPUT;
136 58 return ErrorCode;
137 }
138
139 //=============================================================================
140
141 58 int input_readData()
142 //
143 // Input: none
144 // Output: returns error code
145 // Purpose: reads input file to determine input parameters for each object.
146 //
147 {
148 char line[MAXLINE+1]; // line from input data file
149 char wLine[MAXLINE+1]; // working copy of input line
150 char* comment; // ptr. to start of comment in input line
151 int sect, newsect; // data sections
152 int inperr, errsum; // error code & total error count
153 int lineLength; // number of characters in input line
154 int i;
155 58 long lineCount = 0;
156
157 // --- initialize working item count arrays
158 // (final counts in Mobjects, Mnodes & Mlinks should
159 // match those in Nobjects, Nnodes and Nlinks).
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if ( ErrorCode ) return ErrorCode;
161 58 error_setInpError(0, "");
162
2/2
✓ Branch 0 taken 1044 times.
✓ Branch 1 taken 58 times.
1102 for (i = 0; i < MAX_OBJ_TYPES; i++) Mobjects[i] = 0;
163
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 58 times.
348 for (i = 0; i < MAX_NODE_TYPES; i++) Mnodes[i] = 0;
164
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 58 times.
348 for (i = 0; i < MAX_LINK_TYPES; i++) Mlinks[i] = 0;
165 58 Mevents = 0;
166
167 // --- initialize starting date for all time series
168
2/2
✓ Branch 0 taken 102 times.
✓ Branch 1 taken 58 times.
160 for ( i = 0; i < Nobjects[TSERIES]; i++ )
169 {
170 102 Tseries[i].lastDate = StartDate + StartTime;
171 }
172
173 // --- read each line from input file
174 58 sect = 0;
175 58 errsum = 0;
176 58 rewind(Finp.file);
177
2/2
✓ Branch 1 taken 110389 times.
✓ Branch 2 taken 58 times.
110447 while ( fgets(line, MAXLINE, Finp.file) != NULL )
178 {
179 // --- make copy of line and scan for tokens
180 110389 lineCount++;
181 110389 sstrncpy(wLine, line, MAXLINE);
182 110389 Ntokens = getTokens(wLine);
183
184 // --- skip blank lines and comments
185
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 107871 times.
110389 if ( Ntokens == 0 ) continue;
186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107871 times.
107871 if ( *Tok[0] == ';' ) continue;
187
188 // --- check if max. line length exceeded
189 107871 lineLength = (int)strlen(line);
190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107871 times.
107871 if ( lineLength >= MAXLINE )
191 {
192 // --- don't count comment if present
193 comment = strchr(line, ';');
194 if ( comment ) lineLength = (int)(comment - line); // Pointer math here
195 if ( lineLength >= MAXLINE )
196 {
197 inperr = ERR_LINE_LENGTH;
198 report_writeInputErrorMsg(inperr, sect, line, lineCount);
199 errsum++;
200 }
201 }
202
203 // --- check if at start of a new input section
204
2/2
✓ Branch 0 taken 1226 times.
✓ Branch 1 taken 106645 times.
107871 if (*Tok[0] == '[')
205 {
206 // --- match token against list of section keywords
207 1226 newsect = findmatch(Tok[0], SectWords);
208
1/2
✓ Branch 0 taken 1226 times.
✗ Branch 1 not taken.
1226 if (newsect >= 0)
209 {
210 // --- SPECIAL CASE FOR TRANSECTS
211 // finish processing the last set of transect data
212
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1218 times.
1226 if ( sect == s_TRANSECT )
213 8 transect_validate(Nobjects[TRANSECT]-1);
214
215 // --- begin a new input section
216 1226 sect = newsect;
217 1226 continue;
218 }
219 else
220 {
221 inperr = error_setInpError(ERR_KEYWORD, Tok[0]);
222 report_writeInputErrorMsg(inperr, sect, line, lineCount);
223 errsum++;
224 break;
225 }
226 }
227
228 // --- otherwise parse tokens from input line
229 else
230 {
231 106645 inperr = parseLine(sect, line);
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106645 times.
106645 if ( inperr > 0 )
233 {
234 errsum++;
235 if ( errsum > MAXERRS ) report_writeLine(FMT19);
236 else report_writeInputErrorMsg(inperr, sect, line, lineCount);
237 }
238 }
239
240 // --- stop if reach end of file or max. error count
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106645 times.
106645 if (errsum > MAXERRS) break;
242 } /* End of while */
243
244 // --- check for errors
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 if (errsum > 0) ErrorCode = ERR_INPUT;
246 58 return ErrorCode;
247 }
248
249 //=============================================================================
250
251 105057 int addObject(int objType, char* id)
252 //
253 // Input: objType = object type index
254 // id = object's ID string
255 // Output: returns an error code
256 // Purpose: adds a new object to the project.
257 //
258 {
259 105057 int errcode = 0;
260
26/26
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 2393 times.
✓ Branch 2 taken 2186 times.
✓ Branch 3 taken 8006 times.
✓ Branch 4 taken 32 times.
✓ Branch 5 taken 9714 times.
✓ Branch 6 taken 348 times.
✓ Branch 7 taken 117 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 9772 times.
✓ Branch 10 taken 106 times.
✓ Branch 11 taken 159 times.
✓ Branch 12 taken 469 times.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 47 times.
✓ Branch 15 taken 10 times.
✓ Branch 16 taken 1729 times.
✓ Branch 17 taken 1554 times.
✓ Branch 18 taken 40970 times.
✓ Branch 19 taken 343 times.
✓ Branch 20 taken 3 times.
✓ Branch 21 taken 73 times.
✓ Branch 22 taken 13 times.
✓ Branch 23 taken 3 times.
✓ Branch 24 taken 8 times.
✓ Branch 25 taken 26944 times.
105057 switch( objType )
261 {
262 52 case s_RAINGAGE:
263
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
52 if ( !project_addObject(GAGE, id, Nobjects[GAGE]) )
264 errcode = error_setInpError(ERR_DUP_NAME, id);
265 52 Nobjects[GAGE]++;
266 52 break;
267
268 2393 case s_SUBCATCH:
269
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2393 times.
2393 if ( !project_addObject(SUBCATCH, id, Nobjects[SUBCATCH]) )
270 errcode = error_setInpError(ERR_DUP_NAME, id);
271 2393 Nobjects[SUBCATCH]++;
272 2393 break;
273
274 2186 case s_AQUIFER:
275
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2186 times.
2186 if ( !project_addObject(AQUIFER, id, Nobjects[AQUIFER]) )
276 errcode = error_setInpError(ERR_DUP_NAME, id);
277 2186 Nobjects[AQUIFER]++;
278 2186 break;
279
280 8006 case s_UNITHYD:
281 // --- the same Unit Hydrograph can span several lines
282
2/2
✓ Branch 1 taken 220 times.
✓ Branch 2 taken 7786 times.
8006 if ( project_findObject(UNITHYD, id) < 0 )
283 {
284
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 220 times.
220 if ( !project_addObject(UNITHYD, id, Nobjects[UNITHYD]) )
285 errcode = error_setInpError(ERR_DUP_NAME, id);
286 220 Nobjects[UNITHYD]++;
287 }
288 8006 break;
289
290 32 case s_SNOWMELT:
291 // --- the same Snowmelt object can appear on several lines
292
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 24 times.
32 if ( project_findObject(SNOWMELT, id) < 0 )
293 {
294
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if ( !project_addObject(SNOWMELT, id, Nobjects[SNOWMELT]) )
295 errcode = error_setInpError(ERR_DUP_NAME, id);
296 8 Nobjects[SNOWMELT]++;
297 }
298 32 break;
299
300 9714 case s_JUNCTION:
301
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9714 times.
9714 if ( !project_addObject(NODE, id, Nobjects[NODE]) )
302 errcode = error_setInpError(ERR_DUP_NAME, id);
303 9714 Nobjects[NODE]++;
304 9714 Nnodes[JUNCTION]++;
305 9714 break;
306
307 348 case s_OUTFALL:
308
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 348 times.
348 if ( !project_addObject(NODE, id, Nobjects[NODE]) )
309 errcode = error_setInpError(ERR_DUP_NAME, id);
310 348 Nobjects[NODE]++;
311 348 Nnodes[OUTFALL]++;
312 348 break;
313
314 117 case s_STORAGE:
315
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 117 times.
117 if ( !project_addObject(NODE, id, Nobjects[NODE]) )
316 errcode = error_setInpError(ERR_DUP_NAME, id);
317 117 Nobjects[NODE]++;
318 117 Nnodes[STORAGE]++;
319 117 break;
320
321 4 case s_DIVIDER:
322
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if ( !project_addObject(NODE, id, Nobjects[NODE]) )
323 errcode = error_setInpError(ERR_DUP_NAME, id);
324 4 Nobjects[NODE]++;
325 4 Nnodes[DIVIDER]++;
326 4 break;
327
328 9772 case s_CONDUIT:
329
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9772 times.
9772 if ( !project_addObject(LINK, id, Nobjects[LINK]) )
330 errcode = error_setInpError(ERR_DUP_NAME, id);
331 9772 Nobjects[LINK]++;
332 9772 Nlinks[CONDUIT]++;
333 9772 break;
334
335 106 case s_PUMP:
336
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
106 if ( !project_addObject(LINK, id, Nobjects[LINK]) )
337 errcode = error_setInpError(ERR_DUP_NAME, id);
338 106 Nobjects[LINK]++;
339 106 Nlinks[PUMP]++;
340 106 break;
341
342 159 case s_ORIFICE:
343
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 159 times.
159 if ( !project_addObject(LINK, id, Nobjects[LINK]) )
344 errcode = error_setInpError(ERR_DUP_NAME, id);
345 159 Nobjects[LINK]++;
346 159 Nlinks[ORIFICE]++;
347 159 break;
348
349 469 case s_WEIR:
350
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 469 times.
469 if ( !project_addObject(LINK, id, Nobjects[LINK]) )
351 errcode = error_setInpError(ERR_DUP_NAME, id);
352 469 Nobjects[LINK]++;
353 469 Nlinks[WEIR]++;
354 469 break;
355
356 2 case s_OUTLET:
357
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ( !project_addObject(LINK, id, Nobjects[LINK]) )
358 errcode = error_setInpError(ERR_DUP_NAME, id);
359 2 Nobjects[LINK]++;
360 2 Nlinks[OUTLET]++;
361 2 break;
362
363 47 case s_POLLUTANT:
364
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
47 if ( !project_addObject(POLLUT, id, Nobjects[POLLUT]) )
365 errcode = error_setInpError(ERR_DUP_NAME, id);
366 47 Nobjects[POLLUT]++;
367 47 break;
368
369 10 case s_LANDUSE:
370
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
10 if ( !project_addObject(LANDUSE, id, Nobjects[LANDUSE]) )
371 errcode = error_setInpError(ERR_DUP_NAME, id);
372 10 Nobjects[LANDUSE]++;
373 10 break;
374
375 1729 case s_PATTERN:
376 // --- a time pattern can span several lines
377
2/2
✓ Branch 1 taken 452 times.
✓ Branch 2 taken 1277 times.
1729 if ( project_findObject(TIMEPATTERN, id) < 0 )
378 {
379
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
452 if ( !project_addObject(TIMEPATTERN, id, Nobjects[TIMEPATTERN]) )
380 errcode = error_setInpError(ERR_DUP_NAME, id);
381 452 Nobjects[TIMEPATTERN]++;
382 }
383 1729 break;
384
385 1554 case s_CURVE:
386 // --- a Curve can span several lines
387
2/2
✓ Branch 1 taken 221 times.
✓ Branch 2 taken 1333 times.
1554 if ( project_findObject(CURVE, id) < 0 )
388 {
389
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 221 times.
221 if ( !project_addObject(CURVE, id, Nobjects[CURVE]) )
390 errcode = error_setInpError(ERR_DUP_NAME, id);
391 221 Nobjects[CURVE]++;
392
393 // --- check for a conduit shape curve
394 221 id = strtok(NULL, SEPSTR);
395
2/2
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 190 times.
221 if ( findmatch(id, CurveTypeWords) == SHAPE_CURVE )
396 31 Nobjects[SHAPE]++;
397 }
398 1554 break;
399
400 40970 case s_TIMESERIES:
401 // --- a Time Series can span several lines
402
2/2
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 40868 times.
40970 if ( project_findObject(TSERIES, id) < 0 )
403 {
404
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 102 times.
102 if ( !project_addObject(TSERIES, id, Nobjects[TSERIES]) )
405 errcode = error_setInpError(ERR_DUP_NAME, id);
406 102 Nobjects[TSERIES]++;
407 }
408 40970 break;
409
410 343 case s_CONTROL:
411
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 267 times.
343 if ( match(id, w_RULE) ) Nobjects[CONTROL]++;
412 267 else controls_addToCount(id);
413 343 break;
414
415 3 case s_TRANSECT:
416 // --- for TRANSECTS, ID name appears as second entry on X1 line
417
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 2 times.
3 if ( match(id, "X1") )
418 {
419 1 id = strtok(NULL, SEPSTR);
420
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1 if ( id )
421 {
422
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
1 if ( !project_addObject(TRANSECT, id, Nobjects[TRANSECT]) )
423 errcode = error_setInpError(ERR_DUP_NAME, id);
424 1 Nobjects[TRANSECT]++;
425 }
426 }
427 3 break;
428
429 73 case s_LID_CONTROL:
430 // --- an LID object can span several lines
431
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 53 times.
73 if ( project_findObject(LID, id) < 0 )
432 {
433
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
20 if ( !project_addObject(LID, id, Nobjects[LID]) )
434 {
435 errcode = error_setInpError(ERR_DUP_NAME, id);
436 }
437 20 Nobjects[LID]++;
438 }
439 73 break;
440
441 13 case s_EVENT: NumEvents++; break;
442
443 3 case s_STREET:
444
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if ( !project_addObject(STREET, id, Nobjects[STREET]) )
445 errcode = error_setInpError(ERR_DUP_NAME, id);
446 3 Nobjects[STREET]++;
447 3 break;
448
449 8 case s_INLET:
450 // --- an INLET object can span several lines
451
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1 time.
8 if (project_findObject(INLET, id) < 0)
452 {
453
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if ( !project_addObject(INLET, id, Nobjects[INLET]) )
454 errcode = error_setInpError(ERR_DUP_NAME, id);
455 7 Nobjects[INLET]++;
456 }
457 8 break;
458 }
459 105057 return errcode;
460 }
461
462 //=============================================================================
463
464 106645 int parseLine(int sect, char *line)
465 //
466 // Input: sect = current section of input file
467 // *line = line of text read from input file
468 // Output: returns error code or 0 if no error found
469 // Purpose: parses contents of a tokenized line of text read from input file.
470 //
471 {
472 int j, err;
473
47/48
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 52 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 92 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 2393 times.
✓ Branch 6 taken 2393 times.
✓ Branch 7 taken 2389 times.
✓ Branch 8 taken 2186 times.
✓ Branch 9 taken 2241 times.
✓ Branch 10 taken 8 times.
✓ Branch 11 taken 32 times.
✓ Branch 12 taken 9714 times.
✓ Branch 13 taken 348 times.
✓ Branch 14 taken 117 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 9772 times.
✓ Branch 17 taken 106 times.
✓ Branch 18 taken 159 times.
✓ Branch 19 taken 469 times.
✓ Branch 20 taken 2 times.
✓ Branch 21 taken 10400 times.
✓ Branch 22 taken 3 times.
✓ Branch 23 taken 184 times.
✓ Branch 24 taken 47 times.
✓ Branch 25 taken 10 times.
✓ Branch 26 taken 25 times.
✓ Branch 27 taken 25 times.
✓ Branch 28 taken 33 times.
✓ Branch 29 taken 266 times.
✓ Branch 30 taken 3943 times.
✓ Branch 31 taken 1729 times.
✓ Branch 32 taken 3046 times.
✓ Branch 33 taken 8006 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 15 times.
✓ Branch 36 taken 1554 times.
✓ Branch 37 taken 40970 times.
✓ Branch 38 taken 343 times.
✓ Branch 39 taken 677 times.
✓ Branch 40 taken 13 times.
✓ Branch 41 taken 73 times.
✓ Branch 42 taken 18 times.
✓ Branch 43 taken 13 times.
✓ Branch 44 taken 3 times.
✓ Branch 45 taken 8 times.
✓ Branch 46 taken 14 times.
✓ Branch 47 taken 2620 times.
106645 switch (sect)
474 {
475 74 case s_TITLE:
476 74 return readTitle(line);
477
478 52 case s_RAINGAGE:
479 52 j = Mobjects[GAGE];
480 52 err = gage_readParams(j, Tok, Ntokens);
481 52 Mobjects[GAGE]++;
482 52 return err;
483
484 48 case s_TEMP:
485 48 return climate_readParams(Tok, Ntokens);
486
487 92 case s_EVAP:
488 92 return climate_readEvapParams(Tok, Ntokens);
489
490 8 case s_ADJUST:
491 8 return climate_readAdjustments(Tok, Ntokens);
492
493 2393 case s_SUBCATCH:
494 2393 j = Mobjects[SUBCATCH];
495 2393 err = subcatch_readParams(j, Tok, Ntokens);
496 2393 Mobjects[SUBCATCH]++;
497 2393 return err;
498
499 2393 case s_SUBAREA:
500 2393 return subcatch_readSubareaParams(Tok, Ntokens);
501
502 2389 case s_INFIL:
503 2389 return infil_readParams(InfilModel, Tok, Ntokens);
504
505 2186 case s_AQUIFER:
506 2186 j = Mobjects[AQUIFER];
507 2186 err = gwater_readAquiferParams(j, Tok, Ntokens);
508 2186 Mobjects[AQUIFER]++;
509 2186 return err;
510
511 2241 case s_GROUNDWATER:
512 2241 return gwater_readGroundwaterParams(Tok, Ntokens);
513
514 8 case s_GWF:
515 8 return gwater_readFlowExpression(Tok, Ntokens);
516
517 32 case s_SNOWMELT:
518 32 return snow_readMeltParams(Tok, Ntokens);
519
520 9714 case s_JUNCTION:
521 9714 return readNode(JUNCTION);
522
523 348 case s_OUTFALL:
524 348 return readNode(OUTFALL);
525
526 117 case s_STORAGE:
527 117 return readNode(STORAGE);
528
529 4 case s_DIVIDER:
530 4 return readNode(DIVIDER);
531
532 9772 case s_CONDUIT:
533 9772 return readLink(CONDUIT);
534
535 106 case s_PUMP:
536 106 return readLink(PUMP);
537
538 159 case s_ORIFICE:
539 159 return readLink(ORIFICE);
540
541 469 case s_WEIR:
542 469 return readLink(WEIR);
543
544 2 case s_OUTLET:
545 2 return readLink(OUTLET);
546
547 10400 case s_XSECTION:
548 10400 return link_readXsectParams(Tok, Ntokens);
549
550 3 case s_TRANSECT:
551 3 return transect_readParams(&Mobjects[TRANSECT], Tok, Ntokens);
552
553 184 case s_LOSSES:
554 184 return link_readLossParams(Tok, Ntokens);
555
556 47 case s_POLLUTANT:
557 47 j = Mobjects[POLLUT];
558 47 err = landuse_readPollutParams(j, Tok, Ntokens);
559 47 Mobjects[POLLUT]++;
560 47 return err;
561
562 10 case s_LANDUSE:
563 10 j = Mobjects[LANDUSE];
564 10 err = landuse_readParams(j, Tok, Ntokens);
565 10 Mobjects[LANDUSE]++;
566 10 return err;
567
568 25 case s_BUILDUP:
569 25 return landuse_readBuildupParams(Tok, Ntokens);
570
571 25 case s_WASHOFF:
572 25 return landuse_readWashoffParams(Tok, Ntokens);
573
574 33 case s_COVERAGE:
575 33 return subcatch_readLanduseParams(Tok, Ntokens);
576
577 266 case s_INFLOW:
578 266 return inflow_readExtInflow(Tok, Ntokens);
579
580 3943 case s_DWF:
581 3943 return inflow_readDwfInflow(Tok, Ntokens);
582
583 1729 case s_PATTERN:
584 1729 return inflow_readDwfPattern(Tok, Ntokens);
585
586 3046 case s_RDII:
587 3046 return rdii_readRdiiInflow(Tok, Ntokens);
588
589 8006 case s_UNITHYD:
590 8006 return rdii_readUnitHydParams(Tok, Ntokens);
591
592 case s_LOADING:
593 return subcatch_readInitBuildup(Tok, Ntokens);
594
595 15 case s_TREATMENT:
596 15 return treatmnt_readExpression(Tok, Ntokens);
597
598 1554 case s_CURVE:
599 1554 return table_readCurve(Tok, Ntokens);
600
601 40970 case s_TIMESERIES:
602 40970 return table_readTimeseries(Tok, Ntokens);
603
604 343 case s_CONTROL:
605 343 return readControl(Tok, Ntokens);
606
607 677 case s_REPORT:
608 677 return report_readOptions(Tok, Ntokens);
609
610 13 case s_FILE:
611 13 return iface_readFileParams(Tok, Ntokens);
612
613 73 case s_LID_CONTROL:
614 73 return lid_readProcParams(Tok, Ntokens);
615
616 18 case s_LID_USAGE:
617 18 return lid_readGroupParams(Tok, Ntokens);
618
619 13 case s_EVENT:
620 13 return readEvent(Tok, Ntokens);
621
622 3 case s_STREET:
623 3 return street_readParams(Tok, Ntokens);
624
625 8 case s_INLET:
626 8 return inlet_readDesignParams(Tok, Ntokens);
627
628 14 case s_INLET_USAGE:
629 14 return inlet_readUsageParams(Tok, Ntokens);
630
631 2620 default: return 0;
632 }
633 }
634
635 //=============================================================================
636
637 343 int readControl(char* tok[], int ntoks)
638 //
639 // Input: tok[] = array of string tokens
640 // ntoks = number of tokens
641 // Output: returns error code
642 // Purpose: reads a line of input for a control rule.
643 //
644 {
645 int index;
646 int keyword;
647
648 // --- check for minimum number of tokens
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 343 times.
343 if ( ntoks < 2 ) return error_setInpError(ERR_ITEMS, "");
650
651
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 340 times.
343 if (match(tok[0], w_VARIABLE))
652 3 return controls_addVariable(tok, ntoks);
653
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 334 times.
340 if (match(tok[0], w_EXPRESSION))
654 6 return controls_addExpression(tok, ntoks);
655
656 // --- get index of control rule keyword
657 334 keyword = findmatch(tok[0], RuleKeyWords);
658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334 times.
334 if ( keyword < 0 ) return error_setInpError(ERR_KEYWORD, tok[0]);
659
660 // --- if line begins a new control rule, add rule ID to the database
661
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 258 times.
334 if ( keyword == 0 )
662 {
663
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
76 if ( !project_addObject(CONTROL, tok[1], Mobjects[CONTROL]) )
664 {
665 return error_setInpError(ERR_DUP_NAME, Tok[1]);
666 }
667 76 Mobjects[CONTROL]++;
668 }
669
670 // --- get index of last control rule processed
671 334 index = Mobjects[CONTROL] - 1;
672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334 times.
334 if ( index < 0 ) return error_setInpError(ERR_RULE, "");
673
674 // --- add current line as a new clause to the control rule
675 334 return controls_addRuleClause(index, keyword, Tok, Ntokens);
676 }
677
678 //=============================================================================
679
680 1588 int readOption(char* line)
681 //
682 // Input: line = line of input data
683 // Output: returns error code
684 // Purpose: reads an input line containing a project option.
685 //
686 {
687 1588 Ntokens = getTokens(line);
688
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1588 times.
1588 if ( Ntokens < 2 ) return 0;
689 1588 return project_readOption(Tok[0], Tok[1]);
690 }
691
692 //=============================================================================
693
694 74 int readTitle(char* line)
695 //
696 // Input: line = line from input file
697 // Output: returns error code
698 // Purpose: reads project title from line of input.
699 //
700 {
701 int i, n;
702
1/2
✓ Branch 0 taken 94 times.
✗ Branch 1 not taken.
94 for (i = 0; i < MAXTITLE; i++)
703 {
704 // --- find next empty Title entry
705
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 20 times.
94 if ( strlen(Title[i]) == 0 )
706 {
707 // --- strip line feed character from input line
708 74 n = (int)strlen(line);
709
1/2
✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
74 if (line[n-1] == 10) line[n-1] = ' ';
710
711 // --- copy input line into Title entry
712 74 sstrncpy(Title[i], line, MAXMSG);
713 74 break;
714 }
715 }
716 74 return 0;
717 }
718
719 //=============================================================================
720
721 10183 int readNode(int type)
722 //
723 // Input: type = type of node
724 // Output: returns error code
725 // Purpose: reads data for a node from a line of input.
726 //
727 {
728 10183 int j = Mobjects[NODE];
729 10183 int k = Mnodes[type];
730 10183 int err = node_readParams(j, type, k, Tok, Ntokens);
731 10183 Mobjects[NODE]++;
732 10183 Mnodes[type]++;
733 10183 return err;
734 }
735
736 //=============================================================================
737
738 10508 int readLink(int type)
739 //
740 // Input: type = type of link
741 // Output: returns error code
742 // Purpose: reads data for a link from a line of input.
743 //
744 {
745 10508 int j = Mobjects[LINK];
746 10508 int k = Mlinks[type];
747 10508 int err = link_readParams(j, type, k, Tok, Ntokens);
748 10508 Mobjects[LINK]++;
749 10508 Mlinks[type]++;
750 10508 return err;
751 }
752
753 //=============================================================================
754
755 13 int readEvent(char* tok[], int ntoks)
756 {
757 DateTime x[4];
758
759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( ntoks < 4 ) return error_setInpError(ERR_ITEMS, "");
760
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if ( !datetime_strToDate(tok[0], &x[0]) )
761 return error_setInpError(ERR_DATETIME, tok[0]);
762
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if ( !datetime_strToTime(tok[1], &x[1]) )
763 return error_setInpError(ERR_DATETIME, tok[1]);
764
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if ( !datetime_strToDate(tok[2], &x[2]) )
765 return error_setInpError(ERR_DATETIME, tok[2]);
766
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
13 if ( !datetime_strToTime(tok[3], &x[3]) )
767 return error_setInpError(ERR_DATETIME, tok[3]);
768
769 13 Event[Mevents].start = x[0] + x[1];
770 13 Event[Mevents].end = x[2] + x[3];
771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if ( Event[Mevents].start >= Event[Mevents].end )
772 return error_setInpError(ERR_DATETIME, " - start date exceeds end date");
773 13 Mevents++;
774 13 return 0;
775 }
776
777 //=============================================================================
778
779 33595 int findmatch(char *s, char *keyword[])
780 //
781 // Input: s = character string
782 // keyword = array of keyword strings
783 // Output: returns index of matching keyword or -1 if no match found
784 // Purpose: finds match between string and array of keyword strings.
785 //
786 {
787 33595 int i = 0;
788
2/2
✓ Branch 0 taken 174268 times.
✓ Branch 1 taken 2620 times.
176888 while (keyword[i] != NULL)
789 {
790
2/2
✓ Branch 1 taken 30975 times.
✓ Branch 2 taken 143293 times.
174268 if (match(s, keyword[i])) return(i);
791 143293 i++;
792 }
793 2620 return(-1);
794 }
795
796 //=============================================================================
797
798 180183 int match(char *str, char *substr)
799 //
800 // Input: str = character string being searched
801 // substr = sub-string being searched for
802 // Output: returns 1 if sub-string found, 0 if not
803 // Purpose: sees if a sub-string of characters appears in a string
804 // (not case sensitive).
805 //
806 {
807 int i,j,k;
808
809 // --- fail if substring is empty
810
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 180179 times.
180183 if (!substr[0]) return(0);
811
812 // --- skip leading blanks of str
813
1/2
✓ Branch 0 taken 180179 times.
✗ Branch 1 not taken.
180179 for (k = 0; str[k]; k++)
814 {
815
1/2
✓ Branch 0 taken 180179 times.
✗ Branch 1 not taken.
180179 if (str[k] != ' ') break;
816 }
817
818 // --- check if substr matches remainder of str
819
2/2
✓ Branch 0 taken 436603 times.
✓ Branch 1 taken 35355 times.
471958 for (i = k,j = 0; substr[j]; i++,j++)
820 {
821
8/12
✓ Branch 0 taken 436589 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 36716 times.
✓ Branch 3 taken 399873 times.
✓ Branch 4 taken 36716 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 436589 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 144810 times.
✓ Branch 11 taken 291779 times.
436603 if (!str[i] || UCHAR(str[i]) != UCHAR(substr[j])) return(0);
822 }
823 35355 return(1);
824 }
825
826 //=============================================================================
827
828 17 int getInt(char *s, int *y)
829 //
830 // Input: s = a character string
831 // Output: y = converted value of s,
832 // returns 1 if conversion successful, 0 if not
833 // Purpose: converts a string to an integer number.
834 //
835 {
836 double x;
837
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 if ( getDouble(s, &x) )
838 {
839
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if ( x < 0.0 ) x -= 0.01;
840 17 else x += 0.01;
841 17 *y = (int)x;
842 17 return 1;
843 }
844 *y = 0;
845 return 0;
846 }
847
848 //=============================================================================
849
850 int getFloat(char *s, float *y)
851 //
852 // Input: s = a character string
853 // Output: y = converted value of s,
854 // returns 1 if conversion successful, 0 if not
855 // Purpose: converts a string to a single precision floating point number.
856 //
857 {
858 char *endptr;
859 *y = (float) strtod(s, &endptr);
860 if (*endptr > 0) return(0);
861 return(1);
862 }
863
864 //=============================================================================
865
866 642598 int getDouble(char *s, double *y)
867 //
868 // Input: s = a character string
869 // Output: y = converted value of s,
870 // returns 1 if conversion successful, 0 if not
871 // Purpose: converts a string to a double precision floating point number.
872 //
873 {
874 char *endptr;
875 642598 *y = strtod(s, &endptr);
876
2/2
✓ Branch 0 taken 168501 times.
✓ Branch 1 taken 474097 times.
642598 if (*endptr > 0) return(0);
877 474097 return(1);
878 }
879
880 //=============================================================================
881
882 111977 int getTokens(char *s)
883 //
884 // Input: s = a character string
885 // Output: returns number of tokens found in s
886 // Purpose: scans a string for tokens, saving pointers to them
887 // in shared variable Tok[].
888 //
889 // Notes: Tokens can be separated by the characters listed in SEPSTR
890 // (spaces, tabs, newline, carriage return) which is defined
891 // in CONSTS.H. Text between quotes is treated as a single token.
892 //
893 {
894 int len, n;
895 int m;
896 char *c;
897
898 // --- begin with no tokens
899
2/2
✓ Branch 0 taken 4479080 times.
✓ Branch 1 taken 111977 times.
4591057 for (n = 0; n < MAXTOKS; n++) Tok[n] = NULL;
900 111977 n = 0;
901
902 // --- truncate s at start of comment
903 111977 c = strchr(s,';');
904
2/2
✓ Branch 0 taken 787 times.
✓ Branch 1 taken 111190 times.
111977 if (c) *c = '\0';
905 111977 len = (int)strlen(s);
906
907 // --- scan s for tokens until nothing left
908
3/4
✓ Branch 0 taken 4895993 times.
✓ Branch 1 taken 111977 times.
✓ Branch 2 taken 4895993 times.
✗ Branch 3 not taken.
5007970 while (len > 0 && n < MAXTOKS)
909 {
910 4895993 m = (int)strcspn(s,SEPSTR); // find token length
911
2/2
✓ Branch 0 taken 4238264 times.
✓ Branch 1 taken 657729 times.
4895993 if (m == 0) s++; // no token found
912 else
913 {
914
2/2
✓ Branch 0 taken 16018 times.
✓ Branch 1 taken 641711 times.
657729 if (*s == '"') // token begins with quote
915 {
916 16018 s++; // start token after quote
917 16018 len--; // reduce length of s
918 16018 m = (int)strcspn(s,"\"\n"); // find end quote or new line
919 }
920 657729 s[m] = '\0'; // null-terminate the token
921 657729 Tok[n] = s; // save pointer to token
922 657729 n++; // update token count
923 657729 s += m+1; // begin next token
924 }
925 4895993 len -= m+1; // update length of s
926 }
927 111977 return n;
928 }
929
930 //=============================================================================
931