From df1920d75c8c63af8d98edec2df8cbfa97f51d84 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 21 May 2011 15:06:42 -0400 Subject: [PATCH] JSON - Completed JSON parser with the addition of syntax error messages. --- src/JSON.cpp | 22 +++++++++++++--- test/.gitignore | 3 +++ test/CMakeLists.txt | 3 ++- test/json_test.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 test/json_test.cpp diff --git a/src/JSON.cpp b/src/JSON.cpp index 417b1600e..db8f5dd99 100644 --- a/src/JSON.cpp +++ b/src/JSON.cpp @@ -199,15 +199,20 @@ json::array* json::array::parse (Nibbler& nibbler) else { delete arr; - return NULL; + throw std::string ("Error: missing value after ',' at position ") + + format ((int) n.cursor ()); } } } + if (n.skip (']')) { nibbler = n; return arr; } + else + throw std::string ("Error: missing ']' at position ") + + format ((int) n.cursor ()); delete arr; } @@ -283,7 +288,8 @@ json::object* json::object::parse (Nibbler& nibbler) else { delete obj; - return NULL; + throw std::string ("Error: missing value after ',' at position ") + + format ((int) n.cursor ()); } } } @@ -293,6 +299,9 @@ json::object* json::object::parse (Nibbler& nibbler) nibbler = n; return obj; } + else + throw std::string ("Error: missing '}' at position ") + + format ((int) n.cursor ()); delete obj; } @@ -319,7 +328,13 @@ bool json::object::parse_pair ( nibbler = n; return true; } + else + throw std::string ("Error: missing value at position ") + + format ((int) n.cursor ()); } + else + throw std::string ("Error: missing ':' at position ") + + format ((int) n.cursor ()); } return NULL; @@ -372,7 +387,8 @@ json::value* json::parse (const std::string& input) if (!n.depleted ()) { delete root; - throw std::string ("Error: extra characters found: ") + n.dump (); + throw std::string ("Error: extra characters found at position ") + + format ((int) n.cursor ()); } return root; diff --git a/test/.gitignore b/test/.gitignore index 49b882d3e..bbc1018f4 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -36,3 +36,6 @@ uri.t util.t variant.t view.t + +json_test + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f8ab8bfdc..962b94a98 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,7 +9,8 @@ set (test_SRCS att.t autocomplete.t cmd.t color.t config.t date.t directory.t dom.t duration.t file.t filt.t json.t list.t nibbler.t path.t record.t rectangle.t rx.t seq.t subst.t t.benchmark.t t.t taskmod.t tdb.t tdb2.t text.t tree.t tree2.t uri.t util.t - variant.t view.t) + variant.t view.t + json_test) add_custom_target (test ./run_all DEPENDS ${test_SRCS} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/test) diff --git a/test/json_test.cpp b/test/json_test.cpp new file mode 100644 index 000000000..f60609491 --- /dev/null +++ b/test/json_test.cpp @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// taskwarrior - a command line task list manager. +// +// Copyright 2006 - 2011, Paul Beckingham. +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free Software +// Foundation; either version 2 of the License, or (at your option) any later +// version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the +// +// Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, +// Boston, MA +// 02110-1301 +// USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +Context context; + +//////////////////////////////////////////////////////////////////////////////// +int main (int argc, char** argv) +{ + if (argc == 1) + { + std::cout << "\nUsage: json_test '{...}' ...\n\n"; + return 0; + } + + for (int i = 1; i < argc; ++i) + { + try + { + json::value* root = json::parse (argv[i]); + if (root) + { + std::cout << root->dump () << "\n"; + delete root; + } + } + + catch (const std::string& e) { std::cout << e << "\n"; } + catch (...) { std::cout << "Unknown error\n"; } + } + + return 0; +} + +////////////////////////////////////////////////////////////////////////////////