From d09161716f2da9160dc7f08f017bfe57c546de84 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Fri, 13 Apr 2018 15:33:35 -0400 Subject: [PATCH] Fix duplicate key check in parseCompString The check was being done at a stage where the token being checked could be just a part of a key (if the key contained a colon), where this partial key could correspond to another valid key. Fixes #525 --- .../cython/cantera/test/test_convert.py | 29 ++++++++++--------- src/base/stringUtils.cpp | 9 +++--- test/data/species-names.inp | 7 ++++- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/interfaces/cython/cantera/test/test_convert.py b/interfaces/cython/cantera/test/test_convert.py index 27c0a5c546..ca169eb1bf 100644 --- a/interfaces/cython/cantera/test/test_convert.py +++ b/interfaces/cython/cantera/test/test_convert.py @@ -142,7 +142,7 @@ def test_pathologicalSpeciesNames(self): outName=pjoin(self.test_work_dir, 'species-names.cti'), quiet=True) gas = ct.Solution('species-names.cti') - self.assertEqual(gas.n_species, 8) + self.assertEqual(gas.n_species, 9) self.assertEqual(gas.species_name(0), '(Parens)') self.assertEqual(gas.species_name(1), '@#$%^-2') self.assertEqual(gas.species_index('co:lons:'), 2) @@ -150,20 +150,23 @@ def test_pathologicalSpeciesNames(self): self.assertEqual(gas.species_name(4), 'plus+') self.assertEqual(gas.species_name(5), 'eq=uals') self.assertEqual(gas.species_name(6), 'plus') + self.assertEqual(gas.species_name(7), 'trans_butene') + self.assertEqual(gas.species_name(8), 'co') - self.assertEqual(gas.n_reactions, 11) + self.assertEqual(gas.n_reactions, 12) nu = gas.product_stoich_coeffs() - gas.reactant_stoich_coeffs() - self.assertEqual(list(nu[:,0]), [-1, -1, 0, 2, 0, 0, 0, 0]) - self.assertEqual(list(nu[:,1]), [-2, 3, 0, -1, 0, 0, 0, 0]) - self.assertEqual(list(nu[:,2]), [-1, 0, 0, 0, 1, 0, 0, 0]) - self.assertEqual(list(nu[:,3]), [3, 0, 0, 0, -2, -1, 0, 0]) - self.assertEqual(list(nu[:,4]), [2, 0, 0, 0, -1, 0, -1, 0]) - self.assertEqual(list(nu[:,5]), [1, 0, 0, 0, 1, -1, -1, 0]) - self.assertEqual(list(nu[:,6]), [2, 0, -1, 0, 0, -1, 0, 0]) - self.assertEqual(list(nu[:,7]), [0, 0, 0, 0, -1, 1, 0, 0]) - self.assertEqual(list(nu[:,8]), [0, 0, 0, 0, -1, 1, 0, 0]) - self.assertEqual(list(nu[:,9]), [0, 0, 0, 0, -1, 1, 0, 0]) - self.assertEqual(list(nu[:,10]), [0, 0, -1, 0, 2, 0, 0, -1]) + self.assertEqual(list(nu[:,0]), [-1, -1, 0, 2, 0, 0, 0, 0, 0]) + self.assertEqual(list(nu[:,1]), [-2, 3, 0, -1, 0, 0, 0, 0, 0]) + self.assertEqual(list(nu[:,2]), [-1, 0, 0, 0, 1, 0, 0, 0, 0]) + self.assertEqual(list(nu[:,3]), [3, 0, 0, 0, -2, -1, 0, 0, 0]) + self.assertEqual(list(nu[:,4]), [2, 0, 0, 0, -1, 0, -1, 0, 0]) + self.assertEqual(list(nu[:,5]), [1, 0, 0, 0, 1, -1, -1, 0, 0]) + self.assertEqual(list(nu[:,6]), [2, 0, -1, 0, 0, -1, 0, 0, 0]) + self.assertEqual(list(nu[:,7]), [0, 0, 0, 0, -1, 1, 0, 0, 0]) + self.assertEqual(list(nu[:,8]), [0, 0, 0, 0, -1, 1, 0, 0, 0]) + self.assertEqual(list(nu[:,9]), [0, 0, 0, 0, -1, 1, 0, 0, 0]) + self.assertEqual(list(nu[:,10]), [0, 0, -1, 0, 2, 0, 0, -1, 0]) + self.assertEqual(list(nu[:,11]), [0, 0, -1, 0, 2, 0, 0, 0, -1]) def test_unterminatedSections(self): with self.assertRaises(ck2cti.InputParseError): diff --git a/src/base/stringUtils.cpp b/src/base/stringUtils.cpp index 2eb6b7ddea..4816b435bd 100644 --- a/src/base/stringUtils.cpp +++ b/src/base/stringUtils.cpp @@ -80,10 +80,6 @@ compositionMap parseCompString(const std::string& ss, throw CanteraError("parseCompString", "unknown species '" + name + "'"); } - if (getValue(x, name, 0.0) != 0.0) { - throw CanteraError("parseCompString", - "Duplicate key: '" + name + "'."); - } double value; try { @@ -105,6 +101,11 @@ compositionMap parseCompString(const std::string& ss, throw; } } + if (getValue(x, name, 0.0) != 0.0) { + throw CanteraError("parseCompString", + "Duplicate key: '" + name + "'."); + } + x[name] = value; start = ss.find_first_not_of(", ;\n\t", stop+1); left = start; diff --git a/test/data/species-names.inp b/test/data/species-names.inp index 6e97053703..8371af2ab3 100644 --- a/test/data/species-names.inp +++ b/test/data/species-names.inp @@ -2,7 +2,7 @@ Elements H C End SPEC -(Parens) @#$%^-2 co:lons: [xy2]*{.} plus+ eq=uals plus trans_butene +(Parens) @#$%^-2 co:lons: [xy2]*{.} plus+ eq=uals plus trans_butene co end thermo @@ -19,6 +19,10 @@ co:lons: C 1H 4 G 200.000 3500.000 1000.000 1 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 -9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 -4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 +co C 1H 4 G 200.000 3500.000 1000.000 1 + 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 +-9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 +-4.84743026E-08 1.66693956E-11-1.02466476E+04-4.64130376E+00 4 [xy2]*{.} C 1H 4 G 200.000 3500.000 1000.000 1 7.48514950E-02 1.33909467E-02-5.73285809E-06 1.22292535E-09-1.01815230E-13 2 -9.46834459E+03 1.84373180E+01 5.14987613E+00-1.36709788E-02 4.91800599E-05 3 @@ -56,5 +60,6 @@ LOW / 8.888e8 8.8 888.8 / plus+ (+plus+) = eq=uals (+plus+) 9.999e9 9.9 999.9 LOW / 8.888e8 8.8 888.8 / trans_butene + co:lons: = 2 plus+ 9.999e9 9.9 999.9 +co + co:lons: = 2 plus+ 9.999e9 9.9 999.9 end