Fix a bug with splitting strings in Ascii input reader

The previous way of splitting strings would break if the last string in
the line was an empty string, and it would return one fewer fields than
it should have. This was breaking the last line in the
scripts.base.framework.input.ascii.setspecialcases once the bug fixed in
GH #1628 was fixed.
This commit is contained in:
Tim Wojtulewicz 2022-07-19 10:40:11 -07:00
parent a0cc34efb2
commit d57ad3e405
3 changed files with 16 additions and 37 deletions

View file

@ -170,7 +170,6 @@ bool Ascii::ReadHeader(bool useCached)
{ {
// try to read the header line... // try to read the header line...
string line; string line;
map<string, uint32_t> ifields;
if ( ! useCached ) if ( ! useCached )
{ {
@ -190,17 +189,7 @@ bool Ascii::ReadHeader(bool useCached)
line = headerline; line = headerline;
// construct list of field names. // construct list of field names.
istringstream splitstream(line); auto ifields = util::split(line, separator[0]);
int pos = 0;
while ( splitstream )
{
string s;
if ( ! getline(splitstream, s, separator[0]) )
break;
ifields[s] = pos;
pos++;
}
// printf("Updating fields from description %s\n", line.c_str()); // printf("Updating fields from description %s\n", line.c_str());
columnMap.clear(); columnMap.clear();
@ -211,7 +200,7 @@ bool Ascii::ReadHeader(bool useCached)
{ {
const Field* field = fields[i]; const Field* field = fields[i];
auto fit = ifields.find(field->name); auto fit = std::find(ifields.begin(), ifields.end(), field->name);
if ( fit == ifields.end() ) if ( fit == ifields.end() )
{ {
if ( field->optional ) if ( field->optional )
@ -232,11 +221,12 @@ bool Ascii::ReadHeader(bool useCached)
return false; return false;
} }
FieldMapping f(field->name, field->type, field->subtype, static_cast<int>(ifields[field->name])); int index = static_cast<int>(std::distance(ifields.begin(), fit));
FieldMapping f(field->name, field->type, field->subtype, index);
if ( field->secondary_name && strlen(field->secondary_name) != 0 ) if ( field->secondary_name && strlen(field->secondary_name) != 0 )
{ {
auto fit2 = ifields.find(field->secondary_name); auto fit2 = std::find(ifields.begin(), ifields.end(), field->secondary_name);
if ( fit2 == ifields.end() ) if ( fit2 == ifields.end() )
{ {
FailWarn(fail_on_file_problem, FailWarn(fail_on_file_problem,
@ -247,7 +237,7 @@ bool Ascii::ReadHeader(bool useCached)
return false; return false;
} }
f.secondary_position = static_cast<int>(ifields[field->secondary_name]); f.secondary_position = static_cast<int>(std::distance(ifields.begin(), fit2));
} }
columnMap.push_back(f); columnMap.push_back(f);
@ -366,21 +356,10 @@ bool Ascii::DoUpdate()
{ {
// split on tabs // split on tabs
bool error = false; bool error = false;
istringstream splitstream(line); auto stringfields = util::split(line, separator[0]);
map<int, string> stringfields; // This needs to be a signed value or the comparisons below will fail.
int pos = 0; int pos = static_cast<int>(stringfields.size() - 1);
while ( splitstream )
{
string s;
if ( ! getline(splitstream, s, separator[0]) )
break;
stringfields[pos] = s;
pos++;
}
pos--; // for easy comparisons of max element.
Value** fields = new Value*[NumFields()]; Value** fields = new Value*[NumFields()];

View file

@ -17,9 +17,9 @@ testing,
testing,testing,testing, testing,testing,testing,
{ {
} }
}, s=[, , , ]], }, ss=[, , , ]],
}, s=[, testing]], }, ss=[, testing]],
}, s=[]], }, ss=[]],
}, s=[testing, , testing]], }, ss=[testing, , testing]],
}, s=[testing, ]], }, ss=[testing, ]],
}, s=[testing,testing,testing,]] }, ss=[testing,testing,testing,]]

View file

@ -26,7 +26,7 @@ type Idx: record {
type Val: record { type Val: record {
s: set[string]; s: set[string];
s: vector of string; ss: vector of string;
}; };
global servers: table[int] of Val = table(); global servers: table[int] of Val = table();