3c3
< #include <fstream>
---
> #include <sstream> // string streams
5a6
> #include <algorithm> // for_each
7d7
< #include <cstdlib> /* exit() */
13a14,17
> 
> #include "ImplementLandoaf.h" // function object
> 
> // exceptions
15c19
< #include "FileException.h"
---
> #include "InvalidDataLineException.h"
17c21,26
< #include "util.h"
---
> #include "FssimUtil.h"
> 
> #include "BlockStruct.h"
> #include "AxsDefStruct.h"
> #include "GroupStruct.h"
> 
24,27d32
< Data::Data(const string& inputDatafileDirectory)
<     : m_dataPath(inputDatafileDirectory), m_pApp(FssimApp::getApp())
< {
< }
29c34
< int Data::processDataFile(const char* functionName, PDataMemberFn pMemberFunction, Data& pObj)
---
> void Data::processDataFile(const char* functionName, PDataMemberFn pMemberFunction, Data& pObj)
32,33c37
<     //cout << endl << functionName << endl;
<     printf("\n %s \n", functionName);
---
>     cout << endl << functionName << endl;
35c39,53
<     (pObj.*pMemberFunction)(); // call member function;
---
>     try
>     {
>         (pObj.*pMemberFunction)(); // call member function;
>     }
>     catch (OpenException& e)
>     {
>         if (e.isFatal())
>         {
>             throw;
>         }
>         else
>         {
>             cerr << endl << e.what() << endl;
>         }
>     }
38,39c56
<     //cout << " Done" << endl;
<     printf("\nDone");
---
>     cout << " Done" << endl;
41c58
<     return 1;
---
>     return;
43a61
> 
46,50c64,68
<     FILE* fp = 0;
<     ZONE* zone = 0;
<     GROUP* group = 0;
<     char dataLine[255];
<     char UnitTypeStr[20];
---
>     FILE* pFile = 0;
>     ZoneStruct* pZone = 0;
>     GroupStruct* pGroup = 0;
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char UnitTypeStr[FssimUtil::MAX_LABEL_LENGTH];
70,71c88,91
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if ( 0 == fp )
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if ( 0 == pFile )
73,77c93
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
80c96
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
82,83c98
<     int line_no = 1;
<     while ( !feof(fp) )
---
>     while ( !feof(pFile) )
85,87c100,102
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
89c104
<             fclose(fp);
---
>             fclose(pFile);
92c107
<         int count = sscanf(dataLine, "%s %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
---
>         m_fieldCount = sscanf(inputDataLine, "%s %s %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
101c116
<         if ( count != 16)
---
>         if ( m_fieldCount != 16)
103c118
<             if (count != -1)
---
>             if (m_fieldCount != -1)
105c120
<                 printf("\nWARNING: %s(Line#:%d): Discarding invalid dataLine", m_fileName.c_str(), line_no);
---
>                 this->discardInvalidDataLine();
107,109c122,125
<         } else {
<             strcpy(UnitTypeStr, to_lowercase(UnitTypeStr).c_str());
<             if (strcmp(UnitTypeStr, "zone") == 0)
---
>         }
>         else
>         {
>             try
111,112c127,128
<                 zone = static_cast<ZONE*>(func_find_zone(UnitIDStr));
<                 if (zone == 0)
---
>                 strcpy(UnitTypeStr, FssimUtil::to_lowercase(UnitTypeStr).c_str());
>                 if (UnitTypeStr == FssimUtil::m_kZoneIdentifier)
114,115c130,163
<                     printf("\n\nERROR: %s(Line#:%d): Could not find specified zone(%s)\n\n", m_fileName.c_str(), line_no, UnitIDStr);
<                     exit(1);
---
>                     pZone = ZoneStruct::find(UnitIDStr);
>                     if ( pZone->reportFlags == 0 )
>                     {
>                         pZone->reportFlags = new ReportFlagsStruct;
>                         if ( pZone->reportFlags == 0 )
>                         {
>                             cerr << endl << endl << "ERROR: read_report_flags(): malloc() failed" << endl << endl;
>                             throw bad_alloc();
>                         }
>                         pZone->reportFlags->inv_start = FssimApp::MAX_PLAN_HORIZON;
>                         pZone->reportFlags->inv_end = 0;
>                     }
>                     pZone->reportFlags->inv_ha_rep_start = inv_ha_rep_start;
>                     pZone->reportFlags->inv_ha_rep_end = inv_ha_rep_end;
>                     pZone->reportFlags->inv_ha_sum_start = inv_ha_sum_start;
>                     pZone->reportFlags->inv_ha_sum_end = inv_ha_sum_end;
>                     pZone->reportFlags->inv_m3_rep_start = inv_m3_rep_start;
>                     pZone->reportFlags->inv_m3_rep_end = inv_m3_rep_end;
>                     pZone->reportFlags->inv_m3_sum_start = inv_m3_sum_start;
>                     pZone->reportFlags->inv_m3_sum_end = inv_m3_sum_end;
>                     pZone->reportFlags->hage_rep_start = hage_rep_start;
>                     pZone->reportFlags->hage_rep_end = hage_rep_end;
>                     pZone->reportFlags->levels_rep_start = levels_rep_start;
>                     pZone->reportFlags->levels_rep_end = levels_rep_end;
>                     pZone->reportFlags->axs_rep_start = axs_rep_start;
>                     pZone->reportFlags->axs_rep_end = axs_rep_end;
>                     if ( inv_ha_rep_start < pZone->reportFlags->inv_start ) pZone->reportFlags->inv_start = inv_ha_rep_start;
>                     if ( inv_m3_rep_start < pZone->reportFlags->inv_start ) pZone->reportFlags->inv_start = inv_m3_rep_start;
>                     if ( inv_ha_sum_start < pZone->reportFlags->inv_start ) pZone->reportFlags->inv_start = inv_ha_sum_start;
>                     if ( inv_m3_sum_start < pZone->reportFlags->inv_start ) pZone->reportFlags->inv_start = inv_m3_sum_start;
>                     if ( inv_ha_rep_end > pZone->reportFlags->inv_end ) pZone->reportFlags->inv_end = inv_ha_rep_end;
>                     if ( inv_m3_rep_end > pZone->reportFlags->inv_end ) pZone->reportFlags->inv_end = inv_m3_rep_end;
>                     if ( inv_ha_sum_end > pZone->reportFlags->inv_end ) pZone->reportFlags->inv_end = inv_ha_sum_end;
>                     if ( inv_m3_sum_end > pZone->reportFlags->inv_end ) pZone->reportFlags->inv_end = inv_m3_sum_end;
117c165
<                 if ( zone->reportFlags == 0 )
---
>                 else if (UnitTypeStr == FssimUtil::m_kGroupIdentifier)
119,120c167,168
<                     zone->reportFlags = new REPORT_FLAGS;
<                     if ( zone->reportFlags == 0 )
---
>                     pGroup = GroupStruct::find(UnitIDStr);
>                     if ( pGroup->reportFlags == 0 )
122,123c170,177
<                         printf("\n\nERROR: this->read_report_flags(): malloc() failed\n\n");
<                         exit(1);
---
>                         pGroup->reportFlags = new ReportFlagsStruct;
>                         if ( pGroup->reportFlags == 0 )
>                         {
>                             cerr << endl << endl << "ERROR: read_report_flags(): malloc() failed" << endl << endl;
>                             throw bad_alloc();
>                         }
>                         pGroup->reportFlags->inv_start = FssimApp::MAX_PLAN_HORIZON;
>                         pGroup->reportFlags->inv_end = 0;
125,126c179,200
<                     zone->reportFlags->inv_start = FssimApp::MAX_PLAN_HORIZON;
<                     zone->reportFlags->inv_end = 0;
---
>                     pGroup->reportFlags->inv_ha_rep_start = inv_ha_rep_start;
>                     pGroup->reportFlags->inv_ha_rep_end = inv_ha_rep_end;
>                     pGroup->reportFlags->inv_ha_sum_start = inv_ha_sum_start;
>                     pGroup->reportFlags->inv_ha_sum_end = inv_ha_sum_end;
>                     pGroup->reportFlags->inv_m3_rep_start = inv_m3_rep_start;
>                     pGroup->reportFlags->inv_m3_rep_end = inv_m3_rep_end;
>                     pGroup->reportFlags->inv_m3_sum_start = inv_m3_sum_start;
>                     pGroup->reportFlags->inv_m3_sum_end = inv_m3_sum_end;
>                     pGroup->reportFlags->hage_rep_start = hage_rep_start;
>                     pGroup->reportFlags->hage_rep_end = hage_rep_end;
>                     pGroup->reportFlags->levels_rep_start = levels_rep_start;
>                     pGroup->reportFlags->levels_rep_end = levels_rep_end;
>                     pGroup->reportFlags->axs_rep_start = axs_rep_start;
>                     pGroup->reportFlags->axs_rep_end = axs_rep_end;
>                     if ( inv_ha_rep_start < pGroup->reportFlags->inv_start ) pGroup->reportFlags->inv_start = inv_ha_rep_start;
>                     if ( inv_m3_rep_start < pGroup->reportFlags->inv_start ) pGroup->reportFlags->inv_start = inv_m3_rep_start;
>                     if ( inv_ha_sum_start < pGroup->reportFlags->inv_start ) pGroup->reportFlags->inv_start = inv_ha_sum_start;
>                     if ( inv_m3_sum_start < pGroup->reportFlags->inv_start ) pGroup->reportFlags->inv_start = inv_m3_sum_start;
>                     if ( inv_ha_rep_end > pGroup->reportFlags->inv_end ) pGroup->reportFlags->inv_end = inv_ha_rep_end;
>                     if ( inv_m3_rep_end > pGroup->reportFlags->inv_end ) pGroup->reportFlags->inv_end = inv_m3_rep_end;
>                     if ( inv_ha_sum_end > pGroup->reportFlags->inv_end ) pGroup->reportFlags->inv_end = inv_ha_sum_end;
>                     if ( inv_m3_sum_end > pGroup->reportFlags->inv_end ) pGroup->reportFlags->inv_end = inv_m3_sum_end;
128,149c202,205
<                 zone->reportFlags->inv_ha_rep_start = inv_ha_rep_start;
<                 zone->reportFlags->inv_ha_rep_end = inv_ha_rep_end;
<                 zone->reportFlags->inv_ha_sum_start = inv_ha_sum_start;
<                 zone->reportFlags->inv_ha_sum_end = inv_ha_sum_end;
<                 zone->reportFlags->inv_m3_rep_start = inv_m3_rep_start;
<                 zone->reportFlags->inv_m3_rep_end = inv_m3_rep_end;
<                 zone->reportFlags->inv_m3_sum_start = inv_m3_sum_start;
<                 zone->reportFlags->inv_m3_sum_end = inv_m3_sum_end;
<                 zone->reportFlags->hage_rep_start = hage_rep_start;
<                 zone->reportFlags->hage_rep_end = hage_rep_end;
<                 zone->reportFlags->levels_rep_start = levels_rep_start;
<                 zone->reportFlags->levels_rep_end = levels_rep_end;
<                 zone->reportFlags->axs_rep_start = axs_rep_start;
<                 zone->reportFlags->axs_rep_end = axs_rep_end;
<                 if ( inv_ha_rep_start < zone->reportFlags->inv_start ) zone->reportFlags->inv_start = inv_ha_rep_start;
<                 if ( inv_m3_rep_start < zone->reportFlags->inv_start ) zone->reportFlags->inv_start = inv_m3_rep_start;
<                 if ( inv_ha_sum_start < zone->reportFlags->inv_start ) zone->reportFlags->inv_start = inv_ha_sum_start;
<                 if ( inv_m3_sum_start < zone->reportFlags->inv_start ) zone->reportFlags->inv_start = inv_m3_sum_start;
<                 if ( inv_ha_rep_end > zone->reportFlags->inv_end ) zone->reportFlags->inv_end = inv_ha_rep_end;
<                 if ( inv_m3_rep_end > zone->reportFlags->inv_end ) zone->reportFlags->inv_end = inv_m3_rep_end;
<                 if ( inv_ha_sum_end > zone->reportFlags->inv_end ) zone->reportFlags->inv_end = inv_ha_sum_end;
<                 if ( inv_m3_sum_end > zone->reportFlags->inv_end ) zone->reportFlags->inv_end = inv_m3_sum_end;
---
>                 else
>                 {
>                     throw InvalidDataException(UnitTypeStr, "Invalid unit type specification");
>                 }
151c207
<             else if (strcmp(UnitTypeStr, "group") == 0)
---
>             catch (InvalidDataException& e)
153,154c209
<                 group = static_cast<GROUP*>(func_find_group(UnitIDStr));
<                 if (group == 0)
---
>                 if (e.isFatal())
156,157c211
<                     printf("\n\nERROR: %s(Line#:%d): Could not find specified group(%s)\n\n", m_fileName.c_str(), line_no, UnitIDStr);
<                     exit(1);
---
>                     throw;
159c213
<                 if ( group->reportFlags == 0 )
---
>                 else
161,168c215
<                     group->reportFlags = new REPORT_FLAGS;
<                     if ( group->reportFlags == 0 )
<                     {
<                         printf("\n\nERROR: this->read_report_flags(): malloc() failed\n\n");
<                         exit(1);
<                     }
<                     group->reportFlags->inv_start = FssimApp::MAX_PLAN_HORIZON;
<                     group->reportFlags->inv_end = 0;
---
>                     cerr << endl << e.what() << endl;
170,194d216
<                 group->reportFlags->inv_ha_rep_start = inv_ha_rep_start;
<                 group->reportFlags->inv_ha_rep_end = inv_ha_rep_end;
<                 group->reportFlags->inv_ha_sum_start = inv_ha_sum_start;
<                 group->reportFlags->inv_ha_sum_end = inv_ha_sum_end;
<                 group->reportFlags->inv_m3_rep_start = inv_m3_rep_start;
<                 group->reportFlags->inv_m3_rep_end = inv_m3_rep_end;
<                 group->reportFlags->inv_m3_sum_start = inv_m3_sum_start;
<                 group->reportFlags->inv_m3_sum_end = inv_m3_sum_end;
<                 group->reportFlags->hage_rep_start = hage_rep_start;
<                 group->reportFlags->hage_rep_end = hage_rep_end;
<                 group->reportFlags->levels_rep_start = levels_rep_start;
<                 group->reportFlags->levels_rep_end = levels_rep_end;
<                 group->reportFlags->axs_rep_start = axs_rep_start;
<                 group->reportFlags->axs_rep_end = axs_rep_end;
<                 if ( inv_ha_rep_start < group->reportFlags->inv_start ) group->reportFlags->inv_start = inv_ha_rep_start;
<                 if ( inv_m3_rep_start < group->reportFlags->inv_start ) group->reportFlags->inv_start = inv_m3_rep_start;
<                 if ( inv_ha_sum_start < group->reportFlags->inv_start ) group->reportFlags->inv_start = inv_ha_sum_start;
<                 if ( inv_m3_sum_start < group->reportFlags->inv_start ) group->reportFlags->inv_start = inv_m3_sum_start;
<                 if ( inv_ha_rep_end > group->reportFlags->inv_end ) group->reportFlags->inv_end = inv_ha_rep_end;
<                 if ( inv_m3_rep_end > group->reportFlags->inv_end ) group->reportFlags->inv_end = inv_m3_rep_end;
<                 if ( inv_ha_sum_end > group->reportFlags->inv_end ) group->reportFlags->inv_end = inv_ha_sum_end;
<                 if ( inv_m3_sum_end > group->reportFlags->inv_end ) group->reportFlags->inv_end = inv_m3_sum_end;
<             } else {
<                 printf("\n\nERROR: %s(Line#:%d): Invalid unit type specification(%s); expecting [ZONE,GROUP]\n\n", m_fileName.c_str(), line_no, UnitTypeStr);
<                 exit(1);
199c221,223
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
204c228
<     FILE* fp = 0;
---
>     FILE* pFile = 0;
208,209c232,235
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp ==  0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile ==  0)
211,215c237
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
217,218c239,240
<     string headerStringBuffer = "Block";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kBlockIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
220,226c242,247
<     int line_no = 1;
<     BLOCK* Block1 = 0;
<     BLOCK* Block2 = 0;
<     char dataLine[255];
<     char inBlock1[255];
<     char inBlock2[255];
<     while (!feof(fp))
---
>     BlockStruct* Block1 = 0;
>     BlockStruct* Block2 = 0;
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inBlock1[FssimUtil::MAX_PATH_LENGTH];
>     char inBlock2[FssimUtil::MAX_PATH_LENGTH];
>     while (!feof(pFile))
228,230c249,251
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
232c253
<             fclose(fp);
---
>             fclose(pFile);
235,236c256,257
<         int count = sscanf(dataLine, "%s %s", inBlock1, inBlock2);
<         if (count != 2)
---
>         m_fieldCount = sscanf(inputDataLine, "%s %s", inBlock1, inBlock2);
>         if (m_fieldCount != 2)
238c259
<             if (count != -1)
---
>             if (m_fieldCount != -1)
240c261
<                 printf("\nWARNING: %s(Line#:%d): Discarding invalid dataLine", m_fileName.c_str(), line_no);
---
>                 this->discardInvalidDataLine();
242,255d262
<         } else {
<             Block1 = static_cast<BLOCK*>(func_find_block(inBlock1));
<             if (Block1 ==  0)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Could not find specified block(%s)\n\n", m_fileName.c_str(),line_no,inBlock1);
<                 exit(1);
<             }
<             Block2 = static_cast<BLOCK*>(func_find_block(inBlock2));
<             if (Block2 ==  0)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Could not find specified block(%s)\n\n", m_fileName.c_str(),line_no,inBlock2);
<                 exit(1);
<             }
<             Block1->Neighbours = static_cast<LIST_PTR*>(List::insert(Block1->Neighbours, Block2, 0/*NULL*/));
256a264,270
>         else
>         {
>             Block1 = BlockStruct::find(inBlock1);
>             Block2 = BlockStruct::find(inBlock2);
> 
>             Block1->m_neighbourIndices.push_front(Block2->id);
>         }
258c272,274
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
263,264c279,280
<     FILE* fp = 0;
<     GROUP* group = 0;
---
>     FILE* pFile = 0;
>     GroupStruct* pGroup = 0;
266,268c282
< 
<     // v3.0 to v4.0: changed name of dataline to dataLine
<     char dataLine[255];
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
272,279c286,293
<     int instart = 0;
<     int inend = 0;
<     char inzonestr[255];
<     char inaustr[255];
<     char inagestr[255];
<     char inctypestr[255];
<     char inragestr[255];
<     char ingroupstr[255];
---
>     int inputStart = 0;
>     int inputEnd = 0;
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inagestr[FssimUtil::MAX_PATH_LENGTH];
>     char inctypestr[FssimUtil::MAX_PATH_LENGTH];
>     char inragestr[FssimUtil::MAX_PATH_LENGTH];
>     char ingroupstr[FssimUtil::MAX_PATH_LENGTH];
283,284c297,300
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp ==  0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile ==  0)
286,289d301
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
291c303
<         return;
---
>         throw OpenException(false, false); // not fatal
295,296c307,308
<     string headerStringBuffer = "Group";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kGroupIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
298,299c310
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
301,302c312,313
<         fgets(dataLine, sizeof(dataLine), fp);
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         if (feof(pFile))
304c315
<             fclose(fp);
---
>             fclose(pFile);
307,313c318,321
<         line_no++;
<         int count = sscanf(dataLine, "%s %d %d %s %s %s %s %s",
<             // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<             //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<             //&ingroupstr, &instart, &inend, &inzonestr, &inaustr, &inagestr, &inctypestr, &inragestr);
<             ingroupstr, &instart, &inend, inzonestr, inaustr, inagestr, inctypestr, inragestr);
<         if (count != 8)
---
>         m_lineNumber++;
>         m_fieldCount = sscanf(inputDataLine, "%s %d %d %s %s %s %s %s",
>             ingroupstr, &inputStart, &inputEnd, inputZoneString, inputAUString, inagestr, inctypestr, inragestr);
>         if (m_fieldCount != 8)
315c323
<             if (count != -1)
---
>             if (m_fieldCount != -1)
317c325
<                 printf("\nWARNING: %s(Line#:%d): Discarding invalid dataLine", m_fileName.c_str(), line_no);
---
>                 this->discardInvalidDataLine();
322c330
<             if (strlen(ingroupstr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(ingroupstr) > FssimUtil::MAX_LABEL_LENGTH)
324,325c332
<                 printf("\n\nERROR: %s(Line#:%d): Group label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kGroupIdentifier);
327c334
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputZoneString) > FssimUtil::MAX_LABEL_LENGTH)
329,330c336
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
332c338
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputAUString) > FssimUtil::MAX_LABEL_LENGTH)
334,335c340
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
337,339c342,344
<             strcpy(inagestr, to_lowercase(inagestr).c_str());
<             strcpy(inctypestr, to_lowercase(inctypestr).c_str());
<             strcpy(inragestr, to_lowercase(inragestr).c_str());
---
>             strcpy(inagestr, FssimUtil::to_lowercase(inagestr).c_str());
>             strcpy(inctypestr, FssimUtil::to_lowercase(inctypestr).c_str());
>             strcpy(inragestr, FssimUtil::to_lowercase(inragestr).c_str());
341,342c346,347
<             group = static_cast<GROUP*>(func_find_group(ingroupstr));
<             if (group ==  0)
---
>             pGroup = GroupStruct::find(ingroupstr);
>             if ((inputStart <= 0)||(inputStart > FssimApp::MAX_PLAN_HORIZON))
344,345c349
<                 printf("\n\nERROR: %s(Line#:%d): Could not find specified group(%s)\n\n", m_fileName.c_str(), line_no, ingroupstr);
<                 exit(1);
---
>                 throw InvalidDataException(inputStart, "Specified Start Period outside allowed range");
347c351
<             if ((instart <= 0)||(instart>FssimApp::MAX_PLAN_HORIZON))
---
>             if ((inputEnd < inputStart)||(inputEnd > FssimApp::MAX_PLAN_HORIZON))
349,350c353
<                 printf("\n\nERROR: %s(Line#:%d): Specified Start Period(%d) outside allowed range(%d,%d)\n\n", m_fileName.c_str(), line_no, instart, 1, FssimApp::MAX_PLAN_HORIZON);
<                 exit(1);
---
>                 throw InvalidDataException(inputEnd, "Specified End Period outside allowed range");
352c355,356
<             if ((inend<instart)||(inend>FssimApp::MAX_PLAN_HORIZON))
---
> 
>             if ((inagestr == FssimUtil::m_kNullString))
354,355c358
<                 printf("\n\nERROR: %s(Line#:%d): Specified End Period(%d) outside allowed range(%d,%d)\n\n", m_fileName.c_str(), line_no, inend, instart, FssimApp::MAX_PLAN_HORIZON);
<                 exit(1);
---
>                 inage = FssimUtil::DUMMY_INPUT;
357,358c360
< 
<             if ((strcmp(inagestr, FssimApp::m_kNullString) == 0))
---
>             else
360,361d361
<                 inage = FssimApp::DUMMYINPUT;
<             } else {
363c363
<                 if (inage == FssimApp::ERRORVAL)
---
>                 if (inage == FssimUtil::ERRORVAL)
365,366c365
<                     printf("\n\nERROR: %s(Line#:%d): Invalid Age value(%s)\n\n", m_fileName.c_str(), line_no, inagestr);
<                     exit(1);
---
>                     throw InvalidDataException(inagestr, "Invalid Age value");
370c369
<             if ((strcmp(inctypestr, FssimApp::m_kNullString) == 0))
---
>             if ((inctypestr == FssimUtil::m_kNullString))
372c371
<                 inctype = FssimApp::DUMMYINPUT;
---
>                 inctype = FssimUtil::DUMMY_INPUT;
376c375
<                 if (strcmp(inctypestr, "o") == 0)
---
>                 if (inctypestr[0] == FssimUtil::m_kOperableClassIdentifier)
378c377
<                     inctype = FssimApp::OPERABLE;
---
>                     inctype = GroupDefStruct::OPERABLE;
380c379
<                 else if (strcmp(inctypestr, "i") == 0)
---
>                 else if (inctypestr[0] == FssimUtil::m_kInoperableClassIdentifier)
382c381
<                     inctype = FssimApp::INOPERABLE;
---
>                     inctype = GroupDefStruct::INOPERABLE;
384c383
<                 else if (strcmp(inctypestr, "d") == 0)
---
>                 else if (inctypestr[0] == FssimUtil::m_kDeferredClassIdentifier)
386c385
<                     inctype = FssimApp::DEFERRED;
---
>                     inctype = GroupDefStruct::DEFERRED;
388c387
<                 else if (strcmp(inctypestr, "n") == 0)
---
>                 else if (inctypestr[0] == FssimUtil::m_kNonContributingClassIdentifier)
390c389
<                     inctype = FssimApp::NONCONTRIBUTING;
---
>                     inctype = GroupDefStruct::NONCONTRIBUTING;
394,395c393
<                     printf("\n\nERROR: %s(Line#:%d): Invalid ClassType value(%s)\n\n", m_fileName.c_str(), line_no, inctypestr);
<                     exit(1);
---
>                     throw InvalidDataException(inctypestr, "Invalid ClassType value");
399c397
<             if ((strcmp(inragestr, FssimApp::m_kNullString) == 0))
---
>             if ((inragestr == FssimUtil::m_kNullString))
401c399
<                 inrage = FssimApp::DUMMYINPUT;
---
>                 inrage = FssimUtil::DUMMY_INPUT;
406c404
<                 if (inrage == FssimApp::ERRORVAL)
---
>                 if (inrage == FssimUtil::ERRORVAL)
408,409c406
<                     printf("\n\nERROR: %s(Line#:%d): Invalid Reversion Age value(%s)\n\n", m_fileName.c_str(), line_no, inragestr);
<                     exit(1);
---
>                     throw InvalidDataException(inragestr, "Invalid Reversion Age value");
413c410,434
<             init_make_transfer(group, instart, inend, inzonestr, inaustr, inage, inctype, inrage);
---
>             // zone
>             int zoneID = FssimUtil::DUMMY_INPUT;
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
>             {
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
>             }
>             if ( FssimUtil::to_lowercase(inputZoneString) != FssimUtil::m_kNullString )
>             {
>                 ZoneStruct* pZone = ZoneStruct::find(inputZoneString);
>                 zoneID = pZone->id;
>             }
> 
>             // au
>             int auLabelIndex = FssimUtil::DUMMY_INPUT;
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
>             {
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
>             }
>             if ( FssimUtil::to_lowercase(inputAUString) != FssimUtil::m_kNullString )
>             {
>                 AUStruct* pAU = AUStruct::find(inputAUString);
>                 auLabelIndex = pAU->m_labelIndex;
>             }
> 
>             init_make_transfer(pGroup, inputStart, inputEnd, zoneID, auLabelIndex, inage, inctype, inrage);
417c438,440
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
422a446,453
>     FILE* pFile = 0;
>     ZoneStruct* pZone = 0;
>     AUStruct* pAU = 0;
>     GroupStruct* pGroup = 0;
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char ingroupstr[FssimUtil::MAX_PATH_LENGTH];
424,431c455,457
<     FILE* fp = 0;
<     ZONE* zone = 0;
<     AU* au = 0;
<     GROUP* group = 0;
<     char dataLine[255];
<     char inzonestr[255];
<     char inaustr[255];
<     char ingroupstr[255];
---
>     int	inputStart = 0;
>     int inputEnd = 0;
>     int inputPriority = 0;
433,435d458
<     int	instart = 0;
<     int inend = 0;
<     int inprio = 0;
437d459
< 
440,441c462,465
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
443,447c467
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
449,450c469,470
<     string headerStringBuffer = "Zone";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kZoneIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
452,453c472
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
455,457c474,476
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
459c478
<             fclose(fp);
---
>             fclose(pFile);
462,466c481,482
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //c = sscanf(dataLine, "%s %s %s %d %d %d", &inzonestr, &inaustr, &ingroupstr, &instart, &inend, &inprio);
<         int count = sscanf(dataLine, "%s %s %s %d %d %d", inzonestr, inaustr, ingroupstr, &instart, &inend, &inprio);
<         if (count != 6)
---
>         m_fieldCount = sscanf(inputDataLine, "%s %s %s %d %d %d", inputZoneString, inputAUString, ingroupstr, &inputStart, &inputEnd, &inputPriority);
>         if (m_fieldCount != 6)
468c484
<             if (count != -1)
---
>             if (m_fieldCount != -1)
470c486
<                 printf("\nWARNING: %s(Line#:%d): Fields read: %d; Discarding invalid dataLine", m_fileName.c_str(), line_no, count);
---
>                 this->discardInvalidDataLine();
475c491
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
477,478c493
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
480c495
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
482,483c497
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
485c499
<             if (strlen(ingroupstr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(ingroupstr)>FssimUtil::MAX_LABEL_LENGTH)
487,488c501
<                 printf("\n\nERROR: %s(Line#:%d): Group label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kGroupIdentifier);
490,491c503,505
<             /* validate data */
<             if ((instart <= 0)||(instart>FssimApp::MAX_PLAN_HORIZON))
---
> 
>             // validate data
>             if ((inputStart <= 0)||(inputStart > FssimApp::MAX_PLAN_HORIZON))
493,494c507,509
<                 printf("\n\nERROR: %s(Line#:%d): Specified period(%d) outside allowed range (%d, %d)\n\n", m_fileName.c_str(), line_no, instart, 1, FssimApp::MAX_PLAN_HORIZON);
<                 exit(1);
---
>                 ostringstream message;
>                 message << "Specified period outside allowed range: " << 1 << " to " << FssimApp::MAX_PLAN_HORIZON;
>                 throw InvalidDataException(inputStart, message.str());
496c511
<             if ((inend<instart)||(inend>FssimApp::MAX_PLAN_HORIZON))
---
>             if ((inputEnd < inputStart) || (inputEnd > FssimApp::MAX_PLAN_HORIZON))
498,499c513,515
<                 printf("\n\nERROR: %s(Line#:%d): Specified period(%d) outside allowed range (%d, %d)\n\n", m_fileName.c_str(), line_no, inend, instart, FssimApp::MAX_PLAN_HORIZON);
<                 exit(1);
---
>                 ostringstream message;
>                 message << "Specified period outside allowed range: " << inputStart << " to " << FssimApp::MAX_PLAN_HORIZON;
>                 throw InvalidDataException(inputEnd, message.str());
501c517
<             if ((inprio<FssimApp::MIN_PRIORITY)||(inprio>FssimApp::MAX_PRIORITY))
---
>             if ((inputPriority < FssimApp::MIN_PRIORITY) || (inputPriority > FssimApp::MAX_PRIORITY))
503,504c519,521
<                 printf("\n\nERROR: %s(Line#:%d): Specified priority(%d) outside allowed range (%d, %d)\n\n", m_fileName.c_str(), line_no, inprio, FssimApp::MIN_PRIORITY, FssimApp::MAX_PRIORITY);
<                 exit(1);
---
>                 ostringstream message;
>                 message << "Specified period outside allowed range: " << FssimApp::MIN_PRIORITY << " to " << FssimApp::MAX_PRIORITY;
>                 throw InvalidDataException(inputPriority, message.str());
507c524
<             if (!strcmp(inzonestr, FssimApp::m_kNullString) == 0)
---
>             if (inputZoneString != FssimUtil::m_kNullString) // if priority is by zone...
509c526
<                 if (!strcmp(ingroupstr, FssimApp::m_kNullString) == 0)
---
>                 if (ingroupstr != FssimUtil::m_kNullString) // ... it can't be by group too!
511,512c528,530
<                     printf("\n\nERROR: %s(Line#:%d): Cannot specify zone(%s) and group(%s) in same record\n\n", m_fileName.c_str(), line_no, inzonestr, ingroupstr);
<                     exit(1);
---
>                     ostringstream invalidValue;
>                     invalidValue << inputZoneString << " / " << ingroupstr;
>                     throw InvalidDataException(invalidValue.str(), "Cannot specify zone and group in same record");
514,515c532,534
<                 zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<                 if (zone == 0)
---
> 
>                 pZone = ZoneStruct::find(inputZoneString);
>                 if (inputAUString != FssimUtil::m_kNullString)
517,523c536,538
<                     printf("\n\nERROR: %s(Line#:%d): Could not find specified zone (%s)\n\n", m_fileName.c_str(), line_no, inzonestr);
<                     exit(1);
<                 }
<                 if (!strcmp(inaustr, FssimApp::m_kNullString) == 0)
<                 {
<                     au = static_cast<AU*>(func_find_au(zone, inaustr));
<                     if (au == 0)
---
>                     pAU = pZone->findAU(inputAUString);
> 
>                     for(int i = inputStart;i <= inputEnd; i++)
525,529d539
<                         printf("\n\nERROR: %s(Line#:%d): Could not find specified zone/au (%s,%s)\n\n", m_fileName.c_str(), line_no, inzonestr, inaustr);
<                         exit(1);
<                     }
<                     for(int i = instart;i <= inend; i++)
<                     {
532c542
<                             au->priority[i] = inprio;
---
>                             pAU->priority[i] = inputPriority;
536c546
<                 else
---
>                 else // priority is by zone only
538c548
<                     for(int j = instart;j <= inend; j++)
---
>                     for(int j = inputStart;j <= inputEnd; j++)
542c552
<                             zone->priority[j] = inprio;
---
>                             pZone->priority[j] = inputPriority;
547c557
<             else
---
>             else // priority is not by zone
549,550c559
<                 bool got_au = false;
<                 if (!strcmp(inaustr, FssimApp::m_kNullString) == 0)
---
>                 if (inputAUString != FssimUtil::m_kNullString) // if priority is by AU only...
552c561
<                     if (!strcmp(ingroupstr,FssimApp::m_kNullString) == 0)
---
>                     if (ingroupstr != FssimUtil::m_kNullString) // ... it can't be by group too!
554,555c563,565
<                         printf("\n\nERROR: %s(Line#:%d): Cannot specify AU(%s) and group(%s) in same record\n\n", m_fileName.c_str(), line_no, inaustr, ingroupstr);
<                         exit(1);
---
>                         ostringstream invalidValue;
>                         invalidValue << inputAUString << " / " << ingroupstr;
>                         throw InvalidDataException(invalidValue.str(), "Cannot specify AUStruct and group in same record");
557,560c567,571
<                     got_au = false;
<                     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<                     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<                     while (zone != 0)
---
> 
>                     bool foundAUInAtLeastOneZone = false;
>                     typedef vector<ZoneStruct*>::iterator ZI;
>                     int auLabelIndex = AUStruct::findLabelIndex(inputAUString);
>                     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
562,563c573
<                         au = static_cast<AU*>(func_find_au(zone, inaustr));
<                         if (au !=  0)
---
>                         try
565,567c575,578
<                             got_au = true;
<                             for(int k = instart; k <= inend; k++)
<                             {
---
>                             pAU = (*zoneIter)->findAU(auLabelIndex);
>                             foundAUInAtLeastOneZone = true;
>                             for(int k = inputStart; k <= inputEnd; k++) // set priorities in specified AU
>                             {                                           // within each zone that has such an AU
570c581
<                                     au->priority[k] = inprio;
---
>                                     pAU->priority[k] = inputPriority;
574c585,588
<                         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
---
>                         catch(DataNotFoundException& e)
>                         {
>                             // continue to next zone, no such AU for this zone
>                         }
576c590
<                     if (got_au == false)
---
>                     if (!foundAUInAtLeastOneZone)
578,579c592
<                         printf("\n\nERROR: %s(Line#:%d): Could not find specified AU(%s)\n\n", m_fileName.c_str(), line_no, inaustr);
<                         exit(1);
---
>                         throw DataNotFoundException(FssimUtil::m_kAUIdentifier, inputAUString);
584c597
<                     if (strcmp(ingroupstr,FssimApp::m_kNullString) == 0)
---
>                     if (ingroupstr == FssimUtil::m_kNullString)
586,587c599
<                         printf("\n\nERROR: %s(Line#:%d): No landunit specified; must specify at least one of zone/AU/group\n\n", m_fileName.c_str(), line_no);
<                         exit(1);
---
>                         throw InvalidDataLineException(0, "No landunit specified; must specify at least one of zone/AUStruct/group");
589,590c601,602
<                     group = static_cast<GROUP*>(func_find_group(ingroupstr));
<                     if (group == 0)
---
>                     pGroup = GroupStruct::find(ingroupstr);
>                     for(int m = inputStart;m <= inputEnd; m++)
592,596d603
<                         printf("\n\nERROR: %s(Line#:%d): Could not find specified group (%s)\n\n", m_fileName.c_str(), line_no, ingroupstr);
<                         exit(1);
<                     }
<                     for(int m = instart;m <= inend; m++)
<                     {
599c606
<                             group->priority[m] = inprio;
---
>                             pGroup->priority[m] = inputPriority;
606c613,615
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
612,619c621,622
< 
<     ZONE* zone = 0;
<     AU* au = 0;
<     TIMBER_CLASS* timber_class = 0;
< 
<     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<     while (zone != 0)
---
>     typedef vector<ZoneStruct*>::iterator ZI;
>     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
621,623c624,625
<         zone->aulist = static_cast<LIST_PTR*>(List::reset(zone->aulist));
<         au = static_cast<AU*>(List::next(zone->aulist));
<         while (au != 0)
---
>         typedef vector<AUStruct*>::iterator AI;
>         for (AI auIter = (*zoneIter)->aulist.begin(); auIter != (*zoneIter)->aulist.end(); ++auIter)
625,632c627,628
<             au->classlist = static_cast<LIST_PTR*>(List::reset(au->classlist));
<             timber_class = static_cast<TIMBER_CLASS*>(List::next(au->classlist));
<             while (timber_class != 0)
<             {
<                 timber_class->area = timber_class->area * au->landoaf;
<                 timber_class = static_cast<TIMBER_CLASS*>(List::next(au->classlist));
<             }
<             au = static_cast<AU*>(List::next(zone->aulist));
---
>             ImplementLandoaf scalarMultiplier((*auIter)->landoaf);
>             for_each( (*auIter)->classlist.begin(), (*auIter)->classlist.end(), scalarMultiplier );
634c630
<         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
---
> 
640a637
>     FILE* pFile = 0;
642,649d638
<     FILE* fp = 0;
< 
< char dataLine[255], inzonestr[255], inaustr[255];
<     ZONE* zone = 0;
<     AU* au = 0;
<     int		found_au, count, line_no;
<     double		inoaf;
< 
652,653c641,644
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
655,659c646
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
661,662c648,649
<     string headerStringBuffer = "Zone";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kZoneIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
664,665c651
<     line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
667,669c653,656
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
671c658
<             fclose(fp);
---
>             fclose(pFile);
674,679d660
<         memset(inzonestr, '\0', sizeof(inzonestr));
<         memset(inaustr, '\0', sizeof(inaustr));
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %s %lf", &inzonestr, &inaustr, &inoaf);
<         count = sscanf(dataLine, "%s %s %lf", inzonestr, inaustr, &inoaf);
681c662,670
<         if (count != 3)
---
>         char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>         char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>         memset(inputZoneString, '\0', sizeof(inputZoneString));
>         memset(inputAUString, '\0', sizeof(inputAUString));
> 
>         double inputOaf = 0.0;
>         m_fieldCount = sscanf(inputDataLine, "%s %s %lf", inputZoneString, inputAUString, &inputOaf);
> 
>         if (m_fieldCount != 3)
683c672
<             if (count != -1)
---
>             if (m_fieldCount != -1)
685c674
<                 printf("\nWARNING: this->read_landoaf(Line#:%d): Fields read: %d; Discarding invalid dataLine", line_no, count);
---
>                 this->discardInvalidDataLine();
690c679
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
692,693c681
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
695c683
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
697,698c685
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
700,701c687,689
<             /* validate data */
<             if (inoaf < 0.0)
---
> 
>             // validate data
>             if (inputOaf < 0)
703,704c691,693
<                 printf("\n\nERROR: this->read_landoaf(Line#:%d): Landbase OAF < 0.0 for zone/au (%s,%s)\n\n", line_no, inzonestr, inaustr);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << inputZoneString << " / " << inputAUString;
>                 throw InvalidDataException(invalidValue.str(), "Landbase OAF < 0 for zone/au:");
707c696
<             if ((strcmp(inzonestr, FssimApp::m_kNullString) == 0))
---
>             if (inputZoneString == FssimUtil::m_kNullString)
709c698
<                 if ((strcmp(inaustr, FssimApp::m_kNullString) == 0))
---
>                 if (inputAUString == FssimUtil::m_kNullString)
711,714c700,702
<                     // ZONE 0, AU 0
<                     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<                     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<                     while (zone != 0)
---
>                     // ZoneStruct 0, AUStruct 0
>                     typedef vector<ZoneStruct*>::iterator ZI;
>                     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
716,718c704,705
<                         zone->aulist = static_cast<LIST_PTR*>(List::reset(zone->aulist));
<                         au = static_cast<AU*>(List::next(zone->aulist));
<                         while (au != 0)
---
>                         typedef vector<AUStruct*>::iterator AI;
>                         for (AI auIter = (*zoneIter)->aulist.begin(); auIter != (*zoneIter)->aulist.end(); ++auIter)
720c707,708
<                             if (au->landoaf != 1.00)
---
>                             AUStruct* pCurrentAU = (*auIter);
>                             if (pCurrentAU->landoaf != 1.00)
722c710,713
<                                 printf("\nFYI: this->read_landoaf(): Multiple landbase OAFs (%5.2lf, %5.2lf) applied to zone/AU (%s, %s); using %5.2lf", au->landoaf, inoaf, zone->label, au->label, inoaf);
---
>                                 cout << "FYI: this->read_landoaf(): Multiple landbase OAFs ("
>                                      << pCurrentAU->landoaf << ", " << inputOaf
>                                      << ") applied to zone/AUStruct (" << (*zoneIter)->label << ", " << pCurrentAU->label
>                                      << "); using " << inputOaf << endl;
724,725c715,716
<                             au->landoaf = inoaf;
<                             au = static_cast<AU*>(List::next(zone->aulist));
---
>                             pCurrentAU->landoaf = inputOaf;
> 
727c718
<                         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
---
> 
732,736c723,726
<                     // ZONE 0, AU SPECIFIED
<                     found_au = false;
<                     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<                     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<                     while (zone != 0)
---
>                     // ZoneStruct 0, AUStruct SPECIFIED
>                     int auLabelIndex = AUStruct::findLabelIndex(inputAUString);
>                     typedef vector<ZoneStruct*>::iterator ZI;
>                     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
738,739c728,730
<                         au = static_cast<AU*>(func_find_au(zone, inaustr));
<                         if (au !=  0)
---
>                         AUStruct* pAU = (*zoneIter)->findAU(auLabelIndex);
> 
>                         if (pAU->landoaf != 1.00)
741,746c732,735
<                             found_au = true;
<                             if (au->landoaf != 1.00)
<                             {
<                                 printf("\nFYI: this->read_landoaf(): Multiple landbase OAFs (%5.2lf, %5.2lf) applied to zone/AU (%s, %s); using %5.2lf", au->landoaf, inoaf, zone->label, au->label, inoaf);
<                             }
<                             au->landoaf = inoaf;
---
>                             cout << "FYI: this->read_landoaf(): Multiple landbase OAFs ("
>                                  << pAU->landoaf << ", " << inputOaf
>                                  << ") applied to zone/AUStruct (" << (*zoneIter)->label << ", " << pAU->label
>                                  << "); using " << inputOaf << endl;
748c737
<                         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
---
>                         pAU->landoaf = inputOaf;
750,754d738
<                     if (found_au == false)
<                     {
<                         printf("\n\nERROR: this->read_landoaf(Line#:%d): Could not find specified AU(%s)\n\n", line_no, inaustr);
<                         exit(1);
<                     }
756,758c740,744
<             } else {
<                 zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<                 if (zone ==  0)
---
>             }
>             else
>             {
>                 ZoneStruct* pZone = ZoneStruct::find(inputZoneString);
>                 if (inputAUString == FssimUtil::m_kNullString)
760,768c746,748
<                     printf("\n\nERROR: this->read_landoaf(Line#:%d): Could not find specified zone(%s)\n\n", line_no, inzonestr);
<                     exit(1);
<                 }
<                 if ((strcmp(inaustr, FssimApp::m_kNullString) == 0))
<                 {
<                     // ZONE SPECIFIED, AU 0
<                     zone->aulist = static_cast<LIST_PTR*>(List::reset(zone->aulist));
<                     au = static_cast<AU*>(List::next(zone->aulist));
<                     while (au != 0)
---
>                     // ZoneStruct SPECIFIED, AUStruct 0
>                     typedef vector<AUStruct*>::iterator AI;
>                     for (AI auIter = pZone->aulist.begin(); auIter != pZone->aulist.end(); ++auIter)
770c750,751
<                         if (au->landoaf != 1.00)
---
>                         AUStruct* pCurrentAU = (*auIter);
>                         if (pCurrentAU->landoaf != 1.00)
772c753,756
<                             printf("\nFYI: this->read_landoaf(): Multiple landbase OAFs (%5.2lf, %5.2lf) applied to zone/AU (%s, %s); using %5.2lf", au->landoaf, inoaf, zone->label, au->label, inoaf);
---
>                             cout << "FYI: this->read_landoaf(): Multiple landbase OAFs ("
>                                  << pCurrentAU->landoaf << ", " << inputOaf
>                                  << ") applied to zone/AUStruct (" << pZone->label << ", " << pCurrentAU->label
>                                  << "); using " << inputOaf << endl;
774,775c758
<                         au->landoaf = inoaf;
<                         au = static_cast<AU*>(List::next(zone->aulist));
---
>                         pCurrentAU->landoaf = inputOaf;
777,780c760,766
<                 } else {
<                     /* ZONE SPECIFIED, AU SPECIFIED */
<                     au = static_cast<AU*>(func_find_au(zone, inaustr));
<                     if (au == 0)
---
>                 }
>                 else
>                 {
>                     // ZoneStruct SPECIFIED, AUStruct SPECIFIED
>                     AUStruct* pAU = pZone->findAU(inputAUString);
> 
>                     if (pAU->landoaf != 1.00)
782,783c768,771
<                         printf("\n\nERROR: this->read_landoaf(Line#:%d): Could not find specified zone/au (%s,%s)\n\n", line_no, inzonestr, inaustr);
<                         exit(1);
---
>                         cout << "FYI: this->read_landoaf(): Multiple landbase OAFs ("
>                              << pAU->landoaf << ", " << inputOaf
>                              << ") applied to zone/AUStruct (" << pZone->label << ", " << pAU->label
>                              << "); using " << inputOaf << endl;
785,789c773
<                     if (au->landoaf != 1.00)
<                     {
<                         printf("\nFYI: this->read_landoaf(): Multiple landbase OAFs (%5.2lf, %5.2lf) applied to zone/AU (%s, %s); using %5.2lf", au->landoaf, inoaf, zone->label, au->label, inoaf);
<                     }
<                     au->landoaf = inoaf;
---
>                     pAU->landoaf = inputOaf;
794c778
<     fclose(fp);
---
>     fclose(pFile);
799a784
>     double totalPercentage = 0.0;
801,809c786,787
< 
<     ZONE* zone = 0;
<     AU* au = 0;
<     REGEN* regen = 0;
<     double acc = 0.0;
< 
<     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<     while (zone != 0)
---
>     typedef vector<ZoneStruct*>::iterator ZI;
>     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
811,813c789,790
<         zone->aulist = static_cast<LIST_PTR*>(List::reset(zone->aulist));
<         au = static_cast<AU*>(List::next(zone->aulist));
<         while (au != 0)
---
>         typedef vector<AUStruct*>::iterator AI;
>         for (AI auIter = (*zoneIter)->aulist.begin(); auIter != (*zoneIter)->aulist.end(); ++auIter)
815,816c792,794
<             /* If no regen, create dummy regen; simplifies processing later */
<             if (au->regenlist == 0)
---
>             // If no regen, create dummy regen; simplifies processing later
>             AUStruct* pCurrentAU = (*auIter);
>             if (pCurrentAU->regenlist.empty())
818,819c796,797
<                 acc = 100.0;
<                 regen = init_make_regen(au, au, 0, 100.0, 0, 0);
---
>                 totalPercentage = 100.0;
>                 init_make_regen(pCurrentAU, pCurrentAU->m_labelIndex);
821c799,801
<                 cout << endl << "creating default regen with age 0" << endl;
---
>             cout << endl << "creating default regen with pParentAU label/id/label index: "
>                  << pCurrentAU->label << "/" << pCurrentAU->id << "/"
>                  << pCurrentAU->m_labelIndex << endl;
826,830c806,810
<                 /* Check that regen percentages add up to 100% (within double tolerances) */
<                 acc = 0.0;
<                 au->regenlist = static_cast<LIST_PTR*>(List::reset(au->regenlist));
<                 regen = static_cast<REGEN*>(List::next(au->regenlist));
<                 while (regen != 0)
---
>                 // Check that regen percentages add up to 100% (within double tolerances)
>                 totalPercentage = 0.0;
> 
>                 vector<RegenStruct*>::iterator regenIter = pCurrentAU->regenlist.begin();
>                 while (regenIter != pCurrentAU->regenlist.end())
832c812
<                     acc += regen->percent;
---
>                     totalPercentage += (*regenIter)->percent;
834c814
<                     cout << "checking regen with age: " << regen->ToAge << endl;
---
>                     cout << "checking regen with age: " << (*regenIter)->ToAge << endl;
836c816
<                     regen = static_cast<REGEN*>(List::next(au->regenlist));
---
>                     regenIter++;
838c818,819
<                 if ((acc<100.0-FssimApp::m_kRoundError)||(acc>100.0+FssimApp::m_kRoundError))
---
>                 if ( (totalPercentage < 100.0 - FssimUtil::m_kRoundError) ||
>                      (totalPercentage > 100.0 + FssimUtil::m_kRoundError) )
840,841c821,824
<                     printf("\n\nERROR: this->check_regen(): Regeneration percentages for zone/au (%s,%s) do not add up to 100%%\n\n", zone->label, au->label);
<                     exit(1);
---
>                     ostringstream message;
>                     message << "ERROR: check_regen(): Regeneration percentages for zone/aus (";
>                     message << (*zoneIter)->label << ", " << pCurrentAU->label << ") do not add up to 100%%";
>                     throw InvalidDataException(totalPercentage, message.str());
844d826
<             au = static_cast<AU*>(List::next(zone->aulist));
846d827
<         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
848,851d828
< #ifdef _TSB_REGEN_DEBUG
<     // for debug only
<     //exit(1);
< #endif
857,864c834,835
< 
<     ZONE* zone = 0;
<     AU* au = 0;
<     TIMBER_CLASS* timber_class = 0;
< 
<     m_pApp->m_zoneList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_zoneList));
<     zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
<     while (zone !=  0)
---
>     typedef vector<ZoneStruct*>::iterator ZI;
>     for (ZI zoneIter = m_pApp->m_zoneList.begin(); zoneIter != m_pApp->m_zoneList.end(); ++zoneIter)
866,868c837,838
<         zone->aulist = static_cast<LIST_PTR*>(List::reset(zone->aulist));
<         au = static_cast<AU*>(List::next(zone->aulist));
<         while (au !=  0)
---
>         typedef vector<AUStruct*>::iterator AI;
>         for (AI auIter = (*zoneIter)->aulist.begin(); auIter != (*zoneIter)->aulist.end(); ++auIter)
870c840,841
<             if (au->RoadRec !=  0)
---
>             AUStruct* pCurrentAU = (*auIter);
>             if (pCurrentAU->RoadRec !=  0)
872,874c843,844
<                 au->classlist = static_cast<LIST_PTR*>(List::reset(au->classlist));
<                 timber_class = static_cast<TIMBER_CLASS*>(List::next(au->classlist));
<                 while (timber_class !=  0)
---
>                 typedef multimap<int, TimberClassStruct*>::iterator CI;
>                 for (CI classIter = pCurrentAU->classlist.begin(); classIter != pCurrentAU->classlist.end(); ++classIter)
876c846,848
<                     if (timber_class->age<au->RoadRec->age)
---
>                     assert(classIter->second->parent_au != 0);
> 
>                     if (classIter->second->age<pCurrentAU->RoadRec->age)
878c850
<                         timber_class->roaded = true;
---
>                         classIter->second->roaded = true;
880c852
<                     timber_class = static_cast<TIMBER_CLASS*>(List::next(au->classlist));
---
> 
883c855
<             au = static_cast<AU*>(List::next(zone->aulist));
---
> 
885c857
<         zone = static_cast<ZONE*>(List::next(m_pApp->m_zoneList));
---
> 
891c863
<     FILE* fp = 0;
---
>     FILE* pFile = 0;
893,899c865,871
<     char dataLine[255];
<     char inzonestr[255];
<     char inaustr[255];
<     char inraustr[255];
<     char inreentrystr[255];
<     char intoagestr[255];
<     char inoffsetstr[255];
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inputRegenAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inputReEntryString[FssimUtil::MAX_PATH_LENGTH];
>     char inputToAgeString[FssimUtil::MAX_PATH_LENGTH];
>     char inputOffsetString[FssimUtil::MAX_PATH_LENGTH];
902,905c874,877
<     int intoage = 0;
<     int inreentry = 0;
<     int inoffset = 0;
<     double inpercent = 0;
---
>     int inputToAge = 0;
>     int inputReEntry = 0;
>     int inputOffset = 0;
>     double inpercent = 0.0;
907,909c879,881
<     ZONE* zone = 0;
<     AU* au = 0;
<     ROADREC* r = 0;
---
>     ZoneStruct* pZone = 0;
>     AUStruct* pParentAU = 0;
>     RoadRecStruct* r = 0;
914,915c886,889
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
917,921c891
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
923,924c893,894
<     string headerStringBuffer = "Zone";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kZoneIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
926,927c896
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
929,931c898,900
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
933c902
<             fclose(fp);
---
>             fclose(pFile);
936,938c905,907
<         int count = sscanf(dataLine, "%s %s %d %lf %s %s %s %s",
<             inzonestr,inaustr,&inage,&inpercent,inraustr,intoagestr,inoffsetstr,inreentrystr);
<         if (count != 8)
---
>         m_fieldCount = sscanf(inputDataLine, "%s %s %d %lf %s %s %s %s",
>             inputZoneString,inputAUString,&inage,&inpercent,inputRegenAUString,inputToAgeString,inputOffsetString,inputReEntryString);
>         if (m_fieldCount != 8)
940,942c909,913
<             printf("\nWARNING: this->read_road(Line#:%d): Discarding invalid dataLine", line_no);
<         } else {
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>                 this->discardInvalidDataLine();
>         }
>         else
>         {
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
944,945c915
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
947c917
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
949,950c919
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
952c921
<             if (strlen(inraustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputRegenAUString)>FssimUtil::MAX_LABEL_LENGTH)
954,955c923
<                 printf("\n\nERROR: %s(Line#:%d): Regen AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kGroupIdentifier);
957,958c925,930
<             zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<             if (zone == 0)
---
>             pZone = ZoneStruct::find(inputZoneString);
>             pParentAU = pZone->findAU(inputAUString);
> 
>             strcpy(inputToAgeString, FssimUtil::to_lowercase(inputToAgeString).c_str());
>             if ( inputToAgeString == FssimUtil::m_kKeepRegenAgeString ||
>                  inputToAgeString == FssimUtil::to_lowercase(FssimUtil::m_kKeepRegenAgeString.c_str()) )
960,961c932
<                 printf("\n\nERROR: this->read_road(Line#:%d): Could not find/make specified zone(%s)\n\n", line_no, inzonestr);
<                 exit(1);
---
>                 inputToAge = -FssimUtil::INFINITY;
963,964c934
<             au = static_cast<AU*>(func_find_au(zone, inaustr));
<             if (au == 0)
---
>             else
966,975c936,937
<                 printf("\n\nERROR: this->read_road(Line#:%d): Could not find/make specified zone/au(%s,%s)\n\n", line_no, inzonestr, inaustr);
<                 exit(1);
<             }
<             strcpy(intoagestr, to_lowercase(intoagestr).c_str());
<             if ((strcmp(intoagestr, "KEEP") == 0)||(strcmp(intoagestr, "keep") == 0))
<             {
<                 intoage = -FssimApp::INFINITY;
<             } else {
<                 intoage = func_derive_integer(intoagestr);
<                 if (intoage == FssimApp::ERRORVAL)
---
>                 inputToAge = func_derive_integer(inputToAgeString);
>                 if (inputToAge == FssimUtil::ERRORVAL)
977,978c939
<                     printf("\n\nERROR: %s(Line#:%d): Invalid RegenAge value(%s)\n\n", m_fileName.c_str(), line_no, intoagestr);
<                     exit(1);
---
>                     throw InvalidDataException(inputToAgeString, "Invalid RegenAge value");
981,982c942,943
<             inoffset = func_derive_integer(inoffsetstr);
<             if (inoffset == FssimApp::ERRORVAL)
---
>             inputOffset = func_derive_integer(inputOffsetString);
>             if (inputOffset == FssimUtil::ERRORVAL)
984,985c945
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Offset value(%s)\n\n", m_fileName.c_str(), line_no, inoffsetstr);
<                 exit(1);
---
>                 throw InvalidDataException(inputOffsetString, "Invalid Offset value");
987,988c947,948
<             inreentry = func_derive_integer(inreentrystr);
<             if (inreentry == FssimApp::ERRORVAL)
---
>             inputReEntry = func_derive_integer(inputReEntryString);
>             if (inputReEntry == FssimUtil::ERRORVAL)
990,991c950
<                 printf("\n\nERROR: %s(Line#:%d): Invalid ReEntry value(%s)\n\n", m_fileName.c_str(), line_no, inreentrystr);
<                 exit(1);
---
>                 throw InvalidDataException(inputReEntryString, "Invalid ReEntry value");
993c952,953
<             r = static_cast<ROADREC*>(init_make_roadrec(zone, au, inage, inpercent, intoage, inraustr, inoffset, inreentry));
---
>             r = init_make_roadrec(pParentAU, inage, inpercent, inputToAge,
> 	                              AUStruct::find(inputRegenAUString)->m_labelIndex, inputOffset, inputReEntry);
996,997c956,957
<                 printf("\n\nERROR: this->read_road(Line#:%d): Could not allocate new ROADREC structure\n\n", line_no);
<                 exit(1);
---
>                 cerr << endl << endl << "Could not allocate new RoadRecStruct structure" << endl << endl;
>                 throw bad_alloc();
1001c961,963
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1006,1010c968,972
<     FILE* fp = 0;
<     ZONE* zone = 0;
<     AU* au = 0;
<     AU* rau = 0;
<     REGEN* regen = 0;
---
>     FILE* pFile = 0;
>     ZoneStruct* pZone = 0;
>     AUStruct* pParentAU = 0;
>     AUStruct* pRegenAU = 0;
>     RegenStruct* pRegen = 0;
1012,1023c974,984
<     char dataLine[255];
<     char intoagestr[255];
<     char inzonestr[255];
<     char inaustr[255];
<     char inraustr[255];
<     char inreentrystr[255];
<     char inoffsetstr[255];
<     int	intoage = 0;
<     int inreentry = 0;
<     int inoffset = 0;
<     // v3.0 to v4.0: changed name of inrpc to inrpercent
<     double inrpercent = 0.0;
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inputToAgeString[FssimUtil::MAX_PATH_LENGTH];
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inputRegenAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inputReEntryString[FssimUtil::MAX_PATH_LENGTH];
>     char inputOffsetString[FssimUtil::MAX_PATH_LENGTH];
>     int	inputToAge = 0;
>     int inputReEntry = 0;
>     int inputOffset = 0;
>     double inputRegenPercent = 0.0;
1028,1029c989,992
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
1031,1035c994
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
1037,1038c996,997
<     string headerStringBuffer = "Zone";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kZoneIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
1040,1041c999
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1043,1045c1001,1003
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
1047c1005
<             fclose(fp);
---
>             fclose(pFile);
1050,1059c1008,1014
<         memset(inzonestr, '\0', sizeof(inzonestr));
<         memset(inaustr, '\0', sizeof(inaustr));
<         memset(inraustr, '\0', sizeof(inraustr));
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %s %lf %s %s %s %s",
<         //    inzonestr, inaustr, &inrpercent, inraustr, intoagestr, inoffsetstr, &inreentrystr);
<         int count = sscanf(dataLine, "%s %s %lf %s %s %s %s",
<             inzonestr, inaustr, &inrpercent, inraustr, intoagestr, inoffsetstr, inreentrystr);
<         if (count != 7)
---
>         memset(inputZoneString, '\0', sizeof(inputZoneString));
>         memset(inputAUString, '\0', sizeof(inputAUString));
>         memset(inputRegenAUString, '\0', sizeof(inputRegenAUString));
> 
>         m_fieldCount = sscanf(inputDataLine, "%s %s %lf %s %s %s %s",
>             inputZoneString, inputAUString, &inputRegenPercent, inputRegenAUString, inputToAgeString, inputOffsetString, inputReEntryString);
>         if (m_fieldCount != 7)
1061,1063c1016,1020
<             printf("\nWARNING: this->read_regen(Line#:%d): Discarding invalid dataLine", line_no);
<         } else {
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>                 this->discardInvalidDataLine();
>         }
>         else
>         {
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
1065,1066c1022
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
1068c1024
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
1070,1071c1026
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
1073c1028
<             if (strlen(inraustr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(inputRegenAUString)>FssimUtil::MAX_LABEL_LENGTH)
1075,1076c1030
<                 printf("\n\nERROR: %s(Line#:%d): Regen AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong("Regen AU");
1078,1079c1032,1037
<             zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<             if (zone == 0)
---
>             pZone = ZoneStruct::find(inputZoneString);
>             pParentAU = pZone->findAU(inputAUString);
>             pRegenAU = pZone->findAU(inputRegenAUString);
> 
>             if ( inputToAgeString == FssimUtil::m_kKeepRegenAgeString ||
>                  inputToAgeString == FssimUtil::to_lowercase(FssimUtil::m_kKeepRegenAgeString.c_str()) )
1081,1082c1039
<                 printf("\n\nERROR: this->read_regen(Line#:%d): Could not find/make specified zone(%s)\n\n", line_no, inzonestr);
<                 exit(1);
---
>                 inputToAge = -FssimUtil::INFINITY;
1084,1085c1041
<             au = static_cast<AU*>(func_find_au(zone, inaustr));
<             if (au == 0)
---
>             else
1087,1101c1043,1044
<                 printf("\n\nERROR: this->read_regen(Line#:%d): Could not find/make specified zone/au(%s,%s)\n\n", line_no, inzonestr, inaustr);
<                 exit(1);
<             }
<             rau = static_cast<AU*>(func_find_au(zone, inraustr));
<             if (rau == 0)
<             {
<                 printf("\n\nERROR: this->read_regen(Line#:%d): Could not find/make specified zone/au(%s,%s)\n\n", line_no, inzonestr, inraustr);
<                 exit(1);
<             }
<             if ((strcmp(intoagestr, "KEEP") == 0)||(strcmp(intoagestr, "keep") == 0))
<             {
<                 intoage = -FssimApp::INFINITY;
<             } else {
<                 intoage = func_derive_integer(intoagestr);
<                 if (intoage == FssimApp::ERRORVAL)
---
>                 inputToAge = func_derive_integer(inputToAgeString);
>                 if (inputToAge == FssimUtil::ERRORVAL)
1103,1104c1046
<                     printf("\n\nERROR: %s(Line#:%d): Invalid RegenAge value(%s)\n\n", m_fileName.c_str(), line_no, intoagestr);
<                     exit(1);
---
>                     throw InvalidDataException(inputToAgeString, "Invalid RegenAge value");
1107,1108c1049,1050
<             inoffset = func_derive_integer(inoffsetstr);
<             if (inoffset == FssimApp::ERRORVAL)
---
>             inputOffset = func_derive_integer(inputOffsetString);
>             if (inputOffset == FssimUtil::ERRORVAL)
1110,1111c1052
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Offset value(%s)\n\n", m_fileName.c_str(), line_no, inoffsetstr);
<                 exit(1);
---
>                 throw InvalidDataException(inputOffsetString, "Invalid Offset value");
1113,1114c1054,1055
<             inreentry = func_derive_integer(inreentrystr);
<             if (inreentry == FssimApp::ERRORVAL)
---
>             inputReEntry = func_derive_integer(inputReEntryString);
>             if (inputReEntry == FssimUtil::ERRORVAL)
1116,1117c1057
<                 printf("\n\nERROR: %s(Line#:%d): Invalid ReEntryLag value(%s)\n\n", m_fileName.c_str(), line_no, inreentrystr);
<                 exit(1);
---
>                 throw InvalidDataException(inputReEntryString, "Invalid ReEntryLag value");
1119,1120c1059,1062
< #ifdef _TSB_REENTRY_DEBUG
<             cout << endl << "creating regen with reentrylag: " << inreentry << endl;
---
> #ifdef _TSB_REGEN_DEBUG
>             cout << endl << "creating regen with pParentAU label/id/label index: "
>                  << pParentAU->label << "/" << pParentAU->id << "/"
>                  << pParentAU->m_labelIndex << endl;
1122c1064
<             regen = init_make_regen(au, rau, intoage, inrpercent, inoffset, inreentry);
---
>             pRegen = init_make_regen(pParentAU, pRegenAU->m_labelIndex, inputToAge, inputRegenPercent, inputOffset, inputReEntry);
1125c1067,1069
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1131,1132c1075
< 
<     if (m_pApp->m_zone0->target ==  0)
---
>     if (m_pApp->m_zone0->target == 0)
1134,1135c1077
<         printf("\n\nERROR: this->check_targets(): No targets specified for m_pApp->m_zone0\n\n");
<         exit(1);
---
>         InvalidDataException(0, "check_targets(): No targets specified for m_pApp->m_zone0");
1142,1158c1084,1097
< 
<     FILE* fp = 0;
<     ZONE* zone = 0;
<     GROUP* group = 0;
<     TARGET* t = 0;
< 	// v3.0 to v4.0: changed name of dataline to dataLine
<     char dataLine[255];
< 	// v3.0 to v4.0: changed name of dataline to dataLine
<     char unitType[255];
<     // v3.0 to v4.0: changed name of unittype to unitType
<     char inunit[255];
<     char inminareastr[255];
<     char inmaxareastr[255];
<     char inminvolstr[255];
<     char inmaxvolstr[255];
<     int instart = 0;
<     int inend = 0;
---
>     FILE* pFile = 0;
>     ZoneStruct* pZone = 0;
>     GroupStruct* pGroup = 0;
>     StandSet* pStandSet = 0;
>     TargetStruct* t = 0;
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char unitType[FssimUtil::MAX_PATH_LENGTH];
>     char inunit[FssimUtil::MAX_PATH_LENGTH];
>     char inminareastr[FssimUtil::MAX_PATH_LENGTH];
>     char inmaxareastr[FssimUtil::MAX_PATH_LENGTH];
>     char inminvolstr[FssimUtil::MAX_PATH_LENGTH];
>     char inmaxvolstr[FssimUtil::MAX_PATH_LENGTH];
>     int inputStart = 0;
>     int inputEnd = 0;
1164,1167d1102
<     double period_minarea = 0.0;
<     double period_maxarea = 0.0;
<     double period_minvol = 0.0;
<     double period_maxvol = 0.0;
1172,1173c1107,1110
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
1175,1176c1112
<         printf("\n\nERROR: Could not open %s\n\n", m_fileName.c_str());
<         exit(1);
---
>         throw OpenException(/* fatal */);
1179c1115
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
1181,1182c1117
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1184,1186c1119,1121
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
1188c1123
<             fclose(fp);
---
>             fclose(pFile);
1191,1197c1126,1129
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %s %d %d %s %s %s %s",
<         //    unitType, inunit, &instart, &inend, &inminareastr, &inmaxareastr, &inminvolstr, &inmaxvolstr);
<         int count = sscanf(dataLine, "%s %s %d %d %s %s %s %s",
<             unitType, inunit, &instart, &inend, inminareastr, inmaxareastr, inminvolstr, inmaxvolstr);
<         if (count != 8)
---
> 
>         m_fieldCount = sscanf(inputDataLine, "%s %s %d %d %s %s %s %s",
>             unitType, inunit, &inputStart, &inputEnd, inminareastr, inmaxareastr, inminvolstr, inmaxvolstr);
>         if (m_fieldCount != 8)
1199c1131
<             if (count != -1)
---
>             if (m_fieldCount != -1)
1201c1133
<                 printf("\nWARNING: this->read_target(Line#:%d): Fields read: %d; Discarding invalid dataLine", line_no, count);
---
>                 this->discardInvalidDataLine();
1203,1204c1135,1138
<         } else {
<             if (strlen(inunit)>FssimApp::MAX_LABEL_LENGTH)
---
>         }
>         else
>         {
>             if (strlen(inunit)>FssimUtil::MAX_LABEL_LENGTH)
1206,1207c1140
<                 printf("\n\nERROR: %s(Line#:%d): Unit label length exceeds max label length (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong("Unit");
1209,1211c1142,1143
<             /* cast to lower case for ease of processing */
<             //strcpy(unitType, to_lowercase(unitType).c_str());
< 			strcpy(unitType, to_lowercase(unitType).c_str());
---
>             // cast to lower case for ease of comparison
> 			strcpy(unitType, FssimUtil::to_lowercase(unitType).c_str());
1213c1145
<             if ((strcmp(inminareastr, FssimApp::m_kNullString) == 0))
---
>             if (inminareastr == FssimUtil::m_kNullString)
1215,1216c1147,1150
<                 inminarea = (double)FssimApp::DUMMYINPUT;
<             } else {
---
>                 inminarea = FssimUtil::DUMMY_INPUT;
>             }
>             else
>             {
1218c1152
<                 if (inminarea == FssimApp::ERRORVAL)
---
>                 if (inminarea == FssimUtil::ERRORVAL)
1220,1221c1154
<                     printf("\n\nERROR: %s(Line#:%d): Invalid MinArea value(%s)\n\n", m_fileName.c_str(), line_no, inminareastr);
<                     exit(1);
---
>                     throw InvalidDataException(inminareastr, "Invalid MinArea value");
1224c1157
<             if ((strcmp(inmaxareastr, FssimApp::m_kNullString) == 0))
---
>             if (inmaxareastr == FssimUtil::m_kNullString)
1226,1227c1159,1162
<                 inmaxarea = (double)FssimApp::DUMMYINPUT;
<             } else {
---
>                 inmaxarea = FssimUtil::DUMMY_INPUT;
>             }
>             else
>             {
1229c1164
<                 if (inmaxarea == FssimApp::ERRORVAL)
---
>                 if (inmaxarea == FssimUtil::ERRORVAL)
1231,1232c1166
<                     printf("\n\nERROR: %s(Line#:%d): Invalid MaxArea value(%s)\n\n", m_fileName.c_str(), line_no, inmaxareastr);
<                     exit(1);
---
>                     throw InvalidDataException(inmaxareastr, "Invalid MaxArea value");
1235c1169
<             if ((strcmp(inminvolstr, FssimApp::m_kNullString) == 0))
---
>             if (inminvolstr == FssimUtil::m_kNullString)
1237,1238c1171,1174
<                 inminvol = (double)FssimApp::DUMMYINPUT;
<             } else {
---
>                 inminvol = FssimUtil::DUMMY_INPUT;
>             }
>             else
>             {
1240c1176
<                 if (inminvol == FssimApp::ERRORVAL)
---
>                 if (inminvol == FssimUtil::ERRORVAL)
1242,1243c1178
<                     printf("\n\nERROR: %s(Line#:%d): Invalid MinVolume value(%s)\n\n", m_fileName.c_str(), line_no, inminvolstr);
<                     exit(1);
---
>                     throw InvalidDataException(inminvolstr, "Invalid MinVolume value");
1246c1181
<             if ((strcmp(inmaxvolstr, FssimApp::m_kNullString) == 0))
---
>             if (inmaxvolstr == FssimUtil::m_kNullString)
1248,1249c1183,1186
<                 inmaxvol = (double)FssimApp::DUMMYINPUT;
<             } else {
---
>                 inmaxvol = FssimUtil::DUMMY_INPUT;
>             }
>             else
>             {
1251c1188
<                 if (inmaxvol == FssimApp::ERRORVAL)
---
>                 if (inmaxvol == FssimUtil::ERRORVAL)
1253,1254c1190
<                     printf("\n\nERROR: %s(Line#:%d): Invalid MaxVolume value(%s)\n\n", m_fileName.c_str(), line_no, inmaxvolstr);
<                     exit(1);
---
>                     throw InvalidDataException(inmaxvolstr, "Invalid MaxVolume value");
1259c1195
<             if (inend < instart) // the end date can't be after the start date or time runs backward ;-)
---
>             if (inputEnd < inputStart) // the end date can't be after the start date or time runs backward ;-)
1261,1262c1197,1199
<                 printf("\n\nERROR: this->read_target(Line#:%d) Start Period (%d) > End Period (%d)", line_no, instart, inend);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << inputStart << "/" << inputEnd;
>                 throw InvalidDataException(invalidValue.str(), "read_target: Start Period > End Period");
1267c1204
<             if (instart > m_pApp->m_planHorizon)
---
>             if (inputStart > m_pApp->m_planHorizon)
1269,1271c1206,1212
<                 printf("\nWARNING: this->read_target(Line#:%d): Specified StartPeriod(%d)>PlanHorizon(%d); Setting StartPeriod = PlanHorizon",
<                        line_no, instart, m_pApp->m_planHorizon);
<                 instart = m_pApp->m_planHorizon;
---
>                 ostringstream message;
>                 message << "WARNING: read_target(Line#:" << m_lineNumber << "): "
>                         << "Specified StartPeriod (" << inputStart << ") is greater than the PlanHorizon ("
>                         << m_pApp->m_planHorizon << "). Setting StartPeriod equal to PlanHorizon.";
>                 cerr << endl << message.str() << endl;
> 
>                 inputStart = m_pApp->m_planHorizon;
1273c1214
<             if (inend > m_pApp->m_planHorizon)
---
>             if (inputEnd > m_pApp->m_planHorizon)
1275,1277c1216,1222
<                 printf("\nWARNING: this->read_target(Line#:%d): Specified EndPeriod(%d)>PlanHorizon(%d); Setting EndPeriod = PlanHorizon",
<                        line_no, inend, m_pApp->m_planHorizon);
<                 inend = m_pApp->m_planHorizon;
---
>                 ostringstream message;
>                 message << "WARNING: read_target(Line#:" << m_lineNumber << "): "
>                         << "Specified EndPeriod (" << inputEnd << ") is greater than the PlanHorizon ("
>                         << m_pApp->m_planHorizon << "). Setting EndPeriod equal to PlanHorizon.";
>                 cerr << endl << message.str() << endl;
> 
>                 inputEnd = m_pApp->m_planHorizon;
1281c1226
<             if (instart > m_pApp->m_planHorizon)
---
>             if (inputStart > m_pApp->m_planHorizon)
1285,1286c1230,1232
<                 cout << endl << endl << "WARNING: while reading targets.dat(Line#:" << line_no
<                      << "): " << endl << endl << "Specified Start Period(" << instart
---
> 
>                 cerr << endl << endl << "WARNING: while reading targets.dat(Line#:" << m_lineNumber
>                      << "): " << endl << endl << endl << "Specified Start Period(" << inputStart
1289,1291c1235
< 
<                 //printf("\nWARNING: this->read_target(Line#:%d): Specified StartPeriod(%d)>PlanHorizon(%d); Setting StartPeriod = PlanHorizon", line_no, instart, m_pApp->m_planHorizon);
<                 //instart = m_pApp->m_planHorizon;
---
>                 //inputStart = m_pApp->m_planHorizon;
1293c1237
<             if (inend > m_pApp->m_planHorizon)
---
>             if (inputEnd > m_pApp->m_planHorizon)
1297,1301d1240
<                 //
<                 cout << endl << endl << "WARNING: while reading targets.dat(Line#:" << line_no
<                      << "): " << endl << endl << "Specified End Period(" << inend
<                      << ") is beyond the Plan Horizon(" << m_pApp->m_planHorizon << "). Re-setting End Period equal to Plan Horizon" << endl;
<                 inend = m_pApp->m_planHorizon;
1303c1242,1245
<                 //printf("\nWARNING: this->read_target(Line#:%d): Specified EndPeriod(%d)>PlanHorizon(%d); Setting EndPeriod = PlanHorizon", line_no, inend, m_pApp->m_planHorizon);
---
>                 cerr << endl << endl << "WARNING: while reading targets.dat(Line#:" << m_lineNumber
>                      << "): " << endl << endl << endl << "Specified End Period(" << inputEnd
>                      << ") is beyond the Plan Horizon(" << m_pApp->m_planHorizon << "). Re-setting End Period equal to Plan Horizon" << endl;
>                 inputEnd = m_pApp->m_planHorizon;
1306,1308c1248
<             char zoneStringBuffer[20] = "ZONE";
<             char groupStringBuffer[20] = "GROUP";
<             if ( unitType == to_lowercase(zoneStringBuffer) )
---
>             if ( unitType == FssimUtil::m_kZoneIdentifier )
1310,1311c1250,1251
<                 zone = static_cast<ZONE*>(func_find_zone(inunit));
<                 if (zone == 0)
---
>                 pZone = ZoneStruct::find(inunit);
>                 if (pZone->target == 0)
1313,1314c1253
<                     printf("\n\nERROR: this->read_target(Line#:%d): Could not find specified zone(%s)\n\n", line_no, inunit);
<                     exit(1);
---
>                     t = init_make_target(pZone);
1316,1320c1255
<                 if (zone->target == 0)
<                 {
<                     t = static_cast<TARGET*>(init_make_target(zone, 0, FssimApp::ZONE_TYPE, "this->read_target()"));
<                 }
<                 unit = FssimApp::ZONE_TYPE;
---
>                 pStandSet = pZone;
1322c1257
<             else if ( unitType == to_lowercase(groupStringBuffer) )
---
>             else if ( unitType == FssimUtil::m_kGroupIdentifier )
1324,1325c1259,1260
<                 group = static_cast<GROUP*>(func_find_group(inunit));
<                 if (group == 0)
---
>                 pGroup = GroupStruct::find(inunit);
>                 if (pGroup->target == 0)
1327,1328c1262
<                     printf("\n\nERROR: this->read_target(Line#:%d): Could not find specified group(%s)\n\n", line_no, inunit);
<                     exit(1);
---
>                     t = init_make_target(pGroup);
1330,1337c1264
<                 if (group->target ==  0)
<                 {
<                     t = static_cast<TARGET*>(init_make_target(0, group, FssimApp::GROUP_TYPE, "this->read_target()"));
<                 }
<                 unit = FssimApp::GROUP_TYPE;
<             } else {
<                 printf("\n\nERROR: this->read_target(Line#:%d): Invalid unit type specification\n\n", line_no);
<                 exit(1);
---
>                 pStandSet = pGroup;
1339,1340c1266
< 
<             for(int i = instart;i <= inend;i++)
---
>             else
1342,1382c1268,1271
<                 /* Adjust yearly to period target */
<                 if (inmaxvol != (double)FssimApp::DUMMYINPUT)
<                 {
<                     period_maxvol =  inmaxvol * m_pApp->m_periodLength[i];
<                 } else {
<                     period_maxvol =  (double)FssimApp::DUMMYINPUT;
<                 }
<                 if (inminvol != (double)FssimApp::DUMMYINPUT)
<                 {
<                     period_minvol =  inminvol * m_pApp->m_periodLength[i];
<                 } else {
<                     period_minvol =  (double)FssimApp::DUMMYINPUT;
<                 }
<                 if (inmaxarea != (double)FssimApp::DUMMYINPUT)
<                 {
<                     period_maxarea =  inmaxarea * m_pApp->m_periodLength[i];
<                 } else {
<                     period_maxarea =  (double)FssimApp::DUMMYINPUT;
<                 }
<                 if (inminarea != (double)FssimApp::DUMMYINPUT)
<                 {
<                     period_minarea =  inminarea * m_pApp->m_periodLength[i];
<                 } else {
<                     period_minarea =  (double)FssimApp::DUMMYINPUT;
<                 }
<                 if (unit == FssimApp::ZONE_TYPE)
<                 {
<                     zone->target->max_area[i] = period_maxarea;
<                     zone->target->min_area[i] = period_minarea;
<                     zone->target->max_volume[i] = period_maxvol;
<                     zone->target->min_volume[i] = period_minvol;
<                 } else if (unit == FssimApp::GROUP_TYPE)
<                 {
<                     group->target->max_area[i] = period_maxarea;
<                     group->target->min_area[i] = period_minarea;
<                     group->target->max_volume[i] = period_maxvol;
<                     group->target->min_volume[i] = period_minvol;
<                 } else {
<                     printf("\n\nERROR: this->read_targets(): Unknown unit type (%s)\n\n", inunit);
<                     exit(1);
<                 }
---
>                 ostringstream message;
>                 message << "Invalid unit type specification; expecting [" << FssimUtil::m_kZoneIdentifier << ", "
>                         << FssimUtil::m_kGroupIdentifier << "]";
>                 throw InvalidDataException(unitType, message.str());
1383a1273,1277
> 
>             do_target_vectors(inmaxarea, pStandSet->target->max_area, inputStart, inputEnd);
>             do_target_vectors(inminarea, pStandSet->target->min_area, inputStart, inputEnd);
>             do_target_vectors(inmaxvol, pStandSet->target->max_volume, inputStart, inputEnd);
>             do_target_vectors(inminvol, pStandSet->target->min_volume, inputStart, inputEnd);
1386c1280,1282
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1389c1285
< void Data::read_axs()
---
> void Data::do_target_vectors(double inputDataValue, valarray<double>& doubleVector, const int start, const int end)
1391,1400c1287,1325
<     FILE* fp = 0;
<     ZONE* zone = 0;
<     GROUP* group = 0;
<     AXSDEF		*axs;
<     char dataLine[255];
<     char unitType[255];
<     char inAgestr[255];
<     char inPercentableLabel[255];
<     char inunit[255];
<     char inSignstr[255];
---
> 
>     //const int size = end - start + 1; // extra element for zero-based array
> 
>     // create slice_array of correct size to vector multiply
>     // this is correct code, but doesn't work with gcc 2.95 or gcc 3.0!!!
>     //const slice_array<double>& subVector = doubleVector[slice(start, size, 1)];
> 
>     for (int i = start; i <= end; i++)
>     {
>         if (inputDataValue == FssimUtil::DUMMY_INPUT)
>         {
>             // assign FssimUtil::DUMMY_INPUT to every element of sub-vector
>             //subVector = FssimUtil::DUMMY_INPUT;
> 
>             doubleVector[i] = FssimUtil::DUMMY_INPUT;
>         }
>         else
>         {
>             // create slice of correct size to vector multiply by periodLength
>             // slice_array<double>& periodLengthSlice = m_pApp->m_periodLengthDouble[slice(start, size, 1)];
>             // subVector = periodLengthSlice * inputDataValue;
> 
>             doubleVector[i] = m_pApp->m_periodLength[i] * inputDataValue;
>         }
>     }
> }
> 
> void Data::read_axs() throw (OpenException)
> {
>     FILE* pFile = 0;
>     ZoneStruct* pZone = 0;
>     GroupStruct* pGroup = 0;
>     AxsDefStruct* axs = 0;
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char unitType[FssimUtil::MAX_PATH_LENGTH];
>     char inAgestr[FssimUtil::MAX_PATH_LENGTH];
>     char inPercentableLabel[FssimUtil::MAX_PATH_LENGTH];
>     char inunit[FssimUtil::MAX_PATH_LENGTH];
>     char inSignstr[FssimUtil::MAX_PATH_LENGTH];
1404,1405c1329,1330
<     int instart = 0;
<     int inend = 0;
---
>     int inputStart = 0;
>     int inputEnd = 0;
1410,1411c1335,1338
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
1413,1417c1340
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
1420c1343
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
1422,1423c1345
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1425,1427c1347,1349
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
1429c1351
<             fclose(fp);
---
>             fclose(pFile);
1432,1434c1354,1356
<         int count = sscanf(dataLine, "%s %s %d %d %s %s %s",
<             unitType, inunit, &instart, &inend, inPercentableLabel, inSignstr, inAgestr);
<         if (count != 7)
---
>         m_fieldCount = sscanf(inputDataLine, "%s %s %d %d %s %s %s",
>             unitType, inunit, &inputStart, &inputEnd, inPercentableLabel, inSignstr, inAgestr);
>         if (m_fieldCount != 7)
1436c1358
<             if (count != -1)
---
>             if (m_fieldCount != -1)
1438c1360
<                 printf("\nWARNING: this->read_axs(Line#:%d): Fields read: %d; Discarding invalid dataLine", line_no, count);
---
>                 this->discardInvalidDataLine();
1440,1441c1362,1365
<         } else {
<             if (strlen(inunit)>FssimApp::MAX_LABEL_LENGTH)
---
>         }
>         else
>         {
>             if (strlen(inunit)>FssimUtil::MAX_LABEL_LENGTH)
1443,1444c1367
<                 printf("\n\nERROR: %s(Line#:%d): Unit label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong("Unit");
1446c1369
<             if (inend < instart)
---
>             if (inputEnd < inputStart)
1448,1449c1371,1373
<                 printf("\n\nERROR: this->read_axs(Line#:%d) Start Period (%d) > End Period (%d)\n\n", line_no, instart, inend);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << inputStart << "/" << inputEnd;
>                 throw InvalidDataException(invalidValue.str(), "Start Period greater than End Period");
1453c1377
<             if (Percent == FssimApp::ERRORVAL)
---
>             if (Percent == FssimUtil::ERRORVAL)
1455,1456c1379
<                 printf("\n\nERROR: this->read_axs(Line#:%d): Invalid percentage(%s); expecting numeric\n\n", line_no, inPercentableLabel);
<                 exit(1);
---
>                 throw InvalidDataException(inPercentableLabel, "Invalid percentage; expecting a number");
1460,1461c1383,1385
<                 Sign = FssimApp::AXS_GT;
<             } else if (strcmp(inSignstr, "<") == 0)
---
>                 Sign = AxsDefStruct::AXS_GT;
>             }
>             else if (strcmp(inSignstr, "<") == 0)
1463,1466c1387
<                 Sign = FssimApp::AXS_LT;
<             } else {
<                 printf("\n\nERROR: this->read_axs(Line#:%d): Invalid sign(%s); expecting [<, >= ]\n\n", line_no, inSignstr);
<                 exit(1);
---
>                 Sign = AxsDefStruct::AXS_LT;
1467a1389,1392
>             else
>             {
>                 throw InvalidDataException(inSignstr, "Invalid sign; expecting [<, >= ]");
>             }
1469c1394
<             if (Age == FssimApp::ERRORVAL)
---
>             if (Age == FssimUtil::ERRORVAL)
1471,1472c1396
<                 printf("\n\nERROR: this->read_axs(Line#:%d): Invalid value(%s); expecting integer numeric\n\n", line_no, inAgestr);
<                 exit(1);
---
>                 throw InvalidDataException(inAgestr, "Invalid age value; expecting an integer");
1475,1478c1399,1400
<             char zoneStringBuffer[20] = "ZONE";
<             char groupStringBuffer[20] = "GROUP";
<             strcpy(unitType, to_lowercase(unitType).c_str());
<             if ( unitType == to_lowercase(zoneStringBuffer) )
---
>             strcpy(unitType, FssimUtil::to_lowercase(unitType).c_str());
>             if ( unitType == FssimUtil::m_kZoneIdentifier )
1480,1487c1402,1405
<                 zone = static_cast<ZONE*>(func_find_zone(inunit));
<                 if (zone == 0)
<                 {
<                     printf("\n\nERROR: this->read_axs(Line#:%d): Could not find specified zone(%s)\n\n", line_no, inunit);
<                     exit(1);
<                 }
<                 axs = static_cast<AXSDEF*>(init_make_axsdef(zone, 0, FssimApp::ZONE_TYPE, instart, inend, Percent, Sign, Age));
<             } else if ( unitType == to_lowercase(groupStringBuffer) )
---
>                 pZone = ZoneStruct::find(inunit);
>                 axs = init_make_axsdef(pZone, inputStart, inputEnd, Percent, Sign, Age);
>             }
>             else if ( unitType == FssimUtil::m_kGroupIdentifier )
1489,1498c1407,1408
<                 group = static_cast<GROUP*>(func_find_group(inunit));
<                 if (group == 0)
<                 {
<                     printf("\n\nERROR: this->read_axs(Line#:%d): Could not find specified group(%s)\n\n", line_no, inunit);
<                     exit(1);
<                 }
<                 axs = static_cast<AXSDEF*>(init_make_axsdef(0, group, FssimApp::GROUP_TYPE, instart, inend, Percent, Sign, Age));
<             } else {
<                 printf("\n\nERROR: this->read_axs(Line#:%d): Invalid unit type specification(%s); expecting [ZONE,GROUP]\n\n", line_no, unitType);
<                 exit(1);
---
>                 pGroup = GroupStruct::find(inunit);
>                 axs = init_make_axsdef(pGroup, inputStart, inputEnd, Percent, Sign, Age);
1499a1410,1416
>             else
>             {
>                 ostringstream message;
>                 message << "Invalid unit type specification; expecting [" << FssimUtil::m_kZoneIdentifier << ", "
>                         << FssimUtil::m_kGroupIdentifier << "]";
>                 throw InvalidDataException(unitType, message.str());
>             }
1502c1419,1421
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1507c1426
<     FILE* fp = 0;
---
>     FILE* pFile = 0;
1509,1517c1428,1430
<     GROUP* group = 0;
<     GROUPDEF* gd = 0;
<     ZONE* zone = 0;
<     TABLE* au = 0;
<     BLOCK* block = 0;
< 
<     char dataLine[255];
<     char inagelowstr[255];
<     char inagehighstr[255];
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inagelowstr[FssimUtil::MAX_PATH_LENGTH];
>     char inagehighstr[FssimUtil::MAX_PATH_LENGTH];
1519,1523c1432,1436
<     char ingroupstr[255];
<     char inzonestr[255];
<     char inaustr[255];
<     char inctypestr[255];
<     char inblockstr[255];
---
>     char ingroupstr[FssimUtil::MAX_PATH_LENGTH];
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inctypestr[FssimUtil::MAX_PATH_LENGTH];
>     char inblockstr[FssimUtil::MAX_PATH_LENGTH];
1532,1533c1445,1448
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
1535,1539c1450
< #ifdef _TSB_VERBOSE
<         printf("\nWARNING: Could not open file %s", m_fileName.c_str());
<         //cout << "WARNING: Could not open file: " << m_fileName << endl;
< #endif
<         return;
---
>         throw OpenException(false, false); // not fatal
1541,1542c1452,1453
<     string headerStringBuffer = "Group";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kGroupIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
1544,1545c1455
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1547,1549c1457,1459
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
1551c1461
<             fclose(fp);
---
>             fclose(pFile);
1554,1560c1464
<         if ( ( line_no % 1000 ) == 0 ) printf( "." );
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %c %s %s %s %s %s %s",
<         //    &ingroupstr, &ingtype, &inzonestr, &inaustr, &inblockstr, &inagelowstr, &inagehighstr, &inctypestr);
<         int count = sscanf(dataLine, "%s %c %s %s %s %s %s %s",
<             ingroupstr, &ingtype, inzonestr, inaustr, inblockstr, inagelowstr, inagehighstr, inctypestr);
---
>         if ( ( m_lineNumber % 1000 ) == 0 ) printf( "." );
1562c1466,1469
<         if (count != 8)
---
>         m_fieldCount = sscanf(inputDataLine, "%s %c %s %s %s %s %s %s",
>             ingroupstr, &ingtype, inputZoneString, inputAUString, inblockstr, inagelowstr, inagehighstr, inctypestr);
> 
>         if (m_fieldCount != 8)
1564c1471
<             if (count != -1)
---
>             if (m_fieldCount != -1)
1566c1473
<                 printf("\nWARNING: this->read_group(Line#:%d): Fields read: %d; Discarding invalid dataLine", line_no, count);
---
>                 this->discardInvalidDataLine();
1568,1569c1475,1483
<         } else  {
<             if (strlen(ingroupstr)>FssimApp::MAX_LABEL_LENGTH)
---
>         }
>         else
>         {
> 
>             // default values if input string equals FssimUtil::m_kNullString
>             // group
>             GroupStruct* pGroup = 0;
>             GroupDefStruct* pGroupDef = 0;
>             if (strlen(ingroupstr)>FssimUtil::MAX_LABEL_LENGTH)
1571,1572c1485
<                 printf("\n\nERROR: %s(Line#:%d): Group label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kGroupIdentifier);
1574c1487,1490
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
> 
>             // zone
>             int zoneID = FssimUtil::DUMMY_INPUT;
>             if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
1576,1577c1492
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
1579,1580c1494
< 
<             if ( to_lowercase(inzonestr) != FssimApp::m_kNullString )
---
>             if ( FssimUtil::to_lowercase(inputZoneString) != FssimUtil::m_kNullString )
1582,1587c1496,1497
<                 zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<                 if ( 0 == zone )
<                 {
<                     printf("\n\nERROR: %s(Line#:%d): Could not find zone(%s)\n\n", m_fileName.c_str(), line_no, inzonestr);
<                     exit(1);
<                 }
---
>                 ZoneStruct* pZone = ZoneStruct::find(inputZoneString);
>                 zoneID = pZone->id;
1589c1499,1502
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
---
> 
>             // au
>             int auLabelIndex = FssimUtil::DUMMY_INPUT;
>             if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
1591,1592c1504
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
1594c1506
<             if ( to_lowercase(inaustr) != FssimApp::m_kNullString )
---
>             if ( FssimUtil::to_lowercase(inputAUString) != FssimUtil::m_kNullString )
1596,1601c1508,1509
<                 au = static_cast<TABLE*>(func_find_table(inaustr));
<                 if ( 0 == au )
<                 {
<                     printf("\n\nERROR: %s(Line#:%d): Could not find AU(%s)\n\n", m_fileName.c_str(), line_no, inaustr);
<                     exit(1);
<                 }
---
>                 AUStruct* pAU = AUStruct::find(inputAUString);
>                 auLabelIndex = pAU->m_labelIndex;
1603c1511,1514
<             if (strlen(inblockstr)>FssimApp::MAX_LABEL_LENGTH)
---
> 
>             // block
>             int blockID = FssimUtil::DUMMY_INPUT;
>             if (strlen(inblockstr)>FssimUtil::MAX_LABEL_LENGTH)
1605,1606c1516
<                 printf("\n\nERROR: %s(Line#:%d): Block label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong(FssimUtil::m_kBlockIdentifier);
1608c1518
<             if ( to_lowercase(inblockstr) != FssimApp::m_kNullString )
---
>             if ( FssimUtil::to_lowercase(inblockstr) != FssimUtil::m_kNullString )
1610,1615c1520,1521
<                 block = static_cast<BLOCK*>(func_find_block(inblockstr));
<                 if ( 0 == block )
<                 {
<                     printf("\n\nERROR: %s(Line#:%d): Could not find Block(%s)\n\n", m_fileName.c_str(), line_no, inblockstr);
<                     exit(1);
<                 }
---
>                 BlockStruct* pBlock = BlockStruct::find(inblockstr);
>                 blockID = pBlock->id;
1617,1620c1523,1527
<             /* cast to lower case to ease processing */
<             strcpy(inagelowstr, to_lowercase(inagelowstr).c_str());
<             strcpy(inagehighstr, to_lowercase(inagehighstr).c_str());
<             strcpy(inctypestr, to_lowercase(inctypestr).c_str());
---
> 
>             // cast to lower case to ease comparison
>             strcpy(inagelowstr, FssimUtil::to_lowercase(inagelowstr).c_str());
>             strcpy(inagehighstr, FssimUtil::to_lowercase(inagehighstr).c_str());
>             strcpy(inctypestr, FssimUtil::to_lowercase(inctypestr).c_str());
1623,1624c1530,1531
<             /* derive land unit IDs */
<             if (strcmp(ingroupstr, FssimApp::m_kNullString) == 0)
---
>             // derive land unit IDs
>             if (ingroupstr == FssimUtil::m_kNullString)
1626,1627c1533
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Group ID(%s)n\n", m_fileName.c_str(), line_no, ingroupstr);
<                 exit(1);
---
>                 throw InvalidDataException(ingroupstr, "Invalid Group ID");
1630,1631c1536,1537
<             /* derive ages */
<             if (strcmp(inagelowstr, FssimApp::m_kNullString) == 0)
---
>             // derive ages
>             if (inagelowstr == FssimUtil::m_kNullString)
1633,1634c1539,1542
<                 inagelow = -FssimApp::INFINITY;
<             } else {
---
>                 inagelow = -FssimUtil::INFINITY;
>             }
>             else
>             {
1636c1544
<                 if (inagelow == FssimApp::ERRORVAL)
---
>                 if (inagelow == FssimUtil::ERRORVAL)
1638,1639c1546
<                     printf("\n\nERROR: %s(Line#:%d): Invalid AgeLow value(%s)\n\n", m_fileName.c_str(), line_no, inagelowstr);
<                     exit(1);
---
>                     throw InvalidDataException(inagelowstr, "Invalid AgeLow value");
1642c1549
<             if (strcmp(inagehighstr, FssimApp::m_kNullString) == 0)
---
>             if (inagehighstr == FssimUtil::m_kNullString)
1644,1645c1551,1554
<                 inagehigh = FssimApp::INFINITY;
<             } else {
---
>                 inagehigh = FssimUtil::INFINITY;
>             }
>             else
>             {
1647c1556
<                 if (inagehigh == FssimApp::ERRORVAL)
---
>                 if (inagehigh == FssimUtil::ERRORVAL)
1649,1650c1558
<                     printf("\n\nERROR: %s(Line#:%d): Invalid AgeHigh value(%s)\n\n", m_fileName.c_str(), line_no, inagehighstr);
<                     exit(1);
---
>                     throw InvalidDataException(inagehighstr, "Invalid AgeHigh value");
1653c1561
<             if (inagelow>inagehigh)
---
>             if (inagelow > inagehigh)
1655,1656c1563,1565
<                 printf("\n\nERROR: this->read_group(Line#:%d): AgeLow(%d) > AgeHigh(%d)\n\n", line_no, inagelow, inagehigh);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << inagelow << ", " << inagehigh;
>                 throw InvalidDataException(invalidValue.str(), "read_group: AgeLow > AgeHigh");
1659c1568
<             /* group type */
---
>             // group type
1662,1663c1571,1573
<                 gtype = FssimApp::FLOAT_GROUP;
<             } else if (ingtype == 's')
---
>                 gtype = GroupDefStruct::FLOAT_GROUP;
>             }
>             else if (ingtype == 's')
1665,1668c1575
<                 gtype = FssimApp::STATIC_GROUP;
<             } else {
<                 printf("\n\nERROR: %s(Line#:%d): Invalid group(%s) type specification(%c)\n\n", m_fileName.c_str(), line_no, ingroupstr, ingtype);
<                 exit(1);
---
>                 gtype = GroupDefStruct::STATIC_GROUP;
1669a1577,1582
>             else
>             {
>                 ostringstream invalidValue;
>                 invalidValue << ingroupstr << "/" << ingtype;
>                 throw InvalidDataException(invalidValue.str(), "Invalid group/type specification");
>             }
1671,1672c1584,1585
<             /* timber_class type */
<             if (strcmp(inctypestr, FssimApp::m_kNullString) == 0)
---
>             // timber_class type
>             if (inctypestr == FssimUtil::m_kNullString)
1674,1675c1587,1589
<                 ctype = FssimApp::DUMMYINPUT;
<             } else if (strlen(inctypestr) == 1)
---
>                 ctype = FssimUtil::DUMMY_INPUT;
>             }
>             else if (strlen(inctypestr) == 1)
1677c1591
<                 if (strcmp(inctypestr, "o") == 0)
---
>                 if (inctypestr[0] == FssimUtil::m_kOperableClassIdentifier)
1679,1680c1593,1595
<                     ctype = FssimApp::OPERABLE;
<                 } else if (strcmp(inctypestr, "i") == 0)
---
>                     ctype = GroupDefStruct::OPERABLE;
>                 }
>                 else if (inctypestr[0] == FssimUtil::m_kInoperableClassIdentifier)
1682,1683c1597,1599
<                     ctype = FssimApp::INOPERABLE;
<                 } else if (strcmp(inctypestr, "d") == 0)
---
>                     ctype = GroupDefStruct::INOPERABLE;
>                 }
>                 else if (inctypestr[0] == FssimUtil::m_kDeferredClassIdentifier)
1685,1686c1601,1603
<                     ctype = FssimApp::DEFERRED;
<                 } else if (strcmp(inctypestr, "n") == 0)
---
>                     ctype = GroupDefStruct::DEFERRED;
>                 }
>                 else if (inctypestr[0] == FssimUtil::m_kNonContributingClassIdentifier)
1688,1691c1605
<                     ctype = FssimApp::NONCONTRIBUTING;
<                 } else {
<                     printf("\n\nERROR: this->read_group(Line#:%d): Group(%s); Invalid type specification(%s)\n\n", line_no, ingroupstr, inctypestr);
<                     exit(1);
---
>                     ctype = GroupDefStruct::NONCONTRIBUTING;
1693,1695c1607,1612
<             } else {
<                 printf("\n\nERROR: this->read_group(Line#:%d): Group(%s); Invalid type specification(%s)\n\n", line_no, ingroupstr, inctypestr);
<                 exit(1);
---
>                 else
>                 {
>                     ostringstream invalidValue;
>                     invalidValue << ingroupstr << "/" << inctypestr;
>                     throw InvalidDataException(invalidValue.str(), "Invalid group/type specification");
>                 }
1696a1614,1619
>             else
>             {
>                 ostringstream invalidValue;
>                 invalidValue << ingroupstr << "/" << inctypestr;
>                 throw InvalidDataException(invalidValue.str(), "Invalid group/type specification");
>             }
1698,1700c1621,1624
<             /* create group/group def record */
<             group = static_cast<GROUP*>(init_make_group(ingroupstr, gtype, -1 /*reading ascii files, not binary*/));
<             gd = static_cast<GROUPDEF*>(init_make_groupdef(group, inzonestr, inaustr, inblockstr, inagelow, inagehigh, ctype));
---
>             // create group/group def record
>             pGroup = init_make_group(ingroupstr, gtype, -1); // reading ascii files, not binary
> 
>             pGroupDef = init_make_groupdef(pGroup, zoneID, auLabelIndex, blockID, inagelow, inagehigh, ctype);
1703c1627,1629
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1708,1713c1634,1635
<     double fac = 0.0;
< 
<     m_pApp->m_tableList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_tableList));
<     TABLE* table = 0;
<     table = static_cast<TABLE*>(List::next(m_pApp->m_tableList));
<     while (table != 0)
---
>     typedef map<int, TableStruct*>::iterator TI;
>     for (TI tableIter = m_pApp->m_tableList.begin(); tableIter != m_pApp->m_tableList.end(); ++tableIter)
1715c1637,1645
<         for(int i = 0;i < FssimApp::MAX_NUM_TABLE_VERTICES;i++)
---
>         TableStruct* pCurrentTable = tableIter->second;
>         // vectorize for table->volume as valarray (prepare for Altivec vectorization)
> 
>         // vector multiply by scalar
>         //pCurrentTable->Volume *= pCurrentTable->voaf1;
>         //valarray<double> facVector(0.0, FssimUtil::MAX_NUM_TABLE_VERTICES);
> 
>         double fac = 0.0;
>         for(int i = 0;i < FssimUtil::MAX_NUM_TABLE_VERTICES ;i++)
1717,1721c1647,1654
<             /* volume oaf1 */
<             table->Volume[i] = table->Volume[i]*table->voaf1;
<             /* volume oaf2 */
<             fac = ( 100.0 - (table->voaf2 * 100.0 * i / table->RefAge) ) / 100.0;
<             if (fac<0.0)
---
>             // volume oaf1
>             pCurrentTable->Volume[i] = pCurrentTable->Volume[i] * pCurrentTable->voaf1;
> 
>             // volume oaf2
>             //facVector[i] = ( 100.0 - (pCurrentTable->voaf2 * 100.0 * i / pCurrentTable->RefAge) ) / 100.0;
>             fac = ( 100.0 - (pCurrentTable->voaf2 * 100.0 * i / pCurrentTable->RefAge) ) / 100.0;
>             //if (facVector[i] < 0.0)
>             if (fac < 0.0)
1723,1724c1656,1660
<                 printf("\n\nERROR: Table(%s): Volume OAF2(%lf) at ReferenceAge(%d) results in negative volume at age(%d)\n\n", table->label, table->voaf2, table->RefAge, i);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << pCurrentTable->label << "/" << pCurrentTable->voaf2 << "/" << pCurrentTable->RefAge;
>                 ostringstream message;
>                 message << "Table/Volume OAF2/ReferenceAge results in negative volume at age: " << pCurrentTable->RefAge;
>                 throw InvalidDataException(invalidValue.str(), message.str());
1726c1662
<             table->Volume[i] = fac*table->Volume[i];
---
>             pCurrentTable->Volume[i] = fac * pCurrentTable->Volume[i];
1728c1664,1666
<         table = static_cast<TABLE*>(List::next(m_pApp->m_tableList));
---
> 
>         // vector multiply the two equally sized vectors
>         //pCurrentTable->Volume *= facVector;
1734,1738d1671
<     int	age1 = 0;
<     int age2 = 0;
<     double vol1 = 0.0;
<     double vol2 = 0.0;
<     double vinc = 0.0;
1740,1743c1673,1677
<     m_pApp->m_tableList = static_cast<LIST_PTR*>(List::reset(m_pApp->m_tableList));
<     TABLE* table = 0;
<     table = static_cast<TABLE*>(List::next(m_pApp->m_tableList));
<     while (table != 0)
---
>     typedef map<int, TableStruct*>::iterator TI;
> 
>     // vectorize for table->volume as valarray (prepare for Altivec vectorization)
>     // cant really vectorize for now due to limitations on slice_array: Altivec should fix this
>     for (TI tableIter = m_pApp->m_tableList.begin(); tableIter != m_pApp->m_tableList.end(); ++tableIter)
1744a1679,1680
>         TableStruct* pCurrentTable = tableIter->second;
> 
1746,1747c1682,1684
<         age1 = 0; vol1 = table->Volume[age1];
<         for(int i = 1;i < FssimApp::MAX_NUM_TABLE_VERTICES;i++)
---
>         int age1 = 0;
>         double vol1 = pCurrentTable->Volume[age1];
>         for(int i = 1;i < FssimUtil::MAX_NUM_TABLE_VERTICES;i++)
1749,1750c1686,1687
<             if ( (table->Volume[i] > FssimApp::DUMMYINPUT + FssimApp::m_kRoundError) ||
<                  (table->Volume[i] < FssimApp::DUMMYINPUT - FssimApp::m_kRoundError) )
---
>             if ((pCurrentTable->Volume[i] > FssimUtil::DUMMY_INPUT + FssimUtil::m_kRoundError) ||
>                 (pCurrentTable->Volume[i] < FssimUtil::DUMMY_INPUT - FssimUtil::m_kRoundError))
1752,1754c1689,1691
<                 age2 = i;
<                 vol2 = table->Volume[i];
<                 vinc = (vol2-vol1) / (age2-age1);
---
>                 int age2 = i;
>                 double vol2 = pCurrentTable->Volume[i];
>                 double volumeIncrease = (vol2-vol1) / (age2-age1);
1758c1695
<                     table->Volume[j] = table->Volume[age1] + (vinc * k);
---
>                     pCurrentTable->Volume[j] = pCurrentTable->Volume[age1] + (volumeIncrease * k);
1765c1702
<         for(int m = age1;m < FssimApp::MAX_NUM_TABLE_VERTICES;m++)
---
>         for(int m = age1;m < FssimUtil::MAX_NUM_TABLE_VERTICES;m++)
1767c1704
<             table->Volume[m] = vol1;
---
>             pCurrentTable->Volume[m] = vol1;
1769d1705
<         table = static_cast<TABLE*>(List::next(m_pApp->m_tableList));
1775,1776c1711,1712
<     FILE* fp = 0;
<     TABLE* table = 0;
---
>     FILE* pFile = 0;
>     TableStruct* pTable = 0;
1778,1779c1714,1715
<     char dataLine[255];
<     char id[255];
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char label[FssimUtil::MAX_PATH_LENGTH];
1789,1790c1725,1728
<     fp = fopen(m_fileName.c_str(), "r");
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = fopen(m_fileName.c_str(), "r");
>     if (pFile == 0)
1792,1793c1730
<         printf("\n\nERROR: Could not open %s\n\n", m_fileName.c_str());
<         exit(1);
---
>         throw OpenException(); // fatal
1796c1733
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
1798,1799c1735
<     int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1801,1803c1737,1739
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_lineNumber++;
>         if (feof(pFile))
1805c1741
<             fclose(fp);
---
>             fclose(pFile);
1808,1812c1744,1745
<         memset(id, '\0', sizeof(id));
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %d %d %d %lf %lf", &id, &mha, &AdjAge, &RefAge, &voaf1, &voaf2);
<         int count = sscanf(dataLine, "%s %d %d %d %lf %lf", id, &mha, &AdjAge, &RefAge, &voaf1, &voaf2);
---
>         memset(label, '\0', sizeof(label));
>         m_fieldCount = sscanf(inputDataLine, "%s %d %d %d %lf %lf", label, &mha, &AdjAge, &RefAge, &voaf1, &voaf2);
1814c1747
<         if (count < 6)
---
>         if (m_fieldCount < 6)
1816c1749
<             if (count != -1)
---
>             if (m_fieldCount != -1)
1818c1751
<                 printf("\nWARNING: %s(Line#:%d): Fields read: %d; Discarding invalid dataLine", m_fileName.c_str(), line_no, count);
---
>                 this->discardInvalidDataLine();
1823c1756
<             if (strlen(id)>FssimApp::MAX_LABEL_LENGTH)
---
>             if (strlen(label) > FssimUtil::MAX_LABEL_LENGTH)
1825,1826c1758
<                 printf("\n\nERROR: %s(Line#:%d): Label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no, FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
---
>                 this->throwLabelTooLong("Label");
1828,1829c1760,1762
<             table = static_cast<TABLE*>(func_find_table(id));
<             if (table == 0)
---
>             pTable = TableStruct::find(label);
> 
>             if (mha < 0)
1831,1832c1764,1766
<                 printf("\n\nERROR: %s(Line#:%d): Could not find specified table(%s)\n\n", m_fileName.c_str(), line_no, id);
<                 exit(1);
---
>                 ostringstream message;
>                 message << "Invalid Minimum harvest age for table label: " << label;
>                 throw InvalidDataException(mha, message.str());
1834c1768
<             if (mha < 0)
---
>             else
1836,1839c1770
<                 printf("\n\nERROR: %s(Line#:%d): Table: %s;  Minimum harvest age (%d) < 0\n\n", m_fileName.c_str(), line_no, id, mha);
<                 exit(1);
<             } else {
<                 table->mha = mha;
---
>                 pTable->mha = mha;
1843,1846c1774,1776
<                 printf("\n\nERROR: %s(Line#:%d): Table: %s;  Adjacency Age (%d) < 0\n\n", m_fileName.c_str(), line_no, id, AdjAge);
<                 exit(1);
<             } else {
<                 table->AdjacencyAge = AdjAge;
---
>                 ostringstream message;
>                 message << "Invalid Minimum harvest age for table label: " << label;
>                 throw InvalidDataException(AdjAge, message.str());
1848c1778
<             if (voaf1 < 0.0)
---
>             else
1850,1853c1780
<                 printf("\n\nERROR: %s(Line#:%d):  Table: %s; Volume OAF1(%5.1lf) < 0.0\n\n", m_fileName.c_str(), line_no, id, voaf1);
<                 exit(1);
<             } else {
<                 table->voaf1 = voaf1;
---
>                 pTable->AdjacencyAge = AdjAge;
1855c1782
<             if (voaf2<0.0)
---
>             if (voaf1 < 0)
1857,1860c1784,1786
<                 printf("\n\nERROR: %s(Line#:%d): Table: %s; Volume OAF2(%5.1lf) < 0.0\n\n", m_fileName.c_str(), line_no, id, voaf2);
<                 exit(1);
<             } else {
<                 table->voaf2 = voaf2;
---
>                 ostringstream message;
>                 message << "Negative Volume OAF1 for table label: " << label;
>                 throw InvalidDataException(voaf1, message.str());
1862c1788
<             if (RefAge<0)
---
>             else
1864,1867c1790
<                 printf("\n\nERROR: %s(Line#:%d): Table: %s; ReferenceAge<0\n\n", m_fileName.c_str(), line_no, id/*, RefAge */);
<                 exit(1);
<             } else {
<                 table->RefAge = RefAge;
---
>                 pTable->voaf1 = voaf1;
1868a1792,1811
>             if (voaf2 < 0)
>             {
>                 ostringstream message;
>                 message << "Negative Volume OAF2 for table label: " << label;
>                 throw InvalidDataException(voaf2, message.str());
>             }
>             else
>             {
>                 pTable->voaf2 = voaf2;
>             }
>             if (RefAge < 0)
>             {
>                 ostringstream message;
>                 message << "Negative ReferenceAge for table label: " << label;
>                 throw InvalidDataException(RefAge, message.str());
>             }
>             else
>             {
>                 pTable->RefAge = RefAge;
>             }
1871c1814,1816
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1876c1821
<     FILE* fp = 0;
---
>     FILE* pFile = 0;
1878c1823
<     TABLE* table = 0;
---
>     TableStruct* pTable = 0;
1880,1882c1825,1827
<     char instr[255];
<     char inagestr[255];
<     char involstr[255];
---
>     char inputHeaderString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAgeString[FssimUtil::MAX_PATH_LENGTH];
>     char inputVolumeString[FssimUtil::MAX_PATH_LENGTH];
1884c1829
<     int got_vol = 0;
---
>     int gotVolume = 0;
1886c1831
<     double vol = 0;
---
>     double volume = 0.0;
1891,1892c1836,1839
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
1894,1895c1841
<         printf("\n\nERROR: Could not open %s", m_fileName.c_str());
<         exit(1);
---
>         throw OpenException(/* fatal */);
1898,1899c1844
<     //int line_no = 1;
<     while (!feof(fp))
---
>     while (!feof(pFile))
1902,1903c1847,1848
<         char fieldLabel[FssimApp::MAX_LABEL_LENGTH];
<     	const char* fieldLabelPointer = strip_label(fp, "Table:");
---
>         char fieldLabel[FssimUtil::MAX_LABEL_LENGTH];
>     	const char* fieldLabelPointer = FssimUtil::strip_label(pFile, "Table:");
1913c1858
<         if (strlen(fieldLabel)>FssimApp::MAX_LABEL_LENGTH)
---
>         if (strlen(fieldLabel)>FssimUtil::MAX_LABEL_LENGTH)
1915,1916c1860
<             printf("\n\nERROR: %s: Table label (%s) width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), fieldLabel, FssimApp::MAX_LABEL_LENGTH);
<             exit(1);
---
>             this->throwLabelTooLong("Table");
1920,1921c1864
<         table = static_cast<TABLE*>(func_find_table(fieldLabel));
<         if (table != 0)
---
>         try
1923,1925c1866,1870
<             string message = "ERROR: init_make_table(): Duplicate table: ";
<             message += fieldLabel;
<             throw(message);
---
>             pTable = TableStruct::find(fieldLabel);
>             if (pTable != 0)
>             {
>                 throw DuplicateDataException(fieldLabel, "ERROR: init_make_table(): Duplicate table: ");
>             }
1927c1872,1875
<         table = static_cast<TABLE*>(init_make_table(fieldLabel, "this->read_table()", -1 /*reading ascii files, not binary*/));
---
>         catch(DataNotFoundException& e) // ok, make new table and continue
>         {
>             pTable = init_make_table(fieldLabel, -1); // reading ascii files, not binary
>         }
1929,1931c1877,1880
<         fgets(instr, sizeof(instr), fp);	/* instr now holds header - discarded */
<         got_vol = 1;
<         while (got_vol)
---
> 
>         fgets(inputHeaderString, sizeof(inputHeaderString), pFile);	// inputHeaderString now holds header - discarded
>         gotVolume = 1;
>         while (gotVolume)
1933,1934c1882,1883
<             fgets(instr, sizeof(instr), fp);
<             if (feof(fp))
---
>             fgets(inputHeaderString, sizeof(inputHeaderString), pFile);
>             if (feof(pFile))
1936c1885
<                 got_vol = 0;
---
>                 gotVolume = 0;
1939,1940c1888,1889
<             int count = sscanf(instr, "%s %s", inagestr, involstr);
<             if (count == 2)
---
>             m_fieldCount = sscanf(inputHeaderString, "%s %s", inputAgeString, inputVolumeString);
>             if (m_fieldCount == 2)
1942,1945c1891
<                 /* no action; expected number of fields */
<             } else {
<                 got_vol = 0;
<                 break;
---
>                 // no action; expected number of fields
1947,1948c1893
<             age = func_derive_integer(inagestr);
<             if (age == FssimApp::ERRORVAL)
---
>             else
1950,1951c1895,1896
<                 printf("\n\nERROR: %s(Table#:%s): Invalid Age value(%s)\n\n", m_fileName.c_str(), table->label, inagestr);
<                 exit(1);
---
>                 gotVolume = 0;
>                 break;
1953c1898,1900
<             if ((age>FssimApp::MAX_NUM_TABLE_VERTICES)||(age<0))
---
>             age = func_derive_integer(inputAgeString);
> 
>             if ( age == FssimUtil::ERRORVAL || age > FssimUtil::MAX_NUM_TABLE_VERTICES || age < 0 )
1955,1958c1902,1904
<                 printf("\n\nERROR: this->read_table(): Invalid age");
<                 printf("\n\tTable: ...... %s", table->label);
<                 printf("\n\tAge: ........ %6d\n\n", age);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << pTable->label << "/" << inputAgeString;
>                 throw InvalidDataException(invalidValue.str(), "Invalid Table/Age value");
1960,1961c1906,1908
<             vol = func_derive_float(involstr);
<             if (vol == FssimApp::ERRORVAL)
---
> 
>             volume = func_derive_float(inputVolumeString);
>             if (volume == FssimUtil::ERRORVAL || volume < 0)
1963,1964c1910,1912
<                 printf("\n\nERROR: %s(Table#:%s): Invalid Volume value(%s)\n\n", m_fileName.c_str(), table->label, involstr);
<                 exit(1);
---
>                 ostringstream invalidValue;
>                 invalidValue << pTable->label << "/" << inputVolumeString;
>                 throw InvalidDataException(invalidValue.str(), "Invalid Table/Volume value");
1966,1974c1914,1919
<             if (vol < 0.0)
<             {
<                 printf("\n\nERROR: this->read_table(): Invalid volume");
<                 printf("\n\tTable: ...... %s", table->label);
<                 printf("\n\tAge: ........ %6d", age);
<                 printf("\n\tVolume: ..... %6.1lf\n\n", vol);
<                 exit(1);
<             }
<             table->Volume[age] = vol;
---
> 
>             pTable->Volume[age] = volume;
> #ifdef _TSB_TABLE_DEBUG
>             cout << endl << "Data just read table (age/volume): "
>                  << age << "/" << volume << endl;
> #endif
1977c1922,1924
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
1980,1985d1926
< void Data::read_class_error(int line_no, const char *str)
< {
<     printf("\n\nERROR: this->read_class(Line#:%d): %s\n\n", line_no, str);
<     exit(1);
< }
< 
1988a1930
>     FILE* pFile = 0;
1990c1932,1935
<     FILE* fp = 0;
---
>     ZoneStruct* pZone = 0;
>     AUStruct* pAU = 0;
>     TimberClassStruct* pTimberClass = 0;
>     BlockStruct* pBlock = 0;
1992,1995c1937,1945
<     ZONE* zone = 0;
<     AU* au = 0;
<     TIMBER_CLASS* timber_class = 0;
<     BLOCK* block = 0;
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
>     char inctypestr[FssimUtil::MAX_PATH_LENGTH];
>     char inputZoneString[FssimUtil::MAX_PATH_LENGTH];
>     char inputAUString[FssimUtil::MAX_PATH_LENGTH];
>     char inblockstr[FssimUtil::MAX_PATH_LENGTH];
>     char inagestr[FssimUtil::MAX_PATH_LENGTH];
>     char inreversionagestr[FssimUtil::MAX_PATH_LENGTH];
>     char inareastr[FssimUtil::MAX_PATH_LENGTH];
>     char testblockstr[FssimUtil::MAX_PATH_LENGTH];
1997,2009d1946
<     // v3.0 to v4.0: changed name of dataline to dataLine
<     char dataLine[255];
<     // v3.0 to v4.0: changed name of inctype to inctypestr
<     char inctypestr[255];
<     char inzonestr[255];
<     char inaustr[255];
<     char inblockstr[255];
<     char inagestr[255];
<     char inreversionagestr[255];
<     char inareastr[255];
<     char testblockstr[255];
<     char errstr[255];
< 
2019,2020c1956,1959
<     fp = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = static_cast<FILE*>(fopen(m_fileName.c_str(), "r"));
>     if (pFile == 0)
2022,2023c1961
<         printf("\n\nERROR: Could not open %s\n\n", m_fileName.c_str());
<         exit(1);
---
>         throw OpenException(); // fatal
2025,2026c1963,1964
<     string headerStringBuffer = "Zone";
<     fp = static_cast<FILE*>(discard_header(fp, m_fileName.c_str(), headerStringBuffer));
---
>     string headerStringBuffer = FssimUtil::m_kZoneIdentifier;
>     pFile = static_cast<FILE*>(FssimUtil::discard_header(pFile, m_fileName.c_str(), headerStringBuffer));
2028,2030c1966
< 
<     int line_no = 1;
<     while (!feof(fp))
---
>     try // throws InvalidDataException
2032,2034c1968
<         fgets(dataLine, sizeof(dataLine), fp);
<         line_no++;
<         if (feof(fp))
---
>         while (!feof(pFile))
2036,2058c1970,1972
<             fclose(fp);
<             return;
<         }
<         if ( ( line_no % 1000 ) == 0 ) printf( "." );
<         inreversionage = -FssimApp::INFINITY; classtype = FssimApp::DUMMYINPUT;
<         memset(inzonestr, '\0', sizeof(inzonestr));
<         memset(inaustr, '\0', sizeof(inaustr));
<         memset(inblockstr, '\0', sizeof(inblockstr));
<         memset(inagestr, '\0', sizeof(inagestr));
<         memset(inareastr, '\0', sizeof(inareastr));
<         memset(inctypestr, '\0', sizeof(inctypestr));
<         memset(inreversionagestr, '\0', sizeof(inreversionagestr));
<         // WARNING!!! The following commented line works but is wrong in indirection: a char array name is by definition
<         //  a pointer to its first element and, so, its name (not its address) should be passed to sscanf!!!
<         //count = sscanf(dataLine, "%s %s %s %s %s %s %s",
<         //    &inzonestr, &inaustr, &inblockstr, &inagestr, &inareastr, &inctypestr, &inreversionagestr);
<         // v3.0 to v4.0: changed name of inctype to inctypestr
<         int count = sscanf(dataLine, "%s %s %s %s %s %s %s",
<             inzonestr, inaustr, inblockstr, inagestr, inareastr, inctypestr, inreversionagestr);
< 
<         if (count < 5)
<         {
<             if (count != -1)
---
>             fgets(inputDataLine, sizeof(inputDataLine), pFile);
>             m_lineNumber++;
>             if (feof(pFile))
2060c1974,1975
<                 printf("\nWARNING: %s(Line#:%d): Fields read: %d; Discarding invalid dataLine", m_fileName.c_str(), line_no, count);
---
>                 fclose(pFile);
>                 return;
2062,2064c1977,1989
<         } else if ((count >= 5)&&(count <= 7))
<         {
<             if (strlen(inzonestr)>FssimApp::MAX_LABEL_LENGTH)
---
>             if ( ( m_lineNumber % 1000 ) == 0 ) printf( "." );
>             inreversionage = -FssimUtil::INFINITY; classtype = FssimUtil::DUMMY_INPUT;
>             memset(inputZoneString, '\0', sizeof(inputZoneString));
>             memset(inputAUString, '\0', sizeof(inputAUString));
>             memset(inblockstr, '\0', sizeof(inblockstr));
>             memset(inagestr, '\0', sizeof(inagestr));
>             memset(inareastr, '\0', sizeof(inareastr));
>             memset(inctypestr, '\0', sizeof(inctypestr));
>             memset(inreversionagestr, '\0', sizeof(inreversionagestr));
>             m_fieldCount = sscanf(inputDataLine, "%s %s %s %s %s %s %s",
>                 inputZoneString, inputAUString, inblockstr, inagestr, inareastr, inctypestr, inreversionagestr);
> 
>             if (m_fieldCount < 5)
2066,2100c1991
<                 printf("\n\nERROR: %s(Line#:%d): Zone label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no,FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
<             }
<             if (strlen(inaustr)>FssimApp::MAX_LABEL_LENGTH)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): AU label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no,FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
<             }
<             if (strlen(inblockstr)>FssimApp::MAX_LABEL_LENGTH)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Block label width exceeds max label width (%d characters)\n\n", m_fileName.c_str(), line_no,FssimApp::MAX_LABEL_LENGTH);
<                 exit(1);
<             }
<             strcpy(testblockstr, to_lowercase(inblockstr).c_str());
<             if (strcmp(testblockstr, "n/a") == 0)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Block label (%s)\n\n", m_fileName.c_str(), line_no, inblockstr);
<                 exit(1);
<             }
<             inage = func_derive_integer(inagestr);
<             if (inage == FssimApp::ERRORVAL)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Age value(%s)\n\n", m_fileName.c_str(), line_no, inagestr);
<                 exit(1);
<             }
<             inarea = func_derive_float(inareastr);
<             if (inarea == FssimApp::ERRORVAL)
<             {
<                 printf("\n\nERROR: %s(Line#:%d): Invalid Area value(%s)\n\n", m_fileName.c_str(), line_no, inareastr);
<                 exit(1);
<             }
<             if ((int)strlen(inreversionagestr) >= 1)
<             {
<                 inreversionage = func_derive_integer(inreversionagestr);
<                 if (inreversionage == FssimApp::ERRORVAL)
---
>                 if (m_fieldCount != -1)
2102,2103c1993
<                     printf("\n\nERROR: %s(Line#:%d): Invalid ReversionAge value(%s)\n\n", m_fileName.c_str(), line_no, inreversionagestr);
<                     exit(1);
---
>                     this->discardInvalidDataLine();
2105,2106d1994
<             } else {
<                 inreversionage = -FssimApp::INFINITY;
2108,2109c1996
<             /* Class types */
<             if ((int)(strlen(inctypestr)) < 1)
---
>             else if ((m_fieldCount >= 5)&&(m_fieldCount <= 7))
2111,2114c1998
<                 classtype = FssimApp::OPERABLE;
<                 reversionage = -FssimApp::INFINITY;
<             } else {
<                 if ((int)(strlen(inctypestr)) > 1)
---
>                 if (strlen(inputZoneString)>FssimUtil::MAX_LABEL_LENGTH)
2116,2118c2000
<                     sprintf(errstr, "Invalid timber_class type string (%s); MUST be one of [O,o,I,i,D,d,N,n] or blank", inctypestr);
<                     this->read_class_error(line_no, errstr);
<                     return;
---
>                     this->throwLabelTooLong(FssimUtil::m_kZoneIdentifier);
2120,2121c2002
<                 strcpy(inctypestr, to_lowercase(inctypestr).c_str());
<                 if (inctypestr[0] == 'd')
---
>                 if (strlen(inputAUString)>FssimUtil::MAX_LABEL_LENGTH)
2123c2004,2028
<                     if (count >= 7)
---
>                     this->throwLabelTooLong(FssimUtil::m_kAUIdentifier);
>                 }
>                 if (strlen(inblockstr)>FssimUtil::MAX_LABEL_LENGTH)
>                 {
>                     this->throwLabelTooLong(FssimUtil::m_kBlockIdentifier);
>                 }
>                 strcpy(testblockstr, FssimUtil::to_lowercase(inblockstr).c_str());
>                 if (testblockstr == FssimUtil::m_kNullString)
>                 {
>                     throw InvalidDataException(inblockstr, "Invalid Block label");
>                 }
>                 inage = func_derive_integer(inagestr);
>                 if (inage == FssimUtil::ERRORVAL)
>                 {
>                     throw InvalidDataException(inagestr, "Invalid Age value");
>                 }
>                 inarea = func_derive_float(inareastr);
>                 if (inarea == FssimUtil::ERRORVAL)
>                 {
>                     throw InvalidDataException(inareastr, "Invalid Area value");
>                 }
>                 if (static_cast<int>(strlen(inreversionagestr)) >= 1)
>                 {
>                     inreversionage = func_derive_integer(inreversionagestr);
>                     if (inreversionage == FssimUtil::ERRORVAL)
2125,2130c2030
<                         classtype = FssimApp::DEFERRED;
<                         reversionage = inreversionage;
<                     } else {
<                         classtype = FssimApp::DEFERRED;
<                         this->read_class_error(line_no, "Must specify a REVERSION AGE for FssimApp::DEFERRED timber class types");
<                         return;
---
>                         throw InvalidDataException(inreversionagestr, "Invalid ReversionAge value");
2132c2032,2033
<                 } else if (inctypestr[0] == 'n')
---
>                 }
>                 else
2134c2035,2046
<                     if (count >= 7)
---
>                     inreversionage = -FssimUtil::INFINITY;
>                 }
> 
>                 // Class types
>                 if (static_cast<int>(strlen(inctypestr)) < 1)
>                 {
>                     classtype = GroupDefStruct::OPERABLE;
>                     reversionage = -FssimUtil::INFINITY;
>                 }
>                 else
>                 {
>                     if (static_cast<int>(strlen(inctypestr)) > 1)
2136,2140c2048
<                         classtype = FssimApp::NONCONTRIBUTING;
<                         reversionage = inreversionage;
<                     } else {
<                         classtype = FssimApp::NONCONTRIBUTING;
<                         this->read_class_error(line_no, "Must specify a REVERSION AGE for NON-CONTRIBUTING timber class types");
---
>                         throw InvalidDataException(inctypestr, "Invalid timber_class type string; MUST be one of [O,o,I,i,D,d,N,n] or blank");
2143c2051,2102
<                 } else if (inctypestr[0] == 'i')
---
>                     strcpy(inctypestr, FssimUtil::to_lowercase(inctypestr).c_str());
>                     if (inctypestr[0] == FssimUtil::m_kDeferredClassIdentifier)
>                     {
>                         if (m_fieldCount >= 7)
>                         {
>                             classtype = GroupDefStruct::DEFERRED;
>                             reversionage = inreversionage;
>                         }
>                         else
>                         {
>                             classtype = GroupDefStruct::DEFERRED;
>                             throw InvalidDataException(classtype, "Must specify a REVERSION AGE for GroupDefStruct::DEFERRED timber class types");
>                         }
>                     }
>                     else if (inctypestr[0] == FssimUtil::m_kNonContributingClassIdentifier)
>                     {
>                         if (m_fieldCount >= 7)
>                         {
>                             classtype = GroupDefStruct::NONCONTRIBUTING;
>                             reversionage = inreversionage;
>                         }
>                         else
>                         {
>                             classtype = GroupDefStruct::NONCONTRIBUTING;
>                             throw InvalidDataException(classtype, "Must specify a REVERSION AGE for NON-CONTRIBUTING timber class types");
>                         }
>                     }
>                     else if (inctypestr[0] == FssimUtil::m_kInoperableClassIdentifier)
>                     {
>                         classtype = GroupDefStruct::INOPERABLE;
>                         reversionage = -FssimUtil::INFINITY;
>                     }
>                     else if (inctypestr[0] == FssimUtil::m_kOperableClassIdentifier)
>                     {
>                         classtype = GroupDefStruct::OPERABLE;
>                         reversionage = -FssimUtil::INFINITY;
>                     }
>                     else if (m_fieldCount == 5)
>                     {
>                         classtype = GroupDefStruct::OPERABLE;
>                         reversionage = -FssimUtil::INFINITY;
>                     }
>                     else
>                     {
>                         ostringstream mess;
>                         mess << classtype << "/" << reversionage;
>                         throw InvalidDataException(mess.str(), "Invalid timber_class type/reversion age");
>                     }
>                 }
> 
>                 // check for valid area
>                 if (inarea < FssimUtil::m_kRoundError)
2145,2147c2104,2109
<                     classtype = FssimApp::INOPERABLE;
<                     reversionage = -FssimApp::INFINITY;
<                 } else if (inctypestr[0] == 'o')
---
>                     throw InvalidDataException(inarea, "Invalid area value");
>                 }
> 
>                 // Reversion age; only applicable for deferred timber_class types
>                 if ( (inreversionage != (-FssimUtil::INFINITY) ) &&
>                      ( (classtype == (GroupDefStruct::OPERABLE)) || (classtype == (GroupDefStruct::INOPERABLE)) ) )
2149,2151c2111,2116
<                     classtype = FssimApp::OPERABLE;
<                     reversionage = -FssimApp::INFINITY;
<                 } else if (count == 5)
---
>                     throw InvalidDataException(inreversionage,
>                                            "Cannot specify reversion age for GroupDefStruct::OPERABLE/GroupDefStruct::INOPERABLE timber class types");
>                 }
> 
>                 // check to see if zone already exists; if not, create
>                 try
2153,2157c2118
<                     classtype = FssimApp::OPERABLE;
<                     reversionage = -FssimApp::INFINITY;
<                 } else {
<                     this->read_class_error(line_no, "Invalid timber_class type/reversion age");
<                     return;
---
>                     pZone = ZoneStruct::find(inputZoneString);
2159c2120,2123
<             }
---
>                 catch(DataNotFoundException& e)
>                 {
>                     pZone = init_make_zone(inputZoneString, -1 /*reading ascii files, not binary*/);
>                 }
2161,2166c2125,2133
<             /* check for valid area */
<             if (inarea<FssimApp::m_kRoundError)
<             {
<                 this->read_class_error(line_no, "Invalid area value");
<                 return;
<             }
---
>                 try
>                 {
>                     pAU = pZone->findAU(inputAUString);
>                 }
>                 catch(DataNotFoundException& e)
>                 {
>                     cerr << e.what();
>                     throw;
>                 }
2168,2174c2135,2147
<             /* Reversion age; only applicable for deferred timber_class types */
<             if ( (inreversionage != (-FssimApp::INFINITY) ) &&
<                  ( (classtype == (FssimApp::OPERABLE)) || (classtype == (FssimApp::INOPERABLE)) ) )
<             {
<                 this->read_class_error(line_no, "Cannot specify reversion age for FssimApp::OPERABLE/FssimApp::INOPERABLE timber class types");
<                 return;
<             }
---
>                 inage += m_pApp->m_ageOffset; // adjust for initial age offset
>                 if (inarea < 0)
>                 {
>                     throw InvalidDataException(inarea, "Invalid area value");
>                 }
>                 try
>                 {
>                     pBlock = BlockStruct::find(inblockstr);
>                 }
>                 catch(DataNotFoundException& e)
>                 {
>                     pBlock = init_make_block(inblockstr, -1); // reading ascii files, not binary;
>                 }
2176,2180c2149,2161
<             // check to see if zone already exists; if not, create
<             zone = static_cast<ZONE*>(func_find_zone(inzonestr));
<             if (zone == 0)
<             {
<                 zone = static_cast<ZONE*>(init_make_zone(inzonestr, -1 /*reading ascii files, not binary*/));
---
>                 pTimberClass = init_make_class(pZone,
>                     pAU,
>                     pBlock,		// cutblock
>                     inage,		// age
>                     1,		    // width; default to 1 at init
>                     inarea,
>                     classtype,
>                     reversionage,
>                     0,		    // ReEntryLag
>                     0,		    // float_group_list
>                     0,		    // static_group_list
>                     false,      // not roaded
>                     -1); // reading ascii files, not binary; dummy flag will be replaced by pseudo-random number
2182,2222d2162
< 
<             if ( 0 == zone )
<             {
<                 printf("\n\n%s(Line#:%d): init_make_zone() returned 0\n\n", m_fileName.c_str(), line_no );
<                 exit(1);
<             }
<             au = static_cast<AU*>(func_find_au(zone, inaustr));
<             if ( 0 == au )
<             {
<                 printf("\n\n%s(Line#:%d): func_find_au() returned 0\n\n", m_fileName.c_str(), line_no );
<                 exit(1);
<             }
<             inage += m_pApp->m_ageOffset; /* adjust for initial age offset */
<             if (inarea < 0.0)
<             {
<                 this->read_class_error(line_no, "Invalid area value");
<                 return;
<             }
<             block = static_cast<BLOCK*>(func_find_block(inblockstr));
<             if (0 == block)
<             {
<                 block = static_cast<BLOCK*>(init_make_block(inblockstr));
<             }
<             if (block ==  0)
<             {
<                 this->read_class_error(line_no, "\n\nERROR: init_make_block() returned 0\n\n");
<                 return;
<             }
<             timber_class = static_cast<TIMBER_CLASS*>(init_make_class(zone,
<                 au,
<                 block,		/* cutblock */
<                 inage,		/* age */
<                 1,		/* width; default to 1 at init */
<                 inarea,
<                 classtype,
<                 reversionage,
<                 0,		/* ReEntryLag */
<                 0,		/* float_group_list */
<                 0,		/* static_group_list */
<                 false,  // not roaded
<                 -1)); // reading ascii files, not binary; dummy flag will be replaced by pseudo-random number
2225,2232c2165
<     fclose(fp);
< }
< 
< /* inlined
< void Data::parseLine()
< {
<     // always start at the top of the file
<     if (m_fromFile.is_open())
---
>     catch (InvalidDataException& e)
2234,2245c2167
<         m_fromFile.close();
<     }
<     m_fromFile.open(m_fileName.c_str());
< 
<     while (m_fromFile)
<     {
<         getline(m_fromFile, m_oneWholeLine);
< #ifdef _TSB_READ_CONFIG_DEBUG
<         cout << endl << "getline got: " << m_oneWholeLine
<              << " while looking for: " << m_lineLabel << endl;
< #endif
<         if ( string::npos != m_oneWholeLine.find(m_lineLabel) )
---
>         if (e.isFatal())
2247,2251c2169
< #ifdef _TSB_READ_CONFIG_DEBUG
<             cout << endl << "find returned !string::npos while looking for: " << m_lineLabel << endl
<                  << "Line found: " << m_oneWholeLine << endl;
< #endif
<             return; // if we found the line, exit loop
---
>             throw;
2253,2311d2170
<     }
<     if (!m_fromFile.eof()) // check for end of file
<     {
<         string message = "Something bad happened while parsing a line from: ";
<         message += m_fileName;
<         throw FileException(message);
<     }
<     else
<     {
<         // reset stream state
<         m_fromFile.clear();
<     }
< 
<     return;
< }
< 
< bool Data::parseData()
< {
<     // find position of end of harvest rule label
<     string::size_type colonPosition = m_oneWholeLine.find(":");
< 
<     // create new string from substring beginning just after colon spanning to end of line
<     string line = m_oneWholeLine;
< #ifdef _TSB_READ_CONFIG_DEBUG
<     cout << endl << "read line of input: " << m_oneWholeLine << endl;
< #endif
<     string subString(line, colonPosition + 1, line.length() - 1);
<     m_dataString = subString;
< #ifdef _TSB_READ_CONFIG_DEBUG
<     cout << "read substring: " << subString << " with length: " << subString.length() << endl;
< #endif
< 
<     if (m_dataString.length() == 0)
<     {
<         cout << endl << endl << "WARNING: " << m_fileName.c_str()
<              << ": Could not find " << m_lineLabel
<              << " field; using default value(" << m_defaultValueString << ")" << endl << endl;
< 
<         return false; // data parse failed
<     }
<     return true; // successfully parsed data
< }
< 
< void Data::doConfigToggle(bool& toggle, const string& toggleName, bool defaultValue)
< {
<     if (!this->parseData()) // if the line is missing, use default
<     {
<         toggle = defaultValue;
<     }
<     else
<     {
<         if ( string::npos != m_dataString.find("On") || string::npos != m_dataString.find("on") )
<         {
<             toggle = true;
<         }
<         else if ( string::npos != m_dataString.find("Off") || string::npos != m_dataString.find("off") )
<         {
<             toggle = false;
<         }
2314,2317c2173
<             string message = "ERROR: " + toggleName;
<             message += " MUST be one of [On/Off]\n\tFilename: ............ %s";
<             message += m_fileName;
<             throw logic_error(message);
---
>             cerr << endl << e.what() << endl;
2320,2328d2175
<     if (toggle)
<     {
<         cout << "FYI: " << toggleName << " ENABLED" << endl;
<     }
<     else
<     {
<         cout << "FYI: " << toggleName << " DISABLED" << endl;
<     }
< }
2330,2349c2177,2179
< void Data::doConfigInt(int& number, const string& numberName, int defaultValue)
< {
<     if (!this->parseData()) // if the line is missing, use default
<     {
<         number = defaultValue;
<     }
<     else
<     {
<         // convert character string to int ignoring leading whitespace
<         errno = 0; // clear state of standard error
<         number = atoi(m_dataString.c_str()); // will return 0 for non-numeric data
<         if (errno == ERANGE) // value too large to represent as an int
<         {
<             string message = "ERROR: ";
<             message += m_fileName + ": Invalid " + numberName;
<             message += " value(";
<             message += m_oneWholeLine + ")";
<             throw logic_error(message);
<         }
<     }
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
2352,2373d2181
< void Data::doConfigDouble(double& number, const string& numberName, double defaultValue)
< {
<     if (!this->parseData()) // if the line is missing, use default
<     {
<         number = defaultValue;
<     }
<     else
<     {
<         // convert character string to int ignoring leading whitespace
<         errno = 0; // clear state of standard error
<         number = atof(m_dataString.c_str()); // will return 0 for non-numeric data; returns double, not float
<         if (errno == ERANGE) // value too large to represent as an int
<         {
<             string message = "ERROR: ";
<             message += m_fileName + ": Invalid " + numberName;
<             message += " value(";
<             message += m_oneWholeLine + ")";
<             throw logic_error(message);
<         }
<     }
< }
< */
2378a2187
>     m_lineNumber = 1;
2392c2201
<         cout << "WARNING: Could not open file: " << m_fileName << endl;
---
>         cerr << "WARNING: Could not open file: " << m_fileName << endl;
2406c2215,2216
<         return;
---
> 
>         throw OpenException(false, false); // not fatal
2420c2230
<         printf("\nFYI: Using harvest rule: ABSOLUTE OLDEST FIRST");
---
>         cout << "FYI: Using harvest rule: ABSOLUTE OLDEST FIRST" << endl;
2424c2234
<         printf("\nFYI: Using harvest rule: RELATIVE OLDEST FIRST");
---
>         cout << "FYI: Using harvest rule: RELATIVE OLDEST FIRST" << endl;
2428c2238
<         printf("\nFYI: Using harvest rule: ABSOLUTE YOUNGEST FIRST");
---
>         cout << "FYI: Using harvest rule: ABSOLUTE YOUNGEST FIRST" << endl;
2432c2242
<         printf("\nFYI: Using harvest rule: FssimApp::RANDOM_PRIORITY");
---
>         cout << "FYI: Using harvest rule: RANDOM_PRIORITY" << endl;
2436,2437c2246
<         printf("\n\nERROR: %s: Unknown harvest rule type(%s)\n\n", m_fileName.c_str(), m_oneWholeLine.c_str());
<         exit(1);
---
>         throw InvalidDataException(m_oneWholeLine.c_str(), "Unknown harvest rule type" /* fatal */);
2446c2255
<     cout << endl << "FYI: Offsetting initial tclass ages by " << m_pApp->m_ageOffset << " years" << endl;
---
>     cout << "FYI: Offsetting initial timber class ages by " << m_pApp->m_ageOffset << " years" << endl;
2470c2279
<         cout << "FYI: Class split threshold " << m_pApp->m_minSplitThreshold << " ha" << endl;
---
>         cout << "FYI: Class split threshold " << setprecision(2) << m_pApp->m_minSplitThreshold << " ha" << endl;
2522c2331
<     if (!this->parseData()) // if the line is missing, use default
---
>     try
2524,2531c2333,2336
<         cout << endl << "WARNING: " << m_fileName
<              << ": Could not find Output Directory field; using default("
<              << m_pApp->m_outputDirectory << ")" << endl;
<     }
<     else
<     {
< #ifdef _TSB_READ_CONFIG_DEBUG
<         cout << endl << "FYI: Output Directory (m_dataString): " << m_dataString << endl;
---
>         this->parseData();
> 
> #ifdef _TSB_READ_CONFIG_DEBUG_OFF
>         cout << "FYI: Output Directory (m_dataString): " << m_dataString << endl;
2537d2341
<             //if (*iter != ' ')
2547c2351,2355
<     cout << endl << "FYI: Output Directory: " << m_pApp->m_outputDirectory << endl;
---
>     catch(DataNotFoundException& e)
>     {
>         cerr << endl << e.what() << endl;
>     }
>     cout << "FYI: Output Directory: " << m_pApp->m_outputDirectory << endl;
2556c2364
<     cout << endl << "FYI: LastPeriodTarget: " << m_pApp->m_lastPeriodTarget << endl;
---
>     cout << "FYI: LastPeriodTarget: " << m_pApp->m_lastPeriodTarget << endl;
2563c2371
<         sprintf(numberBuffer, "%f", FssimApp::DUMMYINPUT);
---
>         sprintf(numberBuffer, "%f", FssimUtil::DUMMY_INPUT);
2566c2374
<         this->doConfigDouble(m_pApp->m_GSPercentTarget, "GS Percent Target", FssimApp::DUMMYINPUT);
---
>         this->doConfigDouble(m_pApp->m_GSPercentTarget, "GS Percent Target", FssimUtil::DUMMY_INPUT);
2571a2380,2381
>     m_lineNumber = 0;
>     m_fieldCount = 0;
2575a2386
>     FILE* pFile = 0;
2577,2581c2388
< 
<     FILE* fp = 0;
< 
<     // v3.0 to v4.0: changed name of dataline to dataLine
<     char dataLine[255];
---
>     char inputDataLine[FssimUtil::MAX_PATH_LENGTH];
2585d2391
< 
2588,2589c2394,2397
<     fp = fopen(m_fileName.c_str(), "r");
<     if (fp == 0)
---
>     m_lineNumber = 1;
> 
>     pFile = fopen(m_fileName.c_str(), "r");
>     if (pFile == 0)
2591,2592c2399
<         printf("\n\nERROR: Could not open %s\n", m_fileName.c_str());
<         exit(1);
---
>         throw OpenException(); // fatal
2595,2597c2402,2404
<     /* extract planning horizon */
<     char fieldLabel[FssimApp::MAX_LABEL_LENGTH];
<     strcpy(fieldLabel, strip_label(fp, "Plan Horizon:"));
---
>     // extract planning horizon
>     char fieldLabel[FssimUtil::MAX_LABEL_LENGTH];
>     strcpy(fieldLabel, FssimUtil::strip_label(pFile, "Plan Horizon:"));
2600,2601c2407
<         printf("\n\nERROR: %s: Plan Horizon MUST be specified\n\n", m_fileName.c_str());
<         exit(1);
---
>         throw InvalidDataException(0, "Plan Horizon MUST be specified");
2604c2410
<     if (m_pApp->m_planHorizon == FssimApp::ERRORVAL)
---
>     if (m_pApp->m_planHorizon == FssimUtil::ERRORVAL)
2606,2607c2412
<         printf("\n\nERROR: %s: Invalid Plan Horizon value(%s)\n\n", m_fileName.c_str(), fieldLabel);
<         exit(1);
---
>         throw InvalidDataException(fieldLabel, "Invalid Plan Horizon value");
2611,2612c2416,2418
<         printf("\n\nERROR: %s: Specified PlanHorizon(%d) outside allowable range(%d-%d)\n\n", m_fileName.c_str(), m_pApp->m_planHorizon, 1, FssimApp::MAX_PLAN_HORIZON);
<         exit(1);
---
>         ostringstream message;
>         message << "PlanHorizon outside allowable range: " << 1 << " to " << FssimApp::MAX_PLAN_HORIZON;
>         throw InvalidDataException(m_pApp->m_planHorizon, message.str());
2615c2421
<     /* extract period length(s) */
---
>     // extract period length(s)
2617,2618c2423,2424
<     fp = discard_header(fp, m_fileName.c_str(), fieldLabel);
<     while (!feof(fp))
---
>     pFile = FssimUtil::discard_header(pFile, m_fileName.c_str(), fieldLabel);
>     while (!feof(pFile))
2620,2622c2426,2428
<         fgets(dataLine, sizeof(dataLine), fp);
<         int count = sscanf(dataLine, "%d %d", &period, &length);
<         if (count != 2)
---
>         fgets(inputDataLine, sizeof(inputDataLine), pFile);
>         m_fieldCount = sscanf(inputDataLine, "%d %d", &period, &length);
>         if (m_fieldCount != 2)
2624c2430
<             if (count != -1)
---
>             if (m_fieldCount != -1)
2626c2432
<                 printf("\nWARNING: this->read_time_parameters(): Fields read: %d; Discarding invalid dataLine", count);
---
>                 this->discardInvalidDataLine();
2628,2629c2434,2437
<         } else {
<             if ((period < 1) || (period > FssimApp::MAX_PLAN_HORIZON))
---
>         }
>         else
>         {
>             if ( period < 1 || period > FssimApp::MAX_PLAN_HORIZON )
2631,2632c2439,2441
<                 printf("\n\nERROR: %s: Specified period(%d) outside allowable range(%d-%d)\n\n", m_fileName.c_str(), period, 1, FssimApp::MAX_PLAN_HORIZON);
<                 exit(1);
---
>                 ostringstream message;
>                 message << "Specified period outside allowable range: " << 1 << " to " << FssimApp::MAX_PLAN_HORIZON;
>                 throw InvalidDataException(period, message.str());
2637,2638c2446
<                 printf("\n\nERROR: %s:  Invalid period length(%d)\n\n", m_fileName.c_str(), length);
<                 exit(1);
---
>                 throw InvalidDataException(length, "Invalid period length");
2640a2449,2450
>             // vectorize m_periodLength as valarray to replace for loop
>             /*
2643c2453,2457
<                 m_pApp->m_periodLength[i] = length;
---
>             */
>                 //m_pApp->m_periodLength[i] = length;
>                 m_pApp->m_periodLength[slice(period, (FssimApp::MAX_PLAN_HORIZON - period + 1), 1)] = length;
>                 m_pApp->m_periodLengthDouble[slice(period, (FssimApp::MAX_PLAN_HORIZON - period + 1), 1)] = length;
>             /*
2644a2459
>             */
2648c2463,2465
<     fclose(fp);
---
>     fclose(pFile);
>     m_lineNumber = 0;
>     m_fieldCount = 0;
2649a2467,2479
> 
> // exception handler utility functions
> void Data::discardInvalidDataLine()
> {
>     throw InvalidDataLineException(m_fieldCount, "Discarding invalid inputDataLine. Fields read:");
> }
> 
> void Data::throwLabelTooLong(const string& labelType)
> {
>     string message(labelType + " label width exceeds max label width");
>     throw InvalidDataException(FssimUtil::MAX_LABEL_LENGTH, message, true /*fatal*/);
> }
> 
