From 27055f178faf91def80f6d826c0efa4344e04096 Mon Sep 17 00:00:00 2001 From: jbeder Date: Sat, 25 Jul 2009 18:58:41 +0000 Subject: [PATCH] Fixed bug with simple keys that are quoted scalars --- src/scantoken.cpp | 9 +- yaml-reader/parsertests.cpp | 473 +++++++++++++++++++----------------- yaml-reader/tests.cpp | 1 + yaml-reader/tests.h | 1 + 4 files changed, 260 insertions(+), 224 deletions(-) diff --git a/src/scantoken.cpp b/src/scantoken.cpp index 4735a1a..bb8373a 100644 --- a/src/scantoken.cpp +++ b/src/scantoken.cpp @@ -309,8 +309,8 @@ namespace YAML { std::string scalar; - // eat single or double quote - char quote = INPUT.get(); + // peek at single or double quote (don't eat because we need to preserve (for the time being) the input position) + char quote = INPUT.peek(); bool single = (quote == '\''); // setup the scanning parameters @@ -330,6 +330,11 @@ namespace YAML InsertSimpleKey(); int line = INPUT.line, column = INPUT.column; + + // now eat that opening quote + INPUT.get(); + + // and scan scalar = ScanScalar(INPUT, params); m_simpleKeyAllowed = false; diff --git a/yaml-reader/parsertests.cpp b/yaml-reader/parsertests.cpp index 2c45eb4..b78cc53 100644 --- a/yaml-reader/parsertests.cpp +++ b/yaml-reader/parsertests.cpp @@ -1,222 +1,251 @@ -#include "tests.h" -#include "yaml.h" -#include - -namespace Test -{ - namespace Parser { - void SimpleScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "Hello, World!"; - desiredOutput = "Hello, World!"; - } - - void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - "normal scalar, but\n" - "over several lines"; - desiredOutput = "normal scalar, but over several lines"; - } - - void LiteralScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - "|\n" - " literal scalar - so we can draw ASCII:\n" - " \n" - " - -\n" - " | - |\n" - " -----\n"; - desiredOutput = - "literal scalar - so we can draw ASCII:\n" - "\n" - " - -\n" - " | - |\n" - " -----\n"; - } - - void FoldedScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - ">\n" - " and a folded scalar... so we\n" - " can just keep writing various\n" - " things. And if we want to keep indentation:\n" - " \n" - " we just indent a little\n" - " see, this stays indented"; - desiredOutput = - "and a folded scalar... so we" - " can just keep writing various" - " things. And if we want to keep indentation:\n" - "\n" - " we just indent a little\n" - " see, this stays indented"; - } - - void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - ">-\n" - " Here's a folded scalar\n" - " that gets chomped."; - desiredOutput = - "Here's a folded scalar" - " that gets chomped."; - } - - void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - "|-\n" - " Here's a literal scalar\n" - " that gets chomped."; - desiredOutput = - "Here's a literal scalar\n" - "that gets chomped."; - } - - void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = - ">2\n" - " Here's a folded scalar\n" - " that starts with some indentation."; - desiredOutput = - " Here's a folded scalar\n" - "that starts with some indentation."; - } - - void ColonScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "::vector"; - desiredOutput = "::vector"; - } - - void QuotedScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "\": - ()\""; - desiredOutput = ": - ()"; - } - - void CommaScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "Up, up, and away!"; - desiredOutput = "Up, up, and away!"; - } - - void DashScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "-123"; - desiredOutput = "-123"; - } - - void URLScalar(std::string& inputScalar, std::string& desiredOutput) - { - inputScalar = "http://example.com/foo#bar"; - desiredOutput = "http://example.com/foo#bar"; - } - - bool SimpleSeq() - { - std::string input = - "- eggs\n" - "- bread\n" - "- milk"; - - std::stringstream stream(input); - YAML::Parser parser(stream); - YAML::Node doc; - parser.GetNextDocument(doc); - - std::string output; - doc[0] >> output; - if(output != "eggs") - return false; - doc[1] >> output; - if(output != "bread") - return false; - doc[2] >> output; - if(output != "milk") - return false; - - return true; - } - - bool SimpleMap() - { - std::string input = - "name: Prince Fielder\n" - "position: 1B\n" - "bats: L"; - - std::stringstream stream(input); - YAML::Parser parser(stream); - YAML::Node doc; - parser.GetNextDocument(doc); - - std::string output; - doc["name"] >> output; - if(output != "Prince Fielder") - return false; - doc["position"] >> output; - if(output != "1B") - return false; - doc["bats"] >> output; - if(output != "L") - return false; - - return true; - } - - bool FlowSeq() - { - std::string input = "[ 2 , 3, 5 , 7, 11]"; - - std::stringstream stream(input); - YAML::Parser parser(stream); - YAML::Node doc; - parser.GetNextDocument(doc); - - int output; - doc[0] >> output; - if(output != 2) - return false; - doc[1] >> output; - if(output != 3) - return false; - doc[2] >> output; - if(output != 5) - return false; - doc[3] >> output; - if(output != 7) - return false; - doc[4] >> output; - if(output != 11) - return false; - - return true; - } - - bool FlowMap() - { - std::string input = "{hr: 65, avg: 0.278}"; - - std::stringstream stream(input); - YAML::Parser parser(stream); - YAML::Node doc; - parser.GetNextDocument(doc); - - std::string output; - doc["hr"] >> output; - if(output != "65") - return false; - doc["avg"] >> output; - if(output != "0.278") - return false; - - return true; - } - } -} +#include "tests.h" +#include "yaml.h" +#include +#include + +namespace Test +{ + namespace Parser { + void SimpleScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "Hello, World!"; + desiredOutput = "Hello, World!"; + } + + void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "normal scalar, but\n" + "over several lines"; + desiredOutput = "normal scalar, but over several lines"; + } + + void LiteralScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "|\n" + " literal scalar - so we can draw ASCII:\n" + " \n" + " - -\n" + " | - |\n" + " -----\n"; + desiredOutput = + "literal scalar - so we can draw ASCII:\n" + "\n" + " - -\n" + " | - |\n" + " -----\n"; + } + + void FoldedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">\n" + " and a folded scalar... so we\n" + " can just keep writing various\n" + " things. And if we want to keep indentation:\n" + " \n" + " we just indent a little\n" + " see, this stays indented"; + desiredOutput = + "and a folded scalar... so we" + " can just keep writing various" + " things. And if we want to keep indentation:\n" + "\n" + " we just indent a little\n" + " see, this stays indented"; + } + + void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">-\n" + " Here's a folded scalar\n" + " that gets chomped."; + desiredOutput = + "Here's a folded scalar" + " that gets chomped."; + } + + void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + "|-\n" + " Here's a literal scalar\n" + " that gets chomped."; + desiredOutput = + "Here's a literal scalar\n" + "that gets chomped."; + } + + void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = + ">2\n" + " Here's a folded scalar\n" + " that starts with some indentation."; + desiredOutput = + " Here's a folded scalar\n" + "that starts with some indentation."; + } + + void ColonScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "::vector"; + desiredOutput = "::vector"; + } + + void QuotedScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "\": - ()\""; + desiredOutput = ": - ()"; + } + + void CommaScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "Up, up, and away!"; + desiredOutput = "Up, up, and away!"; + } + + void DashScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "-123"; + desiredOutput = "-123"; + } + + void URLScalar(std::string& inputScalar, std::string& desiredOutput) + { + inputScalar = "http://example.com/foo#bar"; + desiredOutput = "http://example.com/foo#bar"; + } + + bool SimpleSeq() + { + std::string input = + "- eggs\n" + "- bread\n" + "- milk"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc[0] >> output; + if(output != "eggs") + return false; + doc[1] >> output; + if(output != "bread") + return false; + doc[2] >> output; + if(output != "milk") + return false; + + return true; + } + + bool SimpleMap() + { + std::string input = + "name: Prince Fielder\n" + "position: 1B\n" + "bats: L"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["name"] >> output; + if(output != "Prince Fielder") + return false; + doc["position"] >> output; + if(output != "1B") + return false; + doc["bats"] >> output; + if(output != "L") + return false; + + return true; + } + + bool FlowSeq() + { + std::string input = "[ 2 , 3, 5 , 7, 11]"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + int output; + doc[0] >> output; + if(output != 2) + return false; + doc[1] >> output; + if(output != 3) + return false; + doc[2] >> output; + if(output != 5) + return false; + doc[3] >> output; + if(output != 7) + return false; + doc[4] >> output; + if(output != 11) + return false; + + return true; + } + + bool FlowMap() + { + std::string input = "{hr: 65, avg: 0.278}"; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["hr"] >> output; + if(output != "65") + return false; + doc["avg"] >> output; + if(output != "0.278") + return false; + + return true; + } + + bool QuotedSimpleKeys() + { + std::string KeyValue[3] = { "\"double\": double\n", "'single': single\n", "plain: plain\n" }; + + int perm[3] = { 0, 1, 2 }; + do { + std::string input = KeyValue[perm[0]] + KeyValue[perm[1]] + KeyValue[perm[2]]; + + std::stringstream stream(input); + YAML::Parser parser(stream); + YAML::Node doc; + parser.GetNextDocument(doc); + + std::string output; + doc["double"] >> output; + if(output != "double") + return false; + doc["single"] >> output; + if(output != "single") + return false; + doc["plain"] >> output; + if(output != "plain") + return false; + } while(std::next_permutation(perm, perm + 3)); + + return true; + } + } +} diff --git a/yaml-reader/tests.cpp b/yaml-reader/tests.cpp index c4d222e..a499cb3 100644 --- a/yaml-reader/tests.cpp +++ b/yaml-reader/tests.cpp @@ -262,6 +262,7 @@ namespace Test RunParserTest(&Parser::SimpleMap, "simple map", passed); RunParserTest(&Parser::FlowSeq, "flow seq", passed); RunParserTest(&Parser::FlowMap, "flow map", passed); + RunParserTest(&Parser::QuotedSimpleKeys, "quoted simple keys", passed); RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed); RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed); diff --git a/yaml-reader/tests.h b/yaml-reader/tests.h index fb33c24..20ec4d3 100644 --- a/yaml-reader/tests.h +++ b/yaml-reader/tests.h @@ -28,6 +28,7 @@ namespace Test { bool SimpleMap(); bool FlowSeq(); bool FlowMap(); + bool QuotedSimpleKeys(); } namespace Emitter {