From a06b390187c0b01ea0363b93e3e74117aa55da4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfram=20R=C3=B6sler?= Date: Wed, 18 Oct 2017 07:19:27 +0200 Subject: [PATCH 001/410] Un-deprecate removeMember overloads, return void (#693) * Un-deprecate removeMember overloads, return void Sometimes we just want to remove something we don't need anymore. Having to supply a return buffer for the removeMember function to return something we don't care about is a nuisance. There are removeMember overloads that don't need a return buffer but they are deprecated. This commit un-deprecates these overloads and modifies them to return nothing (void) instead of the object that was removed. Further discussion: https://github.com/open-source-parsers/jsoncpp/pull/689 WARNING: Changes the return type of the formerly deprecated removeMember overloads from Value to void. May break existing client code. * Minor stylistic fixes Don't explicitly return a void value from a void function. Also, convert size_t to unsigned in the CZString ctor to avoid a compiler warning. --- include/json/value.h | 6 ++---- src/lib_json/json_value.cpp | 20 ++++++-------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index ae111fbbb..2e533142f 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -521,13 +521,11 @@ Json::Value obj_value(Json::objectValue); // {} /// \pre type() is objectValue or nullValue /// \post type() is unchanged /// \deprecated - JSONCPP_DEPRECATED("") - Value removeMember(const char* key); + void removeMember(const char* key); /// Same as removeMember(const char*) /// \param key may contain embedded nulls. /// \deprecated - JSONCPP_DEPRECATED("") - Value removeMember(const JSONCPP_STRING& key); + void removeMember(const JSONCPP_STRING& key); /// Same as removeMember(const char* begin, const char* end, Value* removed), /// but 'key' is null-terminated. bool removeMember(const char* key, Value* removed); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index d818208e7..5197d1861 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1187,27 +1187,19 @@ bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) { return removeMember(key.data(), key.data() + key.length(), removed); } -Value Value::removeMember(const char* key) +void Value::removeMember(const char* key) { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, "in Json::Value::removeMember(): requires objectValue"); if (type_ == nullValue) - return nullSingleton(); + return; - Value removed; // null - removeMember(key, key + strlen(key), &removed); - return removed; // still null if removeMember() did nothing + CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); + value_.map_->erase(actualKey); } -Value Value::removeMember(const JSONCPP_STRING& key) +void Value::removeMember(const JSONCPP_STRING& key) { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, - "in Json::Value::removeMember(): requires objectValue"); - if (type_ == nullValue) - return nullSingleton(); - - Value removed; // null - removeMember(key.c_str(), key.c_str() + key.size(), &removed); - return removed; // still null if removeMember() did nothing + removeMember(key.c_str()); } bool Value::removeIndex(ArrayIndex index, Value* removed) { From 5a2dc7a2ad889bfe38901f93c2f694ffae306d4d Mon Sep 17 00:00:00 2001 From: "Brian W. Mulligan" Date: Wed, 18 Oct 2017 00:20:45 -0500 Subject: [PATCH 002/410] Add comment to README giving instructions on how to install to a directory other than /usr/local (#694) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 51d60e1e7..833274205 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ format to store user input files. Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use [meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build for debugging, as well as for continuous integration (see [`travis.sh`](travis.sh) ). Other systems may work, but minor things like version strings might break. First, install both meson (which requires Python3) and ninja. +If you wish to install to a directory other than /usr/local, set an environment variable called DESTDIR with the desired path: + DESTDIR=/path/to/install/dir Then, From d61cddedac68f6dd3991d285045a23aeb253aa53 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sun, 29 Oct 2017 23:45:01 -0500 Subject: [PATCH 003/410] rm unused func --- src/lib_json/json_tool.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 431617830..51aa7a07e 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -61,9 +61,6 @@ static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) { return result; } -/// Returns true if ch is a control character (in range [1,31]). -static inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; } - enum { /// Constant that specify the size of the buffer that must be passed to /// uintToString. From 240c85a10c6e2267cae1122247f763e1cb087b59 Mon Sep 17 00:00:00 2001 From: Marcel Raad Date: Fri, 10 Nov 2017 10:58:43 +0100 Subject: [PATCH 004/410] MSVC warning fixes in tests - only use "#pragma GCC" on GCC-compatible compilers - suppress deprecation warnings also on MSVC --- src/jsontestrunner/main.cpp | 10 ++++++---- src/test_lib_json/main.cpp | 6 ++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index d24d7cfb7..531f541ba 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -3,8 +3,12 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE +#if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif /* This executable is used for testing parser/writer using real JSON files. */ @@ -14,10 +18,6 @@ #include #include -#if defined(_MSC_VER) && _MSC_VER >= 1310 -#pragma warning(disable : 4996) // disable fopen deprecation warning -#endif - struct Options { JSONCPP_STRING path; @@ -328,4 +328,6 @@ int main(int argc, const char* argv[]) { } } +#if defined(__GNUC__) #pragma GCC diagnostic pop +#endif diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 26e01cd05..3bbe89663 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3,8 +3,12 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE +#if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif #include "jsontest.h" #include @@ -2591,4 +2595,6 @@ int main(int argc, const char* argv[]) { return runner.runCommandLine(argc, argv); } +#if defined(__GNUC__) #pragma GCC diagnostic pop +#endif From 7c979e86610f48fa50e740854bcfce170b50fb46 Mon Sep 17 00:00:00 2001 From: Sascha Zelzer Date: Thu, 16 Nov 2017 20:13:55 +0100 Subject: [PATCH 005/410] Suppress implicit-fallthrough warnings from GCC 7 (#697) GCC 7, when compiling with -Wimplicit-fallthrough=1 or higher, issues a warning which can be suppressed using a comment that matches certain regular expressions. The comment change does just that: signal to GCC that the fall through is intentional. Fixes #676 --- src/lib_json/json_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index b4c4dcd44..eb3084372 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1237,7 +1237,7 @@ bool OurReader::readToken(Token& token) { token.type_ = tokenString; ok = readStringSingleQuote(); break; - } // else continue + } // else fall through case '/': token.type_ = tokenComment; ok = readComment(); From e6a588a2461f6c7cc7af37604363dd67757ccae1 Mon Sep 17 00:00:00 2001 From: Josh Soref Date: Sun, 3 Dec 2017 11:54:29 -0500 Subject: [PATCH 006/410] Spelling (#703) --- amalgamate.py | 46 +++++++++++++++++----------------- doc/doxyfile.in | 8 +++--- doc/web_doxyfile.in | 8 +++--- doxybuild.py | 2 +- include/json/config.h | 6 ++--- include/json/value.h | 2 +- include/json/writer.h | 10 ++++---- makerelease.py | 4 +-- src/lib_json/json_tool.h | 2 +- src/lib_json/json_writer.cpp | 22 ++++++++-------- src/test_lib_json/jsontest.cpp | 2 +- src/test_lib_json/main.cpp | 2 +- 12 files changed, 57 insertions(+), 57 deletions(-) diff --git a/amalgamate.py b/amalgamate.py index 9cb2d08cc..f4bff4da3 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -1,9 +1,9 @@ -"""Amalgate json-cpp library sources into a single source and header file. +"""Amalgamate json-cpp library sources into a single source and header file. Works with python2.6+ and python3.4+. Example of invocation (must be invoked from json-cpp top directory): -python amalgate.py +python amalgamate.py """ import os import os.path @@ -50,20 +50,20 @@ def write_to(self, output_path): def amalgamate_source(source_top_dir=None, target_source_path=None, header_include_path=None): - """Produces amalgated source. + """Produces amalgamated source. Parameters: source_top_dir: top-directory target_source_path: output .cpp path header_include_path: generated header path relative to target_source_path. """ - print("Amalgating header...") + print("Amalgamating header...") header = AmalgamationFile(source_top_dir) - header.add_text("/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).") + header.add_text("/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).") header.add_text('/// It is intended to be used with #include "%s"' % header_include_path) header.add_file("LICENSE", wrap_in_comment=True) - header.add_text("#ifndef JSON_AMALGATED_H_INCLUDED") - header.add_text("# define JSON_AMALGATED_H_INCLUDED") - header.add_text("/// If defined, indicates that the source file is amalgated") + header.add_text("#ifndef JSON_AMALGAMATED_H_INCLUDED") + header.add_text("# define JSON_AMALGAMATED_H_INCLUDED") + header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") header.add_file("include/json/version.h") @@ -75,37 +75,37 @@ def amalgamate_source(source_top_dir=None, header.add_file("include/json/reader.h") header.add_file("include/json/writer.h") header.add_file("include/json/assertions.h") - header.add_text("#endif //ifndef JSON_AMALGATED_H_INCLUDED") + header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) - print("Writing amalgated header to %r" % target_header_path) + print("Writing amalgamated header to %r" % target_header_path) header.write_to(target_header_path) base, ext = os.path.splitext(header_include_path) forward_header_include_path = base + "-forwards" + ext - print("Amalgating forward header...") + print("Amalgamating forward header...") header = AmalgamationFile(source_top_dir) - header.add_text("/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).") + header.add_text("/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).") header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path) header.add_text("/// This header provides forward declaration for all JsonCpp types.") header.add_file("LICENSE", wrap_in_comment=True) - header.add_text("#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED") - header.add_text("# define JSON_FORWARD_AMALGATED_H_INCLUDED") - header.add_text("/// If defined, indicates that the source file is amalgated") + header.add_text("#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") + header.add_text("# define JSON_FORWARD_AMALGAMATED_H_INCLUDED") + header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") header.add_file("include/json/config.h") header.add_file("include/json/forwards.h") - header.add_text("#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED") + header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") target_forward_header_path = os.path.join(os.path.dirname(target_source_path), forward_header_include_path) - print("Writing amalgated forward header to %r" % target_forward_header_path) + print("Writing amalgamated forward header to %r" % target_forward_header_path) header.write_to(target_forward_header_path) - print("Amalgating source...") + print("Amalgamating source...") source = AmalgamationFile(source_top_dir) - source.add_text("/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).") + source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).") source.add_text('/// It is intended to be used with #include "%s"' % header_include_path) source.add_file("LICENSE", wrap_in_comment=True) source.add_text("") @@ -123,12 +123,12 @@ def amalgamate_source(source_top_dir=None, source.add_file(os.path.join(lib_json, "json_value.cpp")) source.add_file(os.path.join(lib_json, "json_writer.cpp")) - print("Writing amalgated source to %r" % target_source_path) + print("Writing amalgamated source to %r" % target_source_path) source.write_to(target_source_path) def main(): usage = """%prog [options] -Generate a single amalgated source and header file from the sources. +Generate a single amalgamated source and header file from the sources. """ from optparse import OptionParser parser = OptionParser(usage=usage) @@ -136,7 +136,7 @@ def main(): parser.add_option("-s", "--source", dest="target_source_path", action="http://github.com/store", default="dist/jsoncpp.cpp", help="""Output .cpp source path. [Default: %default]""") parser.add_option("-i", "--include", dest="header_include_path", action="http://github.com/store", default="json/json.h", - help="""Header include path. Used to include the header from the amalgated source file. [Default: %default]""") + help="""Header include path. Used to include the header from the amalgamated source file. [Default: %default]""") parser.add_option("-t", "--top-dir", dest="top_dir", action="http://github.com/store", default=os.getcwd(), help="""Source top-directory. [Default: %default]""") parser.enable_interspersed_args() @@ -149,7 +149,7 @@ def main(): sys.stderr.write(msg + "\n") sys.exit(1) else: - print("Source succesfully amalagated") + print("Source successfully amalgamated") if __name__ == "__main__": main() diff --git a/doc/doxyfile.in b/doc/doxyfile.in index 7265a2267..7bbe9bc5c 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -271,7 +271,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. @@ -1408,7 +1408,7 @@ FORMULA_FONTSIZE = 10 FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# http://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1478,7 +1478,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavours of web server based searching depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is @@ -1959,7 +1959,7 @@ PREDEFINED = "_MSC_VER=1400" \ EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an +# remove all references to function-like macros that are alone on a line, have an # all uppercase name, and do not end with a semicolon. Such function macros are # typically used for boiler-plate code, and will confuse the parser if not # removed. diff --git a/doc/web_doxyfile.in b/doc/web_doxyfile.in index f221e64be..7b4c9340d 100644 --- a/doc/web_doxyfile.in +++ b/doc/web_doxyfile.in @@ -271,7 +271,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. @@ -1408,7 +1408,7 @@ FORMULA_FONTSIZE = 10 FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# http://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using prerendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1478,7 +1478,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavours of web server based searching depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is @@ -1947,7 +1947,7 @@ PREDEFINED = "_MSC_VER=1400" \ EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an +# remove all references to function-like macros that are alone on a line, have an # all uppercase name, and do not end with a semicolon. Such function macros are # typically used for boiler-plate code, and will confuse the parser if not # removed. diff --git a/doxybuild.py b/doxybuild.py index f18c9c069..862c1f43f 100644 --- a/doxybuild.py +++ b/doxybuild.py @@ -156,7 +156,7 @@ def yesno(bool): def main(): usage = """%prog Generates doxygen documentation in build/doxygen. - Optionaly makes a tarball of the documentation to dist/. + Optionally makes a tarball of the documentation to dist/. Must be started in the project top directory. """ diff --git a/include/json/config.h b/include/json/config.h index c83e78a3f..d6bad30a2 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -25,9 +25,9 @@ #define JSON_USE_EXCEPTION 1 #endif -/// If defined, indicates that the source file is amalgated +/// If defined, indicates that the source file is amalgamated /// to prevent private header inclusion. -/// Remarks: it is automatically defined in the generated amalgated header. +/// Remarks: it is automatically defined in the generated amalgamated header. // #define JSON_IS_AMALGAMATION #ifdef JSON_IN_CPPTL @@ -78,7 +78,7 @@ #endif // defined(_MSC_VER) -// In c++11 the override keyword allows you to explicity define that a function +// In c++11 the override keyword allows you to explicitly define that a function // is intended to override the base-class version. This makes the code more // managable and fixes a set of common hard-to-find bugs. #if __cplusplus >= 201103L diff --git a/include/json/value.h b/include/json/value.h index 2e533142f..be40c300d 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -116,7 +116,7 @@ enum CommentPlacement { /** \brief Lightweight wrapper to tag static string. * - * Value constructor and objectValue member assignement takes advantage of the + * Value constructor and objectValue member assignment takes advantage of the * StaticString and avoid the cost of string duplication when storing the * string or the member name. * diff --git a/include/json/writer.h b/include/json/writer.h index 5280016ce..2278bc8a9 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -99,7 +99,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { - "dropNullPlaceholders": false or true - Drop the "null" string from the writer's output for nullValues. Strictly speaking, this is not valid JSON. But when the output is being - fed to a browser's Javascript, it makes for smaller output and the + fed to a browser's JavaScript, it makes for smaller output and the browser can handle the output just fine. - "useSpecialFloats": false or true - If true, outputs non-finite floating point values in the following way: @@ -169,7 +169,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter /** \brief Drop the "null" string from the writer's output for nullValues. * Strictly speaking, this is not valid JSON. But when the output is being - * fed to a browser's Javascript, it makes for smaller output and the + * fed to a browser's JavaScript, it makes for smaller output and the * browser can handle the output just fine. */ void dropNullPlaceholders(); @@ -183,7 +183,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void writeValue(const Value& value); JSONCPP_STRING document_; - bool yamlCompatiblityEnabled_; + bool yamlCompatibilityEnabled_; bool dropNullPlaceholders_; bool omitEndingLineFeed_; }; @@ -234,7 +234,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWrite private: void writeValue(const Value& value); void writeArrayValue(const Value& value); - bool isMultineArray(const Value& value); + bool isMultilineArray(const Value& value); void pushValue(const JSONCPP_STRING& value); void writeIndent(); void writeWithIndent(const JSONCPP_STRING& value); @@ -307,7 +307,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStrea private: void writeValue(const Value& value); void writeArrayValue(const Value& value); - bool isMultineArray(const Value& value); + bool isMultilineArray(const Value& value); void pushValue(const JSONCPP_STRING& value); void writeIndent(); void writeWithIndent(const JSONCPP_STRING& value); diff --git a/makerelease.py b/makerelease.py index ba2e9aa40..bc716cbab 100644 --- a/makerelease.py +++ b/makerelease.py @@ -265,7 +265,7 @@ def main(): Must be started in the project top directory. -Warning: --force should only be used when developping/testing the release script. +Warning: --force should only be used when developing/testing the release script. """ from optparse import OptionParser parser = OptionParser(usage=usage) @@ -377,7 +377,7 @@ def main(): user=options.user, sftp=options.sftp) print('Source and doc release tarballs uploaded') else: - print('No upload user specified. Web site and download tarbal were not uploaded.') + print('No upload user specified. Web site and download tarball were not uploaded.') print('Tarball can be found at:', doc_tarball_path) # Set next version number and commit diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 51aa7a07e..4590bfcf4 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -71,7 +71,7 @@ enum { typedef char UIntToStringBuffer[uintToStringBufferSize]; /** Converts an unsigned integer to string. - * @param value Unsigned interger to convert to string + * @param value Unsigned integer to convert to string * @param current Input/Output string buffer. * Must have at least uintToStringBufferSize chars free. */ diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 0852b48b1..9a912acf8 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -128,7 +128,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p snprintf(formatString, sizeof(formatString), "%%.%dg", precision); // Print into the buffer. We need not request the alternative representation - // that always has a decimal point because JSON doesn't distingish the + // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. if (isfinite(value)) { len = snprintf(buffer, sizeof(buffer), formatString, value); @@ -334,10 +334,10 @@ Writer::~Writer() {} // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false), + : yamlCompatibilityEnabled_(false), dropNullPlaceholders_(false), omitEndingLineFeed_(false) {} -void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; } +void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } @@ -397,7 +397,7 @@ void FastWriter::writeValue(const Value& value) { if (it != members.begin()) document_ += ','; document_ += valueToQuotedStringN(name.data(), static_cast(name.length())); - document_ += yamlCompatiblityEnabled_ ? ": " : ":"; + document_ += yamlCompatibilityEnabled_ ? ": " : ":"; writeValue(value[name]); } document_ += '}'; @@ -486,7 +486,7 @@ void StyledWriter::writeArrayValue(const Value& value) { if (size == 0) pushValue("[]"); else { - bool isArrayMultiLine = isMultineArray(value); + bool isArrayMultiLine = isMultilineArray(value); if (isArrayMultiLine) { writeWithIndent("["); indent(); @@ -524,7 +524,7 @@ void StyledWriter::writeArrayValue(const Value& value) { } } -bool StyledWriter::isMultineArray(const Value& value) { +bool StyledWriter::isMultilineArray(const Value& value) { ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); @@ -703,7 +703,7 @@ void StyledStreamWriter::writeArrayValue(const Value& value) { if (size == 0) pushValue("[]"); else { - bool isArrayMultiLine = isMultineArray(value); + bool isArrayMultiLine = isMultilineArray(value); if (isArrayMultiLine) { writeWithIndent("["); indent(); @@ -743,7 +743,7 @@ void StyledStreamWriter::writeArrayValue(const Value& value) { } } -bool StyledStreamWriter::isMultineArray(const Value& value) { +bool StyledStreamWriter::isMultilineArray(const Value& value) { ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); @@ -860,7 +860,7 @@ struct BuiltStyledStreamWriter : public StreamWriter private: void writeValue(Value const& value); void writeArrayValue(Value const& value); - bool isMultineArray(Value const& value); + bool isMultilineArray(Value const& value); void pushValue(JSONCPP_STRING const& value); void writeIndent(); void writeWithIndent(JSONCPP_STRING const& value); @@ -984,7 +984,7 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { if (size == 0) pushValue("[]"); else { - bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value); + bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value); if (isMultiLine) { writeWithIndent("["); indent(); @@ -1026,7 +1026,7 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { } } -bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { +bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) { ArrayIndex const size = value.size(); bool isMultiLine = size * 3 >= rightMargin_; childValues_.clear(); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index f8c076771..94a0672b8 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -398,7 +398,7 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) -// @todo investiguate this handler (for buffer overflow) +// @todo investigate this handler (for buffer overflow) // _set_security_error_handler #if defined(_WIN32) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3bbe89663..4e5aad166 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2040,7 +2040,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { } } JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { - // This is interpretted as an int value followed by a colon. + // This is interpreted as an int value followed by a colon. Json::CharReaderBuilder b; Json::Value root; char const doc[] = From 42ca02b83399c42efee63344574260cbdb38d075 Mon Sep 17 00:00:00 2001 From: Remy Jette Date: Mon, 4 Dec 2017 17:49:36 -0800 Subject: [PATCH 007/410] Fix sign mismatch in `valueToString` `valueToString` takes an argument `unsigned int precision`, but it is used with `%d` rather than `%u` in the `snprintf` format string. Make the format string look for an unsigned value instead. --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 9a912acf8..de26b242b 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -125,7 +125,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p int len = -1; char formatString[15]; - snprintf(formatString, sizeof(formatString), "%%.%dg", precision); + snprintf(formatString, sizeof(formatString), "%%.%ug", precision); // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the From 9079422ac11314e7f6485ac35e8d66c5bdaad4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfram=20R=C3=B6sler?= Date: Tue, 5 Dec 2017 18:18:55 +0100 Subject: [PATCH 008/410] Allow Json::Value to be used in a boolean context (#695) Must bump soversion too. --- include/json/value.h | 4 ++-- src/lib_json/json_value.cpp | 2 +- src/test_lib_json/main.cpp | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index be40c300d..67d0333d2 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -400,8 +400,8 @@ Json::Value obj_value(Json::objectValue); // {} /// otherwise, false. bool empty() const; - /// Return isNull() - bool operator!() const; + /// Return !isNull() + explicit operator bool() const; /// Remove all object members and array elements. /// \pre type() is arrayValue, objectValue, or nullValue diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 5197d1861..91d4802e6 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -962,7 +962,7 @@ bool Value::empty() const { return false; } -bool Value::operator!() const { return isNull(); } +Value::operator bool() const { return ! isNull(); } void Value::clear() { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 4e5aad166..d00e107a3 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -308,6 +308,12 @@ JSONTEST_FIXTURE(ValueTest, null) { JSONTEST_ASSERT_STRING_EQUAL("", null_.asString()); JSONTEST_ASSERT_EQUAL(Json::Value::null, null_); + + // Test using a Value in a boolean context (false iff null) + JSONTEST_ASSERT_EQUAL(null_,false); + JSONTEST_ASSERT_EQUAL(object1_,true); + JSONTEST_ASSERT_EQUAL(!null_,true); + JSONTEST_ASSERT_EQUAL(!object1_,false); } JSONTEST_FIXTURE(ValueTest, strings) { From 41ff85f443e67eeefb33dbdc6e15dc4373f544c5 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 20 Dec 2017 14:24:51 -0600 Subject: [PATCH 009/410] pyenv install (#713) ``` Unfortunately, since our latest image update, Python 3.5 doesn't come pre-installed anymore. Hence, you will have to install it via `pyenv` as a first step e.g. before_install - pyenv install 3.5.0 && pyenv global 3.5.0 support@travis-ci.com ``` --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 028e91a28..b218c02b8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ # http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448 # to allow C++11, though we are not yet building with -std=c++11 -before_install: pyenv global 3.5 +before_install: pyenv install 3.5.4 && pyenv global 3.5.4 install: - if [[ $TRAVIS_OS_NAME == osx ]]; then brew update; From 63ab03ca28d13763f7e05dedf3eca90cbf052a64 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 20 Dec 2017 14:43:55 -0600 Subject: [PATCH 010/410] replace code point in range(0xD800, 0xDFFF) to replacement mark (#714) closes #712 --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index de26b242b..5ffaa15c6 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -199,7 +199,7 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { s += 2; // surrogates aren't valid codepoints itself // shouldn't be UTF-8 encoded - if (calculated >= 0xD800 && calculated >= 0xDFFF) + if (calculated >= 0xD800 && calculated <= 0xDFFF) return REPLACEMENT_CHARACTER; // oversized encoded characters are invalid return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated; From ddabf50f72cf369bf652a95c4d9fe31a1865a781 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 20 Dec 2017 14:52:26 -0600 Subject: [PATCH 011/410] 1.8.4; soversion=20 --- CMakeLists.txt | 2 +- include/json/version.h | 4 ++-- meson.build | 4 ++-- version | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cfaf53d8..ddcc16564 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,7 @@ ENDMACRO() #SET( JSONCPP_VERSION_MAJOR X ) #SET( JSONCPP_VERSION_MINOR Y ) #SET( JSONCPP_VERSION_PATCH Z ) -SET( JSONCPP_VERSION 1.8.3 ) +SET( JSONCPP_VERSION 1.8.4 ) jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION ) #IF(NOT JSONCPP_VERSION_FOUND) # MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") diff --git a/include/json/version.h b/include/json/version.h index b1d2a5ff4..06c61870f 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -3,10 +3,10 @@ #ifndef JSON_VERSION_H_INCLUDED # define JSON_VERSION_H_INCLUDED -# define JSONCPP_VERSION_STRING "1.8.3" +# define JSONCPP_VERSION_STRING "1.8.4" # define JSONCPP_VERSION_MAJOR 1 # define JSONCPP_VERSION_MINOR 8 -# define JSONCPP_VERSION_PATCH 3 +# define JSONCPP_VERSION_PATCH 4 # define JSONCPP_VERSION_QUALIFIER # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) diff --git a/meson.build b/meson.build index 8f0bfaf11..8daab9c78 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'jsoncpp', 'cpp', - version : '1.8.3', + version : '1.8.4', default_options : [ 'buildtype=release', 'warning_level=1'], @@ -53,7 +53,7 @@ jsoncpp_lib = library( 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp'], - soversion : 19, + soversion : 20, install : true, include_directories : jsoncpp_include_directories) diff --git a/version b/version index a7ee35a3e..bfa363e76 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.8.3 +1.8.4 From 899894f0f5fbb544e19d90222ae2a0311bde2e4d Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Thu, 21 Dec 2017 01:22:40 -0600 Subject: [PATCH 012/410] -std=c++11 (#715) We set this is the Meson build to eliminate warnings, but c++0x should still work, at least for now. See #695 for discussion. --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index 8daab9c78..f5573c04e 100644 --- a/meson.build +++ b/meson.build @@ -4,6 +4,7 @@ project( version : '1.8.4', default_options : [ 'buildtype=release', + 'cpp_std=c++11', 'warning_level=1'], license : 'Public Domain', meson_version : '>= 0.41.1') From de5fb8e022b02bd12cc5f73b01bf606d5f4eda4f Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Thu, 21 Dec 2017 01:25:42 -0600 Subject: [PATCH 013/410] Try to use default python on Trusty, for speed Running `pyenv install` wastes about 3 minutes. * https://docs.travis-ci.com/user/languages/python "for Trusty, this means 2.7.6 and 3.4.3" --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b218c02b8..271cb49f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,9 @@ # http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448 # to allow C++11, though we are not yet building with -std=c++11 -before_install: pyenv install 3.5.4 && pyenv global 3.5.4 +#before_install: pyenv install 3.5.4 && pyenv global 3.5.4 +# https://docs.travis-ci.com/user/languages/python/ +# "for Trusty, this means 2.7.6 and 3.4.3" install: - if [[ $TRAVIS_OS_NAME == osx ]]; then brew update; From d3ce75c74e8d54a4f0561c38feffa1eb47836179 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Thu, 21 Dec 2017 02:05:52 -0600 Subject: [PATCH 014/410] pyenv global 3.6 We need pip3, and TravisCI build error says: The `pip3` command exists in these Python versions: 3.6, 3.6.3 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 271cb49f5..33e65c4ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ # to allow C++11, though we are not yet building with -std=c++11 #before_install: pyenv install 3.5.4 && pyenv global 3.5.4 +before_install: pyenv global 3.6 # https://docs.travis-ci.com/user/languages/python/ # "for Trusty, this means 2.7.6 and 3.4.3" install: From 798f6ba0552d7fc7e27bbb44a22108a2ce21ab0e Mon Sep 17 00:00:00 2001 From: Darcy Beurle Date: Fri, 22 Dec 2017 22:48:20 +0100 Subject: [PATCH 015/410] CZString as public when using NVCC, see issue #486 --- include/json/value.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 67d0333d2..d1bf8ffcd 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -220,7 +220,14 @@ class JSON_API Value { static const UInt64 maxUInt64; #endif // defined(JSON_HAS_INT64) +// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler +// when using gcc and clang backend compilers. CZString +// cannot be defined as private. See issue #486 +#ifdef __NVCC__ +public: +#else private: +#endif #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION class CZString { public: From c69148c9468b02835803480fd204121f06c7530a Mon Sep 17 00:00:00 2001 From: Andrey Okoshkin Date: Fri, 12 Jan 2018 11:26:34 +0300 Subject: [PATCH 016/410] Fix Value::copyPayload() and Value::copy() (#704) Value copy constructor shares the same code with Value::copy() and Value::copyPayload(). New Value::releasePayload() is used to free payload memory. Fixes: #704 --- include/json/value.h | 1 + src/lib_json/json_value.cpp | 131 +++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 63 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index d1bf8ffcd..164321060 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -606,6 +606,7 @@ Json::Value obj_value(Json::objectValue); // {} private: void initBasic(ValueType type, bool allocated = false); + void releasePayload(); Value& resolveReference(const char* key); Value& resolveReference(const char* key, const char* end); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 91d4802e6..eb7b6b08e 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -441,48 +441,11 @@ Value::Value(bool value) { value_.bool_ = value; } -Value::Value(Value const& other) - : type_(other.type_), allocated_(false) - , - comments_(0), start_(other.start_), limit_(other.limit_) -{ - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - value_ = other.value_; - break; - case stringValue: - if (other.value_.string_ && other.allocated_) { - unsigned len; - char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, - &len, &str); - value_.string_ = duplicateAndPrefixStringValue(str, len); - allocated_ = true; - } else { - value_.string_ = other.value_.string_; - allocated_ = false; - } - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(*other.value_.map_); - break; - default: - JSON_ASSERT_UNREACHABLE; - } - if (other.comments_) { - comments_ = new CommentInfo[numberOfCommentPlacement]; - for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { - const CommentInfo& otherComment = other.comments_[comment]; - if (otherComment.comment_) - comments_[comment].setComment( - otherComment.comment_, strlen(otherComment.comment_)); - } - } +Value::Value(const Value& other) { + type_ = nullValue; + allocated_ = false; + comments_ = 0; + copy(other); } #if JSON_HAS_RVALUE_REFERENCES @@ -494,24 +457,7 @@ Value::Value(Value&& other) { #endif Value::~Value() { - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - break; - case stringValue: - if (allocated_) - releasePrefixedStringValue(value_.string_); - break; - case arrayValue: - case objectValue: - delete value_.map_; - break; - default: - JSON_ASSERT_UNREACHABLE; - } + releasePayload(); delete[] comments_; @@ -534,9 +480,36 @@ void Value::swapPayload(Value& other) { } void Value::copyPayload(const Value& other) { + releasePayload(); type_ = other.type_; - value_ = other.value_; - allocated_ = other.allocated_; + allocated_ = false; + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if (other.value_.string_ && other.allocated_) { + unsigned len; + char const* str; + decodePrefixedString(other.allocated_, other.value_.string_, + &len, &str); + value_.string_ = duplicateAndPrefixStringValue(str, len); + allocated_ = true; + } else { + value_.string_ = other.value_.string_; + } + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(*other.value_.map_); + break; + default: + JSON_ASSERT_UNREACHABLE; + } } void Value::swap(Value& other) { @@ -548,7 +521,18 @@ void Value::swap(Value& other) { void Value::copy(const Value& other) { copyPayload(other); - comments_ = other.comments_; + delete[] comments_; + if (other.comments_) { + comments_ = new CommentInfo[numberOfCommentPlacement]; + for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { + const CommentInfo& otherComment = other.comments_[comment]; + if (otherComment.comment_) + comments_[comment].setComment( + otherComment.comment_, strlen(otherComment.comment_)); + } + } else { + comments_ = 0; + } start_ = other.start_; limit_ = other.limit_; } @@ -1049,6 +1033,27 @@ void Value::initBasic(ValueType vtype, bool allocated) { limit_ = 0; } +void Value::releasePayload() { + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if (allocated_) + releasePrefixedStringValue(value_.string_); + break; + case arrayValue: + case objectValue: + delete value_.map_; + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + // Access an object value by name, create a null member if it does not exist. // @pre Type of '*this' is object or null. // @param key is null-terminated. From 392e3a5b49cd63554694d57f3f4bd24b49dbb108 Mon Sep 17 00:00:00 2001 From: Andrey Okoshkin Date: Fri, 12 Jan 2018 11:27:11 +0300 Subject: [PATCH 017/410] Add basic test for Value::copy() (#704) --- src/test_lib_json/main.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index d00e107a3..ee8179067 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1433,6 +1433,40 @@ JSONTEST_FIXTURE(ValueTest, compareType) { Json::Value(Json::objectValue))); } +JSONTEST_FIXTURE(ValueTest, CopyObject) { + Json::Value arrayVal; + arrayVal.append("val1"); + arrayVal.append("val2"); + arrayVal.append("val3"); + Json::Value stringVal("string value"); + Json::Value copy1, copy2; + { + Json::Value arrayCopy, stringCopy; + arrayCopy.copy(arrayVal); + stringCopy.copy(stringVal); + JSONTEST_ASSERT_PRED(checkIsEqual(arrayCopy, arrayVal)); + JSONTEST_ASSERT_PRED(checkIsEqual(stringCopy, stringVal)); + arrayCopy.append("val4"); + JSONTEST_ASSERT(arrayCopy.size() == 4); + arrayVal.append("new4"); + arrayVal.append("new5"); + JSONTEST_ASSERT(arrayVal.size() == 5); + JSONTEST_ASSERT(!(arrayCopy == arrayVal)); + stringCopy = "another string"; + JSONTEST_ASSERT(!(stringCopy == stringVal)); + copy1.copy(arrayCopy); + copy2.copy(stringCopy); + } + JSONTEST_ASSERT(arrayVal.size() == 5); + JSONTEST_ASSERT(stringVal == "string value"); + JSONTEST_ASSERT(copy1.size() == 4); + JSONTEST_ASSERT(copy2 == "another string"); + copy1.copy(stringVal); + JSONTEST_ASSERT(copy1 == "string value"); + copy2.copy(arrayVal); + JSONTEST_ASSERT(copy2.size() == 5); +} + void ValueTest::checkIsLess(const Json::Value& x, const Json::Value& y) { JSONTEST_ASSERT(x < y); JSONTEST_ASSERT(y > x); @@ -2544,6 +2578,7 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType); + JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CopyObject); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString); From 9b569c8ce38419fa8ad98de4db27a349ecdaf3d0 Mon Sep 17 00:00:00 2001 From: Andrey Okoshkin Date: Fri, 12 Jan 2018 15:59:20 +0300 Subject: [PATCH 018/410] Make Value copy constructor simplier Helper private methods Value::dupPayload() and Value::dupMeta() are added. Value copy constructor doesn't attempt to delete its data first. * Value::dupPayload() duplicates a payload. * Value::dupMeta() duplicates comments and an offset position with a limit. --- include/json/value.h | 2 + src/lib_json/json_value.cpp | 98 ++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 164321060..bcf3675d7 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -606,7 +606,9 @@ Json::Value obj_value(Json::objectValue); // {} private: void initBasic(ValueType type, bool allocated = false); + void dupPayload(const Value& other); void releasePayload(); + void dupMeta(const Value& other); Value& resolveReference(const char* key); Value& resolveReference(const char* key, const char* end); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index eb7b6b08e..30449fd22 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -442,10 +442,8 @@ Value::Value(bool value) { } Value::Value(const Value& other) { - type_ = nullValue; - allocated_ = false; - comments_ = 0; - copy(other); + dupPayload(other); + dupMeta(other); } #if JSON_HAS_RVALUE_REFERENCES @@ -481,35 +479,7 @@ void Value::swapPayload(Value& other) { void Value::copyPayload(const Value& other) { releasePayload(); - type_ = other.type_; - allocated_ = false; - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - value_ = other.value_; - break; - case stringValue: - if (other.value_.string_ && other.allocated_) { - unsigned len; - char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, - &len, &str); - value_.string_ = duplicateAndPrefixStringValue(str, len); - allocated_ = true; - } else { - value_.string_ = other.value_.string_; - } - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(*other.value_.map_); - break; - default: - JSON_ASSERT_UNREACHABLE; - } + dupPayload(other); } void Value::swap(Value& other) { @@ -522,19 +492,7 @@ void Value::swap(Value& other) { void Value::copy(const Value& other) { copyPayload(other); delete[] comments_; - if (other.comments_) { - comments_ = new CommentInfo[numberOfCommentPlacement]; - for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { - const CommentInfo& otherComment = other.comments_[comment]; - if (otherComment.comment_) - comments_[comment].setComment( - otherComment.comment_, strlen(otherComment.comment_)); - } - } else { - comments_ = 0; - } - start_ = other.start_; - limit_ = other.limit_; + dupMeta(other); } ValueType Value::type() const { return type_; } @@ -1033,6 +991,38 @@ void Value::initBasic(ValueType vtype, bool allocated) { limit_ = 0; } +void Value::dupPayload(const Value& other) { + type_ = other.type_; + allocated_ = false; + switch (type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + value_ = other.value_; + break; + case stringValue: + if (other.value_.string_ && other.allocated_) { + unsigned len; + char const* str; + decodePrefixedString(other.allocated_, other.value_.string_, + &len, &str); + value_.string_ = duplicateAndPrefixStringValue(str, len); + allocated_ = true; + } else { + value_.string_ = other.value_.string_; + } + break; + case arrayValue: + case objectValue: + value_.map_ = new ObjectValues(*other.value_.map_); + break; + default: + JSON_ASSERT_UNREACHABLE; + } +} + void Value::releasePayload() { switch (type_) { case nullValue: @@ -1054,6 +1044,22 @@ void Value::releasePayload() { } } +void Value::dupMeta(const Value& other) { + if (other.comments_) { + comments_ = new CommentInfo[numberOfCommentPlacement]; + for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { + const CommentInfo& otherComment = other.comments_[comment]; + if (otherComment.comment_) + comments_[comment].setComment( + otherComment.comment_, strlen(otherComment.comment_)); + } + } else { + comments_ = 0; + } + start_ = other.start_; + limit_ = other.limit_; +} + // Access an object value by name, create a null member if it does not exist. // @pre Type of '*this' is object or null. // @param key is null-terminated. From edb4bdb7ec104b055b17490ed2a6497b72c96ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christof=20Kr=C3=BCger?= Date: Fri, 12 Jan 2018 21:35:17 +0100 Subject: [PATCH 019/410] Do not deprecate whole class but only constructors of Json::Reader. This should fix warning C4996 issued by Visual Studio in cases where Json::Reader is not even used by client code. --- include/json/reader.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/json/reader.h b/include/json/reader.h index 82859fda1..dc1da1f3e 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -32,7 +32,7 @@ namespace Json { * * \deprecated Use CharReader and CharReaderBuilder. */ -class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_API Reader { +class JSON_API Reader { public: typedef char Char; typedef const Char* Location; @@ -52,11 +52,13 @@ class JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") JSON_AP /** \brief Constructs a Reader allowing all features * for parsing. */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set * for parsing. */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON From 04abe38148d99b2a5270521935115d769a714adc Mon Sep 17 00:00:00 2001 From: drgler Date: Sat, 13 Jan 2018 15:28:19 +0100 Subject: [PATCH 020/410] Issue #731: Provide new JSONCPP_OP_EXPLICIT macro to restore VS 2012 support after recent introduction of explicit conversion function in JSON::Value. --- include/json/config.h | 8 ++++++++ include/json/value.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/include/json/config.h b/include/json/config.h index d6bad30a2..9410449e0 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -84,15 +84,23 @@ #if __cplusplus >= 201103L # define JSONCPP_OVERRIDE override # define JSONCPP_NOEXCEPT noexcept +# define JSONCPP_OP_EXPLICIT explicit #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 # define JSONCPP_OVERRIDE override # define JSONCPP_NOEXCEPT throw() +# if _MSC_VER >= 1800 // MSVC 2013 +# define JSONCPP_OP_EXPLICIT explicit +# else +# define JSONCPP_OP_EXPLICIT +# endif #elif defined(_MSC_VER) && _MSC_VER >= 1900 # define JSONCPP_OVERRIDE override # define JSONCPP_NOEXCEPT noexcept +# define JSONCPP_OP_EXPLICIT explicit #else # define JSONCPP_OVERRIDE # define JSONCPP_NOEXCEPT throw() +# define JSONCPP_OP_EXPLICIT #endif #ifndef JSON_HAS_RVALUE_REFERENCES diff --git a/include/json/value.h b/include/json/value.h index bcf3675d7..8d049ad1e 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -408,7 +408,7 @@ Json::Value obj_value(Json::objectValue); // {} bool empty() const; /// Return !isNull() - explicit operator bool() const; + JSONCPP_OP_EXPLICIT operator bool() const; /// Remove all object members and array elements. /// \pre type() is arrayValue, objectValue, or nullValue From c27936e0aab4e4b86fec59af41d50adc28d18dc1 Mon Sep 17 00:00:00 2001 From: Maxim Ky Date: Mon, 29 Jan 2018 16:58:45 +0300 Subject: [PATCH 021/410] Value::removeMember moves the existing value to "removed" now --- src/lib_json/json_value.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 30449fd22..3a572eefb 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1186,7 +1186,11 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed) ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; +#if JSON_HAS_RVALUE_REFERENCES + *removed = std::move(it->second); +#else *removed = it->second; +#endif value_.map_->erase(it); return true; } From 1ec85c76a43872fde6a0c27ba5ba737a445724f1 Mon Sep 17 00:00:00 2001 From: Maxim Ky Date: Mon, 29 Jan 2018 16:59:24 +0300 Subject: [PATCH 022/410] Value::removeMember arg "removed" is optional now (could be nullptr) --- src/lib_json/json_value.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 3a572eefb..a3e6550c7 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1186,10 +1186,11 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed) ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; + if (removed) #if JSON_HAS_RVALUE_REFERENCES - *removed = std::move(it->second); + *removed = std::move(it->second); #else - *removed = it->second; + *removed = it->second; #endif value_.map_->erase(it); return true; From 5b45aa55cada165278f5b447425affae818dce2a Mon Sep 17 00:00:00 2001 From: luzpaz Date: Thu, 8 Feb 2018 20:05:50 -0500 Subject: [PATCH 023/410] Misc-typos (#741) Found in downstream CMake repo via `codespell -q 3` --- doc/doxyfile.in | 2 +- doc/web_doxyfile.in | 2 +- include/json/config.h | 2 +- include/json/writer.h | 2 +- src/test_lib_json/jsontest.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/doxyfile.in b/doc/doxyfile.in index 7bbe9bc5c..baf04c19a 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -1072,7 +1072,7 @@ HTML_STYLESHEET = # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. +# standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. diff --git a/doc/web_doxyfile.in b/doc/web_doxyfile.in index 7b4c9340d..938ecd125 100644 --- a/doc/web_doxyfile.in +++ b/doc/web_doxyfile.in @@ -1072,7 +1072,7 @@ HTML_STYLESHEET = # defined cascading style sheet that is included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. +# standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet file to the output directory. For an example # see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. diff --git a/include/json/config.h b/include/json/config.h index 9410449e0..7d3469228 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -80,7 +80,7 @@ // In c++11 the override keyword allows you to explicitly define that a function // is intended to override the base-class version. This makes the code more -// managable and fixes a set of common hard-to-find bugs. +// manageable and fixes a set of common hard-to-find bugs. #if __cplusplus >= 201103L # define JSONCPP_OVERRIDE override # define JSONCPP_NOEXCEPT noexcept diff --git a/include/json/writer.h b/include/json/writer.h index 2278bc8a9..9e7adde9f 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -152,7 +152,7 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { * * The JSON document is written in a single line. It is not intended for 'human' *consumption, - * but may be usefull to support feature such as RPC where bandwith is limited. + * but may be useful to support feature such as RPC where bandwidth is limited. * \sa Reader, Value * \deprecated Use StreamWriterBuilder. */ diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 955317df2..dd3285198 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -270,7 +270,7 @@ TestResult& checkStringEqual(TestResult& result, return new Test##FixtureType##name(); \ } \ \ - public: /* overidden from TestCase */ \ + public: /* overridden from TestCase */ \ const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; } \ void runTestCase() JSONCPP_OVERRIDE; \ }; \ From 592d942b3be5e25619edbfe3d37a69bfa75810aa Mon Sep 17 00:00:00 2001 From: Thomas Jandecka Date: Wed, 14 Feb 2018 14:23:58 +0100 Subject: [PATCH 024/410] fix: byte shift when interpreting 32-bit utf-8 codepoints --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 5ffaa15c6..456424d6a 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -209,7 +209,7 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { if (e - s < 4) return REPLACEMENT_CHARACTER; - unsigned int calculated = ((firstByte & 0x07) << 24) + unsigned int calculated = ((firstByte & 0x07) << 18) | ((static_cast(s[1]) & 0x3F) << 12) | ((static_cast(s[2]) & 0x3F) << 6) | (static_cast(s[3]) & 0x3F); From c7728e86589a6b46758a1bfdb35160e826c2c74c Mon Sep 17 00:00:00 2001 From: uvok cheetah Date: Sat, 3 Mar 2018 12:45:54 +0100 Subject: [PATCH 025/410] Clarify documentation regarding indentation / newline --- include/json/writer.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/json/writer.h b/include/json/writer.h index 9e7adde9f..35ec3965b 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -93,7 +93,8 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { /** Configuration of this builder. Available settings (case-sensitive): - "commentStyle": "None" or "All" - - "indentation": "" + - "indentation": "". + - Setting this to an empty string also omits newline characters. - "enableYAMLCompatibility": false or true - slightly change the whitespace around colons - "dropNullPlaceholders": false or true From 3e2b8ea9ccf6c9068f54c8ba5523abd8a62cb760 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 3 Mar 2018 12:51:17 -0600 Subject: [PATCH 026/410] Minor changes for static analysis (#749) re: #747 --- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index a3e6550c7..1633f4984 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -931,7 +931,7 @@ void Value::resize(ArrayIndex newSize) { if (newSize == 0) clear(); else if (newSize > oldSize) - (*this)[newSize - 1]; + this->operator[](newSize - 1); else { for (ArrayIndex index = newSize; index < oldSize; ++index) { value_.map_->erase(index); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 456424d6a..5167c31de 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -623,7 +623,8 @@ bool StyledWriter::hasCommentForValue(const Value& value) { StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) : document_(NULL), rightMargin_(74), indentation_(indentation), - addChildValues_() {} + addChildValues_(), indented_(false) +{} void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { document_ = &out; From 1d95628ba84189cd81fbabf70add5c1baf2912c5 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Tue, 6 Mar 2018 12:51:58 -0500 Subject: [PATCH 027/410] Remove std::swap in favor of ADL Comply with http://en.cppreference.com/w/cpp/concept/Swappable Don't open namespace std. --- include/json/value.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 8d049ad1e..264378255 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -880,14 +880,9 @@ class JSON_API ValueIterator : public ValueIteratorBase { pointer operator->() const { return &deref(); } }; -} // namespace Json - +inline void swap(Value& a, Value& b) { a.swap(b); } -namespace std { -/// Specialize std::swap() for Json::Value. -template<> -inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); } -} +} // namespace Json #pragma pack(pop) From a07fc53287d4efeada0bc295ed70e195b2f7aa4f Mon Sep 17 00:00:00 2001 From: Mike R Date: Tue, 13 Mar 2018 23:35:31 +0300 Subject: [PATCH 028/410] Add setting precision for json writers and also add decimal places precision type. (#752) * Added setting precision for writers. * Added special case for precise precision and global precision. * Added good setting of type of precision and also added this type to BuiltStreamWriter and for its settings. * Added some tests. --- include/json/value.h | 10 +++++++++ include/json/writer.h | 7 ++++++- src/lib_json/json_tool.h | 14 +++++++++++++ src/lib_json/json_value.cpp | 2 ++ src/lib_json/json_writer.cpp | 39 +++++++++++++++++++++++++++++------- src/test_lib_json/main.cpp | 21 +++++++++++++++++++ 6 files changed, 85 insertions(+), 8 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 264378255..3474cd840 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -109,6 +109,13 @@ enum CommentPlacement { numberOfCommentPlacement }; +/** \brief Type of precision for formatting of real values. + */ +enum PrecisionType { + significantDigits = 0, ///< we set max number of significant digits in string + decimalPlaces ///< we set max number of digits after "." in string +}; + //# ifdef JSON_USE_CPPTL // typedef CppTL::AnyEnumerator EnumMemberNames; // typedef CppTL::AnyEnumerator EnumValues; @@ -220,6 +227,9 @@ class JSON_API Value { static const UInt64 maxUInt64; #endif // defined(JSON_HAS_INT64) + /// Default precision for real value for string representation. + static const UInt defaultRealPrecision; + // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler // when using gcc and clang backend compilers. CZString // cannot be defined as private. See issue #486 diff --git a/include/json/writer.h b/include/json/writer.h index 35ec3965b..767b3bd61 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -106,6 +106,10 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { - If true, outputs non-finite floating point values in the following way: NaN values as "NaN", positive infinity as "Infinity", and negative infinity as "-Infinity". + - "precision": int + - Number of precision digits for formatting of real values. + - "precisionType": "significant"(default) or "decimal" + - Type of precision for formatting of real values. You can examine 'settings_` yourself to see the defaults. You can also write and read them just like any @@ -339,7 +343,8 @@ JSONCPP_STRING JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) JSONCPP_STRING JSON_API valueToString(LargestInt value); JSONCPP_STRING JSON_API valueToString(LargestUInt value); -JSONCPP_STRING JSON_API valueToString(double value); +JSONCPP_STRING JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision, + PrecisionType precisionType = PrecisionType::significantDigits); JSONCPP_STRING JSON_API valueToString(bool value); JSONCPP_STRING JSON_API valueToQuotedString(const char* value); diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 4590bfcf4..86f1f2c6b 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -109,6 +109,20 @@ static inline void fixNumericLocaleInput(char* begin, char* end) { } } +/** + * Delete zeros in the end of string, if it isn't last zero before '.' character. + */ +static inline void fixZerosInTheEnd(char* begin, char* end) { + end--; + while ((begin < end) && (*end == '0')) { + // don't delete last zero before point. + if (*(end - 1) != '.') { + *end = '\0'; + } + end--; + } +} + } // namespace Json { #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 1633f4984..ed49df2ca 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -64,6 +64,8 @@ const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); const LargestUInt Value::maxLargestUInt = LargestUInt(-1); +const UInt Value::defaultRealPrecision = 17; + #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template static inline bool InRange(double d, T min, U max) { diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 5167c31de..be03a66e3 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -118,14 +118,18 @@ JSONCPP_STRING valueToString(UInt value) { #endif // # if defined(JSON_HAS_INT64) namespace { -JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) { +JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) { // Allocate a buffer that is more than large enough to store the 16 digits of // precision requested below. char buffer[36]; int len = -1; char formatString[15]; - snprintf(formatString, sizeof(formatString), "%%.%ug", precision); + if (precisionType == PrecisionType::significantDigits) { + snprintf(formatString, sizeof(formatString), "%%.%ug", precision); + } else { + snprintf(formatString, sizeof(formatString), "%%.%uf", precision); + } // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the @@ -133,6 +137,10 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p if (isfinite(value)) { len = snprintf(buffer, sizeof(buffer), formatString, value); fixNumericLocale(buffer, buffer + len); + // to delete use-less too much zeros in the end of string + if (precisionType == PrecisionType::decimalPlaces) { + fixZerosInTheEnd(buffer, buffer + len); + } // try to ensure we preserve the fact that this was given to us as a double on input if (!strchr(buffer, '.') && !strchr(buffer, 'e')) { @@ -154,7 +162,9 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p } } -JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); } +JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) { + return valueToString(value, false, precision, precisionType); +} JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; } @@ -856,7 +866,8 @@ struct BuiltStyledStreamWriter : public StreamWriter JSONCPP_STRING const& nullSymbol, JSONCPP_STRING const& endingLineFeedSymbol, bool useSpecialFloats, - unsigned int precision); + unsigned int precision, + PrecisionType precisionType); int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE; private: void writeValue(Value const& value); @@ -885,6 +896,7 @@ struct BuiltStyledStreamWriter : public StreamWriter bool indented_ : 1; bool useSpecialFloats_ : 1; unsigned int precision_; + PrecisionType precisionType_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( JSONCPP_STRING const& indentation, @@ -893,7 +905,8 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter( JSONCPP_STRING const& nullSymbol, JSONCPP_STRING const& endingLineFeedSymbol, bool useSpecialFloats, - unsigned int precision) + unsigned int precision, + PrecisionType precisionType) : rightMargin_(74) , indentation_(indentation) , cs_(cs) @@ -904,6 +917,7 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter( , indented_(false) , useSpecialFloats_(useSpecialFloats) , precision_(precision) + , precisionType_(precisionType) { } int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) @@ -933,7 +947,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { pushValue(valueToString(value.asLargestUInt())); break; case realValue: - pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_)); + pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, precisionType_)); break; case stringValue: { @@ -1145,6 +1159,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { JSONCPP_STRING indentation = settings_["indentation"].asString(); JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); + JSONCPP_STRING pt_str = settings_["precisionType"].asString(); bool eyc = settings_["enableYAMLCompatibility"].asBool(); bool dnp = settings_["dropNullPlaceholders"].asBool(); bool usf = settings_["useSpecialFloats"].asBool(); @@ -1157,6 +1172,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const } else { throwRuntimeError("commentStyle must be 'All' or 'None'"); } + PrecisionType precisionType(significantDigits); + if (pt_str == "significant") { + precisionType = PrecisionType::significantDigits; + } else if (pt_str == "decimal") { + precisionType = PrecisionType::decimalPlaces; + } else { + throwRuntimeError("precisionType must be 'significant' or 'decimal'"); + } JSONCPP_STRING colonSymbol = " : "; if (eyc) { colonSymbol = ": "; @@ -1171,7 +1194,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const JSONCPP_STRING endingLineFeedSymbol; return new BuiltStyledStreamWriter( indentation, cs, - colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre); + colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType); } static void getValidWriterKeys(std::set* valid_keys) { @@ -1182,6 +1205,7 @@ static void getValidWriterKeys(std::set* valid_keys) valid_keys->insert("dropNullPlaceholders"); valid_keys->insert("useSpecialFloats"); valid_keys->insert("precision"); + valid_keys->insert("precisionType"); } bool StreamWriterBuilder::validate(Json::Value* invalid) const { @@ -1214,6 +1238,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) (*settings)["dropNullPlaceholders"] = false; (*settings)["useSpecialFloats"] = false; (*settings)["precision"] = 17; + (*settings)["precisionType"] = "significant"; //! [StreamWriterBuilderDefaults] } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index ee8179067..cbf482326 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1757,6 +1757,27 @@ JSONTEST_FIXTURE(ValueTest, precision) { expected = "0.25634569487374054"; result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 5; + b.settings_["precisionType"] = "decimal"; + v = 0.256345694873740545068; + expected = "0.25635"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 1; + b.settings_["precisionType"] = "decimal"; + v = 0.256345694873740545068; + expected = "0.3"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 10; + b.settings_["precisionType"] = "decimal"; + v = 0.23300000; + expected = "0.233"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); } struct WriterTest : JsonTest::TestCase {}; From ffc62d26f3aab06970800f07c8e271d4ee93cb05 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Thu, 5 Apr 2018 16:37:58 -0700 Subject: [PATCH 029/410] [CMake] Generate CMake config files by default --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ddcc16564..33abe8542 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post OPTION(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) OPTION(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON) OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) -OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" OFF) +OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) OPTION(BUILD_STATIC_LIBS "Build jsoncpp_lib static library." ON) From 323450eafca74ea53e457ba4d903a7553744b669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mal=C3=BD?= Date: Tue, 17 Apr 2018 16:16:54 +0200 Subject: [PATCH 030/410] allow out-of-source build --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 33abe8542..e18c89b74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,10 +70,10 @@ SET( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping al MESSAGE(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") # File version.h is only regenerated on CMake configure step CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" - "${PROJECT_SOURCE_DIR}/include/json/version.h" + "${PROJECT_BINARY_DIR}/include/json/version.h" NEWLINE_STYLE UNIX ) CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/version.in" - "${PROJECT_SOURCE_DIR}/version" + "${PROJECT_BINARY_DIR}/version" NEWLINE_STYLE UNIX ) MACRO(UseCompilationWarningAsError) From 3f0d91f08a048a799e3eead16c10bd21977da53a Mon Sep 17 00:00:00 2001 From: fo40225 Date: Sat, 5 May 2018 14:38:53 +0800 Subject: [PATCH 031/410] fix ValueTest/specialFloats test failure when fp:fast on msvc --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index be03a66e3..3b22ee880 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -149,7 +149,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p } else { // IEEE standard states that NaN values will not compare to themselves - if (value != value) { + if (isnan(value)) { len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); } else if (value < 0) { len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999"); From 4050143288562d0775e0f028910ce5451c326846 Mon Sep 17 00:00:00 2001 From: fo40225 Date: Sat, 5 May 2018 15:05:22 +0800 Subject: [PATCH 032/410] fix ValueTest/integers, CharReaderAllowSpecialFloatsTest/issue209 test failure when fp:fast on msvc --- src/test_lib_json/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index cbf482326..9cddf4112 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -972,8 +972,8 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(Json::UInt64(1) << 63, val.asUInt64()); JSONTEST_ASSERT_EQUAL(Json::UInt64(1) << 63, val.asLargestUInt()); JSONTEST_ASSERT_EQUAL(uint64ToDouble(Json::UInt64(1) << 63), val.asDouble()); - JSONTEST_ASSERT_EQUAL(float(uint64ToDouble(Json::UInt64(1) << 63)), - val.asFloat()); + JSONTEST_ASSERT_EQUAL(float(Json::UInt64(1) << 63), val.asFloat()); + JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18", normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); @@ -2405,7 +2405,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); double n = root["a"].asDouble(); - JSONTEST_ASSERT(n != n); + JSONTEST_ASSERT(isnan(n)); JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), root.get("b", 0.0)); JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root.get("c", 0.0)); } From 6e5e9be7368e5da375dab5cd0b200fd22ab4795c Mon Sep 17 00:00:00 2001 From: fo40225 Date: Tue, 8 May 2018 12:35:08 +0800 Subject: [PATCH 033/410] corss compiler isnan --- src/lib_json/json_writer.cpp | 21 ++++++++++++++++++++- src/test_lib_json/main.cpp | 3 ++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 3b22ee880..b8c7223bf 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -68,6 +68,25 @@ #define snprintf _snprintf #endif +#if defined(_MSC_VER) && !defined(__clang__) +#if _MSC_VER >= 1900 && defined(_WIN64) +#include +#define isnan _isnanf +#else +#include +#define isnan _isnan +#endif +#elif __cplusplus >= 201103L +#include +#define isnan std::isnan +#else +#include +#if !define(isnan) +// IEEE standard states that NaN values will not compare to themselves +#define isnan(x) (x!=x) +#endif +#endif + #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. #pragma warning(disable : 4996) @@ -148,7 +167,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p } } else { - // IEEE standard states that NaN values will not compare to themselves + if (isnan(value)) { len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); } else if (value < 0) { diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 9cddf4112..a0c26ebef 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -18,6 +18,7 @@ #include #include #include +#include // Make numeric limits more convenient to talk about. // Assumes int type in 32 bits. @@ -2405,7 +2406,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); double n = root["a"].asDouble(); - JSONTEST_ASSERT(isnan(n)); + JSONTEST_ASSERT(std::isnan(n)); JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), root.get("b", 0.0)); JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root.get("c", 0.0)); } From 0a62267fe42b87e9000acf7012d24bad80962742 Mon Sep 17 00:00:00 2001 From: binyangl Date: Tue, 8 May 2018 20:55:30 +0800 Subject: [PATCH 034/410] Disable warning "C4702" when compiling json cpp using vs2013 and above --- src/lib_json/json_value.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index ed49df2ca..c7eac08ab 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -19,6 +19,11 @@ #include // size_t #include // min() +// Disable warning C4702 : unreachable code +#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above +#pragma warning(disable:4702) +#endif + #define JSON_ASSERT_UNREACHABLE assert(false) namespace Json { From cf73619e280339b069a79cba0bfa334f79e16811 Mon Sep 17 00:00:00 2001 From: fo40225 Date: Tue, 8 May 2018 16:28:14 +0800 Subject: [PATCH 035/410] refactoring cross compiler macro --- src/lib_json/json_reader.cpp | 36 +++++----- src/lib_json/json_writer.cpp | 123 ++++++++++++++++------------------- 2 files changed, 74 insertions(+), 85 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index eb3084372..afdb595ae 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -11,7 +11,6 @@ #include "json_tool.h" #endif // if !defined(JSON_IS_AMALGAMATION) #include -#include #include #include #include @@ -20,24 +19,25 @@ #include #include -#if defined(_MSC_VER) -#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above -#define snprintf sprintf_s -#elif _MSC_VER >= 1900 // VC++ 14.0 and above -#define snprintf std::snprintf -#else -#define snprintf _snprintf -#endif -#elif defined(__ANDROID__) || defined(__QNXNTO__) -#define snprintf snprintf -#elif __cplusplus >= 201103L -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -#define snprintf std::snprintf -#endif -#endif +#if __cplusplus >= 201103L + #include + + #if !defined(snprintf) + #define snprintf std::snprintf + #endif -#if defined(__QNXNTO__) -#define sscanf std::sscanf + #if !defined(sscanf) + #define sscanf std::sscanf + #endif +#else + #include + + #if defined(_MSC_VER) + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 + #if !defined(snprintf) + #define snprintf _snprintf + #endif + #endif #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index b8c7223bf..823e96d76 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -14,77 +14,66 @@ #include #include #include -#include - -#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 -#include -#define isfinite _finite -#elif defined(__sun) && defined(__SVR4) //Solaris -#if !defined(isfinite) -#include -#define isfinite finite -#endif -#elif defined(_AIX) -#if !defined(isfinite) -#include -#define isfinite finite -#endif -#elif defined(__hpux) -#if !defined(isfinite) -#if defined(__ia64) && !defined(finite) -#define isfinite(x) ((sizeof(x) == sizeof(float) ? \ - _Isfinitef(x) : _IsFinite(x))) -#else -#include -#define isfinite finite -#endif -#endif -#else -#include -#if !(defined(__QNXNTO__)) // QNX already defines isfinite -#define isfinite std::isfinite -#endif -#endif -#if defined(_MSC_VER) -#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above -#define snprintf sprintf_s -#elif _MSC_VER >= 1900 // VC++ 14.0 and above -#define snprintf std::snprintf -#else -#define snprintf _snprintf -#endif -#elif defined(__ANDROID__) || defined(__QNXNTO__) -#define snprintf snprintf -#elif __cplusplus >= 201103L -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -#define snprintf std::snprintf -#endif -#endif +#if __cplusplus >= 201103L + #include + #include -#if defined(__BORLANDC__) -#include -#define isfinite _finite -#define snprintf _snprintf -#endif + #if !defined(isnan) + #define isnan std::isnan + #endif -#if defined(_MSC_VER) && !defined(__clang__) -#if _MSC_VER >= 1900 && defined(_WIN64) -#include -#define isnan _isnanf -#else -#include -#define isnan _isnan -#endif -#elif __cplusplus >= 201103L -#include -#define isnan std::isnan + #if !defined(isfinite) + #define isfinite std::isfinite + #endif + + #if !defined(snprintf) + #define snprintf std::snprintf + #endif #else -#include -#if !define(isnan) -// IEEE standard states that NaN values will not compare to themselves -#define isnan(x) (x!=x) -#endif + #include + #include + + #if defined(_MSC_VER) + #if !defined(isnan) + #include + #define isnan _isnan + #endif + + #if !defined(isfinite) + #include + #define isfinite _finite + #endif + + #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 + #if !defined(snprintf) + #define snprintf _snprintf + #endif + #endif + + #if defined(__sun) && defined(__SVR4) //Solaris + #if !defined(isfinite) + #include + #define isfinite finite + #endif + #endif + + #if defined(__hpux) + #if !defined(isfinite) + #if defined(__ia64) && !defined(finite) + #define isfinite(x) ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) + #endif + #endif + #endif + + #if !defined(isnan) + // IEEE standard states that NaN values will not compare to themselves + #define isnan(x) (x!=x) + #endif + + #if !defined(isfinite) + #define isfinite finite + #endif #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 From 4cec95a2e7cd64a9f45eabc132a883671ec699fd Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 11 May 2018 10:20:04 -0400 Subject: [PATCH 036/410] formatting refactor --- src/lib_json/json_tool.h | 46 +++++++++++++++----------- src/lib_json/json_writer.cpp | 63 +++++++++++++++++------------------- 2 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 86f1f2c6b..bb59e862c 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -88,41 +88,49 @@ static inline void uintToString(LargestUInt value, char*& current) { * We had a sophisticated way, but it did not work in WinCE. * @see https://github.com/open-source-parsers/jsoncpp/pull/9 */ -static inline void fixNumericLocale(char* begin, char* end) { - while (begin < end) { +template +Iter fixNumericLocale(Iter begin, Iter end) { + for (; begin != end; ++begin) { if (*begin == ',') { *begin = '.'; } - ++begin; } + return begin; } -static inline void fixNumericLocaleInput(char* begin, char* end) { +template +void fixNumericLocaleInput(Iter begin, Iter end) { char decimalPoint = getDecimalPoint(); - if (decimalPoint != '\0' && decimalPoint != '.') { - while (begin < end) { - if (*begin == '.') { - *begin = decimalPoint; - } - ++begin; + if (decimalPoint == '\0' || decimalPoint == '.') { + return; + } + for (; begin != end; ++begin) { + if (*begin == '.') { + *begin = decimalPoint; } } } /** - * Delete zeros in the end of string, if it isn't last zero before '.' character. + * Return iterator that would be the new end of the range [begin,end), if we + * were to delete zeros in the end of string, but not the last zero before '.'. */ -static inline void fixZerosInTheEnd(char* begin, char* end) { - end--; - while ((begin < end) && (*end == '0')) { - // don't delete last zero before point. - if (*(end - 1) != '.') { - *end = '\0'; +template +Iter fixZerosInTheEnd(Iter begin, Iter end) { + + for (; begin != end; --end) { + if (*(end-1) != '0') { + return end; + } + // Don't delete the last zero before the decimal point. + if (begin != (end-1) && *(end-2) == '.') { + return end; } - end--; } + return end; + } -} // namespace Json { +} // namespace Json #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 823e96d76..bc0966f32 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -127,48 +127,45 @@ JSONCPP_STRING valueToString(UInt value) { namespace { JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) { - // Allocate a buffer that is more than large enough to store the 16 digits of - // precision requested below. - char buffer[36]; - int len = -1; - - char formatString[15]; - if (precisionType == PrecisionType::significantDigits) { - snprintf(formatString, sizeof(formatString), "%%.%ug", precision); - } else { - snprintf(formatString, sizeof(formatString), "%%.%uf", precision); - } - // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. - if (isfinite(value)) { - len = snprintf(buffer, sizeof(buffer), formatString, value); - fixNumericLocale(buffer, buffer + len); - // to delete use-less too much zeros in the end of string - if (precisionType == PrecisionType::decimalPlaces) { - fixZerosInTheEnd(buffer, buffer + len); - } + if (!isfinite(value)) { + static const char* const reps[2][3] = { + {"NaN", "-Infinity", "Infinity"}, + {"null", "-1e+9999", "1e+9999"}}; + return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; + } - // try to ensure we preserve the fact that this was given to us as a double on input - if (!strchr(buffer, '.') && !strchr(buffer, 'e')) { - strcat(buffer, ".0"); - } + JSONCPP_STRING buffer(36, '\0'); + while (true) { + int len = snprintf(&*buffer.begin(), buffer.size(), + (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", + precision, value); + assert(len >= 0); + size_t wouldPrint = static_cast(len); + if (wouldPrint >= buffer.size()) { + buffer.resize(wouldPrint + 1); + continue; + } + buffer.resize(wouldPrint); + break; + } - } else { + buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); - if (isnan(value)) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); - } else if (value < 0) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999"); - } else { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999"); - } + // strip the zero padding from the right + if (precisionType == PrecisionType::decimalPlaces) { + buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); + } + + // try to ensure we preserve the fact that this was given to us as a double on input + if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { + buffer += ".0"; } - assert(len >= 0); return buffer; } -} +} // namespace JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) { return valueToString(value, false, precision, precisionType); From 9ebfc8d37b1d8fab5980baafbcc051c7cbdc43fc Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 11 May 2018 14:20:51 -0400 Subject: [PATCH 037/410] whitespace cleanup --- src/lib_json/json_tool.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index bb59e862c..f02537b28 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -117,7 +117,6 @@ void fixNumericLocaleInput(Iter begin, Iter end) { */ template Iter fixZerosInTheEnd(Iter begin, Iter end) { - for (; begin != end; --end) { if (*(end-1) != '0') { return end; @@ -128,7 +127,6 @@ Iter fixZerosInTheEnd(Iter begin, Iter end) { } } return end; - } } // namespace Json From fdcc2e4428bdee765021ac88eb11e1b258c14909 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 11 May 2018 14:26:09 -0400 Subject: [PATCH 038/410] single-arg string ctor --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index bc0966f32..2cddbdbf5 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -137,7 +137,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; } - JSONCPP_STRING buffer(36, '\0'); + JSONCPP_STRING buffer(36); while (true) { int len = snprintf(&*buffer.begin(), buffer.size(), (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", From 0ba5c435f4ff98eef979d67dabd08ed2bddbf50b Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 11 May 2018 10:20:04 -0400 Subject: [PATCH 039/410] Improvements in writing precision and json_tool.h helpers --- src/lib_json/json_tool.h | 44 ++++++++++++++----------- src/lib_json/json_writer.cpp | 63 +++++++++++++++++------------------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 86f1f2c6b..f02537b28 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -88,41 +88,47 @@ static inline void uintToString(LargestUInt value, char*& current) { * We had a sophisticated way, but it did not work in WinCE. * @see https://github.com/open-source-parsers/jsoncpp/pull/9 */ -static inline void fixNumericLocale(char* begin, char* end) { - while (begin < end) { +template +Iter fixNumericLocale(Iter begin, Iter end) { + for (; begin != end; ++begin) { if (*begin == ',') { *begin = '.'; } - ++begin; } + return begin; } -static inline void fixNumericLocaleInput(char* begin, char* end) { +template +void fixNumericLocaleInput(Iter begin, Iter end) { char decimalPoint = getDecimalPoint(); - if (decimalPoint != '\0' && decimalPoint != '.') { - while (begin < end) { - if (*begin == '.') { - *begin = decimalPoint; - } - ++begin; + if (decimalPoint == '\0' || decimalPoint == '.') { + return; + } + for (; begin != end; ++begin) { + if (*begin == '.') { + *begin = decimalPoint; } } } /** - * Delete zeros in the end of string, if it isn't last zero before '.' character. + * Return iterator that would be the new end of the range [begin,end), if we + * were to delete zeros in the end of string, but not the last zero before '.'. */ -static inline void fixZerosInTheEnd(char* begin, char* end) { - end--; - while ((begin < end) && (*end == '0')) { - // don't delete last zero before point. - if (*(end - 1) != '.') { - *end = '\0'; +template +Iter fixZerosInTheEnd(Iter begin, Iter end) { + for (; begin != end; --end) { + if (*(end-1) != '0') { + return end; + } + // Don't delete the last zero before the decimal point. + if (begin != (end-1) && *(end-2) == '.') { + return end; } - end--; } + return end; } -} // namespace Json { +} // namespace Json #endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 823e96d76..2cddbdbf5 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -127,48 +127,45 @@ JSONCPP_STRING valueToString(UInt value) { namespace { JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) { - // Allocate a buffer that is more than large enough to store the 16 digits of - // precision requested below. - char buffer[36]; - int len = -1; - - char formatString[15]; - if (precisionType == PrecisionType::significantDigits) { - snprintf(formatString, sizeof(formatString), "%%.%ug", precision); - } else { - snprintf(formatString, sizeof(formatString), "%%.%uf", precision); - } - // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. - if (isfinite(value)) { - len = snprintf(buffer, sizeof(buffer), formatString, value); - fixNumericLocale(buffer, buffer + len); - // to delete use-less too much zeros in the end of string - if (precisionType == PrecisionType::decimalPlaces) { - fixZerosInTheEnd(buffer, buffer + len); - } + if (!isfinite(value)) { + static const char* const reps[2][3] = { + {"NaN", "-Infinity", "Infinity"}, + {"null", "-1e+9999", "1e+9999"}}; + return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; + } - // try to ensure we preserve the fact that this was given to us as a double on input - if (!strchr(buffer, '.') && !strchr(buffer, 'e')) { - strcat(buffer, ".0"); - } + JSONCPP_STRING buffer(36); + while (true) { + int len = snprintf(&*buffer.begin(), buffer.size(), + (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", + precision, value); + assert(len >= 0); + size_t wouldPrint = static_cast(len); + if (wouldPrint >= buffer.size()) { + buffer.resize(wouldPrint + 1); + continue; + } + buffer.resize(wouldPrint); + break; + } - } else { + buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); - if (isnan(value)) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); - } else if (value < 0) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999"); - } else { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999"); - } + // strip the zero padding from the right + if (precisionType == PrecisionType::decimalPlaces) { + buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); + } + + // try to ensure we preserve the fact that this was given to us as a double on input + if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { + buffer += ".0"; } - assert(len >= 0); return buffer; } -} +} // namespace JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) { return valueToString(value, false, precision, precisionType); From aa1b3836667d3af20ef3f66a3cb5e1e321f41854 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 13 May 2018 18:28:05 -0400 Subject: [PATCH 040/410] fix string construction --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 2cddbdbf5..30c6833b1 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -137,7 +137,7 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; } - JSONCPP_STRING buffer(36); + JSONCPP_STRING buffer(size_t(36), '\0'); while (true) { int len = snprintf(&*buffer.begin(), buffer.size(), (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", From abd39e791b08d0e2f46ff7986f3559bffa0b5fc4 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 20 May 2018 16:32:06 -0400 Subject: [PATCH 041/410] json_tool missing include --- src/lib_json/json_tool.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index f02537b28..d5f6d2f17 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -6,6 +6,7 @@ #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED +#include // Also support old flag NO_LOCALE_SUPPORT #ifdef NO_LOCALE_SUPPORT @@ -23,7 +24,7 @@ */ namespace Json { -static char getDecimalPoint() { +static inline char getDecimalPoint() { #ifdef JSONCPP_NO_LOCALE_SUPPORT return '\0'; #else From b5e1fe89aa3429dd7946209f0cb541882b81e466 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 20 May 2018 16:55:27 -0400 Subject: [PATCH 042/410] Apply the formatting specified in .clang-format file. $ clang-format --version clang-format version 7.0.0 (tags/google/stable/2018-01-11) $ clang-format -i --style=file $(find . -name '*.cpp' -o -name '*.h') --- include/json/allocator.h | 135 ++++---- include/json/assertions.h | 23 +- include/json/config.h | 117 +++---- include/json/json.h | 4 +- include/json/reader.h | 51 +-- include/json/value.h | 92 +++--- include/json/version.h | 16 +- include/json/writer.h | 49 +-- src/jsontestrunner/main.cpp | 94 ++---- src/lib_json/json_reader.cpp | 388 ++++++++++------------ src/lib_json/json_tool.h | 13 +- src/lib_json/json_value.cpp | 384 ++++++++++----------- src/lib_json/json_writer.cpp | 473 +++++++++++++------------- src/test_lib_json/jsontest.cpp | 21 +- src/test_lib_json/jsontest.h | 38 +-- src/test_lib_json/main.cpp | 587 ++++++++++++++------------------- 16 files changed, 1188 insertions(+), 1297 deletions(-) diff --git a/include/json/allocator.h b/include/json/allocator.h index 9c7e573ae..d5f987e97 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -12,86 +12,77 @@ #pragma pack(push, 8) namespace Json { -template -class SecureAllocator { - public: - // Type definitions - using value_type = T; - using pointer = T*; - using const_pointer = const T*; - using reference = T&; - using const_reference = const T&; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - - /** - * Allocate memory for N items using the standard allocator. - */ - pointer allocate(size_type n) { - // allocate using "global operator new" - return static_cast(::operator new(n * sizeof(T))); - } - - /** - * Release memory which was allocated for N items at pointer P. - * - * The memory block is filled with zeroes before being released. - * The pointer argument is tagged as "volatile" to prevent the - * compiler optimizing out this critical step. - */ - void deallocate(volatile pointer p, size_type n) { - std::memset(p, 0, n * sizeof(T)); - // free using "global operator delete" - ::operator delete(p); - } - - /** - * Construct an item in-place at pointer P. - */ - template - void construct(pointer p, Args&&... args) { - // construct using "placement new" and "perfect forwarding" - ::new (static_cast(p)) T(std::forward(args)...); - } - - size_type max_size() const { - return size_t(-1) / sizeof(T); - } - - pointer address( reference x ) const { - return std::addressof(x); - } - - const_pointer address( const_reference x ) const { - return std::addressof(x); - } - - /** - * Destroy an item in-place at pointer P. - */ - void destroy(pointer p) { - // destroy using "explicit destructor" - p->~T(); - } - - // Boilerplate - SecureAllocator() {} - template SecureAllocator(const SecureAllocator&) {} - template struct rebind { using other = SecureAllocator; }; +template class SecureAllocator { +public: + // Type definitions + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + /** + * Allocate memory for N items using the standard allocator. + */ + pointer allocate(size_type n) { + // allocate using "global operator new" + return static_cast(::operator new(n * sizeof(T))); + } + + /** + * Release memory which was allocated for N items at pointer P. + * + * The memory block is filled with zeroes before being released. + * The pointer argument is tagged as "volatile" to prevent the + * compiler optimizing out this critical step. + */ + void deallocate(volatile pointer p, size_type n) { + std::memset(p, 0, n * sizeof(T)); + // free using "global operator delete" + ::operator delete(p); + } + + /** + * Construct an item in-place at pointer P. + */ + template void construct(pointer p, Args&&... args) { + // construct using "placement new" and "perfect forwarding" + ::new (static_cast(p)) T(std::forward(args)...); + } + + size_type max_size() const { return size_t(-1) / sizeof(T); } + + pointer address(reference x) const { return std::addressof(x); } + + const_pointer address(const_reference x) const { return std::addressof(x); } + + /** + * Destroy an item in-place at pointer P. + */ + void destroy(pointer p) { + // destroy using "explicit destructor" + p->~T(); + } + + // Boilerplate + SecureAllocator() {} + template SecureAllocator(const SecureAllocator&) {} + template struct rebind { using other = SecureAllocator; }; }; - -template +template bool operator==(const SecureAllocator&, const SecureAllocator&) { - return true; + return true; } -template +template bool operator!=(const SecureAllocator&, const SecureAllocator&) { - return false; + return false; } -} //namespace Json +} // namespace Json #pragma pack(pop) diff --git a/include/json/assertions.h b/include/json/assertions.h index 1cca28d95..482c4ca48 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -6,8 +6,8 @@ #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED #define CPPTL_JSON_ASSERTIONS_H_INCLUDED -#include #include +#include #if !defined(JSON_IS_AMALGAMATION) #include "config.h" @@ -20,30 +20,35 @@ #if JSON_USE_EXCEPTION // @todo <= add detail about condition in exception -# define JSON_ASSERT(condition) \ - {if (!(condition)) {Json::throwLogicError( "assert json failed" );}} +#define JSON_ASSERT(condition) \ + { \ + if (!(condition)) { \ + Json::throwLogicError("assert json failed"); \ + } \ + } -# define JSON_FAIL_MESSAGE(message) \ +#define JSON_FAIL_MESSAGE(message) \ { \ - JSONCPP_OSTRINGSTREAM oss; oss << message; \ + JSONCPP_OSTRINGSTREAM oss; \ + oss << message; \ Json::throwLogicError(oss.str()); \ abort(); \ } #else // JSON_USE_EXCEPTION -# define JSON_ASSERT(condition) assert(condition) +#define JSON_ASSERT(condition) assert(condition) // The call to assert() will show the failure message in debug builds. In // release builds we abort, for a core-dump or debugger. -# define JSON_FAIL_MESSAGE(message) \ +#define JSON_FAIL_MESSAGE(message) \ { \ - JSONCPP_OSTRINGSTREAM oss; oss << message; \ + JSONCPP_OSTRINGSTREAM oss; \ + oss << message; \ assert(false && oss.str().c_str()); \ abort(); \ } - #endif #define JSON_ASSERT_MESSAGE(condition, message) \ diff --git a/include/json/config.h b/include/json/config.h index 7d3469228..33a84f5af 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -6,8 +6,8 @@ #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED #include -#include //typedef String #include //typedef int64_t, uint64_t +#include //typedef String /// If defined, indicates that json library is embedded in CppTL library. //# define JSON_IN_CPPTL 1 @@ -60,21 +60,21 @@ // #define JSON_NO_INT64 1 #if defined(_MSC_VER) // MSVC -# if _MSC_VER <= 1200 // MSVC 6 - // Microsoft Visual Studio 6 only support conversion from __int64 to double - // (no conversion from unsigned __int64). -# define JSON_USE_INT64_DOUBLE_CONVERSION 1 - // Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' - // characters in the debug information) - // All projects I've ever seen with VS6 were using this globally (not bothering - // with pragma push/pop). -# pragma warning(disable : 4786) -# endif // MSVC 6 - -# if _MSC_VER >= 1500 // MSVC 2008 - /// Indicates that the following function is deprecated. -# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) -# endif +#if _MSC_VER <= 1200 // MSVC 6 +// Microsoft Visual Studio 6 only support conversion from __int64 to double +// (no conversion from unsigned __int64). +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' +// characters in the debug information) +// All projects I've ever seen with VS6 were using this globally (not bothering +// with pragma push/pop). +#pragma warning(disable : 4786) +#endif // MSVC 6 + +#if _MSC_VER >= 1500 // MSVC 2008 + /// Indicates that the following function is deprecated. +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif #endif // defined(_MSC_VER) @@ -82,25 +82,25 @@ // is intended to override the base-class version. This makes the code more // manageable and fixes a set of common hard-to-find bugs. #if __cplusplus >= 201103L -# define JSONCPP_OVERRIDE override -# define JSONCPP_NOEXCEPT noexcept -# define JSONCPP_OP_EXPLICIT explicit +#define JSONCPP_OVERRIDE override +#define JSONCPP_NOEXCEPT noexcept +#define JSONCPP_OP_EXPLICIT explicit #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 -# define JSONCPP_OVERRIDE override -# define JSONCPP_NOEXCEPT throw() -# if _MSC_VER >= 1800 // MSVC 2013 -# define JSONCPP_OP_EXPLICIT explicit -# else -# define JSONCPP_OP_EXPLICIT -# endif +#define JSONCPP_OVERRIDE override +#define JSONCPP_NOEXCEPT throw() +#if _MSC_VER >= 1800 // MSVC 2013 +#define JSONCPP_OP_EXPLICIT explicit +#else +#define JSONCPP_OP_EXPLICIT +#endif #elif defined(_MSC_VER) && _MSC_VER >= 1900 -# define JSONCPP_OVERRIDE override -# define JSONCPP_NOEXCEPT noexcept -# define JSONCPP_OP_EXPLICIT explicit +#define JSONCPP_OVERRIDE override +#define JSONCPP_NOEXCEPT noexcept +#define JSONCPP_OP_EXPLICIT explicit #else -# define JSONCPP_OVERRIDE -# define JSONCPP_NOEXCEPT throw() -# define JSONCPP_OP_EXPLICIT +#define JSONCPP_OVERRIDE +#define JSONCPP_NOEXCEPT throw() +#define JSONCPP_OP_EXPLICIT #endif #ifndef JSON_HAS_RVALUE_REFERENCES @@ -112,12 +112,12 @@ #ifdef __clang__ #if __has_feature(cxx_rvalue_references) #define JSON_HAS_RVALUE_REFERENCES 1 -#endif // has_feature +#endif // has_feature #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) #if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) #define JSON_HAS_RVALUE_REFERENCES 1 -#endif // GXX_EXPERIMENTAL +#endif // GXX_EXPERIMENTAL #endif // __clang__ || __GNUC__ @@ -128,15 +128,15 @@ #endif #ifdef __clang__ -# if __has_extension(attribute_deprecated_with_message) -# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) -# endif +#if __has_extension(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#endif #elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) -# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message))) -# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) -# endif // GNUC version +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif // GNUC version #endif // __clang__ || __GNUC__ #if !defined(JSONCPP_DEPRECATED) @@ -144,16 +144,16 @@ #endif // if !defined(JSONCPP_DEPRECATED) #if __GNUC__ >= 6 -# define JSON_USE_INT64_DOUBLE_CONVERSION 1 +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif #if !defined(JSON_IS_AMALGAMATION) -# include "version.h" +#include "version.h" -# if JSONCPP_USING_SECURE_MEMORY -# include "allocator.h" //typedef Allocator -# endif +#if JSONCPP_USING_SECURE_MEMORY +#include "allocator.h" //typedef Allocator +#endif #endif // if !defined(JSON_IS_AMALGAMATION) @@ -172,23 +172,28 @@ typedef unsigned __int64 UInt64; #else // if defined(_MSC_VER) // Other platforms, use long long typedef int64_t Int64; typedef uint64_t UInt64; -#endif // if defined(_MSC_VER) +#endif // if defined(_MSC_VER) typedef Int64 LargestInt; typedef UInt64 LargestUInt; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) #if JSONCPP_USING_SECURE_MEMORY -#define JSONCPP_STRING std::basic_string, Json::SecureAllocator > -#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream, Json::SecureAllocator > -#define JSONCPP_OSTREAM std::basic_ostream> -#define JSONCPP_ISTRINGSTREAM std::basic_istringstream, Json::SecureAllocator > -#define JSONCPP_ISTREAM std::istream +#define JSONCPP_STRING \ + std::basic_string, Json::SecureAllocator > +#define JSONCPP_OSTRINGSTREAM \ + std::basic_ostringstream, \ + Json::SecureAllocator > +#define JSONCPP_OSTREAM std::basic_ostream > +#define JSONCPP_ISTRINGSTREAM \ + std::basic_istringstream, \ + Json::SecureAllocator > +#define JSONCPP_ISTREAM std::istream #else -#define JSONCPP_STRING std::string +#define JSONCPP_STRING std::string #define JSONCPP_OSTRINGSTREAM std::ostringstream -#define JSONCPP_OSTREAM std::ostream +#define JSONCPP_OSTREAM std::ostream #define JSONCPP_ISTRINGSTREAM std::istringstream -#define JSONCPP_ISTREAM std::istream +#define JSONCPP_ISTREAM std::istream #endif // if JSONCPP_USING_SECURE_MEMORY } // end namespace Json diff --git a/include/json/json.h b/include/json/json.h index 3d2798a6c..19f14c266 100644 --- a/include/json/json.h +++ b/include/json/json.h @@ -7,9 +7,9 @@ #define JSON_JSON_H_INCLUDED #include "autolink.h" -#include "value.h" +#include "features.h" #include "reader.h" +#include "value.h" #include "writer.h" -#include "features.h" #endif // JSON_JSON_H_INCLUDED diff --git a/include/json/reader.h b/include/json/reader.h index dc1da1f3e..d8f1be108 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -12,9 +12,9 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include #include +#include #include #include -#include // Disable warning C4251: : needs to have dll-interface to // be used by... @@ -52,13 +52,13 @@ class JSON_API Reader { /** \brief Constructs a Reader allowing all features * for parsing. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set * for parsing. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON @@ -151,7 +151,9 @@ class JSON_API Reader { * \return \c true if the error was successfully added, \c false if either * Value offset exceeds the document size. */ - bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); + bool pushError(const Value& value, + const JSONCPP_STRING& message, + const Value& extra); /** \brief Return whether there are any errors. * \return \c true if there are no errors to report \c false if @@ -218,7 +220,8 @@ class JSON_API Reader { Location& current, Location end, unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + bool + addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, @@ -247,7 +250,7 @@ class JSON_API Reader { JSONCPP_STRING commentsBefore_; Features features_; bool collectComments_; -}; // Reader +}; // Reader /** Interface for reading JSON from a char array. */ @@ -256,7 +259,8 @@ class JSON_API CharReader { virtual ~CharReader() {} /** \brief Read a Value from a JSON document. - * The document must be a UTF-8 encoded string containing the document to read. + * The document must be a UTF-8 encoded string containing the document to + read. * * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the document to read. @@ -271,9 +275,10 @@ class JSON_API CharReader { * \return \c true if the document was successfully parsed, \c false if an error occurred. */ - virtual bool parse( - char const* beginDoc, char const* endDoc, - Value* root, JSONCPP_STRING* errs) = 0; + virtual bool parse(char const* beginDoc, + char const* endDoc, + Value* root, + JSONCPP_STRING* errs) = 0; class JSON_API Factory { public: @@ -282,8 +287,8 @@ class JSON_API CharReader { * \throw std::exception if something goes wrong (e.g. invalid settings) */ virtual CharReader* newCharReader() const = 0; - }; // Factory -}; // CharReader + }; // Factory +}; // CharReader /** \brief Build a CharReader implementation. @@ -313,7 +318,8 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { - `"strictRoot": false or true` - true if root must be either an array or an object value - `"allowDroppedNullPlaceholders": false or true` - - true if dropped null placeholders are allowed. (See StreamWriterBuilder.) + - true if dropped null placeholders are allowed. (See + StreamWriterBuilder.) - `"allowNumericKeys": false or true` - true if numeric object keys are allowed. - `"allowSingleQuotes": false or true` @@ -327,9 +333,10 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { - If true, `parse()` returns false when extra non-whitespace trails the JSON value in the input string. - `"rejectDupKeys": false or true` - - If true, `parse()` returns false when a key is duplicated within an object. + - If true, `parse()` returns false when a key is duplicated within an + object. - `"allowSpecialFloats": false or true` - - If true, special float values (NaNs and infinities) are allowed + - If true, special float values (NaNs and infinities) are allowed and their values are lossfree restorable. You can examine 'settings_` yourself @@ -368,13 +375,13 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { }; /** Consume entire stream and use its begin/end. - * Someday we might have a real StreamReader, but for now this - * is convenient. - */ -bool JSON_API parseFromStream( - CharReader::Factory const&, - JSONCPP_ISTREAM&, - Value* root, std::string* errs); + * Someday we might have a real StreamReader, but for now this + * is convenient. + */ +bool JSON_API parseFromStream(CharReader::Factory const&, + JSONCPP_ISTREAM&, + Value* root, + std::string* errs); /** \brief Read from 'sin' into 'root'. diff --git a/include/json/value.h b/include/json/value.h index 3474cd840..06a6c0c01 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -9,9 +9,9 @@ #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" #endif // if !defined(JSON_IS_AMALGAMATION) +#include #include #include -#include #ifndef JSON_USE_CPPTL_SMALLMAP #include @@ -22,17 +22,17 @@ #include #endif -//Conditional NORETURN attribute on the throw functions would: +// Conditional NORETURN attribute on the throw functions would: // a) suppress false positives from static code analysis // b) possibly improve optimization opportunities. #if !defined(JSONCPP_NORETURN) -# if defined(_MSC_VER) -# define JSONCPP_NORETURN __declspec(noreturn) -# elif defined(__GNUC__) -# define JSONCPP_NORETURN __attribute__ ((__noreturn__)) -# else -# define JSONCPP_NORETURN -# endif +#if defined(_MSC_VER) +#define JSONCPP_NORETURN __declspec(noreturn) +#elif defined(__GNUC__) +#define JSONCPP_NORETURN __attribute__((__noreturn__)) +#else +#define JSONCPP_NORETURN +#endif #endif // Disable warning C4251: : needs to have dll-interface to @@ -57,6 +57,7 @@ class JSON_API Exception : public std::exception { Exception(JSONCPP_STRING const& msg); ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; + protected: JSONCPP_STRING msg_; }; @@ -183,6 +184,7 @@ class JSON_API StaticString { */ class JSON_API Value { friend class ValueIteratorBase; + public: typedef std::vector Members; typedef ValueIterator iterator; @@ -200,8 +202,10 @@ class JSON_API Value { // Required for boost integration, e. g. BOOST_TEST typedef std::string value_type; - static const Value& null; ///< We regret this reference to a global instance; prefer the simpler Value(). - static const Value& nullRef; ///< just a kludge for binary-compatibility; same as null + static const Value& null; ///< We regret this reference to a global instance; + ///< prefer the simpler Value(). + static const Value& nullRef; ///< just a kludge for binary-compatibility; same + ///< as null static Value const& nullSingleton(); ///< Prefer this to null or nullRef. /// Minimum signed integer value that can be stored in a Json::Value. @@ -241,11 +245,7 @@ class JSON_API Value { #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION class CZString { public: - enum DuplicationPolicy { - noDuplication = 0, - duplicate, - duplicateOnCopy - }; + enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy }; CZString(ArrayIndex index); CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(CZString const& other); @@ -262,7 +262,7 @@ class JSON_API Value { bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; ArrayIndex index() const; - //const char* c_str() const; ///< \deprecated + // const char* c_str() const; ///< \deprecated char const* data() const; unsigned length() const; bool isStaticString() const; @@ -271,11 +271,11 @@ class JSON_API Value { void swap(CZString& other); struct StringStorage { - unsigned policy_: 2; - unsigned length_: 30; // 1GB max + unsigned policy_ : 2; + unsigned length_ : 30; // 1GB max }; - char const* cstr_; // actually, a prefixed string, unless policy is noDup + char const* cstr_; // actually, a prefixed string, unless policy is noDup union { ArrayIndex index_; StringStorage storage_; @@ -332,7 +332,8 @@ Json::Value obj_value(Json::objectValue); // {} * \endcode */ Value(const StaticString& value); - Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded zeroes too. + Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded + ///< zeroes too. #ifdef JSON_USE_CPPTL Value(const CppTL::ConstString& value); #endif @@ -346,7 +347,8 @@ Json::Value obj_value(Json::objectValue); // {} ~Value(); /// Deep copy, then swap(other). - /// \note Over-write existing comments. To preserve comments, use #swapPayload(). + /// \note Over-write existing comments. To preserve comments, use + /// #swapPayload(). Value& operator=(Value other); /// Swap everything. @@ -372,14 +374,14 @@ Json::Value obj_value(Json::objectValue); // {} const char* asCString() const; ///< Embedded zeroes could cause you trouble! #if JSONCPP_USING_SECURE_MEMORY - unsigned getCStringLength() const; //Allows you to understand the length of the CString + unsigned getCStringLength() const; // Allows you to understand the length of + // the CString #endif JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. /** Get raw char* of string-value. * \return false if !string. (Seg-fault if str or end are NULL.) */ - bool getString( - char const** begin, char const** end) const; + bool getString(char const** begin, char const** end) const; #ifdef JSON_USE_CPPTL CppTL::ConstString asConstString() const; #endif @@ -490,7 +492,8 @@ Json::Value obj_value(Json::objectValue); // {} /** \brief Access an object value by name, create a null member if it does not exist. - * If the object has no entry for that name, then the member name used to store + * If the object has no entry for that name, then the member name used to + store * the new entry is not duplicated. * Example of use: * \code @@ -513,7 +516,8 @@ Json::Value obj_value(Json::objectValue); // {} /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \note key may contain embedded nulls. - Value get(const char* begin, const char* end, const Value& defaultValue) const; + Value + get(const char* begin, const char* end, const Value& defaultValue) const; /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \param key may contain embedded nulls. @@ -646,12 +650,14 @@ Json::Value obj_value(Json::objectValue); // {} LargestUInt uint_; double real_; bool bool_; - char* string_; // actually ptr to unsigned, followed by str, unless !allocated_ + char* string_; // actually ptr to unsigned, followed by str, unless + // !allocated_ ObjectValues* map_; } value_; ValueType type_ : 8; - unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless. - // If not allocated_, string_ must be null-terminated. + unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is + // useless. If not allocated_, string_ must be + // null-terminated. CommentInfo* comments_; // [start, limit) byte offsets in the source JSON text from which this Value @@ -673,11 +679,7 @@ class JSON_API PathArgument { PathArgument(const JSONCPP_STRING& key); private: - enum Kind { - kindNone = 0, - kindIndex, - kindKey - }; + enum Kind { kindNone = 0, kindIndex, kindKey }; JSONCPP_STRING key_; ArrayIndex index_; Kind kind_; @@ -745,7 +747,8 @@ class JSON_API ValueIteratorBase { /// Value. Value key() const; - /// Return the index of the referenced Value, or -1 if it is not an arrayValue. + /// Return the index of the referenced Value, or -1 if it is not an + /// arrayValue. UInt index() const; /// Return the member name of the referenced Value, or "" if it is not an @@ -755,7 +758,8 @@ class JSON_API ValueIteratorBase { /// Return the member name of the referenced Value. "" if it is not an /// objectValue. - /// \deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls. + /// \deprecated This cannot be used for UTF-8 strings, since there can be + /// embedded nulls. JSONCPP_DEPRECATED("Use `key = name();` instead.") char const* memberName() const; /// Return the member name of the referenced Value, or NULL if it is not an @@ -796,8 +800,8 @@ class JSON_API ValueConstIterator : public ValueIteratorBase { public: typedef const Value value_type; - //typedef unsigned int size_t; - //typedef int difference_type; + // typedef unsigned int size_t; + // typedef int difference_type; typedef const Value& reference; typedef const Value* pointer; typedef ValueConstIterator SelfType; @@ -806,9 +810,10 @@ class JSON_API ValueConstIterator : public ValueIteratorBase { ValueConstIterator(ValueIterator const& other); private: -/*! \internal Use by Value to create an iterator. - */ + /*! \internal Use by Value to create an iterator. + */ explicit ValueConstIterator(const Value::ObjectValues::iterator& current); + public: SelfType& operator=(const ValueIteratorBase& other); @@ -857,9 +862,10 @@ class JSON_API ValueIterator : public ValueIteratorBase { ValueIterator(const ValueIterator& other); private: -/*! \internal Use by Value to create an iterator. - */ + /*! \internal Use by Value to create an iterator. + */ explicit ValueIterator(const Value::ObjectValues::iterator& current); + public: SelfType& operator=(const SelfType& other); diff --git a/include/json/version.h b/include/json/version.h index 06c61870f..027f73173 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -1,14 +1,16 @@ // DO NOT EDIT. This file (and "version") is generated by CMake. // Run CMake configure step to update it. #ifndef JSON_VERSION_H_INCLUDED -# define JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED -# define JSONCPP_VERSION_STRING "1.8.4" -# define JSONCPP_VERSION_MAJOR 1 -# define JSONCPP_VERSION_MINOR 8 -# define JSONCPP_VERSION_PATCH 4 -# define JSONCPP_VERSION_QUALIFIER -# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) +#define JSONCPP_VERSION_STRING "1.8.4" +#define JSONCPP_VERSION_MAJOR 1 +#define JSONCPP_VERSION_MINOR 8 +#define JSONCPP_VERSION_PATCH 4 +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA \ + ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ + (JSONCPP_VERSION_PATCH << 8)) #ifdef JSONCPP_USING_SECURE_MEMORY #undef JSONCPP_USING_SECURE_MEMORY diff --git a/include/json/writer.h b/include/json/writer.h index 767b3bd61..30424b055 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -9,9 +9,9 @@ #if !defined(JSON_IS_AMALGAMATION) #include "value.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#include -#include #include +#include +#include // Disable warning C4251: : needs to have dll-interface to // be used by... @@ -41,15 +41,15 @@ class Value; */ class JSON_API StreamWriter { protected: - JSONCPP_OSTREAM* sout_; // not owned; will not delete + JSONCPP_OSTREAM* sout_; // not owned; will not delete public: StreamWriter(); virtual ~StreamWriter(); /** Write Value into document as configured in sub-class. Do not take ownership of sout, but maintain a reference during function. \pre sout != NULL - \return zero on success (For now, we always return zero, so check the stream instead.) - \throw std::exception possibly, depending on configuration + \return zero on success (For now, we always return zero, so check the + stream instead.) \throw std::exception possibly, depending on configuration */ virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; @@ -62,14 +62,14 @@ class JSON_API StreamWriter { * \throw std::exception if something goes wrong (e.g. invalid settings) */ virtual StreamWriter* newStreamWriter() const = 0; - }; // Factory -}; // StreamWriter + }; // Factory +}; // StreamWriter /** \brief Write into stringstream, then return string, for convenience. * A StreamWriter will be created from the factory, used, and then deleted. */ -JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, Value const& root); - +JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, + Value const& root); /** \brief Build a StreamWriter implementation. @@ -104,8 +104,8 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { browser can handle the output just fine. - "useSpecialFloats": false or true - If true, outputs non-finite floating point values in the following way: - NaN values as "NaN", positive infinity as "Infinity", and negative infinity - as "-Infinity". + NaN values as "NaN", positive infinity as "Infinity", and negative + infinity as "-Infinity". - "precision": int - Number of precision digits for formatting of real values. - "precisionType": "significant"(default) or "decimal" @@ -163,9 +163,10 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { */ #if defined(_MSC_VER) #pragma warning(push) -#pragma warning(disable:4996) // Deriving from deprecated class +#pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter + : public Writer { public: FastWriter(); ~FastWriter() JSONCPP_OVERRIDE {} @@ -222,9 +223,10 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter */ #if defined(_MSC_VER) #pragma warning(push) -#pragma warning(disable:4996) // Deriving from deprecated class +#pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledWriter : public Writer { public: StyledWriter(); ~StyledWriter() JSONCPP_OVERRIDE {} @@ -290,13 +292,14 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWrite */ #if defined(_MSC_VER) #pragma warning(push) -#pragma warning(disable:4996) // Deriving from deprecated class +#pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledStreamWriter { +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledStreamWriter { public: -/** - * \param indentation Each level will be indented by this amount extra. - */ + /** + * \param indentation Each level will be indented by this amount extra. + */ StyledStreamWriter(JSONCPP_STRING indentation = "\t"); ~StyledStreamWriter() {} @@ -343,8 +346,10 @@ JSONCPP_STRING JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) JSONCPP_STRING JSON_API valueToString(LargestInt value); JSONCPP_STRING JSON_API valueToString(LargestUInt value); -JSONCPP_STRING JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision, - PrecisionType precisionType = PrecisionType::significantDigits); +JSONCPP_STRING JSON_API +valueToString(double value, + unsigned int precision = Value::defaultRealPrecision, + PrecisionType precisionType = PrecisionType::significantDigits); JSONCPP_STRING JSON_API valueToString(bool value); JSONCPP_STRING JSON_API valueToQuotedString(const char* value); diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 531f541ba..7105b390f 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -13,13 +13,12 @@ /* This executable is used for testing parser/writer using real JSON files. */ -#include #include // sort +#include #include #include -struct Options -{ +struct Options { JSONCPP_STRING path; Json::Features features; bool parseOnly; @@ -45,8 +44,8 @@ static JSONCPP_STRING normalizeFloatingPointStr(double value) { JSONCPP_STRING::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); JSONCPP_STRING exponent = "0"; - if (indexDigit != - JSONCPP_STRING::npos) // There is an exponent different from 0 + if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different + // from 0 { exponent = s.substr(indexDigit); } @@ -73,8 +72,9 @@ static JSONCPP_STRING readInputTestFile(const char* path) { return text; } -static void -printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") { +static void printValueTree(FILE* fout, + Json::Value& value, + const JSONCPP_STRING& path = ".") { if (value.hasComment(Json::commentBefore)) { fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); } @@ -83,21 +83,15 @@ printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") fprintf(fout, "%s=null\n", path.c_str()); break; case Json::intValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), + fprintf(fout, "%s=%s\n", path.c_str(), Json::valueToString(value.asLargestInt()).c_str()); break; case Json::uintValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), + fprintf(fout, "%s=%s\n", path.c_str(), Json::valueToString(value.asLargestUInt()).c_str()); break; case Json::realValue: - fprintf(fout, - "%s=%s\n", - path.c_str(), + fprintf(fout, "%s=%s\n", path.c_str(), normalizeFloatingPointStr(value.asDouble()).c_str()); break; case Json::stringValue: @@ -125,8 +119,7 @@ printValueTree(FILE* fout, Json::Value& value, const JSONCPP_STRING& path = ".") std::sort(members.begin(), members.end()); JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : "."; for (Json::Value::Members::iterator it = members.begin(); - it != members.end(); - ++it) { + it != members.end(); ++it) { const JSONCPP_STRING name = *it; printValueTree(fout, value[name], path + suffix + name); } @@ -145,13 +138,12 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input, const JSONCPP_STRING& kind, const Json::Features& features, bool parseOnly, - Json::Value* root) -{ + Json::Value* root) { Json::Reader reader(features); - bool parsingSuccessful = reader.parse(input.data(), input.data() + input.size(), *root); + bool parsingSuccessful = + reader.parse(input.data(), input.data() + input.size(), *root); if (!parsingSuccessful) { - printf("Failed to parse %s file: \n%s\n", - kind.c_str(), + printf("Failed to parse %s file: \n%s\n", kind.c_str(), reader.getFormattedErrorMessages().c_str()); return 1; } @@ -171,32 +163,24 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input, // writer.enableYAMLCompatibility(); // return writer.write(root); // } -static JSONCPP_STRING useStyledWriter( - Json::Value const& root) -{ +static JSONCPP_STRING useStyledWriter(Json::Value const& root) { Json::StyledWriter writer; return writer.write(root); } -static JSONCPP_STRING useStyledStreamWriter( - Json::Value const& root) -{ +static JSONCPP_STRING useStyledStreamWriter(Json::Value const& root) { Json::StyledStreamWriter writer; JSONCPP_OSTRINGSTREAM sout; writer.write(sout, root); return sout.str(); } -static JSONCPP_STRING useBuiltStyledStreamWriter( - Json::Value const& root) -{ +static JSONCPP_STRING useBuiltStyledStreamWriter(Json::Value const& root) { Json::StreamWriterBuilder builder; return Json::writeString(builder, root); } -static int rewriteValueTree( - const JSONCPP_STRING& rewritePath, - const Json::Value& root, - Options::writeFuncType write, - JSONCPP_STRING* rewrite) -{ +static int rewriteValueTree(const JSONCPP_STRING& rewritePath, + const Json::Value& root, + Options::writeFuncType write, + JSONCPP_STRING* rewrite) { *rewrite = write(root); FILE* fout = fopen(rewritePath.c_str(), "wt"); if (!fout) { @@ -209,7 +193,7 @@ static int rewriteValueTree( } static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path, - const JSONCPP_STRING& extension) { + const JSONCPP_STRING& extension) { if (extension.length() >= path.length()) return JSONCPP_STRING(""); JSONCPP_STRING suffix = path.substr(path.length() - extension.length()); @@ -232,9 +216,7 @@ static int printUsage(const char* argv[]) { return 3; } -static int parseCommandLine( - int argc, const char* argv[], Options* opts) -{ +static int parseCommandLine(int argc, const char* argv[], Options* opts) { opts->parseOnly = false; opts->write = &useStyledWriter; if (argc < 2) { @@ -270,8 +252,7 @@ static int parseCommandLine( opts->path = argv[index]; return 0; } -static int runTest(Options const& opts) -{ +static int runTest(Options const& opts) { int exitCode = 0; JSONCPP_STRING input = readInputTestFile(opts.path.c_str()); @@ -283,7 +264,7 @@ static int runTest(Options const& opts) JSONCPP_STRING basePath = removeSuffix(opts.path, ".json"); if (!opts.parseOnly && basePath.empty()) { printf("Bad input path. Path does not end with '.expected':\n%s\n", - opts.path.c_str()); + opts.path.c_str()); return 3; } @@ -292,9 +273,8 @@ static int runTest(Options const& opts) JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite"; Json::Value root; - exitCode = parseAndSaveValueTree( - input, actualPath, "input", - opts.features, opts.parseOnly, &root); + exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features, + opts.parseOnly, &root); if (exitCode || opts.parseOnly) { return exitCode; } @@ -304,9 +284,8 @@ static int runTest(Options const& opts) return exitCode; } Json::Value rewriteRoot; - exitCode = parseAndSaveValueTree( - rewrite, rewriteActualPath, "rewrite", - opts.features, opts.parseOnly, &rewriteRoot); + exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite", + opts.features, opts.parseOnly, &rewriteRoot); if (exitCode) { return exitCode; } @@ -315,14 +294,13 @@ static int runTest(Options const& opts) int main(int argc, const char* argv[]) { Options opts; try { - int exitCode = parseCommandLine(argc, argv, &opts); - if (exitCode != 0) { - printf("Failed to parse command-line."); - return exitCode; - } + int exitCode = parseCommandLine(argc, argv, &opts); + if (exitCode != 0) { + printf("Failed to parse command-line."); + return exitCode; + } return runTest(opts); - } - catch (const std::exception& e) { + } catch (const std::exception& e) { printf("Unhandled exception:\n%s\n", e.what()); return 1; } diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index afdb595ae..0bef78ede 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -5,39 +5,39 @@ // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) +#include "json_tool.h" #include #include #include -#include "json_tool.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#include #include #include #include -#include +#include #include #include -#include +#include +#include #if __cplusplus >= 201103L - #include +#include - #if !defined(snprintf) - #define snprintf std::snprintf - #endif +#if !defined(snprintf) +#define snprintf std::snprintf +#endif - #if !defined(sscanf) - #define sscanf std::sscanf - #endif +#if !defined(sscanf) +#define sscanf std::sscanf +#endif #else - #include - - #if defined(_MSC_VER) - #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 - #if !defined(snprintf) - #define snprintf _snprintf - #endif - #endif +#include + +#if defined(_MSC_VER) +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#if !defined(snprintf) +#define snprintf _snprintf +#endif +#endif #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 @@ -45,19 +45,21 @@ #pragma warning(disable : 4996) #endif -// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit +// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile +// time to change the stack limit #if !defined(JSONCPP_DEPRECATED_STACK_LIMIT) #define JSONCPP_DEPRECATED_STACK_LIMIT 1000 #endif -static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() +static size_t const stackLimit_g = + JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr CharReaderPtr; #else -typedef std::auto_ptr CharReaderPtr; +typedef std::auto_ptr CharReaderPtr; #endif // Implementation of class Features @@ -101,8 +103,9 @@ Reader::Reader(const Features& features) lastValue_(), commentsBefore_(), features_(features), collectComments_() { } -bool -Reader::parse(const std::string& document, Value& root, bool collectComments) { +bool Reader::parse(const std::string& document, + Value& root, + bool collectComments) { document_.assign(document.begin(), document.end()); const char* begin = document_.c_str(); const char* end = begin + document_.length(); @@ -165,9 +168,11 @@ bool Reader::parse(const char* beginDoc, bool Reader::readValue() { // readValue() may call itself only if it calls readObject() or ReadArray(). - // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). - // parse() executes one nodes_.push(), so > instead of >=. - if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); + // These methods execute nodes_.push() just before and nodes_.pop)() just + // after calling readValue(). parse() executes one nodes_.push(), so > instead + // of >=. + if (nodes_.size() > stackLimit_g) + throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; skipCommentTokens(token); @@ -193,30 +198,24 @@ bool Reader::readValue() { case tokenString: successful = decodeString(token); break; - case tokenTrue: - { + case tokenTrue: { Value v(true); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { + } break; + case tokenFalse: { Value v(false); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { + } break; + case tokenNull: { Value v; currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; + } break; case tokenArraySeparator: case tokenObjectEnd: case tokenArrayEnd: @@ -369,7 +368,8 @@ bool Reader::readComment() { return true; } -JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { +JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, + Reader::Location end) { JSONCPP_STRING normalized; normalized.reserve(static_cast(end - begin)); Reader::Location current = begin; @@ -377,8 +377,8 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -388,8 +388,9 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end return normalized; } -void -Reader::addComment(Location begin, Location end, CommentPlacement placement) { +void Reader::addComment(Location begin, + Location end, + CommentPlacement placement) { assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { @@ -426,7 +427,7 @@ bool Reader::readCppStyleComment() { } void Reader::readNumber() { - const char *p = current_; + const char* p = current_; char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') @@ -488,8 +489,8 @@ bool Reader::readObject(Token& tokenStart) { Token colon; if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); + return addErrorAndRecover("Missing ':' after object member name", colon, + tokenObjectEnd); } Value& value = currentValue()[name]; nodes_.push(&value); @@ -502,8 +503,8 @@ bool Reader::readObject(Token& tokenStart) { if (!readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return addErrorAndRecover("Missing ',' or '}' in object declaration", + comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) @@ -511,8 +512,8 @@ bool Reader::readObject(Token& tokenStart) { if (comma.type_ == tokenObjectEnd) return true; } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); + return addErrorAndRecover("Missing '}' or object member name", tokenName, + tokenObjectEnd); } bool Reader::readArray(Token& tokenStart) { @@ -544,8 +545,8 @@ bool Reader::readArray(Token& tokenStart) { bool badTokenType = (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return addErrorAndRecover("Missing ',' or ']' in array declaration", + token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -571,7 +572,8 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 : Value::maxLargestUInt; @@ -703,8 +705,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token, if (end - current < 6) return addError( "additional six characters expected to parse unicode surrogate pair.", - token, - current); + token, current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { @@ -714,8 +715,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token, } else return addError("expecting another \\u token to begin the second half of " "a unicode surrogate pair", - token, - current); + token, current); } return true; } @@ -726,8 +726,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, unsigned int& ret_unicode) { if (end - current < 4) return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, + "Bad unicode escape sequence in string: four digits expected.", token, current); int unicode = 0; for (int index = 0; index < 4; ++index) { @@ -742,15 +741,15 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, else return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); + token, current); } ret_unicode = static_cast(unicode); return true; } -bool -Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { +bool Reader::addError(const JSONCPP_STRING& message, + Token& token, + Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -826,8 +825,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const { JSONCPP_STRING Reader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + itError != errors_.end(); ++itError) { const ErrorInfo& error = *itError; formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; @@ -842,8 +840,7 @@ JSONCPP_STRING Reader::getFormattedErrorMessages() const { std::vector Reader::getStructuredErrors() const { std::vector allErrors; for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + itError != errors_.end(); ++itError) { const ErrorInfo& error = *itError; Reader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; @@ -856,8 +853,7 @@ std::vector Reader::getStructuredErrors() const { bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { ptrdiff_t const length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) + if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; @@ -871,11 +867,12 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { return true; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { +bool Reader::pushError(const Value& value, + const JSONCPP_STRING& message, + const Value& extra) { ptrdiff_t const length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) + if (value.getOffsetStart() > length || value.getOffsetLimit() > length || + extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; @@ -889,9 +886,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const return true; } -bool Reader::good() const { - return !errors_.size(); -} +bool Reader::good() const { return !errors_.size(); } // exact copy of Features class OurFeatures { @@ -906,7 +901,7 @@ class OurFeatures { bool rejectDupKeys_; bool allowSpecialFloats_; int stackLimit_; -}; // OurFeatures +}; // OurFeatures // exact copy of Implementation of class Features // //////////////////////////////// @@ -935,12 +930,14 @@ class OurReader { JSONCPP_STRING getFormattedErrorMessages() const; std::vector getStructuredErrors() const; bool pushError(const Value& value, const JSONCPP_STRING& message); - bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); + bool pushError(const Value& value, + const JSONCPP_STRING& message, + const Value& extra); bool good() const; private: - OurReader(OurReader const&); // no impl - void operator=(OurReader const&); // no impl + OurReader(OurReader const&); // no impl + void operator=(OurReader const&); // no impl enum TokenType { tokenEndOfStream = 0, @@ -1004,7 +1001,8 @@ class OurReader { Location& current, Location end, unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + bool + addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, @@ -1034,11 +1032,12 @@ class OurReader { OurFeatures const features_; bool collectComments_; -}; // OurReader +}; // OurReader // complete copy of Read impl, for OurReader -bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end) { +bool OurReader::containsNewLine(OurReader::Location begin, + OurReader::Location end) { for (; begin < end; ++begin) if (*begin == '\n' || *begin == '\r') return true; @@ -1047,14 +1046,13 @@ bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location e OurReader::OurReader(OurFeatures const& features) : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), - features_(features), collectComments_() { + lastValue_(), commentsBefore_(), features_(features), collectComments_() { } bool OurReader::parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments) { + const char* endDoc, + Value& root, + bool collectComments) { if (!features_.allowComments_) { collectComments = false; } @@ -1075,7 +1073,8 @@ bool OurReader::parse(const char* beginDoc, Token token; skipCommentTokens(token); if (features_.failIfExtra_) { - if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) { + if ((features_.strictRoot_ || token.type_ != tokenError) && + token.type_ != tokenEndOfStream) { addError("Extra non-whitespace after JSON value.", token); return false; } @@ -1100,7 +1099,8 @@ bool OurReader::parse(const char* beginDoc, bool OurReader::readValue() { // To preserve the old behaviour we cast size_t to int. - if (static_cast(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); + if (static_cast(nodes_.size()) > features_.stackLimit_) + throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; skipCommentTokens(token); bool successful = true; @@ -1125,54 +1125,42 @@ bool OurReader::readValue() { case tokenString: successful = decodeString(token); break; - case tokenTrue: - { + case tokenTrue: { Value v(true); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { + } break; + case tokenFalse: { Value v(false); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { + } break; + case tokenNull: { Value v; currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNaN: - { + } break; + case tokenNaN: { Value v(std::numeric_limits::quiet_NaN()); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenPosInf: - { + } break; + case tokenPosInf: { Value v(std::numeric_limits::infinity()); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNegInf: - { + } break; + case tokenNegInf: { Value v(-std::numeric_limits::infinity()); currentValue().swapPayload(v); currentValue().setOffsetStart(token.start_ - begin_); currentValue().setOffsetLimit(token.end_ - begin_); - } - break; + } break; case tokenArraySeparator: case tokenObjectEnd: case tokenArrayEnd: @@ -1234,9 +1222,9 @@ bool OurReader::readToken(Token& token) { break; case '\'': if (features_.allowSingleQuotes_) { - token.type_ = tokenString; - ok = readStringSingleQuote(); - break; + token.type_ = tokenString; + ok = readStringSingleQuote(); + break; } // else fall through case '/': token.type_ = tokenComment; @@ -1354,7 +1342,8 @@ bool OurReader::readComment() { return true; } -JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Location end) { +JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, + OurReader::Location end) { JSONCPP_STRING normalized; normalized.reserve(static_cast(end - begin)); OurReader::Location current = begin; @@ -1362,8 +1351,8 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -1373,8 +1362,9 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc return normalized; } -void -OurReader::addComment(Location begin, Location end, CommentPlacement placement) { +void OurReader::addComment(Location begin, + Location end, + CommentPlacement placement) { assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { @@ -1411,7 +1401,7 @@ bool OurReader::readCppStyleComment() { } bool OurReader::readNumber(bool checkInf) { - const char *p = current_; + const char* p = current_; if (checkInf && p != end_ && *p == 'I') { current_ = ++p; return false; @@ -1448,7 +1438,6 @@ bool OurReader::readString() { return c == '"'; } - bool OurReader::readStringSingleQuote() { Char c = 0; while (current_ != end_) { @@ -1490,14 +1479,14 @@ bool OurReader::readObject(Token& tokenStart) { Token colon; if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); + return addErrorAndRecover("Missing ':' after object member name", colon, + tokenObjectEnd); } - if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); + if (name.length() >= (1U << 30)) + throwRuntimeError("keylength >= 2^30"); if (features_.rejectDupKeys_ && currentValue().isMember(name)) { JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; - return addErrorAndRecover( - msg, tokenName, tokenObjectEnd); + return addErrorAndRecover(msg, tokenName, tokenObjectEnd); } Value& value = currentValue()[name]; nodes_.push(&value); @@ -1510,8 +1499,8 @@ bool OurReader::readObject(Token& tokenStart) { if (!readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return addErrorAndRecover("Missing ',' or '}' in object declaration", + comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) @@ -1519,8 +1508,8 @@ bool OurReader::readObject(Token& tokenStart) { if (comma.type_ == tokenObjectEnd) return true; } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); + return addErrorAndRecover("Missing '}' or object member name", tokenName, + tokenObjectEnd); } bool OurReader::readArray(Token& tokenStart) { @@ -1552,8 +1541,8 @@ bool OurReader::readArray(Token& tokenStart) { bool badTokenType = (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return addErrorAndRecover("Missing ',' or ']' in array declaration", + token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -1579,7 +1568,8 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. Value::LargestUInt maxIntegerValue = isNegative ? Value::LargestUInt(-Value::minLargestInt) : Value::maxLargestUInt; @@ -1724,9 +1714,9 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { } bool OurReader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { + Location& current, + Location end, + unsigned int& unicode) { if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; @@ -1735,8 +1725,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token, if (end - current < 6) return addError( "additional six characters expected to parse unicode surrogate pair.", - token, - current); + token, current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { @@ -1746,20 +1735,18 @@ bool OurReader::decodeUnicodeCodePoint(Token& token, } else return addError("expecting another \\u token to begin the second half of " "a unicode surrogate pair", - token, - current); + token, current); } return true; } bool OurReader::decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& ret_unicode) { + Location& current, + Location end, + unsigned int& ret_unicode) { if (end - current < 4) return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, + "Bad unicode escape sequence in string: four digits expected.", token, current); int unicode = 0; for (int index = 0; index < 4; ++index) { @@ -1774,15 +1761,15 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, else return addError( "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); + token, current); } ret_unicode = static_cast(unicode); return true; } -bool -OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { +bool OurReader::addError(const JSONCPP_STRING& message, + Token& token, + Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -1805,8 +1792,8 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) { } bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, - Token& token, - TokenType skipUntilToken) { + Token& token, + TokenType skipUntilToken) { addError(message, token); return recoverFromError(skipUntilToken); } @@ -1820,8 +1807,8 @@ OurReader::Char OurReader::getNextChar() { } void OurReader::getLocationLineAndColumn(Location location, - int& line, - int& column) const { + int& line, + int& column) const { Location current = begin_; Location lastLineStart = current; line = 0; @@ -1853,8 +1840,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { JSONCPP_STRING OurReader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + itError != errors_.end(); ++itError) { const ErrorInfo& error = *itError; formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; @@ -1869,8 +1855,7 @@ JSONCPP_STRING OurReader::getFormattedErrorMessages() const { std::vector OurReader::getStructuredErrors() const { std::vector allErrors; for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + itError != errors_.end(); ++itError) { const ErrorInfo& error = *itError; OurReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; @@ -1883,8 +1868,7 @@ std::vector OurReader::getStructuredErrors() const { bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { ptrdiff_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) + if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; @@ -1898,11 +1882,12 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { return true; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { +bool OurReader::pushError(const Value& value, + const JSONCPP_STRING& message, + const Value& extra) { ptrdiff_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) + if (value.getOffsetStart() > length || value.getOffsetLimit() > length || + extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; @@ -1916,24 +1901,19 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, con return true; } -bool OurReader::good() const { - return !errors_.size(); -} - +bool OurReader::good() const { return !errors_.size(); } class OurCharReader : public CharReader { bool const collectComments_; OurReader reader_; + public: - OurCharReader( - bool collectComments, - OurFeatures const& features) - : collectComments_(collectComments) - , reader_(features) - {} - bool parse( - char const* beginDoc, char const* endDoc, - Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE { + OurCharReader(bool collectComments, OurFeatures const& features) + : collectComments_(collectComments), reader_(features) {} + bool parse(char const* beginDoc, + char const* endDoc, + Value* root, + JSONCPP_STRING* errs) JSONCPP_OVERRIDE { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { *errs = reader_.getFormattedErrorMessages(); @@ -1942,19 +1922,15 @@ class OurCharReader : public CharReader { } }; -CharReaderBuilder::CharReaderBuilder() -{ - setDefaults(&settings_); -} -CharReaderBuilder::~CharReaderBuilder() -{} -CharReader* CharReaderBuilder::newCharReader() const -{ +CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } +CharReaderBuilder::~CharReaderBuilder() {} +CharReader* CharReaderBuilder::newCharReader() const { bool collectComments = settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); features.allowComments_ = settings_["allowComments"].asBool(); features.strictRoot_ = settings_["strictRoot"].asBool(); - features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); + features.allowDroppedNullPlaceholders_ = + settings_["allowDroppedNullPlaceholders"].asBool(); features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); features.stackLimit_ = settings_["stackLimit"].asInt(); @@ -1963,8 +1939,7 @@ CharReader* CharReaderBuilder::newCharReader() const features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); return new OurCharReader(collectComments, features); } -static void getValidReaderKeys(std::set* valid_keys) -{ +static void getValidReaderKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("collectComments"); valid_keys->insert("allowComments"); @@ -1977,10 +1952,10 @@ static void getValidReaderKeys(std::set* valid_keys) valid_keys->insert("rejectDupKeys"); valid_keys->insert("allowSpecialFloats"); } -bool CharReaderBuilder::validate(Json::Value* invalid) const -{ +bool CharReaderBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + if (!invalid) + invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; std::set valid_keys; getValidReaderKeys(&valid_keys); @@ -1994,14 +1969,12 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const } return 0u == inv.size(); } -Value& CharReaderBuilder::operator[](JSONCPP_STRING key) -{ +Value& CharReaderBuilder::operator[](JSONCPP_STRING key) { return settings_[key]; } // static -void CharReaderBuilder::strictMode(Json::Value* settings) -{ -//! [CharReaderBuilderStrictMode] +void CharReaderBuilder::strictMode(Json::Value* settings) { + //! [CharReaderBuilderStrictMode] (*settings)["allowComments"] = false; (*settings)["strictRoot"] = true; (*settings)["allowDroppedNullPlaceholders"] = false; @@ -2011,12 +1984,11 @@ void CharReaderBuilder::strictMode(Json::Value* settings) (*settings)["failIfExtra"] = true; (*settings)["rejectDupKeys"] = true; (*settings)["allowSpecialFloats"] = false; -//! [CharReaderBuilderStrictMode] + //! [CharReaderBuilderStrictMode] } // static -void CharReaderBuilder::setDefaults(Json::Value* settings) -{ -//! [CharReaderBuilderDefaults] +void CharReaderBuilder::setDefaults(Json::Value* settings) { + //! [CharReaderBuilderDefaults] (*settings)["collectComments"] = true; (*settings)["allowComments"] = true; (*settings)["strictRoot"] = false; @@ -2027,16 +1999,16 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) (*settings)["failIfExtra"] = false; (*settings)["rejectDupKeys"] = false; (*settings)["allowSpecialFloats"] = false; -//! [CharReaderBuilderDefaults] + //! [CharReaderBuilderDefaults] } ////////////////////////////////// // global functions -bool parseFromStream( - CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, - Value* root, JSONCPP_STRING* errs) -{ +bool parseFromStream(CharReader::Factory const& fact, + JSONCPP_ISTREAM& sin, + Value* root, + JSONCPP_STRING* errs) { JSONCPP_OSTRINGSTREAM ssin; ssin << sin.rdbuf(); JSONCPP_STRING doc = ssin.str(); diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index d5f6d2f17..3a22015b4 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -89,8 +89,7 @@ static inline void uintToString(LargestUInt value, char*& current) { * We had a sophisticated way, but it did not work in WinCE. * @see https://github.com/open-source-parsers/jsoncpp/pull/9 */ -template -Iter fixNumericLocale(Iter begin, Iter end) { +template Iter fixNumericLocale(Iter begin, Iter end) { for (; begin != end; ++begin) { if (*begin == ',') { *begin = '.'; @@ -99,8 +98,7 @@ Iter fixNumericLocale(Iter begin, Iter end) { return begin; } -template -void fixNumericLocaleInput(Iter begin, Iter end) { +template void fixNumericLocaleInput(Iter begin, Iter end) { char decimalPoint = getDecimalPoint(); if (decimalPoint == '\0' || decimalPoint == '.') { return; @@ -116,14 +114,13 @@ void fixNumericLocaleInput(Iter begin, Iter end) { * Return iterator that would be the new end of the range [begin,end), if we * were to delete zeros in the end of string, but not the last zero before '.'. */ -template -Iter fixZerosInTheEnd(Iter begin, Iter end) { +template Iter fixZerosInTheEnd(Iter begin, Iter end) { for (; begin != end; --end) { - if (*(end-1) != '0') { + if (*(end - 1) != '0') { return end; } // Don't delete the last zero before the decimal point. - if (begin != (end-1) && *(end-2) == '.') { + if (begin != (end - 1) && *(end - 2) == '.') { return end; } } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index c7eac08ab..6bf981ef1 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -8,20 +8,20 @@ #include #include #endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include #include #include #include -#include -#include #ifdef JSON_USE_CPPTL #include #endif -#include // size_t #include // min() +#include // size_t // Disable warning C4702 : unreachable code #if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above -#pragma warning(disable:4702) +#pragma warning(disable : 4702) #endif #define JSON_ASSERT_UNREACHABLE assert(false) @@ -36,20 +36,19 @@ namespace Json { #else #define ALIGNAS(byte_alignment) #endif -//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; -//const unsigned char& kNullRef = kNull[0]; -//const Value& Value::null = reinterpret_cast(kNullRef); -//const Value& Value::nullRef = null; +// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; +// const unsigned char& kNullRef = kNull[0]; +// const Value& Value::null = reinterpret_cast(kNullRef); +// const Value& Value::nullRef = null; // static -Value const& Value::nullSingleton() -{ - static Value const nullStatic; - return nullStatic; +Value const& Value::nullSingleton() { + static Value const nullStatic; + return nullStatic; } -// for backwards compatibility, we'll leave these global references around, but DO NOT -// use them in JSONCPP library code any more! +// for backwards compatibility, we'll leave these global references around, but +// DO NOT use them in JSONCPP library code any more! Value const& Value::null = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton(); @@ -76,12 +75,13 @@ template static inline bool InRange(double d, T min, U max) { // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn - //return d >= static_cast(min) && d <= static_cast(max); + // return d >= static_cast(min) && d <= static_cast(max); return d >= min && d <= max; } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) static inline double integerToDouble(Json::UInt64 value) { - return static_cast(Int64(value / 2)) * 2.0 + static_cast(Int64(value & 1)); + return static_cast(Int64(value / 2)) * 2.0 + + static_cast(Int64(value & 1)); } template static inline double integerToDouble(T value) { @@ -101,9 +101,7 @@ static inline bool InRange(double d, T min, U max) { * computed using strlen(value). * @return Pointer on the duplicate instance of string. */ -static inline char* duplicateStringValue(const char* value, - size_t length) -{ +static inline char* duplicateStringValue(const char* value, size_t length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. if (length >= static_cast(Value::maxInt)) @@ -111,9 +109,8 @@ static inline char* duplicateStringValue(const char* value, char* newString = static_cast(malloc(length + 1)); if (newString == NULL) { - throwRuntimeError( - "in Json::Value::duplicateStringValue(): " - "Failed to allocate string value buffer"); + throwRuntimeError("in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); } memcpy(newString, value, length); newString[length] = 0; @@ -122,31 +119,30 @@ static inline char* duplicateStringValue(const char* value, /* Record the length as a prefix. */ -static inline char* duplicateAndPrefixStringValue( - const char* value, - unsigned int length) -{ +static inline char* duplicateAndPrefixStringValue(const char* value, + unsigned int length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. - JSON_ASSERT_MESSAGE(length <= static_cast(Value::maxInt) - sizeof(unsigned) - 1U, + JSON_ASSERT_MESSAGE(length <= static_cast(Value::maxInt) - + sizeof(unsigned) - 1U, "in Json::Value::duplicateAndPrefixStringValue(): " "length too big for prefixing"); unsigned actualLength = length + static_cast(sizeof(unsigned)) + 1U; char* newString = static_cast(malloc(actualLength)); if (newString == 0) { - throwRuntimeError( - "in Json::Value::duplicateAndPrefixStringValue(): " - "Failed to allocate string value buffer"); + throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " + "Failed to allocate string value buffer"); } *reinterpret_cast(newString) = length; memcpy(newString + sizeof(unsigned), value, length); - newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later + newString[actualLength - 1U] = + 0; // to avoid buffer over-run accidents by users later return newString; } -inline static void decodePrefixedString( - bool isPrefixed, char const* prefixed, - unsigned* length, char const** value) -{ +inline static void decodePrefixedString(bool isPrefixed, + char const* prefixed, + unsigned* length, + char const** value) { if (!isPrefixed) { *length = static_cast(strlen(prefixed)); *value = prefixed; @@ -155,7 +151,8 @@ inline static void decodePrefixedString( *value = prefixed + sizeof(unsigned); } } -/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). +/** Free the string duplicated by + * duplicateStringValue()/duplicateAndPrefixStringValue(). */ #if JSONCPP_USING_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { @@ -168,17 +165,13 @@ static inline void releasePrefixedStringValue(char* value) { } static inline void releaseStringValue(char* value, unsigned length) { // length==0 => we allocated the strings memory - size_t size = (length==0) ? strlen(value) : length; + size_t size = (length == 0) ? strlen(value) : length; memset(value, 0, size); free(value); } -#else // !JSONCPP_USING_SECURE_MEMORY -static inline void releasePrefixedStringValue(char* value) { - free(value); -} -static inline void releaseStringValue(char* value, unsigned) { - free(value); -} +#else // !JSONCPP_USING_SECURE_MEMORY +static inline void releasePrefixedStringValue(char* value) { free(value); } +static inline void releaseStringValue(char* value, unsigned) { free(value); } #endif // JSONCPP_USING_SECURE_MEMORY } // namespace Json @@ -197,27 +190,15 @@ static inline void releaseStringValue(char* value, unsigned) { namespace Json { -Exception::Exception(JSONCPP_STRING const& msg) - : msg_(msg) -{} -Exception::~Exception() JSONCPP_NOEXCEPT -{} -char const* Exception::what() const JSONCPP_NOEXCEPT -{ - return msg_.c_str(); -} -RuntimeError::RuntimeError(JSONCPP_STRING const& msg) - : Exception(msg) -{} -LogicError::LogicError(JSONCPP_STRING const& msg) - : Exception(msg) -{} -JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) -{ +Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) {} +Exception::~Exception() JSONCPP_NOEXCEPT {} +char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } +RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {} +LogicError::LogicError(JSONCPP_STRING const& msg) : Exception(msg) {} +JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) { throw RuntimeError(msg); } -JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) -{ +JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { throw LogicError(msg); } @@ -229,8 +210,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() : comment_(0) -{} +Value::CommentInfo::CommentInfo() : comment_(0) {} Value::CommentInfo::~CommentInfo() { if (comment_) @@ -263,7 +243,9 @@ void Value::CommentInfo::setComment(const char* text, size_t len) { Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {} -Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate) +Value::CZString::CZString(char const* str, + unsigned ulength, + DuplicationPolicy allocate) : cstr_(str) { // allocate != duplicate storage_.policy_ = allocate & 0x3; @@ -272,25 +254,34 @@ Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy a Value::CZString::CZString(const CZString& other) { cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 - ? duplicateStringValue(other.cstr_, other.storage_.length_) - : other.cstr_); - storage_.policy_ = static_cast(other.cstr_ - ? (static_cast(other.storage_.policy_) == noDuplication - ? noDuplication : duplicate) - : static_cast(other.storage_.policy_)) & 3U; + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_); + storage_.policy_ = + static_cast( + other.cstr_ + ? (static_cast(other.storage_.policy_) == + noDuplication + ? noDuplication + : duplicate) + : static_cast(other.storage_.policy_)) & + 3U; storage_.length_ = other.storage_.length_; } #if JSON_HAS_RVALUE_REFERENCES Value::CZString::CZString(CZString&& other) - : cstr_(other.cstr_), index_(other.index_) { + : cstr_(other.cstr_), index_(other.index_) { other.cstr_ = nullptr; } #endif Value::CZString::~CZString() { if (cstr_ && storage_.policy_ == duplicate) { - releaseStringValue(const_cast(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary + releaseStringValue(const_cast(cstr_), + storage_.length_ + 1u); // +1 for null terminating + // character for sake of + // completeness but not actually + // necessary } } @@ -315,26 +306,31 @@ Value::CZString& Value::CZString::operator=(CZString&& other) { #endif bool Value::CZString::operator<(const CZString& other) const { - if (!cstr_) return index_ < other.index_; - //return strcmp(cstr_, other.cstr_) < 0; + if (!cstr_) + return index_ < other.index_; + // return strcmp(cstr_, other.cstr_) < 0; // Assume both are strings. unsigned this_len = this->storage_.length_; unsigned other_len = other.storage_.length_; unsigned min_len = std::min(this_len, other_len); JSON_ASSERT(this->cstr_ && other.cstr_); int comp = memcmp(this->cstr_, other.cstr_, min_len); - if (comp < 0) return true; - if (comp > 0) return false; + if (comp < 0) + return true; + if (comp > 0) + return false; return (this_len < other_len); } bool Value::CZString::operator==(const CZString& other) const { - if (!cstr_) return index_ == other.index_; - //return strcmp(cstr_, other.cstr_) == 0; + if (!cstr_) + return index_ == other.index_; + // return strcmp(cstr_, other.cstr_) == 0; // Assume both are strings. unsigned this_len = this->storage_.length_; unsigned other_len = other.storage_.length_; - if (this_len != other_len) return false; + if (this_len != other_len) + return false; JSON_ASSERT(this->cstr_ && other.cstr_); int comp = memcmp(this->cstr_, other.cstr_, this_len); return comp == 0; @@ -342,10 +338,12 @@ bool Value::CZString::operator==(const CZString& other) const { ArrayIndex Value::CZString::index() const { return index_; } -//const char* Value::CZString::c_str() const { return cstr_; } +// const char* Value::CZString::c_str() const { return cstr_; } const char* Value::CZString::data() const { return cstr_; } unsigned Value::CZString::length() const { return storage_.length_; } -bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } +bool Value::CZString::isStaticString() const { + return storage_.policy_ == noDuplication; +} // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// @@ -416,19 +414,20 @@ Value::Value(double value) { Value::Value(const char* value) { initBasic(stringValue, true); JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast(strlen(value))); + value_.string_ = duplicateAndPrefixStringValue( + value, static_cast(strlen(value))); } Value::Value(const char* beginValue, const char* endValue) { initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(beginValue, static_cast(endValue - beginValue)); + value_.string_ = duplicateAndPrefixStringValue( + beginValue, static_cast(endValue - beginValue)); } Value::Value(const JSONCPP_STRING& value) { initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(value.data(), static_cast(value.length())); + value_.string_ = duplicateAndPrefixStringValue( + value.data(), static_cast(value.length())); } Value::Value(const StaticString& value) { @@ -439,7 +438,8 @@ Value::Value(const StaticString& value) { #ifdef JSON_USE_CPPTL Value::Value(const CppTL::ConstString& value) { initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast(value.length())); + value_.string_ = duplicateAndPrefixStringValue( + value, static_cast(value.length())); } #endif @@ -527,23 +527,28 @@ bool Value::operator<(const Value& other) const { return value_.real_ < other.value_.real_; case booleanValue: return value_.bool_ < other.value_.bool_; - case stringValue: - { + case stringValue: { if ((value_.string_ == 0) || (other.value_.string_ == 0)) { - if (other.value_.string_) return true; - else return false; + if (other.value_.string_) + return true; + else + return false; } unsigned this_len; unsigned other_len; char const* this_str; char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + &other_str); unsigned min_len = std::min(this_len, other_len); JSON_ASSERT(this_str && other_str); int comp = memcmp(this_str, other_str, min_len); - if (comp < 0) return true; - if (comp > 0) return false; + if (comp < 0) + return true; + if (comp > 0) + return false; return (this_len < other_len); } case arrayValue: @@ -584,8 +589,7 @@ bool Value::operator==(const Value& other) const { return value_.real_ == other.value_.real_; case booleanValue: return value_.bool_ == other.value_.bool_; - case stringValue: - { + case stringValue: { if ((value_.string_ == 0) || (other.value_.string_ == 0)) { return (value_.string_ == other.value_.string_); } @@ -593,9 +597,12 @@ bool Value::operator==(const Value& other) const { unsigned other_len; char const* this_str; char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); - if (this_len != other_len) return false; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + &other_str); + if (this_len != other_len) + return false; JSON_ASSERT(this_str && other_str); int comp = memcmp(this_str, other_str, this_len); return comp == 0; @@ -615,28 +622,34 @@ bool Value::operator!=(const Value& other) const { return !(*this == other); } const char* Value::asCString() const { JSON_ASSERT_MESSAGE(type_ == stringValue, "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) return 0; + if (value_.string_ == 0) + return 0; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); return this_str; } #if JSONCPP_USING_SECURE_MEMORY unsigned Value::getCStringLength() const { JSON_ASSERT_MESSAGE(type_ == stringValue, - "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) return 0; + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == 0) + return 0; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); return this_len; } #endif bool Value::getString(char const** str, char const** cend) const { - if (type_ != stringValue) return false; - if (value_.string_ == 0) return false; + if (type_ != stringValue) + return false; + if (value_.string_ == 0) + return false; unsigned length; decodePrefixedString(this->allocated_, this->value_.string_, &length, str); *cend = *str + length; @@ -647,12 +660,13 @@ JSONCPP_STRING Value::asString() const { switch (type_) { case nullValue: return ""; - case stringValue: - { - if (value_.string_ == 0) return ""; + case stringValue: { + if (value_.string_ == 0) + return ""; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); return JSONCPP_STRING(this_str, this_len); } case booleanValue: @@ -672,8 +686,7 @@ JSONCPP_STRING Value::asString() const { CppTL::ConstString Value::asConstString() const { unsigned len; char const* str; - decodePrefixedString(allocated_, value_.string_, - &len, &str); + decodePrefixedString(allocated_, value_.string_, &len, &str); return CppTL::ConstString(str, len); } #endif @@ -911,7 +924,7 @@ bool Value::empty() const { return false; } -Value::operator bool() const { return ! isNull(); } +Value::operator bool() const { return !isNull(); } void Value::clear() { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || @@ -1013,8 +1026,7 @@ void Value::dupPayload(const Value& other) { if (other.value_.string_ && other.allocated_) { unsigned len; char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, - &len, &str); + decodePrefixedString(other.allocated_, other.value_.string_, &len, &str); value_.string_ = duplicateAndPrefixStringValue(str, len); allocated_ = true; } else { @@ -1057,8 +1069,8 @@ void Value::dupMeta(const Value& other) { for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { const CommentInfo& otherComment = other.comments_[comment]; if (otherComment.comment_) - comments_[comment].setComment( - otherComment.comment_, strlen(otherComment.comment_)); + comments_[comment].setComment(otherComment.comment_, + strlen(otherComment.comment_)); } } else { comments_ = 0; @@ -1076,8 +1088,8 @@ Value& Value::resolveReference(const char* key) { "in Json::Value::resolveReference(): requires objectValue"); if (type_ == nullValue) *this = Value(objectValue); - CZString actualKey( - key, static_cast(strlen(key)), CZString::noDuplication); // NOTE! + CZString actualKey(key, static_cast(strlen(key)), + CZString::noDuplication); // NOTE! ObjectValues::iterator it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1089,15 +1101,14 @@ Value& Value::resolveReference(const char* key) { } // @param key is not null-terminated. -Value& Value::resolveReference(char const* key, char const* cend) -{ +Value& Value::resolveReference(char const* key, char const* cend) { JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::resolveReference(key, end): requires objectValue"); if (type_ == nullValue) *this = Value(objectValue); - CZString actualKey( - key, static_cast(cend-key), CZString::duplicateOnCopy); + CZString actualKey(key, static_cast(cend - key), + CZString::duplicateOnCopy); ObjectValues::iterator it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1115,27 +1126,29 @@ Value Value::get(ArrayIndex index, const Value& defaultValue) const { bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } -Value const* Value::find(char const* key, char const* cend) const -{ - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::find(key, end, found): requires objectValue or nullValue"); - if (type_ == nullValue) return NULL; - CZString actualKey(key, static_cast(cend-key), CZString::noDuplication); +Value const* Value::find(char const* key, char const* cend) const { + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + "in Json::Value::find(key, end, found): requires " + "objectValue or nullValue"); + if (type_ == nullValue) + return NULL; + CZString actualKey(key, static_cast(cend - key), + CZString::noDuplication); ObjectValues::const_iterator it = value_.map_->find(actualKey); - if (it == value_.map_->end()) return NULL; + if (it == value_.map_->end()) + return NULL; return &(*it).second; } -const Value& Value::operator[](const char* key) const -{ +const Value& Value::operator[](const char* key) const { Value const* found = find(key, key + strlen(key)); - if (!found) return nullSingleton(); + if (!found) + return nullSingleton(); return *found; } -Value const& Value::operator[](JSONCPP_STRING const& key) const -{ +Value const& Value::operator[](JSONCPP_STRING const& key) const { Value const* found = find(key.data(), key.data() + key.length()); - if (!found) return nullSingleton(); + if (!found) + return nullSingleton(); return *found; } @@ -1155,10 +1168,10 @@ Value& Value::operator[](const StaticString& key) { Value& Value::operator[](const CppTL::ConstString& key) { return resolveReference(key.c_str(), key.end_c_str()); } -Value const& Value::operator[](CppTL::ConstString const& key) const -{ +Value const& Value::operator[](CppTL::ConstString const& key) const { Value const* found = find(key.c_str(), key.end_c_str()); - if (!found) return nullSingleton(); + if (!found) + return nullSingleton(); return *found; } #endif @@ -1166,30 +1179,30 @@ Value const& Value::operator[](CppTL::ConstString const& key) const Value& Value::append(const Value& value) { return (*this)[size()] = value; } #if JSON_HAS_RVALUE_REFERENCES - Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); } +Value& Value::append(Value&& value) { + return (*this)[size()] = std::move(value); +} #endif -Value Value::get(char const* key, char const* cend, Value const& defaultValue) const -{ +Value Value::get(char const* key, + char const* cend, + Value const& defaultValue) const { Value const* found = find(key, cend); return !found ? defaultValue : *found; } -Value Value::get(char const* key, Value const& defaultValue) const -{ +Value Value::get(char const* key, Value const& defaultValue) const { return get(key, key + strlen(key), defaultValue); } -Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const -{ +Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const { return get(key.data(), key.data() + key.length(), defaultValue); } - -bool Value::removeMember(const char* key, const char* cend, Value* removed) -{ +bool Value::removeMember(const char* key, const char* cend, Value* removed) { if (type_ != objectValue) { return false; } - CZString actualKey(key, static_cast(cend-key), CZString::noDuplication); + CZString actualKey(key, static_cast(cend - key), + CZString::noDuplication); ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; @@ -1202,16 +1215,13 @@ bool Value::removeMember(const char* key, const char* cend, Value* removed) value_.map_->erase(it); return true; } -bool Value::removeMember(const char* key, Value* removed) -{ +bool Value::removeMember(const char* key, Value* removed) { return removeMember(key, key + strlen(key), removed); } -bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) -{ +bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) { return removeMember(key.data(), key.data() + key.length(), removed); } -void Value::removeMember(const char* key) -{ +void Value::removeMember(const char* key) { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, "in Json::Value::removeMember(): requires objectValue"); if (type_ == nullValue) @@ -1220,8 +1230,7 @@ void Value::removeMember(const char* key) CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); value_.map_->erase(actualKey); } -void Value::removeMember(const JSONCPP_STRING& key) -{ +void Value::removeMember(const JSONCPP_STRING& key) { removeMember(key.c_str()); } @@ -1237,7 +1246,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { *removed = it->second; ArrayIndex oldSize = size(); // shift left all items left, into the place of the "removed" - for (ArrayIndex i = index; i < (oldSize - 1); ++i){ + for (ArrayIndex i = index; i < (oldSize - 1); ++i) { CZString keey(i); (*value_.map_)[keey] = (*this)[i + 1]; } @@ -1255,17 +1264,14 @@ Value Value::get(const CppTL::ConstString& key, } #endif -bool Value::isMember(char const* key, char const* cend) const -{ +bool Value::isMember(char const* key, char const* cend) const { Value const* value = find(key, cend); return NULL != value; } -bool Value::isMember(char const* key) const -{ +bool Value::isMember(char const* key) const { return isMember(key, key + strlen(key)); } -bool Value::isMember(JSONCPP_STRING const& key) const -{ +bool Value::isMember(JSONCPP_STRING const& key) const { return isMember(key.data(), key.data() + key.length()); } @@ -1286,8 +1292,7 @@ Value::Members Value::getMemberNames() const { ObjectValues::const_iterator it = value_.map_->begin(); ObjectValues::const_iterator itEnd = value_.map_->end(); for (; it != itEnd; ++it) { - members.push_back(JSONCPP_STRING((*it).first.data(), - (*it).first.length())); + members.push_back(JSONCPP_STRING((*it).first.data(), (*it).first.length())); } return members; } @@ -1410,25 +1415,29 @@ bool Value::isUInt64() const { bool Value::isIntegral() const { switch (type_) { - case intValue: - case uintValue: - return true; - case realValue: + case intValue: + case uintValue: + return true; + case realValue: #if defined(JSON_HAS_INT64) - // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a - // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we - // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return value_.real_ >= double(minInt64) && + value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); #else - return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_); + return value_.real_ >= minInt && value_.real_ <= maxUInt && + IsIntegral(value_.real_); #endif // JSON_HAS_INT64 - default: - break; + default: + break; } return false; } -bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; } +bool Value::isDouble() const { + return type_ == intValue || type_ == uintValue || type_ == realValue; +} bool Value::isNumeric() const { return isDouble(); } @@ -1438,10 +1447,12 @@ bool Value::isArray() const { return type_ == arrayValue; } bool Value::isObject() const { return type_ == objectValue; } -void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { +void Value::setComment(const char* comment, + size_t len, + CommentPlacement placement) { if (!comments_) comments_ = new CommentInfo[numberOfCommentPlacement]; - if ((len > 0) && (comment[len-1] == '\n')) { + if ((len > 0) && (comment[len - 1] == '\n')) { // Always discard trailing newline, to aid indentation. len -= 1; } @@ -1452,7 +1463,8 @@ void Value::setComment(const char* comment, CommentPlacement placement) { setComment(comment, strlen(comment), placement); } -void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) { +void Value::setComment(const JSONCPP_STRING& comment, + CommentPlacement placement) { setComment(comment.c_str(), comment.length(), placement); } diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 30c6833b1..95e7b1c49 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -4,76 +4,77 @@ // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) -#include #include "json_tool.h" +#include #endif // if !defined(JSON_IS_AMALGAMATION) +#include +#include #include #include +#include #include #include -#include -#include -#include #if __cplusplus >= 201103L - #include - #include +#include +#include - #if !defined(isnan) - #define isnan std::isnan - #endif +#if !defined(isnan) +#define isnan std::isnan +#endif - #if !defined(isfinite) - #define isfinite std::isfinite - #endif +#if !defined(isfinite) +#define isfinite std::isfinite +#endif - #if !defined(snprintf) - #define snprintf std::snprintf - #endif +#if !defined(snprintf) +#define snprintf std::snprintf +#endif #else - #include - #include - - #if defined(_MSC_VER) - #if !defined(isnan) - #include - #define isnan _isnan - #endif - - #if !defined(isfinite) - #include - #define isfinite _finite - #endif - - #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 - #if !defined(snprintf) - #define snprintf _snprintf - #endif - #endif - - #if defined(__sun) && defined(__SVR4) //Solaris - #if !defined(isfinite) - #include - #define isfinite finite - #endif - #endif - - #if defined(__hpux) - #if !defined(isfinite) - #if defined(__ia64) && !defined(finite) - #define isfinite(x) ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) - #endif - #endif - #endif - - #if !defined(isnan) - // IEEE standard states that NaN values will not compare to themselves - #define isnan(x) (x!=x) - #endif - - #if !defined(isfinite) - #define isfinite finite - #endif +#include +#include + +#if defined(_MSC_VER) +#if !defined(isnan) +#include +#define isnan _isnan +#endif + +#if !defined(isfinite) +#include +#define isfinite _finite +#endif + +#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 +#if !defined(snprintf) +#define snprintf _snprintf +#endif +#endif + +#if defined(__sun) && defined(__SVR4) // Solaris +#if !defined(isfinite) +#include +#define isfinite finite +#endif +#endif + +#if defined(__hpux) +#if !defined(isfinite) +#if defined(__ia64) && !defined(finite) +#define isfinite(x) \ + ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) +#endif +#endif +#endif + +#if !defined(isnan) +// IEEE standard states that NaN values will not compare to themselves +#define isnan(x) (x != x) +#endif + +#if !defined(isfinite) +#define isfinite finite +#endif #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 @@ -86,7 +87,7 @@ namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr StreamWriterPtr; #else -typedef std::auto_ptr StreamWriterPtr; +typedef std::auto_ptr StreamWriterPtr; #endif JSONCPP_STRING valueToString(LargestInt value) { @@ -126,30 +127,34 @@ JSONCPP_STRING valueToString(UInt value) { #endif // # if defined(JSON_HAS_INT64) namespace { -JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) { +JSONCPP_STRING valueToString(double value, + bool useSpecialFloats, + unsigned int precision, + PrecisionType precisionType) { // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. if (!isfinite(value)) { - static const char* const reps[2][3] = { - {"NaN", "-Infinity", "Infinity"}, - {"null", "-1e+9999", "1e+9999"}}; - return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 : (value < 0) ? 1 : 2]; + static const char* const reps[2][3] = { { "NaN", "-Infinity", "Infinity" }, + { "null", "-1e+9999", "1e+9999" } }; + return reps[useSpecialFloats ? 0 : 1] + [isnan(value) ? 0 : (value < 0) ? 1 : 2]; } JSONCPP_STRING buffer(size_t(36), '\0'); while (true) { - int len = snprintf(&*buffer.begin(), buffer.size(), - (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", - precision, value); - assert(len >= 0); - size_t wouldPrint = static_cast(len); - if (wouldPrint >= buffer.size()) { - buffer.resize(wouldPrint + 1); - continue; - } - buffer.resize(wouldPrint); - break; + int len = snprintf( + &*buffer.begin(), buffer.size(), + (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", + precision, value); + assert(len >= 0); + size_t wouldPrint = static_cast(len); + if (wouldPrint >= buffer.size()) { + buffer.resize(wouldPrint + 1); + continue; + } + buffer.resize(wouldPrint); + break; } buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); @@ -159,15 +164,18 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); } - // try to ensure we preserve the fact that this was given to us as a double on input + // try to ensure we preserve the fact that this was given to us as a double on + // input if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { buffer += ".0"; } return buffer; } -} // namespace +} // namespace -JSONCPP_STRING valueToString(double value, unsigned int precision, PrecisionType precisionType) { +JSONCPP_STRING valueToString(double value, + unsigned int precision, + PrecisionType precisionType) { return valueToString(value, false, precision, precisionType); } @@ -178,8 +186,8 @@ static bool isAnyCharRequiredQuoting(char const* s, size_t n) { char const* const end = s + n; for (char const* cur = s; cur < end; ++cur) { - if (*cur == '\\' || *cur == '\"' || *cur < ' ' - || static_cast(*cur) < 0x80) + if (*cur == '\\' || *cur == '\"' || *cur < ' ' || + static_cast(*cur) < 0x80) return true; } return false; @@ -197,8 +205,8 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { if (e - s < 2) return REPLACEMENT_CHARACTER; - unsigned int calculated = ((firstByte & 0x1F) << 6) - | (static_cast(s[1]) & 0x3F); + unsigned int calculated = + ((firstByte & 0x1F) << 6) | (static_cast(s[1]) & 0x3F); s += 1; // oversized encoded characters are invalid return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated; @@ -208,9 +216,9 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { if (e - s < 3) return REPLACEMENT_CHARACTER; - unsigned int calculated = ((firstByte & 0x0F) << 12) - | ((static_cast(s[1]) & 0x3F) << 6) - | (static_cast(s[2]) & 0x3F); + unsigned int calculated = ((firstByte & 0x0F) << 12) | + ((static_cast(s[1]) & 0x3F) << 6) | + (static_cast(s[2]) & 0x3F); s += 2; // surrogates aren't valid codepoints itself // shouldn't be UTF-8 encoded @@ -224,10 +232,10 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { if (e - s < 4) return REPLACEMENT_CHARACTER; - unsigned int calculated = ((firstByte & 0x07) << 18) - | ((static_cast(s[1]) & 0x3F) << 12) - | ((static_cast(s[2]) & 0x3F) << 6) - | (static_cast(s[3]) & 0x3F); + unsigned int calculated = ((firstByte & 0x07) << 18) | + ((static_cast(s[1]) & 0x3F) << 12) | + ((static_cast(s[2]) & 0x3F) << 6) | + (static_cast(s[3]) & 0x3F); s += 3; // oversized encoded characters are invalid return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated; @@ -236,23 +244,22 @@ static unsigned int utf8ToCodepoint(const char*& s, const char* e) { return REPLACEMENT_CHARACTER; } -static const char hex2[] = - "000102030405060708090a0b0c0d0e0f" - "101112131415161718191a1b1c1d1e1f" - "202122232425262728292a2b2c2d2e2f" - "303132333435363738393a3b3c3d3e3f" - "404142434445464748494a4b4c4d4e4f" - "505152535455565758595a5b5c5d5e5f" - "606162636465666768696a6b6c6d6e6f" - "707172737475767778797a7b7c7d7e7f" - "808182838485868788898a8b8c8d8e8f" - "909192939495969798999a9b9c9d9e9f" - "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" - "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" - "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" - "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" - "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" - "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; +static const char hex2[] = "000102030405060708090a0b0c0d0e0f" + "101112131415161718191a1b1c1d1e1f" + "202122232425262728292a2b2c2d2e2f" + "303132333435363738393a3b3c3d3e3f" + "404142434445464748494a4b4c4d4e4f" + "505152535455565758595a5b5c5d5e5f" + "606162636465666768696a6b6c6d6e6f" + "707172737475767778797a7b7c7d7e7f" + "808182838485868788898a8b8c8d8e8f" + "909192939495969798999a9b9c9d9e9f" + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf" + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf" + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf" + "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; static JSONCPP_STRING toHex16Bit(unsigned int x) { const unsigned int hi = (x >> 8) & 0xff; @@ -274,8 +281,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { // We have to walk value and escape any special characters. // Appending to JSONCPP_STRING is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - JSONCPP_STRING::size_type maxsize = - length * 2 + 3; // allescaped+quotes+NULL + JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL JSONCPP_STRING result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; @@ -312,25 +318,23 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { // Should add a flag to allow this compatibility mode and prevent this // sequence from occurring. default: { - unsigned int cp = utf8ToCodepoint(c, end); - // don't escape non-control characters - // (short escape sequence are applied above) - if (cp < 0x80 && cp >= 0x20) - result += static_cast(cp); - else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane - result += "\\u"; - result += toHex16Bit(cp); - } - else { // codepoint is not in Basic Multilingual Plane + unsigned int cp = utf8ToCodepoint(c, end); + // don't escape non-control characters + // (short escape sequence are applied above) + if (cp < 0x80 && cp >= 0x20) + result += static_cast(cp); + else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane + result += "\\u"; + result += toHex16Bit(cp); + } else { // codepoint is not in Basic Multilingual Plane // convert to surrogate pair first - cp -= 0x10000; - result += "\\u"; - result += toHex16Bit((cp >> 10) + 0xD800); - result += "\\u"; - result += toHex16Bit((cp & 0x3FF) + 0xDC00); - } + cp -= 0x10000; + result += "\\u"; + result += toHex16Bit((cp >> 10) + 0xD800); + result += "\\u"; + result += toHex16Bit((cp & 0x3FF) + 0xDC00); } - break; + } break; } } result += "\""; @@ -381,13 +385,13 @@ void FastWriter::writeValue(const Value& value) { case realValue: document_ += valueToString(value.asDouble()); break; - case stringValue: - { + case stringValue: { // Is NULL possible for value.string_? No. char const* str; char const* end; bool ok = value.getString(&str, &end); - if (ok) document_ += valueToQuotedStringN(str, static_cast(end-str)); + if (ok) + document_ += valueToQuotedStringN(str, static_cast(end - str)); break; } case booleanValue: @@ -411,7 +415,8 @@ void FastWriter::writeValue(const Value& value) { const JSONCPP_STRING& name = *it; if (it != members.begin()) document_ += ','; - document_ += valueToQuotedStringN(name.data(), static_cast(name.length())); + document_ += valueToQuotedStringN(name.data(), + static_cast(name.length())); document_ += yamlCompatibilityEnabled_ ? ": " : ":"; writeValue(value[name]); } @@ -451,14 +456,15 @@ void StyledWriter::writeValue(const Value& value) { case realValue: pushValue(valueToString(value.asDouble())); break; - case stringValue: - { + case stringValue: { // Is NULL possible for value.string_? No. char const* str; char const* end; bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); - else pushValue(""); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast(end - str))); + else + pushValue(""); break; } case booleanValue: @@ -546,7 +552,7 @@ bool StyledWriter::isMultilineArray(const Value& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { @@ -589,7 +595,9 @@ void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) { document_ += value; } -void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); } +void StyledWriter::indent() { + indentString_ += JSONCPP_STRING(indentSize_, ' '); +} void StyledWriter::unindent() { assert(indentString_.size() >= indentSize_); @@ -606,8 +614,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) { JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { document_ += *iter; - if (*iter == '\n' && - ((iter+1) != comment.end() && *(iter + 1) == '/')) + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) writeIndent(); ++iter; } @@ -638,8 +645,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) { StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) : document_(NULL), rightMargin_(74), indentation_(indentation), - addChildValues_(), indented_(false) -{} + addChildValues_(), indented_(false) {} void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { document_ = &out; @@ -647,7 +653,8 @@ void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { indentString_.clear(); indented_ = true; writeCommentBeforeValue(root); - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); indented_ = true; writeValue(root); writeCommentAfterValueOnSameLine(root); @@ -669,14 +676,15 @@ void StyledStreamWriter::writeValue(const Value& value) { case realValue: pushValue(valueToString(value.asDouble())); break; - case stringValue: - { + case stringValue: { // Is NULL possible for value.string_? No. char const* str; char const* end; bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); - else pushValue(""); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast(end - str))); + else + pushValue(""); break; } case booleanValue: @@ -731,7 +739,8 @@ void StyledStreamWriter::writeArrayValue(const Value& value) { if (hasChildValue) writeWithIndent(childValues_[index]); else { - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); indented_ = true; writeValue(childValue); indented_ = false; @@ -766,7 +775,7 @@ bool StyledStreamWriter::isMultilineArray(const Value& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { @@ -802,7 +811,8 @@ void StyledStreamWriter::writeIndent() { } void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) { - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); *document_ << value; indented_ = false; } @@ -818,13 +828,13 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { if (!root.hasComment(commentBefore)) return; - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { *document_ << *iter; - if (*iter == '\n' && - ((iter+1) != comment.end() && *(iter + 1) == '/')) + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) // writeIndent(); // would include newline *document_ << indentString_; ++iter; @@ -856,24 +866,23 @@ bool StyledStreamWriter::hasCommentForValue(const Value& value) { struct CommentStyle { /// Decide whether to write comments. enum Enum { - None, ///< Drop all comments. - Most, ///< Recover odd behavior of previous versions (not implemented yet). - All ///< Keep all comments. + None, ///< Drop all comments. + Most, ///< Recover odd behavior of previous versions (not implemented yet). + All ///< Keep all comments. }; }; -struct BuiltStyledStreamWriter : public StreamWriter -{ - BuiltStyledStreamWriter( - JSONCPP_STRING const& indentation, - CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType); +struct BuiltStyledStreamWriter : public StreamWriter { + BuiltStyledStreamWriter(JSONCPP_STRING const& indentation, + CommentStyle::Enum cs, + JSONCPP_STRING const& colonSymbol, + JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, + bool useSpecialFloats, + unsigned int precision, + PrecisionType precisionType); int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE; + private: void writeValue(Value const& value); void writeArrayValue(Value const& value); @@ -904,35 +913,27 @@ struct BuiltStyledStreamWriter : public StreamWriter PrecisionType precisionType_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( - JSONCPP_STRING const& indentation, - CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType) - : rightMargin_(74) - , indentation_(indentation) - , cs_(cs) - , colonSymbol_(colonSymbol) - , nullSymbol_(nullSymbol) - , endingLineFeedSymbol_(endingLineFeedSymbol) - , addChildValues_(false) - , indented_(false) - , useSpecialFloats_(useSpecialFloats) - , precision_(precision) - , precisionType_(precisionType) -{ -} -int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) -{ + JSONCPP_STRING const& indentation, + CommentStyle::Enum cs, + JSONCPP_STRING const& colonSymbol, + JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, + bool useSpecialFloats, + unsigned int precision, + PrecisionType precisionType) + : rightMargin_(74), indentation_(indentation), cs_(cs), + colonSymbol_(colonSymbol), nullSymbol_(nullSymbol), + endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false), + indented_(false), useSpecialFloats_(useSpecialFloats), + precision_(precision), precisionType_(precisionType) {} +int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { sout_ = sout; addChildValues_ = false; indented_ = true; indentString_.clear(); writeCommentBeforeValue(root); - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); indented_ = true; writeValue(root); writeCommentAfterValueOnSameLine(root); @@ -952,16 +953,18 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { pushValue(valueToString(value.asLargestUInt())); break; case realValue: - pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, precisionType_)); + pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_, + precisionType_)); break; - case stringValue: - { + case stringValue: { // Is NULL is possible for value.string_? No. char const* str; char const* end; bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast(end-str))); - else pushValue(""); + if (ok) + pushValue(valueToQuotedStringN(str, static_cast(end - str))); + else + pushValue(""); break; } case booleanValue: @@ -982,7 +985,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { JSONCPP_STRING const& name = *it; Value const& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedStringN(name.data(), static_cast(name.length()))); + writeWithIndent(valueToQuotedStringN( + name.data(), static_cast(name.length()))); *sout_ << colonSymbol_; writeValue(childValue); if (++it == members.end()) { @@ -1016,7 +1020,8 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { if (hasChildValue) writeWithIndent(childValues_[index]); else { - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); indented_ = true; writeValue(childValue); indented_ = false; @@ -1034,13 +1039,15 @@ void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { { assert(childValues_.size() == size); *sout_ << "["; - if (!indentation_.empty()) *sout_ << " "; + if (!indentation_.empty()) + *sout_ << " "; for (unsigned index = 0; index < size; ++index) { if (index > 0) *sout_ << ((!indentation_.empty()) ? ", " : ","); *sout_ << childValues_[index]; } - if (!indentation_.empty()) *sout_ << " "; + if (!indentation_.empty()) + *sout_ << " "; *sout_ << "]"; } } @@ -1053,7 +1060,7 @@ bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { Value const& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { @@ -1093,7 +1100,8 @@ void BuiltStyledStreamWriter::writeIndent() { } void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) { - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); *sout_ << value; indented_ = false; } @@ -1106,17 +1114,18 @@ void BuiltStyledStreamWriter::unindent() { } void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { - if (cs_ == CommentStyle::None) return; + if (cs_ == CommentStyle::None) + return; if (!root.hasComment(commentBefore)) return; - if (!indented_) writeIndent(); + if (!indented_) + writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { *sout_ << *iter; - if (*iter == '\n' && - ((iter+1) != comment.end() && *(iter + 1) == '/')) + if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) // writeIndent(); // would write extra newline *sout_ << indentString_; ++iter; @@ -1124,8 +1133,10 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { indented_ = false; } -void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) { - if (cs_ == CommentStyle::None) return; +void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine( + Value const& root) { + if (cs_ == CommentStyle::None) + return; if (root.hasComment(commentAfterOnSameLine)) *sout_ << " " + root.getComment(commentAfterOnSameLine); @@ -1145,29 +1156,18 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { /////////////// // StreamWriter -StreamWriter::StreamWriter() - : sout_(NULL) -{ -} -StreamWriter::~StreamWriter() -{ -} -StreamWriter::Factory::~Factory() -{} -StreamWriterBuilder::StreamWriterBuilder() -{ - setDefaults(&settings_); -} -StreamWriterBuilder::~StreamWriterBuilder() -{} -StreamWriter* StreamWriterBuilder::newStreamWriter() const -{ +StreamWriter::StreamWriter() : sout_(NULL) {} +StreamWriter::~StreamWriter() {} +StreamWriter::Factory::~Factory() {} +StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } +StreamWriterBuilder::~StreamWriterBuilder() {} +StreamWriter* StreamWriterBuilder::newStreamWriter() const { JSONCPP_STRING indentation = settings_["indentation"].asString(); JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); JSONCPP_STRING pt_str = settings_["precisionType"].asString(); bool eyc = settings_["enableYAMLCompatibility"].asBool(); bool dnp = settings_["dropNullPlaceholders"].asBool(); - bool usf = settings_["useSpecialFloats"].asBool(); + bool usf = settings_["useSpecialFloats"].asBool(); unsigned int pre = settings_["precision"].asUInt(); CommentStyle::Enum cs = CommentStyle::All; if (cs_str == "All") { @@ -1195,14 +1195,14 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const if (dnp) { nullSymbol.clear(); } - if (pre > 17) pre = 17; + if (pre > 17) + pre = 17; JSONCPP_STRING endingLineFeedSymbol; - return new BuiltStyledStreamWriter( - indentation, cs, - colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType); + return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, + endingLineFeedSymbol, usf, pre, + precisionType); } -static void getValidWriterKeys(std::set* valid_keys) -{ +static void getValidWriterKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("indentation"); valid_keys->insert("commentStyle"); @@ -1212,10 +1212,10 @@ static void getValidWriterKeys(std::set* valid_keys) valid_keys->insert("precision"); valid_keys->insert("precisionType"); } -bool StreamWriterBuilder::validate(Json::Value* invalid) const -{ +bool StreamWriterBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + if (!invalid) + invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; std::set valid_keys; getValidWriterKeys(&valid_keys); @@ -1229,13 +1229,11 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const } return 0u == inv.size(); } -Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) -{ +Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) { return settings_[key]; } // static -void StreamWriterBuilder::setDefaults(Json::Value* settings) -{ +void StreamWriterBuilder::setDefaults(Json::Value* settings) { //! [StreamWriterBuilderDefaults] (*settings)["commentStyle"] = "All"; (*settings)["indentation"] = "\t"; @@ -1247,7 +1245,8 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) //! [StreamWriterBuilderDefaults] } -JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) { +JSONCPP_STRING writeString(StreamWriter::Factory const& builder, + Value const& root) { JSONCPP_OSTRINGSTREAM sout; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 94a0672b8..7ca58c331 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -93,8 +93,8 @@ TestResult::addFailure(const char* file, unsigned int line, const char* expr) { if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext { lastUsedPredicateId_ = lastNode->id_; - addFailureInfo( - lastNode->file_, lastNode->line_, lastNode->expr_, nestingLevel); + addFailureInfo(lastNode->file_, lastNode->line_, lastNode->expr_, + nestingLevel); // Link the PredicateContext to the failure for message target when // popping the PredicateContext. lastNode->failure_ = &(failures_.back()); @@ -180,7 +180,7 @@ void TestResult::printFailure(bool printTestName) const { } JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text, - const JSONCPP_STRING& indent) { + const JSONCPP_STRING& indent) { JSONCPP_STRING reindented; JSONCPP_STRING::size_type lastIndex = 0; while (lastIndex < text.size()) { @@ -257,8 +257,7 @@ void Runner::runTestAt(unsigned int index, TestResult& result) const { #endif // if JSON_USE_EXCEPTION test->run(result); #if JSON_USE_EXCEPTION - } - catch (const std::exception& e) { + } catch (const std::exception& e) { result.addFailure(__FILE__, __LINE__, "Unexpected exception caught:") << e.what(); } @@ -294,9 +293,7 @@ bool Runner::runAllTest(bool printSummary) const { if (printSummary) { unsigned int failedCount = static_cast(failures.size()); unsigned int passedCount = count - failedCount; - printf("%d/%d tests passed (%d failure(s))\n", - passedCount, - count, + printf("%d/%d tests passed (%d failure(s))\n", passedCount, count, failedCount); } return false; @@ -398,8 +395,8 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) -// @todo investigate this handler (for buffer overflow) -// _set_security_error_handler + // @todo investigate this handler (for buffer overflow) + // _set_security_error_handler #if defined(_WIN32) // Prevents the system from popping a dialog for debugging if the @@ -430,9 +427,7 @@ JSONCPP_STRING ToJsonString(const char* toConvert) { return JSONCPP_STRING(toConvert); } -JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { - return in; -} +JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { return in; } #if JSONCPP_USING_SECURE_MEMORY JSONCPP_STRING ToJsonString(std::string in) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index dd3285198..6288d5bd1 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -6,12 +6,12 @@ #ifndef JSONTEST_H_INCLUDED #define JSONTEST_H_INCLUDED +#include #include #include #include -#include -#include #include +#include #include // ////////////////////////////////////////////////////////////////// @@ -104,7 +104,7 @@ class TestResult { const char* expr, unsigned int nestingLevel); static JSONCPP_STRING indentText(const JSONCPP_STRING& text, - const JSONCPP_STRING& indent); + const JSONCPP_STRING& indent); typedef std::deque Failures; Failures failures_; @@ -212,7 +212,7 @@ TestResult& checkStringEqual(TestResult& result, #define JSONTEST_ASSERT(expr) \ if (expr) { \ } else \ - result_->addFailure(__FILE__, __LINE__, #expr) + result_->addFailure(__FILE__, __LINE__, #expr) /// \brief Asserts that the given predicate is true. /// The predicate may do other assertions and be a member function of the @@ -231,21 +231,14 @@ TestResult& checkStringEqual(TestResult& result, /// \brief Asserts that two values are equals. #define JSONTEST_ASSERT_EQUAL(expected, actual) \ - JsonTest::checkEqual(*result_, \ - expected, \ - actual, \ - __FILE__, \ - __LINE__, \ + JsonTest::checkEqual(*result_, expected, actual, __FILE__, __LINE__, \ #expected " == " #actual) /// \brief Asserts that two values are equals. #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \ - JsonTest::checkStringEqual(*result_, \ - JsonTest::ToJsonString(expected), \ - JsonTest::ToJsonString(actual), \ - __FILE__, \ - __LINE__, \ - #expected " == " #actual) + JsonTest::checkStringEqual(*result_, JsonTest::ToJsonString(expected), \ + JsonTest::ToJsonString(actual), __FILE__, \ + __LINE__, #expected " == " #actual) /// \brief Asserts that a given expression throws an exception #define JSONTEST_ASSERT_THROWS(expr) \ @@ -253,13 +246,12 @@ TestResult& checkStringEqual(TestResult& result, bool _threw = false; \ try { \ expr; \ - } \ - catch (...) { \ + } catch (...) { \ _threw = true; \ } \ if (!_threw) \ - result_->addFailure( \ - __FILE__, __LINE__, "expected exception thrown: " #expr); \ + result_->addFailure(__FILE__, __LINE__, \ + "expected exception thrown: " #expr); \ } /// \brief Begin a fixture test case. @@ -270,9 +262,11 @@ TestResult& checkStringEqual(TestResult& result, return new Test##FixtureType##name(); \ } \ \ - public: /* overridden from TestCase */ \ - const char* testName() const JSONCPP_OVERRIDE { return #FixtureType "/" #name; } \ - void runTestCase() JSONCPP_OVERRIDE; \ + public: /* overridden from TestCase */ \ + const char* testName() const JSONCPP_OVERRIDE { \ + return #FixtureType "/" #name; \ + } \ + void runTestCase() JSONCPP_OVERRIDE; \ }; \ \ void Test##FixtureType##name::runTestCase() diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index a0c26ebef..37dbdd666 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -11,14 +11,14 @@ #endif #include "jsontest.h" +#include +#include +#include #include #include -#include #include #include #include -#include -#include // Make numeric limits more convenient to talk about. // Assumes int type in 32 bits. @@ -29,8 +29,8 @@ #define kint64min Json::Value::minInt64 #define kuint64max Json::Value::maxUInt64 -//static const double kdint64max = double(kint64max); -//static const float kfint64max = float(kint64max); +// static const double kdint64max = double(kint64max); +// static const float kfint64max = float(kint64max); static const float kfint32max = float(kint32max); static const float kfuint32max = float(kuint32max); @@ -123,8 +123,8 @@ JSONCPP_STRING ValueTest::normalizeFloatingPointStr(const JSONCPP_STRING& s) { JSONCPP_STRING::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); JSONCPP_STRING exponent = "0"; - if (indexDigit != - JSONCPP_STRING::npos) // There is an exponent different from 0 + if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different + // from 0 { exponent = s.substr(indexDigit); } @@ -269,19 +269,17 @@ JSONTEST_FIXTURE(ValueTest, arrays) { JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } -JSONTEST_FIXTURE(ValueTest, arrayIssue252) -{ +JSONTEST_FIXTURE(ValueTest, arrayIssue252) { int count = 5; Json::Value root; Json::Value item; root["array"] = Json::Value::nullRef; - for (int i = 0; i < count; i++) - { + for (int i = 0; i < count; i++) { item["a"] = i; item["b"] = i; root["array"][i] = item; } - //JSONTEST_ASSERT_EQUAL(5, root["array"].size()); + // JSONTEST_ASSERT_EQUAL(5, root["array"].size()); } JSONTEST_FIXTURE(ValueTest, null) { @@ -311,10 +309,10 @@ JSONTEST_FIXTURE(ValueTest, null) { JSONTEST_ASSERT_EQUAL(Json::Value::null, null_); // Test using a Value in a boolean context (false iff null) - JSONTEST_ASSERT_EQUAL(null_,false); - JSONTEST_ASSERT_EQUAL(object1_,true); - JSONTEST_ASSERT_EQUAL(!null_,true); - JSONTEST_ASSERT_EQUAL(!object1_,false); + JSONTEST_ASSERT_EQUAL(null_, false); + JSONTEST_ASSERT_EQUAL(object1_, true); + JSONTEST_ASSERT_EQUAL(!null_, true); + JSONTEST_ASSERT_EQUAL(!object1_, false); } JSONTEST_FIXTURE(ValueTest, strings) { @@ -660,8 +658,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL((1 << 20), val.asDouble()); JSONTEST_ASSERT_EQUAL((1 << 20), val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("1048576.0", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1048576.0", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // -2^20 val = Json::Value(-(1 << 20)); @@ -901,8 +900,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asDouble()); JSONTEST_ASSERT_EQUAL((Json::Int64(1) << 40), val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("1099511627776.0", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1099511627776.0", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // -2^40 val = Json::Value(-(Json::Int64(1) << 40)); @@ -976,8 +976,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(float(Json::UInt64(1) << 63), val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("9.2233720368547758e+18", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "9.2233720368547758e+18", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // int64 min val = Json::Value(Json::Int64(kint64min)); @@ -1024,8 +1025,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble()); JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("-9.2233720368547758e+18", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "-9.2233720368547758e+18", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // 10^19 const Json::UInt64 ten_to_19 = static_cast(1e19); @@ -1071,8 +1073,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(1e19, val.asDouble()); JSONTEST_ASSERT_EQUAL(1e19, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("1e+19", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1e+19", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // uint64 max val = Json::Value(Json::UInt64(kuint64max)); @@ -1115,8 +1118,9 @@ JSONTEST_FIXTURE(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asDouble()); JSONTEST_ASSERT_EQUAL(18446744073709551616.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_STRING_EQUAL("1.8446744073709552e+19", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1.8446744073709552e+19", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); #endif } @@ -1205,8 +1209,9 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { JSONTEST_ASSERT_EQUAL(2147483647U, val.asLargestUInt()); #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_EQUAL("2147483647.5", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_EQUAL( + "2147483647.5", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A bit under int32 min val = Json::Value(kint32min - 0.5); @@ -1233,8 +1238,9 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { JSONTEST_ASSERT_EQUAL(-(Json::Int64(1) << 31), val.asLargestInt()); #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_EQUAL("-2147483648.5", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_EQUAL( + "-2147483648.5", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A bit over uint32 max val = Json::Value(kuint32max + 0.5); @@ -1263,30 +1269,35 @@ JSONTEST_FIXTURE(ValueTest, nonIntegers) { val.asLargestUInt()); #endif JSONTEST_ASSERT_EQUAL(true, val.asBool()); - JSONTEST_ASSERT_EQUAL("4294967295.5", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_EQUAL( + "4294967295.5", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); val = Json::Value(1.2345678901234); - JSONTEST_ASSERT_STRING_EQUAL("1.2345678901234001", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1.2345678901234001", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A 16-digit floating point number. val = Json::Value(2199023255552000.0f); JSONTEST_ASSERT_EQUAL(float(2199023255552000.0f), val.asFloat()); - JSONTEST_ASSERT_STRING_EQUAL("2199023255552000.0", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "2199023255552000.0", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // A very large floating point number. val = Json::Value(3.402823466385289e38); JSONTEST_ASSERT_EQUAL(float(3.402823466385289e38), val.asFloat()); - JSONTEST_ASSERT_STRING_EQUAL("3.402823466385289e+38", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "3.402823466385289e+38", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // An even larger floating point number. val = Json::Value(1.2345678e300); JSONTEST_ASSERT_EQUAL(double(1.2345678e300), val.asDouble()); - JSONTEST_ASSERT_STRING_EQUAL("1.2345678e+300", - normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); + JSONTEST_ASSERT_STRING_EQUAL( + "1.2345678e+300", + normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); } void ValueTest::checkConstMemberCount(const Json::Value& value, @@ -1608,7 +1619,8 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { JSONTEST_FIXTURE(ValueTest, CommentBefore) { Json::Value val; // fill val - val.setComment(JSONCPP_STRING("// this comment should appear before"), Json::commentBefore); + val.setComment(JSONCPP_STRING("// this comment should appear before"), + Json::commentBefore); Json::StreamWriterBuilder wbuilder; wbuilder.settings_["commentStyle"] = "All"; { @@ -1635,8 +1647,8 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_ASSERT_STRING_EQUAL("null\n", other.toStyledString()); } val = "hello"; - // val.setComment("// this comment should appear before", Json::CommentPlacement::commentBefore); - // Assignment over-writes comments. + // val.setComment("// this comment should appear before", + // Json::CommentPlacement::commentBefore); Assignment over-writes comments. { char const expected[] = "\"hello\""; JSONCPP_STRING result = Json::writeString(wbuilder, val); @@ -1651,7 +1663,7 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_FIXTURE(ValueTest, zeroes) { char const cstr[] = "h\0i"; - JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 + JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); Json::StreamWriterBuilder b; { @@ -1666,12 +1678,10 @@ JSONTEST_FIXTURE(ValueTest, zeroes) { JSONTEST_ASSERT_STRING_EQUAL(binary, root[top].asString()); Json::Value removed; bool did; - did = root.removeMember(top, top + sizeof(top) - 1U, - &removed); + did = root.removeMember(top, top + sizeof(top) - 1U, &removed); JSONTEST_ASSERT(did); JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); - did = root.removeMember(top, top + sizeof(top) - 1U, - &removed); + did = root.removeMember(top, top + sizeof(top) - 1U, &removed); JSONTEST_ASSERT(!did); JSONTEST_ASSERT_STRING_EQUAL(binary, removed.asString()); // still } @@ -1679,7 +1689,7 @@ JSONTEST_FIXTURE(ValueTest, zeroes) { JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { char const cstr[] = "h\0i"; - JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 + JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); { Json::Value root; @@ -1687,19 +1697,21 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { JSONTEST_ASSERT_STRING_EQUAL("there", root[binary].asString()); JSONTEST_ASSERT(!root.isMember("h")); JSONTEST_ASSERT(root.isMember(binary)); - JSONTEST_ASSERT_STRING_EQUAL("there", root.get(binary, Json::Value::nullRef).asString()); + JSONTEST_ASSERT_STRING_EQUAL( + "there", root.get(binary, Json::Value::nullRef).asString()); Json::Value removed; bool did; did = root.removeMember(binary.data(), binary.data() + binary.length(), - &removed); + &removed); JSONTEST_ASSERT(did); JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); did = root.removeMember(binary.data(), binary.data() + binary.length(), - &removed); + &removed); JSONTEST_ASSERT(!did); JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); // still JSONTEST_ASSERT(!root.isMember(binary)); - JSONTEST_ASSERT_STRING_EQUAL("", root.get(binary, Json::Value::nullRef).asString()); + JSONTEST_ASSERT_STRING_EQUAL( + "", root.get(binary, Json::Value::nullRef).asString()); } } @@ -1724,61 +1736,61 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) { } JSONTEST_FIXTURE(ValueTest, precision) { - Json::StreamWriterBuilder b; - b.settings_["precision"] = 5; + Json::StreamWriterBuilder b; + b.settings_["precision"] = 5; - Json::Value v = 100.0/3; - JSONCPP_STRING expected = "33.333"; - JSONCPP_STRING result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); - - v = 0.25000000; - expected = "0.25"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + Json::Value v = 100.0 / 3; + JSONCPP_STRING expected = "33.333"; + JSONCPP_STRING result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - v = 0.2563456; - expected = "0.25635"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + v = 0.25000000; + expected = "0.25"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 1; - expected = "0.3"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + v = 0.2563456; + expected = "0.25635"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 17; - v = 1234857476305.256345694873740545068; - expected = "1234857476305.2563"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 1; + expected = "0.3"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 24; - v = 0.256345694873740545068; - expected = "0.25634569487374054"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 17; + v = 1234857476305.256345694873740545068; + expected = "1234857476305.2563"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 5; - b.settings_["precisionType"] = "decimal"; - v = 0.256345694873740545068; - expected = "0.25635"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 24; + v = 0.256345694873740545068; + expected = "0.25634569487374054"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 1; - b.settings_["precisionType"] = "decimal"; - v = 0.256345694873740545068; - expected = "0.3"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 5; + b.settings_["precisionType"] = "decimal"; + v = 0.256345694873740545068; + expected = "0.25635"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); - b.settings_["precision"] = 10; - b.settings_["precisionType"] = "decimal"; - v = 0.23300000; - expected = "0.233"; - result = Json::writeString(b, v); - JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 1; + b.settings_["precisionType"] = "decimal"; + v = 0.256345694873740545068; + expected = "0.3"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 10; + b.settings_["precisionType"] = "decimal"; + v = 0.23300000; + expected = "0.233"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); } struct WriterTest : JsonTest::TestCase {}; @@ -1804,9 +1816,9 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { } JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { - JSONCPP_STRING binary("hi", 3); // include trailing 0 + JSONCPP_STRING binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); - JSONCPP_STRING expected("\"hi\\u0000\""); // unicoded zero + JSONCPP_STRING expected("\"hi\\u0000\""); // unicoded zero Json::StreamWriterBuilder b; { Json::Value root; @@ -1924,9 +1936,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { JSONCPP_STRING errs; Json::Value root; char const doc[] = "{ \"property\" : \"value\" }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.size() == 0); delete reader; @@ -1937,13 +1947,10 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; Json::Value root; - char const doc[] = - "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " - "null, \"false\" : false }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " + "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " + "null, \"false\" : false }"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.size() == 0); delete reader; @@ -1954,11 +1961,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; Json::Value root; - char const doc[] = - "{ \"property\" :: \"value\" }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + char const doc[] = "{ \"property\" :: \"value\" }"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 15\n Syntax error: value, object or array " @@ -1971,11 +1975,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; Json::Value root; - char const doc[] = - "{ \"pr佐藤erty\" :: \"value\" }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 19\n Syntax error: value, object or array " @@ -1988,11 +1989,8 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; Json::Value root; - char const doc[] = - "{ \"property\" : \"v\\alue\" }"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + char const doc[] = "{ \"property\" : \"v\\alue\" }"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 16\n Bad escape sequence in string\nSee " @@ -2003,28 +2001,24 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { Json::CharReaderBuilder b; Json::Value root; - char const doc[] = - "{ \"property\" : \"value\" }"; + char const doc[] = "{ \"property\" : \"value\" }"; { - b.settings_["stackLimit"] = 2; - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL("value", root["property"]); - delete reader; + b.settings_["stackLimit"] = 2; + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT_EQUAL("value", root["property"]); + delete reader; } { - b.settings_["stackLimit"] = 1; - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - JSONTEST_ASSERT_THROWS(reader->parse( - doc, doc + std::strlen(doc), - &root, &errs)); - delete reader; + b.settings_["stackLimit"] = 1; + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + JSONTEST_ASSERT_THROWS( + reader->parse(doc, doc + std::strlen(doc), &root, &errs)); + delete reader; } } @@ -2039,14 +2033,11 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { b.strictMode(&b.settings_); Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL( - "* Line 1, Column 41\n" - " Duplicate key: 'key'\n", - errs); + JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 41\n" + " Duplicate key: 'key'\n", + errs); JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far delete reader; } @@ -2057,67 +2048,56 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { // This is interpreted as a string value followed by a colon. Json::CharReaderBuilder b; Json::Value root; - char const doc[] = - " \"property\" : \"value\" }"; + char const doc[] = " \"property\" : \"value\" }"; { - b.settings_["failIfExtra"] = false; - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; + b.settings_["failIfExtra"] = false; + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } { - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; + b.settings_["failIfExtra"] = true; + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL(errs, + "* Line 1, Column 13\n" + " Extra non-whitespace after JSON value.\n"); + JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } { - b.settings_["failIfExtra"] = false; - b.strictMode(&b.settings_); - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); - JSONTEST_ASSERT_EQUAL("property", root); - delete reader; + b.settings_["failIfExtra"] = false; + b.strictMode(&b.settings_); + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL(errs, + "* Line 1, Column 13\n" + " Extra non-whitespace after JSON value.\n"); + JSONTEST_ASSERT_EQUAL("property", root); + delete reader; } } JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { // This is interpreted as an int value followed by a colon. Json::CharReaderBuilder b; Json::Value root; - char const doc[] = - "1:2:3"; + char const doc[] = "1:2:3"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL( - "* Line 1, Column 2\n" - " Extra non-whitespace after JSON value.\n", - errs); + JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 2\n" + " Extra non-whitespace after JSON value.\n", + errs); JSONTEST_ASSERT_EQUAL(1, root.asInt()); delete reader; } @@ -2125,31 +2105,25 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { Json::CharReaderBuilder b; Json::Value root; { - char const doc[] = - "{ \"property\" : \"value\" } //trailing\n//comment\n"; - b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL("value", root["property"]); - delete reader; + char const doc[] = "{ \"property\" : \"value\" } //trailing\n//comment\n"; + b.settings_["failIfExtra"] = true; + Json::CharReader* reader(b.newCharReader()); + JSONCPP_STRING errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT_STRING_EQUAL("", errs); + JSONTEST_ASSERT_EQUAL("value", root["property"]); + delete reader; } } JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { Json::CharReaderBuilder b; Json::Value root; - char const doc[] = - "[ \"property\" , \"value\" ] //trailing\n//comment\n"; + char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL("value", root[1u]); @@ -2158,14 +2132,11 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { Json::CharReaderBuilder b; Json::Value root; - char const doc[] = - " true /*trailing\ncomment*/"; + char const doc[] = " true /*trailing\ncomment*/"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); JSONCPP_STRING errs; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(true, root.asBool()); @@ -2181,9 +2152,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":,\"b\":true}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); @@ -2191,9 +2160,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { } { char const doc[] = "{\"a\":}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(1u, root.size()); @@ -2201,9 +2168,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { } { char const doc[] = "[]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT_EQUAL(0u, root.size()); @@ -2211,90 +2176,70 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { } { char const doc[] = "[null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT_EQUAL(1u, root.size()); } { char const doc[] = "[,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); } { char const doc[] = "[,,,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(4u, root.size()); } { char const doc[] = "[null,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); } { char const doc[] = "[,null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT_EQUAL(2u, root.size()); } { char const doc[] = "[,,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); } { char const doc[] = "[null,,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); } { char const doc[] = "[,null,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); } { char const doc[] = "[,,null]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT_EQUAL(3u, root.size()); } { char const doc[] = "[[],,,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(4u, root.size()); @@ -2302,9 +2247,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { } { char const doc[] = "[,[],,]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(4u, root.size()); @@ -2312,9 +2255,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { } { char const doc[] = "[,,,[]]"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs == ""); JSONTEST_ASSERT_EQUAL(4u, root.size()); @@ -2333,9 +2274,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); @@ -2344,9 +2283,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { } { char const doc[] = "{'a': 'x', \"b\":'y'}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); @@ -2366,9 +2303,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); @@ -2377,9 +2312,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { } { char const doc[] = "{'a': 'x', \"b\":'y'}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); @@ -2399,16 +2332,16 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(3u, root.size()); double n = root["a"].asDouble(); JSONTEST_ASSERT(std::isnan(n)); - JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), root.get("b", 0.0)); - JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root.get("c", 0.0)); + JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), + root.get("b", 0.0)); + JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), + root.get("c", 0.0)); } struct TestData { @@ -2417,49 +2350,37 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { JSONCPP_STRING in; }; const TestData test_data[] = { - {__LINE__, 1, "{\"a\":9}"}, - {__LINE__, 0, "{\"a\":0Infinity}"}, - {__LINE__, 0, "{\"a\":1Infinity}"}, - {__LINE__, 0, "{\"a\":9Infinity}"}, - {__LINE__, 0, "{\"a\":0nfinity}"}, - {__LINE__, 0, "{\"a\":1nfinity}"}, - {__LINE__, 0, "{\"a\":9nfinity}"}, - {__LINE__, 0, "{\"a\":nfinity}"}, - {__LINE__, 0, "{\"a\":.nfinity}"}, - {__LINE__, 0, "{\"a\":9nfinity}"}, - {__LINE__, 0, "{\"a\":-nfinity}"}, - {__LINE__, 1, "{\"a\":Infinity}"}, - {__LINE__, 0, "{\"a\":.Infinity}"}, - {__LINE__, 0, "{\"a\":_Infinity}"}, - {__LINE__, 0, "{\"a\":_nfinity}"}, - {__LINE__, 1, "{\"a\":-Infinity}"} + { __LINE__, 1, "{\"a\":9}" }, { __LINE__, 0, "{\"a\":0Infinity}" }, + { __LINE__, 0, "{\"a\":1Infinity}" }, { __LINE__, 0, "{\"a\":9Infinity}" }, + { __LINE__, 0, "{\"a\":0nfinity}" }, { __LINE__, 0, "{\"a\":1nfinity}" }, + { __LINE__, 0, "{\"a\":9nfinity}" }, { __LINE__, 0, "{\"a\":nfinity}" }, + { __LINE__, 0, "{\"a\":.nfinity}" }, { __LINE__, 0, "{\"a\":9nfinity}" }, + { __LINE__, 0, "{\"a\":-nfinity}" }, { __LINE__, 1, "{\"a\":Infinity}" }, + { __LINE__, 0, "{\"a\":.Infinity}" }, { __LINE__, 0, "{\"a\":_Infinity}" }, + { __LINE__, 0, "{\"a\":_nfinity}" }, { __LINE__, 1, "{\"a\":-Infinity}" } }; for (size_t tdi = 0; tdi < sizeof(test_data) / sizeof(*test_data); ++tdi) { const TestData& td = test_data[tdi]; - bool ok = reader->parse(&*td.in.begin(), - &*td.in.begin() + td.in.size(), + bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), &root, &errs); - JSONTEST_ASSERT(td.ok == ok) - << "line:" << td.line << "\n" - << " expected: {" - << "ok:" << td.ok - << ", in:\'" << td.in << "\'" - << "}\n" - << " actual: {" - << "ok:" << ok - << "}\n"; + JSONTEST_ASSERT(td.ok == ok) << "line:" << td.line << "\n" + << " expected: {" + << "ok:" << td.ok << ", in:\'" << td.in << "\'" + << "}\n" + << " actual: {" + << "ok:" << ok << "}\n"; } { char const doc[] = "{\"posInf\": Infinity, \"NegInf\": -Infinity}"; - bool ok = reader->parse( - doc, doc + std::strlen(doc), - &root, &errs); + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(2u, root.size()); - JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), root["posInf"].asDouble()); - JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root["NegInf"].asDouble()); + JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), + root["posInf"].asDouble()); + JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), + root["NegInf"].asDouble()); } delete reader; } @@ -2542,13 +2463,12 @@ JSONTEST_FIXTURE(IteratorTest, indexes) { JSONTEST_FIXTURE(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( - Json::Value::iterator it(v.begin()) // Compile, but throw. + Json::Value::iterator it(v.begin()) // Compile, but throw. ); Json::Value value; - for(int i = 9; i < 12; ++i) - { + for (int i = 9; i < 12; ++i) { JSONCPP_OSTRINGSTREAM out; out << std::setw(2) << i; JSONCPP_STRING str = out.str(); @@ -2556,10 +2476,9 @@ JSONTEST_FIXTURE(IteratorTest, const) { } JSONCPP_OSTRINGSTREAM out; - //in old code, this will get a compile error + // in old code, this will get a compile error Json::Value::const_iterator iter = value.begin(); - for(; iter != value.end(); ++iter) - { + for (; iter != value.end(); ++iter) { out << *iter << ','; } JSONCPP_STRING expected = "\" 9\",\"10\",\"11\","; @@ -2573,7 +2492,8 @@ JSONTEST_FIXTURE(RValueTest, moveConstruction) { Json::Value json; json["key"] = "value"; Json::Value moved = std::move(json); - JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not equal. + JSONTEST_ASSERT(moved != json); // Possibly not nullValue; definitely not + // equal. JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type()); JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); #endif @@ -2605,7 +2525,7 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore); - //JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); + // JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats); @@ -2616,15 +2536,15 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE( - runner, ReaderTest, parseWithNoErrorsTestingOffsets); + JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, + parseWithNoErrorsTestingOffsets); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseChineseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithDetailError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE( - runner, CharReaderTest, parseWithNoErrorsTestingOffsets); + JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, + parseWithNoErrorsTestingOffsets); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseChineseWithOneError); JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithDetailError); @@ -2634,9 +2554,12 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue164); JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue107); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterObject); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterArray); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, commentAfterBool); + JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, + commentAfterObject); + JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, + commentAfterArray); + JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, + commentAfterBool); JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178); From 85a263e89f132f26812f8f468b146fb8b8690063 Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 19:38:12 +0300 Subject: [PATCH 043/410] Fix improper format specifier in printf %d in format string requires 'int' but the argument type is 'unsigned int'. --- src/jsontestrunner/main.cpp | 4 ++-- src/test_lib_json/jsontest.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 7105b390f..54ca30296 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -106,9 +106,9 @@ static void printValueTree(FILE* fout, for (Json::ArrayIndex index = 0; index < size; ++index) { static char buffer[16]; #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) - sprintf_s(buffer, sizeof(buffer), "[%d]", index); + sprintf_s(buffer, sizeof(buffer), "[%u]", index); #else - snprintf(buffer, sizeof(buffer), "[%d]", index); + snprintf(buffer, sizeof(buffer), "[%u]", index); #endif printValueTree(fout, value[index], path + buffer); } diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 7ca58c331..ce2380085 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -165,7 +165,7 @@ void TestResult::printFailure(bool printTestName) const { const Failure& failure = *it; JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { - printf("%s%s(%d): ", indent.c_str(), failure.file_, failure.line_); + printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); } if (!failure.expr_.empty()) { printf("%s\n", failure.expr_.c_str()); @@ -281,7 +281,7 @@ bool Runner::runAllTest(bool printSummary) const { if (failures.empty()) { if (printSummary) { - printf("All %d tests passed\n", count); + printf("All %u tests passed\n", count); } return true; } else { @@ -293,7 +293,7 @@ bool Runner::runAllTest(bool printSummary) const { if (printSummary) { unsigned int failedCount = static_cast(failures.size()); unsigned int passedCount = count - failedCount; - printf("%d/%d tests passed (%d failure(s))\n", passedCount, count, + printf("%u/%u tests passed (%u failure(s))\n", passedCount, count, failedCount); } return false; From c8bb600d2729d2588e9af9d6d4a95ff0f59f63dc Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 19:41:57 +0300 Subject: [PATCH 044/410] Pass string as a const reference. --- include/json/writer.h | 2 +- src/lib_json/json_writer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/json/writer.h b/include/json/writer.h index 30424b055..7c9ae21c7 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -300,7 +300,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API /** * \param indentation Each level will be indented by this amount extra. */ - StyledStreamWriter(JSONCPP_STRING indentation = "\t"); + StyledStreamWriter(const JSONCPP_STRING& indentation = "\t"); ~StyledStreamWriter() {} public: diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 95e7b1c49..e0e47ad82 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -643,7 +643,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// -StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) +StyledStreamWriter::StyledStreamWriter(const JSONCPP_STRING& indentation) : document_(NULL), rightMargin_(74), indentation_(indentation), addChildValues_(), indented_(false) {} From 48112c8b626d3930ca748328189955219b81aad0 Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 19:43:31 +0300 Subject: [PATCH 045/410] Make several methods static. --- include/json/value.h | 2 +- include/json/writer.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 06a6c0c01..b94aeec76 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -720,7 +720,7 @@ class JSON_API Path { const InArgs& in, InArgs::const_iterator& itInArg, PathArgument::Kind kind); - void invalidPath(const JSONCPP_STRING& path, int location); + static void invalidPath(const JSONCPP_STRING& path, int location); Args args_; }; diff --git a/include/json/writer.h b/include/json/writer.h index 7c9ae21c7..c92d26b0e 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -249,7 +249,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); - bool hasCommentForValue(const Value& value); + static bool hasCommentForValue(const Value& value); static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); typedef std::vector ChildValues; @@ -323,7 +323,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); - bool hasCommentForValue(const Value& value); + static bool hasCommentForValue(const Value& value); static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); typedef std::vector ChildValues; From a7d0ffc7175c6ee7f1fa937cca5601722b96701e Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 19:46:16 +0300 Subject: [PATCH 046/410] Remove unused private function in TestResult class --- src/test_lib_json/jsontest.cpp | 10 ---------- src/test_lib_json/jsontest.h | 1 - 2 files changed, 11 deletions(-) diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index ce2380085..86ed4c17f 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -140,16 +140,6 @@ TestResult& TestResult::popPredicateContext() { bool TestResult::failed() const { return !failures_.empty(); } -unsigned int TestResult::getAssertionNestingLevel() const { - unsigned int level = 0; - const PredicateContext* lastNode = &rootPredicateNode_; - while (lastNode->next_ != 0) { - lastNode = lastNode->next_; - ++level; - } - return level; -} - void TestResult::printFailure(bool printTestName) const { if (failures_.empty()) { return; diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 6288d5bd1..9d50e90c9 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -97,7 +97,6 @@ class TestResult { private: TestResult& addToLastFailure(const JSONCPP_STRING& message); - unsigned int getAssertionNestingLevel() const; /// Adds a failure or a predicate context void addFailureInfo(const char* file, unsigned int line, From 091e03979d9331702e09cef61472159b8b1556b1 Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 19:48:10 +0300 Subject: [PATCH 047/410] Reduce scope of variable. --- src/lib_json/json_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 0bef78ede..58a1b9aaf 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -706,8 +706,8 @@ bool Reader::decodeUnicodeCodePoint(Token& token, return addError( "additional six characters expected to parse unicode surrogate pair.", token, current); - unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { + unsigned int surrogatePair; if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else @@ -1726,8 +1726,8 @@ bool OurReader::decodeUnicodeCodePoint(Token& token, return addError( "additional six characters expected to parse unicode surrogate pair.", token, current); - unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { + unsigned int surrogatePair; if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else From fc20134c92770fe60db522e0c10c2d6c264f7b50 Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 20:15:26 +0300 Subject: [PATCH 048/410] Fix different names for parameters in declaration and definition --- include/json/value.h | 10 ++++---- src/lib_json/json_reader.cpp | 50 ++++++++++++++++++------------------ src/lib_json/json_value.cpp | 48 +++++++++++++++++----------------- src/lib_json/json_writer.cpp | 4 +-- src/test_lib_json/jsontest.h | 2 +- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index b94aeec76..8a0054cbf 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -427,12 +427,12 @@ Json::Value obj_value(Json::objectValue); // {} /// \post type() is unchanged void clear(); - /// Resize the array to size elements. + /// Resize the array to newSize elements. /// New elements are initialized to null. /// May only be called on nullValue or arrayValue. /// \pre type() is arrayValue or nullValue /// \post type() is arrayValue - void resize(ArrayIndex size); + void resize(ArrayIndex newSize); /// Access an array element (zero based index ). /// If the array contains less than index element, then null value are @@ -562,10 +562,10 @@ Json::Value obj_value(Json::objectValue); // {} /** \brief Remove the indexed array element. O(n) expensive operations. - Update 'removed' iff removed. - \return true iff removed (no exceptions) + Update 'removed' if removed. + \return true if removed (no exceptions) */ - bool removeIndex(ArrayIndex i, Value* removed); + bool removeIndex(ArrayIndex index, Value* removed); /// Return true if the object has a member named key. /// \note 'key' must be null-terminated. diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 58a1b9aaf..7628e71cf 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -112,8 +112,8 @@ bool Reader::parse(const std::string& document, return parse(begin, end, root, collectComments); } -bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { - // std::istream_iterator begin(sin); +bool Reader::parse(std::istream& is, Value& root, bool collectComments) { + // std::istream_iterator begin(is); // std::istream_iterator end; // Those would allow streamed input from a file, if parse() were a // template function. @@ -121,7 +121,7 @@ bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { // Since JSONCPP_STRING is reference-counted, this at least does not // create an extra copy. JSONCPP_STRING doc; - std::getline(sin, doc, (char)EOF); + std::getline(is, doc, (char)EOF); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } @@ -460,12 +460,12 @@ bool Reader::readString() { return c == '"'; } -bool Reader::readObject(Token& tokenStart) { +bool Reader::readObject(Token& token) { Token tokenName; JSONCPP_STRING name; Value init(objectValue); currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); + currentValue().setOffsetStart(token.start_ - begin_); while (readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) @@ -516,10 +516,10 @@ bool Reader::readObject(Token& tokenStart) { tokenObjectEnd); } -bool Reader::readArray(Token& tokenStart) { +bool Reader::readArray(Token& token) { Value init(arrayValue); currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); + currentValue().setOffsetStart(token.start_ - begin_); skipSpaces(); if (current_ != end_ && *current_ == ']') // empty array { @@ -536,19 +536,19 @@ bool Reader::readArray(Token& tokenStart) { if (!ok) // error already set return recoverFromError(tokenArrayEnd); - Token token; + Token currentToken; // Accept Comment after last item in the array. - ok = readToken(token); - while (token.type_ == tokenComment && ok) { - ok = readToken(token); + ok = readToken(currentToken); + while (currentToken.type_ == tokenComment && ok) { + ok = readToken(currentToken); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", - token, tokenArrayEnd); + currentToken, tokenArrayEnd); } - if (token.type_ == tokenArrayEnd) + if (currentToken.type_ == tokenArrayEnd) break; } return true; @@ -1450,12 +1450,12 @@ bool OurReader::readStringSingleQuote() { return c == '\''; } -bool OurReader::readObject(Token& tokenStart) { +bool OurReader::readObject(Token& token) { Token tokenName; JSONCPP_STRING name; Value init(objectValue); currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); + currentValue().setOffsetStart(token.start_ - begin_); while (readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) @@ -1512,10 +1512,10 @@ bool OurReader::readObject(Token& tokenStart) { tokenObjectEnd); } -bool OurReader::readArray(Token& tokenStart) { +bool OurReader::readArray(Token& token) { Value init(arrayValue); currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); + currentValue().setOffsetStart(token.start_ - begin_); skipSpaces(); if (current_ != end_ && *current_ == ']') // empty array { @@ -1532,19 +1532,19 @@ bool OurReader::readArray(Token& tokenStart) { if (!ok) // error already set return recoverFromError(tokenArrayEnd); - Token token; + Token currentToken; // Accept Comment after last item in the array. - ok = readToken(token); - while (token.type_ == tokenComment && ok) { - ok = readToken(token); + ok = readToken(currentToken); + while (currentToken.type_ == tokenComment && ok) { + ok = readToken(currentToken); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (currentToken.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", - token, tokenArrayEnd); + currentToken, tokenArrayEnd); } - if (token.type_ == tokenArrayEnd) + if (currentToken.type_ == tokenArrayEnd) break; } return true; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6bf981ef1..1160c2219 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -241,15 +241,15 @@ void Value::CommentInfo::setComment(const char* text, size_t len) { // Notes: policy_ indicates if the string was allocated when // a string is stored. -Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {} +Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {} Value::CZString::CZString(char const* str, - unsigned ulength, + unsigned length, DuplicationPolicy allocate) : cstr_(str) { // allocate != duplicate storage_.policy_ = allocate & 0x3; - storage_.length_ = ulength & 0x3FFFFFFF; + storage_.length_ = length & 0x3FFFFFFF; } Value::CZString::CZString(const CZString& other) { @@ -357,10 +357,10 @@ bool Value::CZString::isStaticString() const { * memset( this, 0, sizeof(Value) ) * This optimization is used in ValueInternalMap fast allocator. */ -Value::Value(ValueType vtype) { +Value::Value(ValueType type) { static char const emptyString[] = ""; - initBasic(vtype); - switch (vtype) { + initBasic(type); + switch (type) { case nullValue: break; case intValue: @@ -418,10 +418,10 @@ Value::Value(const char* value) { value, static_cast(strlen(value))); } -Value::Value(const char* beginValue, const char* endValue) { +Value::Value(const char* begin, const char* end) { initBasic(stringValue, true); value_.string_ = duplicateAndPrefixStringValue( - beginValue, static_cast(endValue - beginValue)); + begin, static_cast(end - begin)); } Value::Value(const JSONCPP_STRING& value) { @@ -645,14 +645,14 @@ unsigned Value::getCStringLength() const { } #endif -bool Value::getString(char const** str, char const** cend) const { +bool Value::getString(char const** begin, char const** end) const { if (type_ != stringValue) return false; if (value_.string_ == 0) return false; unsigned length; - decodePrefixedString(this->allocated_, this->value_.string_, &length, str); - *cend = *str + length; + decodePrefixedString(this->allocated_, this->value_.string_, &length, begin); + *end = *begin + length; return true; } @@ -1003,8 +1003,8 @@ const Value& Value::operator[](int index) const { return (*this)[ArrayIndex(index)]; } -void Value::initBasic(ValueType vtype, bool allocated) { - type_ = vtype; +void Value::initBasic(ValueType type, bool allocated) { + type_ = type; allocated_ = allocated; comments_ = 0; start_ = 0; @@ -1101,13 +1101,13 @@ Value& Value::resolveReference(const char* key) { } // @param key is not null-terminated. -Value& Value::resolveReference(char const* key, char const* cend) { +Value& Value::resolveReference(char const* key, char const* end) { JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::resolveReference(key, end): requires objectValue"); if (type_ == nullValue) *this = Value(objectValue); - CZString actualKey(key, static_cast(cend - key), + CZString actualKey(key, static_cast(end - key), CZString::duplicateOnCopy); ObjectValues::iterator it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) @@ -1126,13 +1126,13 @@ Value Value::get(ArrayIndex index, const Value& defaultValue) const { bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } -Value const* Value::find(char const* key, char const* cend) const { +Value const* Value::find(char const* begin, char const* end) const { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, "in Json::Value::find(key, end, found): requires " "objectValue or nullValue"); if (type_ == nullValue) return NULL; - CZString actualKey(key, static_cast(cend - key), + CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); ObjectValues::const_iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) @@ -1184,10 +1184,10 @@ Value& Value::append(Value&& value) { } #endif -Value Value::get(char const* key, - char const* cend, +Value Value::get(char const* begin, + char const* end, Value const& defaultValue) const { - Value const* found = find(key, cend); + Value const* found = find(begin, end); return !found ? defaultValue : *found; } Value Value::get(char const* key, Value const& defaultValue) const { @@ -1197,11 +1197,11 @@ Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const { return get(key.data(), key.data() + key.length(), defaultValue); } -bool Value::removeMember(const char* key, const char* cend, Value* removed) { +bool Value::removeMember(const char* begin, const char* end, Value* removed) { if (type_ != objectValue) { return false; } - CZString actualKey(key, static_cast(cend - key), + CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); ObjectValues::iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) @@ -1264,8 +1264,8 @@ Value Value::get(const CppTL::ConstString& key, } #endif -bool Value::isMember(char const* key, char const* cend) const { - Value const* value = find(key, cend); +bool Value::isMember(char const* begin, char const* end) const { + Value const* value = find(begin, end); return NULL != value; } bool Value::isMember(char const* key) const { diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index e0e47ad82..5eaa0417a 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -1245,10 +1245,10 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) { //! [StreamWriterBuilderDefaults] } -JSONCPP_STRING writeString(StreamWriter::Factory const& builder, +JSONCPP_STRING writeString(StreamWriter::Factory const& factory, Value const& root) { JSONCPP_OSTRINGSTREAM sout; - StreamWriterPtr const writer(builder.newStreamWriter()); + StreamWriterPtr const writer(factory.newStreamWriter()); writer->write(root, &sout); return sout.str(); } diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 9d50e90c9..9aab53880 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -167,7 +167,7 @@ class Runner { private: void listTests() const; - bool testIndex(const JSONCPP_STRING& testName, unsigned int& index) const; + bool testIndex(const JSONCPP_STRING& testName, unsigned int& indexOut) const; static void preventDialogOnCrash(); private: From 84ca7d6f0bf3148124c0dcb309cb477cd027324e Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 20:27:31 +0300 Subject: [PATCH 049/410] Apply the formatting specified in .clang-format file. --- src/lib_json/json_reader.cpp | 8 ++++---- src/lib_json/json_value.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 7628e71cf..09aeba9b1 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -542,8 +542,8 @@ bool Reader::readArray(Token& token) { while (currentToken.type_ == tokenComment && ok) { ok = readToken(currentToken); } - bool badTokenType = - (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); + bool badTokenType = (currentToken.type_ != tokenArraySeparator && + currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", currentToken, tokenArrayEnd); @@ -1538,8 +1538,8 @@ bool OurReader::readArray(Token& token) { while (currentToken.type_ == tokenComment && ok) { ok = readToken(currentToken); } - bool badTokenType = - (currentToken.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + bool badTokenType = (currentToken.type_ != tokenArraySeparator && + token.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", currentToken, tokenArrayEnd); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 1160c2219..cc5e8fe75 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -420,8 +420,8 @@ Value::Value(const char* value) { Value::Value(const char* begin, const char* end) { initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue( - begin, static_cast(end - begin)); + value_.string_ = + duplicateAndPrefixStringValue(begin, static_cast(end - begin)); } Value::Value(const JSONCPP_STRING& value) { From a5d7c714b1ecdd7ad2a15378f70512384acdafcb Mon Sep 17 00:00:00 2001 From: Marian Klymov Date: Sat, 2 Jun 2018 21:52:45 +0300 Subject: [PATCH 050/410] Fix typo in previous fix. --- src/lib_json/json_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 09aeba9b1..3e58f44d0 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1539,7 +1539,7 @@ bool OurReader::readArray(Token& token) { ok = readToken(currentToken); } bool badTokenType = (currentToken.type_ != tokenArraySeparator && - token.type_ != tokenArrayEnd); + currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { return addErrorAndRecover("Missing ',' or ']' in array declaration", currentToken, tokenArrayEnd); From 86789e7c2f576fe7a679f62667e87de1fea61865 Mon Sep 17 00:00:00 2001 From: "pavel.pimenov" Date: Tue, 5 Jun 2018 10:17:36 +0300 Subject: [PATCH 051/410] Fix #782 --- src/lib_json/json_tool.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 3a22015b4..855f6d7dd 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -6,7 +6,9 @@ #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED +#if !defined(JSON_IS_AMALGAMATION) #include +#endif // Also support old flag NO_LOCALE_SUPPORT #ifdef NO_LOCALE_SUPPORT From ee34ac1fbbdb97220ec0dd6110353c1a387453ee Mon Sep 17 00:00:00 2001 From: Kamel CHAOUCHE Date: Tue, 12 Jun 2018 17:38:41 +0200 Subject: [PATCH 052/410] Add position independent code feature to CMakeList.txt Enable Position Independent Code for shared lib --- src/lib_json/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 9730e9ace..d0d717ffb 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -73,6 +73,7 @@ IF(BUILD_SHARED_LIBS) SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) + SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) # Set library's runtime search path on OSX IF(APPLE) From b87f6dbc8a732ea785798cc76d66314eea38f008 Mon Sep 17 00:00:00 2001 From: Peter Spiess-Knafl Date: Mon, 18 Jun 2018 11:28:56 +0200 Subject: [PATCH 053/410] Fix for #798 Add preprocessor definitions for MSVC dllexport/dllimport statements (cherry picked from commit 2654b6bbbf089bf85d29c9a9ca1283e07cc6fe43) --- meson.build | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index f5573c04e..058d55a2b 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,14 @@ install_headers( jsoncpp_headers, subdir : 'json') +if get_option('default_library') == 'shared' and meson.get_compiler('cpp').get_id() == 'msvc' + dll_export_flag = '-DJSON_DLL_BUILD' + dll_import_flag = '-DJSON_DLL' +else + dll_export_flag = '' + dll_import_flag = '' +endif + jsoncpp_lib = library( 'jsoncpp', [ jsoncpp_gen_sources, @@ -56,7 +64,8 @@ jsoncpp_lib = library( 'src/lib_json/json_writer.cpp'], soversion : 20, install : true, - include_directories : jsoncpp_include_directories) + include_directories : jsoncpp_include_directories, + cpp_args: dll_export_flag) import('pkgconfig').generate( libraries : jsoncpp_lib, @@ -82,7 +91,8 @@ jsoncpp_test = executable( 'src/test_lib_json/main.cpp'], include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, - install : false) + install : false, + cpp_args: dll_import_flag) test( 'unittest_jsoncpp_test', jsoncpp_test) @@ -92,7 +102,8 @@ jsontestrunner = executable( 'src/jsontestrunner/main.cpp', include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, - install : false) + install : false, + cpp_args: dll_import_flag) test( 'unittest_jsontestrunner', python, From 59d41de5b1d5588e310f2f31552c66d4f3beef33 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 23 Jun 2018 17:34:40 -0500 Subject: [PATCH 054/410] Try to avoid empty string - g++ has a problem with '' - clang++ does not seem to mind it. --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 058d55a2b..a338cc0dd 100644 --- a/meson.build +++ b/meson.build @@ -50,8 +50,8 @@ if get_option('default_library') == 'shared' and meson.get_compiler('cpp').get_i dll_export_flag = '-DJSON_DLL_BUILD' dll_import_flag = '-DJSON_DLL' else - dll_export_flag = '' - dll_import_flag = '' + dll_export_flag = [] + dll_import_flag = [] endif jsoncpp_lib = library( From 473afca1e3c9531e9d00a6c8f84ff27bfbd72b9d Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 23 Jun 2018 17:43:25 -0500 Subject: [PATCH 055/410] Tell meson/ninja versions --- travis.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/travis.sh b/travis.sh index f80424bd7..f7a80bbb1 100755 --- a/travis.sh +++ b/travis.sh @@ -17,6 +17,8 @@ set -vex env | sort +meson --version +ninja --version meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} ninja -v -C build-${LIB_TYPE} ninja -v -C build-${LIB_TYPE} test From c59db800023ac306ad44cd7c8aa5bef474faf173 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 23 Jun 2018 16:34:57 -0500 Subject: [PATCH 056/410] Try the way I build locally --- README.md | 4 +++- travis.sh | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 833274205..5c9c95f20 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,10 @@ Then, LIB_TYPE=shared #LIB_TYPE=static meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} - ninja -v -C build-${LIB_TYPE} test + #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. + ninja -v -C build-${LIB_TYPE} cd build-${LIB_TYPE} + meson test --no-rebuild --print-errorlogs sudo ninja install ### Building and testing with other build systems diff --git a/travis.sh b/travis.sh index f7a80bbb1..226c64d94 100755 --- a/travis.sh +++ b/travis.sh @@ -21,5 +21,8 @@ meson --version ninja --version meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} ninja -v -C build-${LIB_TYPE} -ninja -v -C build-${LIB_TYPE} test +#ninja -v -C build-${LIB_TYPE} test +cd build-${LIB_TYPE} +meson test --no-rebuild --print-errorlogs +cd - rm -r build-${LIB_TYPE} From 745287275c83538e495bcdbd9dfee4befa097b5e Mon Sep 17 00:00:00 2001 From: "pavel.pimenov" Date: Mon, 4 Jun 2018 09:06:24 +0300 Subject: [PATCH 057/410] "\n" -> '\n' --- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index cc5e8fe75..01e95486a 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1491,7 +1491,7 @@ JSONCPP_STRING Value::toStyledString() const { JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : ""; out += Json::writeString(builder, *this); - out += "\n"; + out += '\n'; return out; } diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 5eaa0417a..47f413d6a 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -366,7 +366,7 @@ JSONCPP_STRING FastWriter::write(const Value& root) { document_.clear(); writeValue(root); if (!omitEndingLineFeed_) - document_ += "\n"; + document_ += '\n'; return document_; } @@ -438,7 +438,7 @@ JSONCPP_STRING StyledWriter::write(const Value& root) { writeCommentBeforeValue(root); writeValue(root); writeCommentAfterValueOnSameLine(root); - document_ += "\n"; + document_ += '\n'; return document_; } @@ -608,7 +608,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) { if (!root.hasComment(commentBefore)) return; - document_ += "\n"; + document_ += '\n'; writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); @@ -620,7 +620,7 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) { } // Comments are stripped of trailing newlines, so add one here - document_ += "\n"; + document_ += '\n'; } void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { @@ -628,9 +628,9 @@ void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { document_ += " " + root.getComment(commentAfterOnSameLine); if (root.hasComment(commentAfter)) { - document_ += "\n"; + document_ += '\n'; document_ += root.getComment(commentAfter); - document_ += "\n"; + document_ += '\n'; } } From da498591fc87191e619d98d7935a99fadd88a4f4 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 18 Apr 2015 18:24:46 -0700 Subject: [PATCH 058/410] In travis-ci, build for osx also Drop gcc b/c it takes too long to install via addon. Build only static/release, to save VMs. (No shared to debug.) --- .travis.yml | 61 ++++++++++++---------------------- travis.before_install.linux.sh | 7 ++++ travis.before_install.osx.sh | 3 ++ travis.install.linux.sh | 14 ++++++++ travis.install.osx.sh | 12 +++++++ travis.sh | 3 ++ 6 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 travis.before_install.linux.sh create mode 100644 travis.before_install.osx.sh create mode 100644 travis.install.linux.sh create mode 100644 travis.install.osx.sh diff --git a/.travis.yml b/.travis.yml index 33e65c4ba..27978e4a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# Build matrix / environment variable are explained on: +# Build matrix / environment variables are explained on: # http://about.travis-ci.org/docs/user/build-configuration/ # This file can be validated on: # http://lint.travis-ci.org/ @@ -6,54 +6,37 @@ # http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448 # to allow C++11, though we are not yet building with -std=c++11 -#before_install: pyenv install 3.5.4 && pyenv global 3.5.4 -before_install: pyenv global 3.6 -# https://docs.travis-ci.com/user/languages/python/ -# "for Trusty, this means 2.7.6 and 3.4.3" +before_install: +- source travis.before_install.${TRAVIS_OS_NAME}.sh install: -- if [[ $TRAVIS_OS_NAME == osx ]]; then - brew update; - brew install python3 ninja; - python3 -m venv venv; - source venv/bin/activate; - elif [[ $TRAVIS_OS_NAME == linux ]]; then - wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip; - unzip -q ninja-linux.zip -d build; - fi -- pip3 install meson -# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available. -- if [[ $CXX = g++ ]]; then export CXX="g++-4.9" CC="gcc-4.9"; fi -# /usr/bin/clang has a conflict with gcc, so use clang-X.Y. -- if [[ $CXX = clang++ ]]; then export CXX="clang++-3.5" CC="clang-3.5"; fi -- echo ${PATH} -- ls /usr/local -- ls /usr/local/bin -- export PATH="${PWD}"/build:/usr/local/bin:/usr/bin:${PATH} -- echo ${CXX} -- ${CXX} --version -- which valgrind +- source travis.install.${TRAVIS_OS_NAME}.sh addons: apt: sources: - - ubuntu-toolchain-r-test + #- ubuntu-toolchain-r-test - llvm-toolchain-precise-3.5 packages: - - gcc-4.9 - - g++-4.9 + #- gcc-4.9 + #- g++-4.9 - clang-3.5 - valgrind -os: - - linux language: cpp -compiler: - - gcc - - clang script: ./travis.sh -env: - matrix: - - LIB_TYPE=static BUILD_TYPE=release - - LIB_TYPE=shared BUILD_TYPE=debug +matrix: + allow_failures: + - os: osx +matrix: + include: + - os: osx + osx_image: xcode9.4 + compiler: clang + #env: PYENV_ROOT=/usr/local/var/pyenv + env: LIB_TYPE=static BUILD_TYPE=release + #- LIB_TYPE=shared BUILD_TYPE=debug + - os: linux + dist: trusty + compiler: clang + env: LIB_TYPE=static BUILD_TYPE=release notifications: email: false -dist: trusty sudo: false diff --git a/travis.before_install.linux.sh b/travis.before_install.linux.sh new file mode 100644 index 000000000..18e019d84 --- /dev/null +++ b/travis.before_install.linux.sh @@ -0,0 +1,7 @@ +set -vex +#before_install: pyenv install 3.5.4 && pyenv global 3.5.4 +#before_install: pyenv global 3.6 +# https://docs.travis-ci.com/user/languages/python/ +# "for Trusty, this means 2.7.6 and 3.4.3" + +pyenv global 3.6 diff --git a/travis.before_install.osx.sh b/travis.before_install.osx.sh new file mode 100644 index 000000000..a8377faef --- /dev/null +++ b/travis.before_install.osx.sh @@ -0,0 +1,3 @@ +set -vex +#brew install pyenv +#which pyenv diff --git a/travis.install.linux.sh b/travis.install.linux.sh new file mode 100644 index 000000000..a049f760c --- /dev/null +++ b/travis.install.linux.sh @@ -0,0 +1,14 @@ +set -vex + +wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip +unzip -q ninja-linux.zip -d build + +pip3 install meson +# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available. +if [[ $CXX = g++ ]]; then export CXX="g++-4.9" CC="gcc-4.9"; fi +# /usr/bin/clang has a conflict with gcc, so use clang-X.Y. +if [[ $CXX = clang++ ]]; then export CXX="clang++-3.5" CC="clang-3.5"; fi +echo ${PATH} +ls /usr/local +ls /usr/local/bin +export PATH="${PWD}"/build:/usr/local/bin:/usr/bin:${PATH} diff --git a/travis.install.osx.sh b/travis.install.osx.sh new file mode 100644 index 000000000..e82bdc660 --- /dev/null +++ b/travis.install.osx.sh @@ -0,0 +1,12 @@ +set -vex + +#brew update +brew upgrade python3 +python3 -m venv venv +source venv/bin/activate + +brew install ninja +brew install meson + +#brew install pyenv +#which pyenv diff --git a/travis.sh b/travis.sh index 226c64d94..f0628fc56 100755 --- a/travis.sh +++ b/travis.sh @@ -17,6 +17,9 @@ set -vex env | sort +echo ${CXX} +${CXX} --version +python3 --version meson --version ninja --version meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} From e32ee4717c3503875594dc6415dbbbba89245bce Mon Sep 17 00:00:00 2001 From: YantaoZhao Date: Tue, 3 Jul 2018 21:29:18 +0800 Subject: [PATCH 059/410] allow nullptr when not care the removed array value --- include/json/value.h | 2 +- src/lib_json/json_value.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 8a0054cbf..e7a9225d3 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -562,7 +562,7 @@ Json::Value obj_value(Json::objectValue); // {} /** \brief Remove the indexed array element. O(n) expensive operations. - Update 'removed' if removed. + Update 'removed' iff removed. \return true if removed (no exceptions) */ bool removeIndex(ArrayIndex index, Value* removed); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 01e95486a..c77d1df4d 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1243,7 +1243,8 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { if (it == value_.map_->end()) { return false; } - *removed = it->second; + if (removed) + *removed = it->second; ArrayIndex oldSize = size(); // shift left all items left, into the place of the "removed" for (ArrayIndex i = index; i < (oldSize - 1); ++i) { From 010a2d04d3ae13f4e60dc3f315ee25468510a71f Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Wed, 3 Oct 2018 09:04:01 +0200 Subject: [PATCH 060/410] Unique lib target name --- src/jsontestrunner/CMakeLists.txt | 4 +-- src/lib_json/CMakeLists.txt | 57 +++++++++---------------------- src/test_lib_json/CMakeLists.txt | 4 +-- 3 files changed, 19 insertions(+), 46 deletions(-) diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 20d01e626..3d2ffee69 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -6,10 +6,8 @@ ADD_EXECUTABLE(jsontestrunner_exe IF(BUILD_SHARED_LIBS) ADD_DEFINITIONS( -DJSON_DLL ) - TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib) -ELSE(BUILD_SHARED_LIBS) - TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib_static) ENDIF() +TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib) SET_TARGET_PROPERTIES(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index d0d717ffb..d710ce0c2 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -69,50 +69,27 @@ ENDIF() IF(BUILD_SHARED_LIBS) ADD_DEFINITIONS( -DJSON_DLL_BUILD ) - ADD_LIBRARY(jsoncpp_lib SHARED ${PUBLIC_HEADERS} ${jsoncpp_sources}) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp - DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) - - # Set library's runtime search path on OSX - IF(APPLE) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) - ENDIF() +ENDIF() - INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC - $ - $) - ENDIF() +ADD_LIBRARY(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) +SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) +SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp + DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) +SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) +# Set library's runtime search path on OSX +IF(APPLE) + SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) ENDIF() -IF(BUILD_STATIC_LIBS) - ADD_LIBRARY(jsoncpp_lib_static STATIC ${PUBLIC_HEADERS} ${jsoncpp_sources}) - SET_TARGET_PROPERTIES( jsoncpp_lib_static PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) - # avoid name clashes on windows as the shared import lib is also named jsoncpp.lib - if (NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) - set (STATIC_SUFFIX "_static") - endif () - set_target_properties (jsoncpp_lib_static PROPERTIES OUTPUT_NAME jsoncpp${STATIC_SUFFIX} - DEBUG_OUTPUT_NAME jsoncpp${STATIC_SUFFIX}${DEBUG_LIBNAME_SUFFIX}) - - INSTALL( TARGETS jsoncpp_lib_static ${INSTALL_EXPORT} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - - IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib_static PUBLIC - $ - $ - ) - ENDIF() +INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC + $ + $) ENDIF() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 7000264a7..246825abc 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -9,10 +9,8 @@ ADD_EXECUTABLE( jsoncpp_test IF(BUILD_SHARED_LIBS) ADD_DEFINITIONS( -DJSON_DLL ) - TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib) -ELSE(BUILD_SHARED_LIBS) - TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib_static) ENDIF() +TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) From a72266d00b8b0b056d00fb0830fd84d01dfc769e Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Wed, 3 Oct 2018 09:04:49 +0200 Subject: [PATCH 061/410] Remove useless BUILD_STATIC_LIBS option --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e18c89b74..4bac090c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,6 @@ OPTION(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) -OPTION(BUILD_STATIC_LIBS "Build jsoncpp_lib static library." ON) # Ensures that CMAKE_BUILD_TYPE is visible in cmake-gui on Unix IF(NOT WIN32) From ec4251b72832cfce719926cfdee6159ce05f5b90 Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Wed, 3 Oct 2018 09:18:16 +0200 Subject: [PATCH 062/410] Use CMAKE_CROSSCOMPILING_EMULATOR to run tests Needed when cross-compiling --- src/test_lib_json/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 246825abc..c6a534f30 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -24,12 +24,12 @@ IF(JSONCPP_WITH_POST_BUILD_UNITTEST) ADD_CUSTOM_COMMAND( TARGET jsoncpp_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - COMMAND $) + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) ELSE(BUILD_SHARED_LIBS) # Just run the test executable. ADD_CUSTOM_COMMAND( TARGET jsoncpp_test POST_BUILD - COMMAND $) + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) ENDIF() ENDIF() From d501fbe741079e560838b4fdbe8323976da10a9b Mon Sep 17 00:00:00 2001 From: Julien Schueller Date: Wed, 3 Oct 2018 09:37:12 +0200 Subject: [PATCH 063/410] Set CMAKE_BUILD_TYPE default on win32 too --- CMakeLists.txt | 16 +++++++--------- appveyor.yml | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bac090c3..8374c41f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,13 @@ # vim: et ts=4 sts=4 sw=4 tw=0 CMAKE_MINIMUM_REQUIRED(VERSION 3.1) + +# Ensures that CMAKE_BUILD_TYPE has a default value +IF(NOT DEFINED CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE Release CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") +ENDIF() + PROJECT(jsoncpp) ENABLE_TESTING() @@ -12,15 +19,6 @@ OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) -# Ensures that CMAKE_BUILD_TYPE is visible in cmake-gui on Unix -IF(NOT WIN32) - IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE Release CACHE STRING - "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage." - FORCE) - ENDIF() -ENDIF() - # Enable runtime search path support for dynamic libraries on OSX IF(APPLE) SET(CMAKE_MACOSX_RPATH 1) diff --git a/appveyor.yml b/appveyor.yml index 5d497de14..a723fca2a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ environment: build_script: - cmake --version - cd c:\projects\jsoncpp - - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX=%CD:\=/%/install -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON . + - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX=%CD:\=/%/install -DBUILD_SHARED_LIBS=ON . - cmake --build . --config Release --target install deploy: From b955e0f69992a1fc855d09a207d2bdfe986dc2a0 Mon Sep 17 00:00:00 2001 From: manang Date: Mon, 3 Dec 2018 10:26:27 +0100 Subject: [PATCH 064/410] Update json_writer.cpp --- src/lib_json/json_writer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 47f413d6a..a8b56ff80 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -72,10 +72,12 @@ #define isnan(x) (x != x) #endif +#if !defined(__APPLE__) #if !defined(isfinite) #define isfinite finite #endif #endif +#endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. From f64244ed3ff0124042cb80d80db0766c1be848f4 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 13:41:06 -0600 Subject: [PATCH 065/410] COMP: Use nullptr instead of 0 or NULL The check converts the usage of null pointer constants (eg. NULL, 0) to use the new C++11 nullptr keyword. SRCDIR=/Users/johnsonhj/src/jsoncpp #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-nullptr -header-filter=.* -fix --- include/json/reader.h | 2 +- src/lib_json/json_reader.cpp | 18 ++++++------- src/lib_json/json_value.cpp | 40 ++++++++++++++--------------- src/lib_json/json_valueiterator.inl | 4 +-- src/lib_json/json_writer.cpp | 10 ++++---- src/test_lib_json/jsontest.cpp | 16 ++++++------ src/test_lib_json/jsontest.h | 2 +- 7 files changed, 46 insertions(+), 46 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index d8f1be108..b700d95bd 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -221,7 +221,7 @@ class JSON_API Reader { Location end, unsigned int& unicode); bool - addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + addError(const JSONCPP_STRING& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 3e58f44d0..96735de43 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -137,8 +137,8 @@ bool Reader::parse(const char* beginDoc, end_ = endDoc; collectComments_ = collectComments; current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; + lastValueEnd_ = nullptr; + lastValue_ = nullptr; commentsBefore_.clear(); errors_.clear(); while (!nodes_.empty()) @@ -394,7 +394,7 @@ void Reader::addComment(Location begin, assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); + assert(lastValue_ != nullptr); lastValue_->setComment(normalized, placement); } else { commentsBefore_ += normalized; @@ -862,7 +862,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = 0; + info.extra_ = nullptr; errors_.push_back(info); return true; } @@ -1002,7 +1002,7 @@ class OurReader { Location end, unsigned int& unicode); bool - addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + addError(const JSONCPP_STRING& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, @@ -1061,8 +1061,8 @@ bool OurReader::parse(const char* beginDoc, end_ = endDoc; collectComments_ = collectComments; current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; + lastValueEnd_ = nullptr; + lastValue_ = nullptr; commentsBefore_.clear(); errors_.clear(); while (!nodes_.empty()) @@ -1368,7 +1368,7 @@ void OurReader::addComment(Location begin, assert(collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); + assert(lastValue_ != nullptr); lastValue_->setComment(normalized, placement); } else { commentsBefore_ += normalized; @@ -1877,7 +1877,7 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = 0; + info.extra_ = nullptr; errors_.push_back(info); return true; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index c77d1df4d..8f3355cb5 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -108,7 +108,7 @@ static inline char* duplicateStringValue(const char* value, size_t length) { length = Value::maxInt - 1; char* newString = static_cast(malloc(length + 1)); - if (newString == NULL) { + if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateStringValue(): " "Failed to allocate string value buffer"); } @@ -129,7 +129,7 @@ static inline char* duplicateAndPrefixStringValue(const char* value, "length too big for prefixing"); unsigned actualLength = length + static_cast(sizeof(unsigned)) + 1U; char* newString = static_cast(malloc(actualLength)); - if (newString == 0) { + if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " "Failed to allocate string value buffer"); } @@ -210,7 +210,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() : comment_(0) {} +Value::CommentInfo::CommentInfo() : comment_(nullptr) {} Value::CommentInfo::~CommentInfo() { if (comment_) @@ -220,9 +220,9 @@ Value::CommentInfo::~CommentInfo() { void Value::CommentInfo::setComment(const char* text, size_t len) { if (comment_) { releaseStringValue(comment_, 0u); - comment_ = 0; + comment_ = nullptr; } - JSON_ASSERT(text != 0); + JSON_ASSERT(text != nullptr); JSON_ASSERT_MESSAGE( text[0] == '\0' || text[0] == '/', "in Json::Value::setComment(): Comments must start with /"); @@ -241,7 +241,7 @@ void Value::CommentInfo::setComment(const char* text, size_t len) { // Notes: policy_ indicates if the string was allocated when // a string is stored. -Value::CZString::CZString(ArrayIndex index) : cstr_(0), index_(index) {} +Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {} Value::CZString::CZString(char const* str, unsigned length, @@ -253,7 +253,7 @@ Value::CZString::CZString(char const* str, } Value::CZString::CZString(const CZString& other) { - cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 + cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr ? duplicateStringValue(other.cstr_, other.storage_.length_) : other.cstr_); storage_.policy_ = @@ -413,7 +413,7 @@ Value::Value(double value) { Value::Value(const char* value) { initBasic(stringValue, true); - JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); + JSON_ASSERT_MESSAGE(value != nullptr, "Null Value Passed to Value Constructor"); value_.string_ = duplicateAndPrefixStringValue( value, static_cast(strlen(value))); } @@ -528,7 +528,7 @@ bool Value::operator<(const Value& other) const { case booleanValue: return value_.bool_ < other.value_.bool_; case stringValue: { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { + if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { if (other.value_.string_) return true; else @@ -590,7 +590,7 @@ bool Value::operator==(const Value& other) const { case booleanValue: return value_.bool_ == other.value_.bool_; case stringValue: { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { + if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { return (value_.string_ == other.value_.string_); } unsigned this_len; @@ -622,8 +622,8 @@ bool Value::operator!=(const Value& other) const { return !(*this == other); } const char* Value::asCString() const { JSON_ASSERT_MESSAGE(type_ == stringValue, "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) - return 0; + if (value_.string_ == nullptr) + return nullptr; unsigned this_len; char const* this_str; decodePrefixedString(this->allocated_, this->value_.string_, &this_len, @@ -648,7 +648,7 @@ unsigned Value::getCStringLength() const { bool Value::getString(char const** begin, char const** end) const { if (type_ != stringValue) return false; - if (value_.string_ == 0) + if (value_.string_ == nullptr) return false; unsigned length; decodePrefixedString(this->allocated_, this->value_.string_, &length, begin); @@ -661,7 +661,7 @@ JSONCPP_STRING Value::asString() const { case nullValue: return ""; case stringValue: { - if (value_.string_ == 0) + if (value_.string_ == nullptr) return ""; unsigned this_len; char const* this_str; @@ -1006,7 +1006,7 @@ const Value& Value::operator[](int index) const { void Value::initBasic(ValueType type, bool allocated) { type_ = type; allocated_ = allocated; - comments_ = 0; + comments_ = nullptr; start_ = 0; limit_ = 0; } @@ -1073,7 +1073,7 @@ void Value::dupMeta(const Value& other) { strlen(otherComment.comment_)); } } else { - comments_ = 0; + comments_ = nullptr; } start_ = other.start_; limit_ = other.limit_; @@ -1131,12 +1131,12 @@ Value const* Value::find(char const* begin, char const* end) const { "in Json::Value::find(key, end, found): requires " "objectValue or nullValue"); if (type_ == nullValue) - return NULL; + return nullptr; CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); ObjectValues::const_iterator it = value_.map_->find(actualKey); if (it == value_.map_->end()) - return NULL; + return nullptr; return &(*it).second; } const Value& Value::operator[](const char* key) const { @@ -1267,7 +1267,7 @@ Value Value::get(const CppTL::ConstString& key, bool Value::isMember(char const* begin, char const* end) const { Value const* value = find(begin, end); - return NULL != value; + return nullptr != value; } bool Value::isMember(char const* key) const { return isMember(key, key + strlen(key)); @@ -1470,7 +1470,7 @@ void Value::setComment(const JSONCPP_STRING& comment, } bool Value::hasComment(CommentPlacement placement) const { - return comments_ != 0 && comments_[placement].comment_ != 0; + return comments_ != nullptr && comments_[placement].comment_ != nullptr; } JSONCPP_STRING Value::getComment(CommentPlacement placement) const { diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 5243bfe4b..7cc379227 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -108,8 +108,8 @@ char const* ValueIteratorBase::memberName() const { char const* ValueIteratorBase::memberName(char const** end) const { const char* cname = (*current_).first.data(); if (!cname) { - *end = NULL; - return NULL; + *end = nullptr; + return nullptr; } *end = cname + (*current_).first.length(); return cname; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index a8b56ff80..60d3251d3 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -275,7 +275,7 @@ static JSONCPP_STRING toHex16Bit(unsigned int x) { } static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { - if (value == NULL) + if (value == nullptr) return ""; if (!isAnyCharRequiredQuoting(value, length)) @@ -646,7 +646,7 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledStreamWriter::StyledStreamWriter(const JSONCPP_STRING& indentation) - : document_(NULL), rightMargin_(74), indentation_(indentation), + : document_(nullptr), rightMargin_(74), indentation_(indentation), addChildValues_(), indented_(false) {} void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { @@ -661,7 +661,7 @@ void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { writeValue(root); writeCommentAfterValueOnSameLine(root); *document_ << "\n"; - document_ = NULL; // Forget the stream, for safety. + document_ = nullptr; // Forget the stream, for safety. } void StyledStreamWriter::writeValue(const Value& value) { @@ -940,7 +940,7 @@ int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { writeValue(root); writeCommentAfterValueOnSameLine(root); *sout_ << endingLineFeedSymbol_; - sout_ = NULL; + sout_ = nullptr; return 0; } void BuiltStyledStreamWriter::writeValue(Value const& value) { @@ -1158,7 +1158,7 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { /////////////// // StreamWriter -StreamWriter::StreamWriter() : sout_(NULL) {} +StreamWriter::StreamWriter() : sout_(nullptr) {} StreamWriter::~StreamWriter() {} StreamWriter::Factory::~Factory() {} StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 86ed4c17f..76e683208 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -74,10 +74,10 @@ namespace JsonTest { // ////////////////////////////////////////////////////////////////// TestResult::TestResult() - : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(0) { + : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(nullptr) { // The root predicate has id 0 rootPredicateNode_.id_ = 0; - rootPredicateNode_.next_ = 0; + rootPredicateNode_.next_ = nullptr; predicateStackTail_ = &rootPredicateNode_; } @@ -89,7 +89,7 @@ TestResult::addFailure(const char* file, unsigned int line, const char* expr) { /// added. unsigned int nestingLevel = 0; PredicateContext* lastNode = rootPredicateNode_.next_; - for (; lastNode != 0; lastNode = lastNode->next_) { + for (; lastNode != nullptr; lastNode = lastNode->next_) { if (lastNode->id_ > lastUsedPredicateId_) // new PredicateContext { lastUsedPredicateId_ = lastNode->id_; @@ -124,17 +124,17 @@ void TestResult::addFailureInfo(const char* file, TestResult& TestResult::popPredicateContext() { PredicateContext* lastNode = &rootPredicateNode_; - while (lastNode->next_ != 0 && lastNode->next_->next_ != 0) { + while (lastNode->next_ != nullptr && lastNode->next_->next_ != nullptr) { lastNode = lastNode->next_; } // Set message target to popped failure PredicateContext* tail = lastNode->next_; - if (tail != 0 && tail->failure_ != 0) { + if (tail != nullptr && tail->failure_ != nullptr) { messageTarget_ = tail->failure_; } // Remove tail from list predicateStackTail_ = lastNode; - lastNode->next_ = 0; + lastNode->next_ = nullptr; return *this; } @@ -186,7 +186,7 @@ JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text, } TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) { - if (messageTarget_ != 0) { + if (messageTarget_ != nullptr) { messageTarget_->message_ += message; } return *this; @@ -207,7 +207,7 @@ TestResult& TestResult::operator<<(bool value) { // class TestCase // ////////////////////////////////////////////////////////////////// -TestCase::TestCase() : result_(0) {} +TestCase::TestCase() : result_(nullptr) {} TestCase::~TestCase() {} diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 9aab53880..58c52510c 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -69,7 +69,7 @@ class TestResult { /// Adds an assertion failure. TestResult& - addFailure(const char* file, unsigned int line, const char* expr = 0); + addFailure(const char* file, unsigned int line, const char* expr = nullptr); /// Removes the last PredicateContext added to the predicate stack /// chained list. From 4abf4ec20823306ddcc1992a05effdaced749b37 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 13:42:53 -0600 Subject: [PATCH 066/410] PERF: Replace explicit return calls of constructor Replaces explicit calls to the constructor in a return with a braced initializer list. This way the return type is not needlessly duplicated in the function definition and the return statement. SRCDIR=/Users/johnsonhj/src/jsoncpp #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-return-braced-init-list -header-filter=.* -fix --- src/lib_json/json_reader.cpp | 4 ++-- src/lib_json/json_value.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 96735de43..264df0b0b 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -69,7 +69,7 @@ Features::Features() : allowComments_(true), strictRoot_(false), allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} -Features Features::all() { return Features(); } +Features Features::all() { return {}; } Features Features::strictMode() { Features features; @@ -906,7 +906,7 @@ class OurFeatures { // exact copy of Implementation of class Features // //////////////////////////////// -OurFeatures OurFeatures::all() { return OurFeatures(); } +OurFeatures OurFeatures::all() { return {}; } // Implementation of class Reader // //////////////////////////////// diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 8f3355cb5..2e7602ea7 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1507,7 +1507,7 @@ Value::const_iterator Value::begin() const { default: break; } - return const_iterator(); + return {}; } Value::const_iterator Value::end() const { @@ -1520,7 +1520,7 @@ Value::const_iterator Value::end() const { default: break; } - return const_iterator(); + return {}; } Value::iterator Value::begin() { From ccd077ffced467068b3cf8e11fcb3c8e98dafa22 Mon Sep 17 00:00:00 2001 From: Radoslav Atanasov Date: Thu, 13 Dec 2018 14:18:04 +0100 Subject: [PATCH 067/410] Fix MSVC 15.9 (2017) warning C4866 by changing operator[] param type from JSONCPP_STRING to const JSONCPP_STRING& for CharReaderBuilder and StreamWriterBuilder (as it is already in Value). https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/c4866?view=vs-2017 --- include/json/reader.h | 2 +- include/json/writer.h | 2 +- src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index b700d95bd..9a7fba220 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -358,7 +358,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { /** A simple way to update a specific setting. */ - Value& operator[](JSONCPP_STRING key); + Value& operator[](const JSONCPP_STRING& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) diff --git a/include/json/writer.h b/include/json/writer.h index c92d26b0e..d70ca1c8b 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -132,7 +132,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { bool validate(Json::Value* invalid) const; /** A simple way to update a specific setting. */ - Value& operator[](JSONCPP_STRING key); + Value& operator[](const JSONCPP_STRING& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 264df0b0b..5a945affe 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1969,7 +1969,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const { } return 0u == inv.size(); } -Value& CharReaderBuilder::operator[](JSONCPP_STRING key) { +Value& CharReaderBuilder::operator[](const JSONCPP_STRING& key) { return settings_[key]; } // static diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 2e7602ea7..6bb73c0f5 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1145,7 +1145,7 @@ const Value& Value::operator[](const char* key) const { return nullSingleton(); return *found; } -Value const& Value::operator[](JSONCPP_STRING const& key) const { +Value const& Value::operator[](const JSONCPP_STRING& key) const { Value const* found = find(key.data(), key.data() + key.length()); if (!found) return nullSingleton(); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 60d3251d3..b93e92fee 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -1231,7 +1231,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { } return 0u == inv.size(); } -Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) { +Value& StreamWriterBuilder::operator[](const JSONCPP_STRING& key) { return settings_[key]; } // static From 5c8e539af475e6156efbfe2b2cb762076d0b8cf6 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 13:31:55 -0600 Subject: [PATCH 068/410] ENH: MSVS 2013 snprintf compatible substitute Simplify the backwards compatible snprintf configuration for pre 1900 version of MSVC. Otherwise prefer C++11 syntax using std::snprintf. --- include/json/config.h | 8 ++++++++ src/jsontestrunner/main.cpp | 12 ++---------- src/lib_json/json_reader.cpp | 13 +++---------- src/lib_json/json_value.cpp | 23 +++++++++++++++++++++++ src/lib_json/json_writer.cpp | 8 +------- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 33a84f5af..b0ecfa23a 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -54,6 +54,14 @@ #define JSON_API #endif +#if defined(_MSC_VER) && _MSC_VER < 1900 +// As recommended at https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 + extern JSON_API int msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...); +# define jsoncpp_snprintf msvc_pre1900_c99_snprintf +#else +# define jsoncpp_snprintf std::snprintf +#endif + // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for // integer // Storages, and 64 bits integer support is disabled. diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 54ca30296..3b5e21a51 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -28,11 +28,7 @@ struct Options { static JSONCPP_STRING normalizeFloatingPointStr(double value) { char buffer[32]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) - sprintf_s(buffer, sizeof(buffer), "%.16g", value); -#else - snprintf(buffer, sizeof(buffer), "%.16g", value); -#endif + jsoncpp_snprintf(buffer, sizeof(buffer), "%.16g", value); buffer[sizeof(buffer) - 1] = 0; JSONCPP_STRING s(buffer); JSONCPP_STRING::size_type index = s.find_last_of("eE"); @@ -105,11 +101,7 @@ static void printValueTree(FILE* fout, Json::ArrayIndex size = value.size(); for (Json::ArrayIndex index = 0; index < size; ++index) { static char buffer[16]; -#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) - sprintf_s(buffer, sizeof(buffer), "[%u]", index); -#else - snprintf(buffer, sizeof(buffer), "[%u]", index); -#endif + jsoncpp_snprintf(buffer, sizeof(buffer), "[%u]", index); printValueTree(fout, value[index], path + buffer); } } break; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 5a945affe..cb88eaba4 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -22,21 +22,14 @@ #if __cplusplus >= 201103L #include -#if !defined(snprintf) -#define snprintf std::snprintf -#endif - #if !defined(sscanf) #define sscanf std::sscanf #endif #else -#include +#include #if defined(_MSC_VER) #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#if !defined(snprintf) -#define snprintf _snprintf -#endif #endif #endif @@ -813,7 +806,7 @@ JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; - snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); + jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } @@ -1833,7 +1826,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; - snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); + jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6bb73c0f5..a95032d22 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -19,6 +19,29 @@ #include // min() #include // size_t +// Provide implementation equivalent of std::snprintf for older _MSC compilers +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include +static int msvc_pre1900_c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) +{ + int count = -1; + if (size != 0) + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + return count; +} + +int JSON_API msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + return count; +} +#endif + // Disable warning C4702 : unreachable code #if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above #pragma warning(disable : 4702) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index b93e92fee..26ee8b789 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -27,9 +27,6 @@ #define isfinite std::isfinite #endif -#if !defined(snprintf) -#define snprintf std::snprintf -#endif #else #include #include @@ -46,9 +43,6 @@ #endif #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#if !defined(snprintf) -#define snprintf _snprintf -#endif #endif #if defined(__sun) && defined(__SVR4) // Solaris @@ -145,7 +139,7 @@ JSONCPP_STRING valueToString(double value, JSONCPP_STRING buffer(size_t(36), '\0'); while (true) { - int len = snprintf( + int len = jsoncpp_snprintf( &*buffer.begin(), buffer.size(), (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", precision, value); From e50bfefef1bee81afce4ce228900e65044e3d236 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 13:34:37 -0600 Subject: [PATCH 069/410] COMP: Prefer the C++ headers over the C99 headers Using the C++11 headers keeps the library cleaner and more rigorously scoped use of namespaces. --- include/json/assertions.h | 2 +- include/json/config.h | 4 ++-- src/jsontestrunner/main.cpp | 2 +- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 4 ++-- src/test_lib_json/jsontest.cpp | 2 +- src/test_lib_json/jsontest.h | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/json/assertions.h b/include/json/assertions.h index 482c4ca48..9bf076f9a 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -7,7 +7,7 @@ #define CPPTL_JSON_ASSERTIONS_H_INCLUDED #include -#include +#include #if !defined(JSON_IS_AMALGAMATION) #include "config.h" diff --git a/include/json/config.h b/include/json/config.h index b0ecfa23a..a36ca1555 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -5,8 +5,8 @@ #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED -#include -#include //typedef int64_t, uint64_t +#include +#include //typedef int64_t, uint64_t #include //typedef String /// If defined, indicates that json library is embedded in CppTL library. diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 3b5e21a51..28691a2de 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -16,7 +16,7 @@ #include // sort #include #include -#include +#include struct Options { JSONCPP_STRING path; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index a95032d22..81640ea42 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -10,7 +10,7 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include #include -#include +#include #include #include #ifdef JSON_USE_CPPTL diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 26ee8b789..3a7fd8e53 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -28,8 +28,8 @@ #endif #else -#include -#include +#include +#include #if defined(_MSC_VER) #if !defined(isnan) diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 76e683208..5e04aa434 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #include "jsontest.h" -#include +#include #include #if defined(_MSC_VER) diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 58c52510c..48761c56b 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include // ////////////////////////////////////////////////////////////////// From 4bfa962967f11a223b19865cc3b1bf07a085d156 Mon Sep 17 00:00:00 2001 From: Kostiantyn Ponomarenko Date: Thu, 18 Oct 2018 20:12:46 +0300 Subject: [PATCH 070/410] Add Meson related info to README Add information about how one can get a Meson wrap file. Signed-off-by: Kostiantyn Ponomarenko --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 5c9c95f20..3edee800c 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,9 @@ When a test is run, output files are generated beside the input test files. Belo ### Amalgamated source https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated +### The Meson Build System +If you are using the [Meson Build System](http://mesonbuild.com), then you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/jsoncpp), or simply use `meson wrap install jsoncpp`. + ### Other ways If you have trouble, see the Wiki, or post a question as an Issue. From 2cb1ad5d0c1b2305b58503ec9363b753f48fd334 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 13:39:59 -0600 Subject: [PATCH 071/410] STYLE: Replace integer literals which are cast to bool. Finds and replaces integer literals which are cast to bool. SRCDIR=/Users/johnsonhj/src/jsoncpp #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-bool-literals -header-filter=.* -fix --- src/test_lib_json/main.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 37dbdd666..32f424be6 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2350,14 +2350,14 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { JSONCPP_STRING in; }; const TestData test_data[] = { - { __LINE__, 1, "{\"a\":9}" }, { __LINE__, 0, "{\"a\":0Infinity}" }, - { __LINE__, 0, "{\"a\":1Infinity}" }, { __LINE__, 0, "{\"a\":9Infinity}" }, - { __LINE__, 0, "{\"a\":0nfinity}" }, { __LINE__, 0, "{\"a\":1nfinity}" }, - { __LINE__, 0, "{\"a\":9nfinity}" }, { __LINE__, 0, "{\"a\":nfinity}" }, - { __LINE__, 0, "{\"a\":.nfinity}" }, { __LINE__, 0, "{\"a\":9nfinity}" }, - { __LINE__, 0, "{\"a\":-nfinity}" }, { __LINE__, 1, "{\"a\":Infinity}" }, - { __LINE__, 0, "{\"a\":.Infinity}" }, { __LINE__, 0, "{\"a\":_Infinity}" }, - { __LINE__, 0, "{\"a\":_nfinity}" }, { __LINE__, 1, "{\"a\":-Infinity}" } + { __LINE__, true, "{\"a\":9}" }, { __LINE__, false, "{\"a\":0Infinity}" }, + { __LINE__, false, "{\"a\":1Infinity}" }, { __LINE__, false, "{\"a\":9Infinity}" }, + { __LINE__, false, "{\"a\":0nfinity}" }, { __LINE__, false, "{\"a\":1nfinity}" }, + { __LINE__, false, "{\"a\":9nfinity}" }, { __LINE__, false, "{\"a\":nfinity}" }, + { __LINE__, false, "{\"a\":.nfinity}" }, { __LINE__, false, "{\"a\":9nfinity}" }, + { __LINE__, false, "{\"a\":-nfinity}" }, { __LINE__, true, "{\"a\":Infinity}" }, + { __LINE__, false, "{\"a\":.Infinity}" }, { __LINE__, false, "{\"a\":_Infinity}" }, + { __LINE__, false, "{\"a\":_nfinity}" }, { __LINE__, true, "{\"a\":-Infinity}" } }; for (size_t tdi = 0; tdi < sizeof(test_data) / sizeof(*test_data); ++tdi) { const TestData& td = test_data[tdi]; From 0417e626c0123de23dbc912fda65e4701b467c1c Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 09:40:05 -0600 Subject: [PATCH 072/410] STYLE: Convert CMake-language commands to lower case Ancient CMake versions required upper-case commands. Later command names became case-insensitive. Now the preferred style is lower-case. --- CMakeLists.txt | 186 +++++++++++++++--------------- include/CMakeLists.txt | 4 +- src/CMakeLists.txt | 10 +- src/jsontestrunner/CMakeLists.txt | 26 ++--- src/lib_json/CMakeLists.txt | 88 +++++++------- src/test_lib_json/CMakeLists.txt | 26 ++--- 6 files changed, 170 insertions(+), 170 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8374c41f6..83486cd64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,156 +1,156 @@ # vim: et ts=4 sts=4 sw=4 tw=0 -CMAKE_MINIMUM_REQUIRED(VERSION 3.1) +cmake_minimum_required(VERSION 3.1) # Ensures that CMAKE_BUILD_TYPE has a default value -IF(NOT DEFINED CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE Release CACHE STRING +if(NOT DEFINED CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") -ENDIF() +endif() -PROJECT(jsoncpp) -ENABLE_TESTING() +project(jsoncpp) +enable_testing() -OPTION(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) -OPTION(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) -OPTION(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) -OPTION(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON) -OPTION(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) -OPTION(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) -OPTION(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) +option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) +option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) +option(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) +option(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON) +option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) +option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) +option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) # Enable runtime search path support for dynamic libraries on OSX -IF(APPLE) - SET(CMAKE_MACOSX_RPATH 1) -ENDIF() +if(APPLE) + set(CMAKE_MACOSX_RPATH 1) +endif() # Adhere to GNU filesystem layout conventions -INCLUDE(GNUInstallDirs) +include(GNUInstallDirs) -SET(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build") +set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build") # Set variable named ${VAR_NAME} to value ${VALUE} -FUNCTION(set_using_dynamic_name VAR_NAME VALUE) - SET( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE) -ENDFUNCTION() +function(set_using_dynamic_name VAR_NAME VALUE) + set( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE) +endfunction() # Extract major, minor, patch from version text # Parse a version string "X.Y.Z" and outputs # version parts in ${OUPUT_PREFIX}_MAJOR, _MINOR, _PATCH. # If parse succeeds then ${OUPUT_PREFIX}_FOUND is TRUE. -MACRO(jsoncpp_parse_version VERSION_TEXT OUPUT_PREFIX) - SET(VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9_]+)?") - IF( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) - STRING(REGEX MATCHALL "[0-9]+|-([A-Za-z0-9_]+)" VERSION_PARTS ${VERSION_TEXT}) - LIST(GET VERSION_PARTS 0 ${OUPUT_PREFIX}_MAJOR) - LIST(GET VERSION_PARTS 1 ${OUPUT_PREFIX}_MINOR) - LIST(GET VERSION_PARTS 2 ${OUPUT_PREFIX}_PATCH) +macro(jsoncpp_parse_version VERSION_TEXT OUPUT_PREFIX) + set(VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9_]+)?") + if( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) + string(REGEX MATCHALL "[0-9]+|-([A-Za-z0-9_]+)" VERSION_PARTS ${VERSION_TEXT}) + list(GET VERSION_PARTS 0 ${OUPUT_PREFIX}_MAJOR) + list(GET VERSION_PARTS 1 ${OUPUT_PREFIX}_MINOR) + list(GET VERSION_PARTS 2 ${OUPUT_PREFIX}_PATCH) set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" TRUE ) - ELSE( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) + else( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" FALSE ) - ENDIF() -ENDMACRO() + endif() +endmacro() # Read out version from "version" file -#FILE(STRINGS "version" JSONCPP_VERSION) -#SET( JSONCPP_VERSION_MAJOR X ) -#SET( JSONCPP_VERSION_MINOR Y ) -#SET( JSONCPP_VERSION_PATCH Z ) -SET( JSONCPP_VERSION 1.8.4 ) +#file(STRINGS "version" JSONCPP_VERSION) +#set( JSONCPP_VERSION_MAJOR X ) +#set( JSONCPP_VERSION_MINOR Y ) +#set( JSONCPP_VERSION_PATCH Z ) +set( JSONCPP_VERSION 1.8.4 ) jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION ) -#IF(NOT JSONCPP_VERSION_FOUND) -# MESSAGE(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") -#ENDIF(NOT JSONCPP_VERSION_FOUND) -SET( JSONCPP_SOVERSION 19 ) -SET( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) +#if(NOT JSONCPP_VERSION_FOUND) +# message(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") +#endif(NOT JSONCPP_VERSION_FOUND) +set( JSONCPP_SOVERSION 19 ) +set( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) -MESSAGE(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") +message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") # File version.h is only regenerated on CMake configure step -CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" +configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" "${PROJECT_BINARY_DIR}/include/json/version.h" NEWLINE_STYLE UNIX ) -CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/version.in" +configure_file( "${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_BINARY_DIR}/version" NEWLINE_STYLE UNIX ) -MACRO(UseCompilationWarningAsError) - IF(MSVC) +macro(UseCompilationWarningAsError) + if(MSVC) # Only enabled in debug because some old versions of VS STL generate # warnings when compiled in release configuration. - SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") - ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") - IF(JSONCPP_WITH_STRICT_ISO) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") - ENDIF() - ENDIF() -ENDMACRO() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + if(JSONCPP_WITH_STRICT_ISO) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") + endif() + endif() +endmacro() # Include our configuration header -INCLUDE_DIRECTORIES( ${jsoncpp_SOURCE_DIR}/include ) +include_directories( ${jsoncpp_SOURCE_DIR}/include ) -IF(MSVC) +if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. - SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") -ENDIF() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") +endif() # Require C++11 support, prefer ISO C++ over GNU variants, # as relying solely on ISO C++ is more portable. -SET(CMAKE_CXX_STANDARD 11) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) -SET(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) -IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang") +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") -ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") # not yet ready for -Wsign-conversion - IF(JSONCPP_WITH_STRICT_ISO) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") - ENDIF() - IF(JSONCPP_WITH_WARNING_AS_ERROR) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") - ENDIF() -ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + if(JSONCPP_WITH_STRICT_ISO) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + endif() + if(JSONCPP_WITH_WARNING_AS_ERROR) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") + endif() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") - IF(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") - ENDIF() -ENDIF() + if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + endif() +endif() -FIND_PROGRAM(CCACHE_FOUND ccache) -IF(CCACHE_FOUND) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) -ENDIF(CCACHE_FOUND) +find_program(CCACHE_FOUND ccache) +if(CCACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) +endif(CCACHE_FOUND) -IF(JSONCPP_WITH_WARNING_AS_ERROR) +if(JSONCPP_WITH_WARNING_AS_ERROR) UseCompilationWarningAsError() -ENDIF() +endif() -IF(JSONCPP_WITH_PKGCONFIG_SUPPORT) - CONFIGURE_FILE( +if(JSONCPP_WITH_PKGCONFIG_SUPPORT) + configure_file( "pkg-config/jsoncpp.pc.in" "pkg-config/jsoncpp.pc" @ONLY) - INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkg-config/jsoncpp.pc" + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pkg-config/jsoncpp.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") -ENDIF() +endif() -IF(JSONCPP_WITH_CMAKE_PACKAGE) - INSTALL(EXPORT jsoncpp +if(JSONCPP_WITH_CMAKE_PACKAGE) + install(EXPORT jsoncpp DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp FILE jsoncppConfig.cmake) -ENDIF() +endif() # Build the different applications -ADD_SUBDIRECTORY( src ) +add_subdirectory( src ) #install the includes -ADD_SUBDIRECTORY( include ) +add_subdirectory( include ) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index cc866f173..7f1cb9822 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,2 +1,2 @@ -FILE(GLOB INCLUDE_FILES "json/*.h") -INSTALL(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json) +file(GLOB INCLUDE_FILES "json/*.h") +install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca8ac15e2..0f82a7463 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,5 @@ -ADD_SUBDIRECTORY(lib_json) -IF(JSONCPP_WITH_TESTS) - ADD_SUBDIRECTORY(jsontestrunner) - ADD_SUBDIRECTORY(test_lib_json) -ENDIF() +add_subdirectory(lib_json) +if(JSONCPP_WITH_TESTS) + add_subdirectory(jsontestrunner) + add_subdirectory(test_lib_json) +endif() diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 3d2ffee69..9862399a8 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -1,23 +1,23 @@ -FIND_PACKAGE(PythonInterp 2.6) +find_package(PythonInterp 2.6) -ADD_EXECUTABLE(jsontestrunner_exe +add_executable(jsontestrunner_exe main.cpp ) -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL ) -ENDIF() -TARGET_LINK_LIBRARIES(jsontestrunner_exe jsoncpp_lib) +if(BUILD_SHARED_LIBS) + add_definitions( -DJSON_DLL ) +endif() +target_link_libraries(jsontestrunner_exe jsoncpp_lib) -SET_TARGET_PROPERTIES(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) +set_target_properties(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) -IF(PYTHONINTERP_FOUND) +if(PYTHONINTERP_FOUND) # Run end to end parser/writer tests - SET(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test) - SET(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py) - ADD_CUSTOM_TARGET(jsoncpp_readerwriter_tests + set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test) + set(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py) + add_custom_target(jsoncpp_readerwriter_tests "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" DEPENDS jsontestrunner_exe jsoncpp_test ) - ADD_CUSTOM_TARGET(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) -ENDIF() + add_custom_target(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) +endif() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index d710ce0c2..6f89eb13a 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -1,45 +1,45 @@ -IF( CMAKE_COMPILER_IS_GNUCXX ) +if( CMAKE_COMPILER_IS_GNUCXX ) #Get compiler version. - EXECUTE_PROCESS( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion + execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GNUCXX_VERSION ) #-Werror=* was introduced -after- GCC 4.1.2 - IF( GNUCXX_VERSION VERSION_GREATER 4.1.2 ) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing") - ENDIF() -ENDIF( CMAKE_COMPILER_IS_GNUCXX ) + if( GNUCXX_VERSION VERSION_GREATER 4.1.2 ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing") + endif() +endif( CMAKE_COMPILER_IS_GNUCXX ) -INCLUDE(CheckIncludeFileCXX) -INCLUDE(CheckTypeSize) -INCLUDE(CheckStructHasMember) -INCLUDE(CheckCXXSymbolExists) +include(CheckIncludeFileCXX) +include(CheckTypeSize) +include(CheckStructHasMember) +include(CheckCXXSymbolExists) check_include_file_cxx(clocale HAVE_CLOCALE) check_cxx_symbol_exists(localeconv clocale HAVE_LOCALECONV) -IF(CMAKE_VERSION VERSION_LESS 3.0.0) +if(CMAKE_VERSION VERSION_LESS 3.0.0) # The "LANGUAGE CXX" parameter is not supported in CMake versions below 3, # so the C compiler and header has to be used. check_include_file(locale.h HAVE_LOCALE_H) - SET(CMAKE_EXTRA_INCLUDE_FILES locale.h) + set(CMAKE_EXTRA_INCLUDE_FILES locale.h) check_type_size("struct lconv" LCONV_SIZE) - UNSET(CMAKE_EXTRA_INCLUDE_FILES) + unset(CMAKE_EXTRA_INCLUDE_FILES) check_struct_has_member("struct lconv" decimal_point locale.h HAVE_DECIMAL_POINT) -ELSE() - SET(CMAKE_EXTRA_INCLUDE_FILES clocale) +else() + set(CMAKE_EXTRA_INCLUDE_FILES clocale) check_type_size(lconv LCONV_SIZE LANGUAGE CXX) - UNSET(CMAKE_EXTRA_INCLUDE_FILES) + unset(CMAKE_EXTRA_INCLUDE_FILES) check_struct_has_member(lconv decimal_point clocale HAVE_DECIMAL_POINT LANGUAGE CXX) -ENDIF() +endif() -IF(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) - MESSAGE(WARNING "Locale functionality is not supported") - ADD_DEFINITIONS(-DJSONCPP_NO_LOCALE_SUPPORT) -ENDIF() +if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) + message(WARNING "Locale functionality is not supported") + add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) +endif() -SET( JSONCPP_INCLUDE_DIR ../../include ) +set( JSONCPP_INCLUDE_DIR ../../include ) -SET( PUBLIC_HEADERS +set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/config.h ${JSONCPP_INCLUDE_DIR}/json/forwards.h ${JSONCPP_INCLUDE_DIR}/json/features.h @@ -50,9 +50,9 @@ SET( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/version.h ) -SOURCE_GROUP( "Public API" FILES ${PUBLIC_HEADERS} ) +source_group( "Public API" FILES ${PUBLIC_HEADERS} ) -SET(jsoncpp_sources +set(jsoncpp_sources json_tool.h json_reader.cpp json_valueiterator.inl @@ -61,35 +61,35 @@ SET(jsoncpp_sources version.h.in) # Install instructions for this target -IF(JSONCPP_WITH_CMAKE_PACKAGE) - SET(INSTALL_EXPORT EXPORT jsoncpp) -ELSE(JSONCPP_WITH_CMAKE_PACKAGE) - SET(INSTALL_EXPORT) -ENDIF() +if(JSONCPP_WITH_CMAKE_PACKAGE) + set(INSTALL_EXPORT EXPORT jsoncpp) +else(JSONCPP_WITH_CMAKE_PACKAGE) + set(INSTALL_EXPORT) +endif() -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL_BUILD ) -ENDIF() +if(BUILD_SHARED_LIBS) + add_definitions( -DJSON_DLL_BUILD ) +endif() -ADD_LIBRARY(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) -SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) -SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp +add_library(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) +set_target_properties( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) +set_target_properties( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) -SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) # Set library's runtime search path on OSX -IF(APPLE) - SET_TARGET_PROPERTIES( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) -ENDIF() +if(APPLE) + set_target_properties( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) +endif() -INSTALL( TARGETS jsoncpp_lib ${INSTALL_EXPORT} +install( TARGETS jsoncpp_lib ${INSTALL_EXPORT} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -IF(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - TARGET_INCLUDE_DIRECTORIES( jsoncpp_lib PUBLIC +if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + target_include_directories( jsoncpp_lib PUBLIC $ $) -ENDIF() +endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index c6a534f30..7c7b6afe7 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -1,36 +1,36 @@ # vim: et ts=4 sts=4 sw=4 tw=0 -ADD_EXECUTABLE( jsoncpp_test +add_executable( jsoncpp_test jsontest.cpp jsontest.h main.cpp ) -IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS( -DJSON_DLL ) -ENDIF() -TARGET_LINK_LIBRARIES(jsoncpp_test jsoncpp_lib) +if(BUILD_SHARED_LIBS) + add_definitions( -DJSON_DLL ) +endif() +target_link_libraries(jsoncpp_test jsoncpp_lib) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) # Run unit tests in post-build # (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) -IF(JSONCPP_WITH_POST_BUILD_UNITTEST) - IF(BUILD_SHARED_LIBS) +if(JSONCPP_WITH_POST_BUILD_UNITTEST) + if(BUILD_SHARED_LIBS) # First, copy the shared lib, for Microsoft. # Then, run the test executable. - ADD_CUSTOM_COMMAND( TARGET jsoncpp_test + add_custom_command( TARGET jsoncpp_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - ELSE(BUILD_SHARED_LIBS) + else(BUILD_SHARED_LIBS) # Just run the test executable. - ADD_CUSTOM_COMMAND( TARGET jsoncpp_test + add_custom_command( TARGET jsoncpp_test POST_BUILD COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - ENDIF() -ENDIF() + endif() +endif() -SET_TARGET_PROPERTIES(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) +set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) From 892a386018177522c8d48b782fd0418fd8f34d46 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 09:56:19 -0600 Subject: [PATCH 073/410] ENH: Use cmake builtin versioning capabilities The project directive in cmake 3.1 has a builtin mechanism for providing consistent versioning in a package. --- CMakeLists.txt | 38 ++++++++------------------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 83486cd64..189a8c8e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,14 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") endif() -project(jsoncpp) +project(JSONCPP + VERSION 1.8.4 # [.[.[.]]] + LANGUAGES CXX) + +set( JSONCPP_VERSION ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH} ) +message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") +set( JSONCPP_SOVERSION 19 ) + enable_testing() option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) @@ -34,37 +41,8 @@ function(set_using_dynamic_name VAR_NAME VALUE) set( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE) endfunction() -# Extract major, minor, patch from version text -# Parse a version string "X.Y.Z" and outputs -# version parts in ${OUPUT_PREFIX}_MAJOR, _MINOR, _PATCH. -# If parse succeeds then ${OUPUT_PREFIX}_FOUND is TRUE. -macro(jsoncpp_parse_version VERSION_TEXT OUPUT_PREFIX) - set(VERSION_REGEX "[0-9]+\\.[0-9]+\\.[0-9]+(-[a-zA-Z0-9_]+)?") - if( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) - string(REGEX MATCHALL "[0-9]+|-([A-Za-z0-9_]+)" VERSION_PARTS ${VERSION_TEXT}) - list(GET VERSION_PARTS 0 ${OUPUT_PREFIX}_MAJOR) - list(GET VERSION_PARTS 1 ${OUPUT_PREFIX}_MINOR) - list(GET VERSION_PARTS 2 ${OUPUT_PREFIX}_PATCH) - set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" TRUE ) - else( ${VERSION_TEXT} MATCHES ${VERSION_REGEX} ) - set_using_dynamic_name( "${OUPUT_PREFIX}_FOUND" FALSE ) - endif() -endmacro() - -# Read out version from "version" file -#file(STRINGS "version" JSONCPP_VERSION) -#set( JSONCPP_VERSION_MAJOR X ) -#set( JSONCPP_VERSION_MINOR Y ) -#set( JSONCPP_VERSION_PATCH Z ) -set( JSONCPP_VERSION 1.8.4 ) -jsoncpp_parse_version( ${JSONCPP_VERSION} JSONCPP_VERSION ) -#if(NOT JSONCPP_VERSION_FOUND) -# message(FATAL_ERROR "Failed to parse version string properly. Expect X.Y.Z") -#endif(NOT JSONCPP_VERSION_FOUND) -set( JSONCPP_SOVERSION 19 ) set( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) -message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") # File version.h is only regenerated on CMake configure step configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" "${PROJECT_BINARY_DIR}/include/json/version.h" From b3b92df879828d013cadb76e9791c0c6f1d85f26 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 10:02:42 -0600 Subject: [PATCH 074/410] ENH: Provide range for non-warned cmake versions Allow configuring without cmake policy developer warnings for a range of cmake versions. This prevents the need to explicitly enumerate every new policy for each new cmake version. === Moved setting of the CMAKE_CXX_STANDARD to before the project() directive. --- CMakeLists.txt | 62 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 189a8c8e8..6a6e8dc51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,60 @@ # vim: et ts=4 sts=4 sw=4 tw=0 -cmake_minimum_required(VERSION 3.1) +# ==== Define cmake build policies that affect compilation and linkage default behaviors +# +# Set the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION string to the newest cmake version +# policies that provide successful builds. By setting JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION +# to a value greater than the oldest policies, all policies between +# JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION (used for this build) +# are set to their NEW behaivor, thereby suppressing policy warnings related to policies +# between the JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION. +# +# CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will +# continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:" +# +set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.1.0") +set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.1") +cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION} FATAL_ERROR) +if("${CMAKE_VERSION}" VERSION_LESS_EQUAL "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") + #Set and use the newest available cmake policies that are validated to work + set(JSONCPP_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") +else() + set(JSONCPP_CMAKE_POLICY_VERSION "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") +endif() +cmake_policy(VERSION ${JSONCPP_CMAKE_POLICY_VERSION}) +# +# Now enumerate specific policies newer than JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION +# that may need to be individually set to NEW/OLD +# +foreach(pnew "") # Currently Empty + if(POLICY ${pnew}) + cmake_policy(SET ${pnew} NEW) + endif() +endforeach() +foreach(pold "") # Currently Empty + if(POLICY ${pold}) + cmake_policy(SET ${pold} OLD) + endif() +endforeach() + +# ==== Define language standard configurations requiring at least c++11 standard +if(CMAKE_CXX_STANDARD EQUAL "98" ) + message(FATAL_ERROR "CMAKE_CXX_STANDARD:STRING=98 is not supported.") +endif() + +##### +## Set the default target properties +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) # Supported values are ``11``, ``14``, and ``17``. +endif() +if(NOT CMAKE_CXX_STANDARD_REQUIRED) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() +if(NOT CMAKE_CXX_EXTENSIONS) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() + +# ==== # Ensures that CMAKE_BUILD_TYPE has a default value if(NOT DEFINED CMAKE_BUILD_TYPE) @@ -73,12 +127,6 @@ if(MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") endif() -# Require C++11 support, prefer ISO C++ over GNU variants, -# as relying solely on ISO C++ is more portable. -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) - if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") From 97e05c41f222a503b50c5dd85515a6d763374d47 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 12 Dec 2018 10:11:54 -0600 Subject: [PATCH 075/410] COMP: Provide C++11 feature testing during config Test compiler feature sets early so that required features are validated before long compilation process is started. --- src/lib_json/CMakeLists.txt | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 6f89eb13a..fc4e7a08f 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -83,6 +83,56 @@ if(APPLE) set_target_properties( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) endif() +# Specify compiler features required when compiling a given target. +# See https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES +# for complete list of features available +target_compile_features(jsoncpp_lib PUBLIC + cxx_std_11 # Compiler mode is aware of C++ 11. + #MSVC 1900 cxx_alignas # Alignment control alignas, as defined in N2341. + #MSVC 1900 cxx_alignof # Alignment control alignof, as defined in N2341. + #MSVC 1900 cxx_attributes # Generic attributes, as defined in N2761. + cxx_auto_type # Automatic type deduction, as defined in N1984. + #MSVC 1900 cxx_constexpr # Constant expressions, as defined in N2235. + cxx_decltype # Decltype, as defined in N2343. + cxx_default_function_template_args # Default template arguments for function templates, as defined in DR226 + cxx_defaulted_functions # Defaulted functions, as defined in N2346. + #MSVC 1900 cxx_defaulted_move_initializers # Defaulted move initializers, as defined in N3053. + cxx_delegating_constructors # Delegating constructors, as defined in N1986. + #MSVC 1900 cxx_deleted_functions # Deleted functions, as defined in N2346. + cxx_enum_forward_declarations # Enum forward declarations, as defined in N2764. + cxx_explicit_conversions # Explicit conversion operators, as defined in N2437. + cxx_extended_friend_declarations # Extended friend declarations, as defined in N1791. + cxx_extern_templates # Extern templates, as defined in N1987. + cxx_final # Override control final keyword, as defined in N2928, N3206 and N3272. + #MSVC 1900 cxx_func_identifier # Predefined __func__ identifier, as defined in N2340. + #MSVC 1900 cxx_generalized_initializers # Initializer lists, as defined in N2672. + #MSVC 1900 cxx_inheriting_constructors # Inheriting constructors, as defined in N2540. + #MSVC 1900 cxx_inline_namespaces # Inline namespaces, as defined in N2535. + cxx_lambdas # Lambda functions, as defined in N2927. + #MSVC 1900 cxx_local_type_template_args # Local and unnamed types as template arguments, as defined in N2657. + cxx_long_long_type # long long type, as defined in N1811. + #MSVC 1900 cxx_noexcept # Exception specifications, as defined in N3050. + #MSVC 1900 cxx_nonstatic_member_init # Non-static data member initialization, as defined in N2756. + cxx_nullptr # Null pointer, as defined in N2431. + cxx_override # Override control override keyword, as defined in N2928, N3206 and N3272. + cxx_range_for # Range-based for, as defined in N2930. + cxx_raw_string_literals # Raw string literals, as defined in N2442. + #MSVC 1900 cxx_reference_qualified_functions # Reference qualified functions, as defined in N2439. + cxx_right_angle_brackets # Right angle bracket parsing, as defined in N1757. + cxx_rvalue_references # R-value references, as defined in N2118. + #MSVC 1900 cxx_sizeof_member # Size of non-static data members, as defined in N2253. + cxx_static_assert # Static assert, as defined in N1720. + cxx_strong_enums # Strongly typed enums, as defined in N2347. + #MSVC 1900 cxx_thread_local # Thread-local variables, as defined in N2659. + cxx_trailing_return_types # Automatic function return type, as defined in N2541. + #MSVC 1900 cxx_unicode_literals # Unicode string literals, as defined in N2442. + cxx_uniform_initialization # Uniform initialization, as defined in N2640. + #MSVC 1900 cxx_unrestricted_unions # Unrestricted unions, as defined in N2544. + #MSVC 1900 cxx_user_literals # User-defined literals, as defined in N2765. + cxx_variadic_macros # Variadic macros, as defined in N1653. + cxx_variadic_templates # Variadic templates, as defined in N2242. +) + install( TARGETS jsoncpp_lib ${INSTALL_EXPORT} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} From 08ddeed927ed58d69c6c0d971b69cab6cefba1e1 Mon Sep 17 00:00:00 2001 From: "Mathias L. Baumann" Date: Wed, 12 Dec 2018 17:59:43 +0100 Subject: [PATCH 076/410] JsonValue documentation: Rephrase confusing sentence --- include/json/value.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/json/value.h b/include/json/value.h index e7a9225d3..58f1f8b66 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -173,7 +173,7 @@ class JSON_API StaticString { * The get() methods can be used to obtain default value in the case the * required element does not exist. * - * It is possible to iterate over the list of a #objectValue values using + * It is possible to iterate over the list of member keys of an object using * the getMemberNames() method. * * \note #Value string-length fit in size_t, but keys must be < 2^30. From d8723104f36339d348b995b70b3d7cb52b7d8020 Mon Sep 17 00:00:00 2001 From: Orivej Desh Date: Mon, 26 Nov 2018 18:24:18 +0000 Subject: [PATCH 077/410] Update removeMember docs after #693 --- include/json/value.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 58f1f8b66..3d765ec1f 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -538,14 +538,11 @@ Json::Value obj_value(Json::objectValue); // {} /// \brief Remove and return the named member. /// /// Do nothing if it did not exist. - /// \return the removed Value, or null. /// \pre type() is objectValue or nullValue /// \post type() is unchanged - /// \deprecated void removeMember(const char* key); /// Same as removeMember(const char*) /// \param key may contain embedded nulls. - /// \deprecated void removeMember(const JSONCPP_STRING& key); /// Same as removeMember(const char* begin, const char* end, Value* removed), /// but 'key' is null-terminated. From 7d16e10113f632a80adb45f514f72c54bec3673c Mon Sep 17 00:00:00 2001 From: fangguo Date: Tue, 25 Sep 2018 08:57:36 +0800 Subject: [PATCH 078/410] =?UTF-8?q?fiexd=20=E2=80=9CCannot=20take=20the=20?= =?UTF-8?q?address=20of=20a=20bit=20field.=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ```c++ #include class TestBool { public: TestBool():addChildValues_(){} TestBool(int):addChildValues_(false){} bool addChildValues_ : 1; bool indented_ : 1; }; int main() { std::cout << "\n TestBool () addChildValues_ = " << TestBool().addChildValues_; std::cout << "\n TestBool false addChildValues_ = " << TestBool(3).addChildValues_; return 0; } ``` ```text root@osssvr-1 # /opt/SUNWspro/prod/bin/CC testbool.cpp -o testbool Error: Cannot take the address of a bit field. 1 Error(s) detected. ``` --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 3a7fd8e53..2197efba6 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -425,7 +425,7 @@ void FastWriter::writeValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledWriter::StyledWriter() - : rightMargin_(74), indentSize_(3), addChildValues_() {} + : rightMargin_(74), indentSize_(3), addChildValues_(false) {} JSONCPP_STRING StyledWriter::write(const Value& root) { document_.clear(); From 009a3ad24ce45014f0c738f4a7c5a12fbfd41995 Mon Sep 17 00:00:00 2001 From: Stefano Fiorentino Date: Sun, 18 Nov 2018 23:01:24 +0100 Subject: [PATCH 079/410] issue_836: Check if `removed' is a valid pointer before copy data to it functions involved: - bool Value::removeMember(const char* key, const char* cend, Value* removed) Signed-off-by: Stefano Fiorentino --- src/test_lib_json/main.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 32f424be6..23da4b3a3 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -222,6 +222,12 @@ JSONTEST_FIXTURE(ValueTest, objects) { did = object1_.removeMember("some other id", &got); JSONTEST_ASSERT_EQUAL(Json::Value("bar"), got); JSONTEST_ASSERT_EQUAL(false, did); + + object1_["some other id"] = "foo"; + Json::Value* gotPtr = nullptr; + did = object1_.removeMember("some other id", gotPtr); + JSONTEST_ASSERT_EQUAL(nullptr, gotPtr); + JSONTEST_ASSERT_EQUAL(true, did); } JSONTEST_FIXTURE(ValueTest, arrays) { From 056850c44bde57772b52ee3092a45770ebf873ba Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 11 Dec 2018 12:48:46 -0500 Subject: [PATCH 080/410] reader: fix signed overflow when parsing negative value Clang's ubsan (-fsanitize=undefined) reports: runtime error: negation of -9223372036854775808 cannot be represented in type 'Json::Value::LargestInt' (aka 'long'); cast to an unsigned type to negate this value to itself Follow its advice and update the code to remove the explicit negation. --- src/lib_json/json_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index cb88eaba4..ad7e15d6f 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1564,7 +1564,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { // TODO: Help the compiler do the div and mod at compile time or get rid of // them. Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(-Value::minLargestInt) + isNegative ? Value::LargestUInt(Value::minLargestInt) : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; From f8ad1ab352d2cd5bfd9abf319250403b339a8bf2 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 11 Jan 2019 14:41:10 -0600 Subject: [PATCH 081/410] BUG: Fix bug in CI where failure during homebrew update occured. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 27978e4a4..2306bea60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ matrix: osx_image: xcode9.4 compiler: clang #env: PYENV_ROOT=/usr/local/var/pyenv - env: LIB_TYPE=static BUILD_TYPE=release + env: LIB_TYPE=static BUILD_TYPE=release HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp #- LIB_TYPE=shared BUILD_TYPE=debug - os: linux dist: trusty From fa61a49b83d540c422c7c21508a420b6c9070fa9 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 11 Jan 2019 15:13:10 -0600 Subject: [PATCH 082/410] ENH: Use recommended homebrew addon for travis. Remove unnecessary python3 environment from osx that made configuring the test environment slower. Use "addon:" features for installing homebrew packages more efficiently. Re-organized the .travis.yml file in a standard order so that the "before-install" and "install" steps occur after the configurations of addons and matrix, and language features are set. --- .travis.yml | 23 ++++++++++++++--------- travis.before_install.osx.sh | 4 +++- travis.install.osx.sh | 15 ++++----------- travis.sh | 3 +++ 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2306bea60..90c17fa54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,12 +5,12 @@ # See also # http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448 # to allow C++11, though we are not yet building with -std=c++11 - -before_install: -- source travis.before_install.${TRAVIS_OS_NAME}.sh -install: -- source travis.install.${TRAVIS_OS_NAME}.sh +language: cpp +sudo: false addons: + homebrew: + packages: meson ninja + update: false # do not update homebrew by default apt: sources: #- ubuntu-toolchain-r-test @@ -20,16 +20,16 @@ addons: #- g++-4.9 - clang-3.5 - valgrind -language: cpp -script: ./travis.sh matrix: allow_failures: - os: osx -matrix: include: - os: osx osx_image: xcode9.4 compiler: clang + addons: + homebrew: + packages: meson ninja #env: PYENV_ROOT=/usr/local/var/pyenv env: LIB_TYPE=static BUILD_TYPE=release HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp #- LIB_TYPE=shared BUILD_TYPE=debug @@ -39,4 +39,9 @@ matrix: env: LIB_TYPE=static BUILD_TYPE=release notifications: email: false -sudo: false + +before_install: +- source ./travis.before_install.${TRAVIS_OS_NAME}.sh +install: +- source ./travis.install.${TRAVIS_OS_NAME}.sh +script: ./travis.sh diff --git a/travis.before_install.osx.sh b/travis.before_install.osx.sh index a8377faef..d7d11a54e 100644 --- a/travis.before_install.osx.sh +++ b/travis.before_install.osx.sh @@ -1,3 +1,5 @@ -set -vex +# NOTHING TO DO HERE +# set -vex + #brew install pyenv #which pyenv diff --git a/travis.install.osx.sh b/travis.install.osx.sh index e82bdc660..1c6c6f0e1 100644 --- a/travis.install.osx.sh +++ b/travis.install.osx.sh @@ -1,12 +1,5 @@ -set -vex +# NOTHING TO DO HERE +# set -vex -#brew update -brew upgrade python3 -python3 -m venv venv -source venv/bin/activate - -brew install ninja -brew install meson - -#brew install pyenv -#which pyenv +#python3 -m venv venv +#source venv/bin/activate diff --git a/travis.sh b/travis.sh index f0628fc56..769110074 100755 --- a/travis.sh +++ b/travis.sh @@ -17,6 +17,9 @@ set -vex env | sort +which python3 +which meson +which ninja echo ${CXX} ${CXX} --version python3 --version From 10a1a38b37c2189bda229f7772ced4c4f919641b Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Sat, 12 Jan 2019 08:54:50 -0600 Subject: [PATCH 083/410] ENH: move travis support scripts to .travis_scripts Move the build support scripts for travis to a hidden subdirectory to keep the top level directory more clean. --- .travis.yml | 17 +++++++---------- .../travis.before_install.linux.sh | 0 .../travis.before_install.osx.sh | 0 .../travis.install.linux.sh | 0 .../travis.install.osx.sh | 0 travis.sh => .travis_scripts/travis.sh | 0 6 files changed, 7 insertions(+), 10 deletions(-) rename travis.before_install.linux.sh => .travis_scripts/travis.before_install.linux.sh (100%) rename travis.before_install.osx.sh => .travis_scripts/travis.before_install.osx.sh (100%) rename travis.install.linux.sh => .travis_scripts/travis.install.linux.sh (100%) rename travis.install.osx.sh => .travis_scripts/travis.install.osx.sh (100%) rename travis.sh => .travis_scripts/travis.sh (100%) diff --git a/.travis.yml b/.travis.yml index 90c17fa54..393bd5ca8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,9 @@ language: cpp sudo: false addons: homebrew: - packages: meson ninja + packages: + - meson + - ninja update: false # do not update homebrew by default apt: sources: @@ -27,12 +29,7 @@ matrix: - os: osx osx_image: xcode9.4 compiler: clang - addons: - homebrew: - packages: meson ninja - #env: PYENV_ROOT=/usr/local/var/pyenv - env: LIB_TYPE=static BUILD_TYPE=release HOMEBREW_LOGS=~/homebrew-logs HOMEBREW_TEMP=~/homebrew-temp - #- LIB_TYPE=shared BUILD_TYPE=debug + env: LIB_TYPE=static BUILD_TYPE=release - os: linux dist: trusty compiler: clang @@ -41,7 +38,7 @@ notifications: email: false before_install: -- source ./travis.before_install.${TRAVIS_OS_NAME}.sh +- source ./.travis_scripts/travis.before_install.${TRAVIS_OS_NAME}.sh install: -- source ./travis.install.${TRAVIS_OS_NAME}.sh -script: ./travis.sh +- source ./.travis_scripts/travis.install.${TRAVIS_OS_NAME}.sh +script: ./.travis_scripts/travis.sh diff --git a/travis.before_install.linux.sh b/.travis_scripts/travis.before_install.linux.sh similarity index 100% rename from travis.before_install.linux.sh rename to .travis_scripts/travis.before_install.linux.sh diff --git a/travis.before_install.osx.sh b/.travis_scripts/travis.before_install.osx.sh similarity index 100% rename from travis.before_install.osx.sh rename to .travis_scripts/travis.before_install.osx.sh diff --git a/travis.install.linux.sh b/.travis_scripts/travis.install.linux.sh similarity index 100% rename from travis.install.linux.sh rename to .travis_scripts/travis.install.linux.sh diff --git a/travis.install.osx.sh b/.travis_scripts/travis.install.osx.sh similarity index 100% rename from travis.install.osx.sh rename to .travis_scripts/travis.install.osx.sh diff --git a/travis.sh b/.travis_scripts/travis.sh similarity index 100% rename from travis.sh rename to .travis_scripts/travis.sh From a3c8e86c0ba77529cf2f03a642fc45e57adbe599 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Sat, 12 Jan 2019 12:32:15 -0600 Subject: [PATCH 084/410] ENH: Refactor and enhance the CI testing infrastructure 1) Improve travis build script for use outside travis. Allow the script used for CI builds to also be used locally in a similar manner to the CI use of the scrips 2) Add ctest compatible testing and CDASH support Report testing and building results to https://my.cdash.org/index.php?project=jsoncpp NOTE: The new ctest infrastructure is not yet robust on winodws Do no yet enable the new features for running test with ctest on windows platform. The previous behaviors are maintainted, but enhance test reporting from windows is not yet supported. 3) Add a cmake coverage testing option Ensure that cmake builds on linux are tested. Ensure that code coverage is reported. 4) Move conditional environment checking into the matrix Avoid multiple places where conditional logic is used to change compiler behavior. As more test environments are created fromt the travis.yml matrix, all settings should be obvious from that one location. 5) Tests with known regressions from the jsonchecker are suppressed Tests that are known to pass with jsoncpp more lenient syntax enforcement are exluded from tests in test/runjsontests.py --- .travis.yml | 51 ++++++++-- .travis_scripts/cmake_builder.sh | 130 ++++++++++++++++++++++++ .travis_scripts/meson_builder.sh | 81 +++++++++++++++ .travis_scripts/travis.install.linux.sh | 4 - .travis_scripts/travis.sh | 34 ------- CMakeLists.txt | 8 +- CTestConfig.cmake | 15 +++ README.md | 6 +- appveyor.yml | 6 +- src/jsontestrunner/CMakeLists.txt | 13 +++ src/test_lib_json/CMakeLists.txt | 8 +- test/runjsontests.py | 40 +++++++- 12 files changed, 341 insertions(+), 55 deletions(-) create mode 100755 .travis_scripts/cmake_builder.sh create mode 100755 .travis_scripts/meson_builder.sh delete mode 100755 .travis_scripts/travis.sh create mode 100644 CTestConfig.cmake diff --git a/.travis.yml b/.travis.yml index 393bd5ca8..fe71962ae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,19 +26,52 @@ matrix: allow_failures: - os: osx include: - - os: osx + - name: Mac clang meson static release testing + os: osx osx_image: xcode9.4 compiler: clang - env: LIB_TYPE=static BUILD_TYPE=release - - os: linux + env: + CXX="clang++-3.5" + CC="clang-3.5" + LIB_TYPE=static + BUILD_TYPE=release + script: ./.travis_scripts/meson_builder.sh + - name: trusty clang meson static release testing + os: linux dist: trusty compiler: clang - env: LIB_TYPE=static BUILD_TYPE=release + env: + CXX="clang++-3.5" + CC="clang-3.5" + LIB_TYPE=static + BUILD_TYPE=release + # before_install and install steps only needed for linux meson builds + before_install: + - source ./.travis_scripts/travis.before_install.${TRAVIS_OS_NAME}.sh + install: + - source ./.travis_scripts/travis.install.${TRAVIS_OS_NAME}.sh + script: ./.travis_scripts/meson_builder.sh + - name: xenial gcc cmake coverage + os: linux + dist: xenial + compiler: gcc + env: + CXX=g++ + CC=gcc + DO_Coverage=ON + BUILD_TOOL="Unix Makefiles" + BUILD_TYPE=Debug + LIB_TYPE=shared + DESTDIR=/tmp/cmake_json_cpp + script: ./.travis_scripts/cmake_builder.sh +# Valgrind has too many false positives from the python wrapping. Need a good suppression file +# - name: xenial gcc cmake coverage +# os: linux +# dist: xenial +# compiler: gcc +# env: DO_MemCheck=ON CXX=/usr/bin/g++ BUILD_TOOL="Unix Makefiles" BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp +# script: ./.travis_scripts/cmake_builder.sh notifications: email: false -before_install: -- source ./.travis_scripts/travis.before_install.${TRAVIS_OS_NAME}.sh -install: -- source ./.travis_scripts/travis.install.${TRAVIS_OS_NAME}.sh -script: ./.travis_scripts/travis.sh + diff --git a/.travis_scripts/cmake_builder.sh b/.travis_scripts/cmake_builder.sh new file mode 100755 index 000000000..c0118782c --- /dev/null +++ b/.travis_scripts/cmake_builder.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env sh +# This script can be used on the command line directly to configure several +# different build environments. +# This is called by `.travis.yml` via Travis CI. +# Travis supplies $TRAVIS_OS_NAME. +# http://docs.travis-ci.com/user/multi-os/ +# Our .travis.yml also defines: + +# - BUILD_TYPE=Release/Debug +# - LIB_TYPE=static/shared +# +# Optional environmental variables +# - DESTDIR <- used for setting the install prefix +# - BUILD_TOOL=["Unix Makefile"|"Ninja"] +# - BUILDNAME <-- how to identify this build on the dashboard +# - DO_MemCheck <- if set, try to use valgrind +# - DO_Coverage <- if set, try to do dashboard coverage testing +# + +env_set=1 +if ${BUILD_TYPE+false}; then + echo "BUILD_TYPE not set in environment." + env_set=0 +fi +if ${LIB_TYPE+false}; then + echo "LIB_TYPE not set in environment." + env_set=0 +fi +if ${CXX+false}; then + echo "CXX not set in environment." + env_set=0 +fi + + +if [ ${env_set} -eq 0 ]; then + echo "USAGE: CXX=$(which clang++) BUILD_TYPE=[Release|Debug] LIB_TYPE=[static|shared] $0" + echo "" + echo "Examples:" + echo " CXX=$(which clang++) BUILD_TYPE=Release LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=Release LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=Debug LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" + + echo " CXX=$(which g++) BUILD_TYPE=Release LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=Release LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=Debug LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" + + exit -1 +fi + +if ${DESTDIR+false}; then + DESTDIR="/usr/local" +fi + +# -e: fail on error +# -v: show commands +# -x: show expanded commands +set -vex + +env | sort + +which cmake +cmake --version + +echo ${CXX} +${CXX} --version +_COMPILER_NAME=`basename ${CXX}` +if [ "${BUILD_TYPE}" == "shared" ]; then + _CMAKE_BUILD_SHARED_LIBS=ON +else + _CMAKE_BUILD_SHARED_LIBS=OFF +fi + +CTEST_TESTING_OPTION="-D ExperimentalTest" +# - DO_MemCheck <- if set, try to use valgrind +if ! ${DO_MemCheck+false}; then + valgrind --version + CTEST_TESTING_OPTION="-D ExperimentalMemCheck" +else +# - DO_Coverage <- if set, try to do dashboard coverage testing + if ! ${DO_Coverage+false}; then + export CXXFLAGS="-fprofile-arcs -ftest-coverage" + export LDFLAGS="-fprofile-arcs -ftest-coverage" + CTEST_TESTING_OPTION="-D ExperimentalTest -D ExperimentalCoverage" + #gcov --version + fi +fi + +# Ninja = Generates build.ninja files. +if ${BUILD_TOOL+false}; then + BUILD_TOOL="Ninja" + export _BUILD_EXE=ninja + which ninja + ninja --version +else +# Unix Makefiles = Generates standard UNIX makefiles. + export _BUILD_EXE=make +fi + +_BUILD_DIR_NAME="build-cmake_${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}_${_BUILD_EXE}" +mkdir -p ${_BUILD_DIR_NAME} +cd "${_BUILD_DIR_NAME}" + if ${BUILDNAME+false}; then + _HOSTNAME=`hostname -s` + BUILDNAME="${_HOSTNAME}_${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}_${_BUILD_EXE}" + fi + cmake \ + -G "${BUILD_TOOL}" \ + -DBUILDNAME:STRING="${BUILDNAME}" \ + -DCMAKE_CXX_COMPILER:PATH=${CXX} \ + -DCMAKE_BUILD_TYPE:STRING=${BUILD_TYPE} \ + -DBUILD_SHARED_LIBS:BOOL=${_CMAKE_BUILD_SHARED_LIBS} \ + -DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR} \ + ../ + + ctest -C ${BUILD_TYPE} -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild ${CTEST_TESTING_OPTION} -D ExperimentalSubmit + # Final step is to verify that installation succeeds + cmake --build . --config ${BUILD_TYPE} --target install + + if [ "${DESTDIR}" != "/usr/local" ]; then + ${_BUILD_EXE} install + fi +cd - + +if ${CLEANUP+false}; then + echo "Skipping cleanup: build directory will persist." +else + rm -r "${_BUILD_DIR_NAME}" +fi diff --git a/.travis_scripts/meson_builder.sh b/.travis_scripts/meson_builder.sh new file mode 100755 index 000000000..dbf03cb2f --- /dev/null +++ b/.travis_scripts/meson_builder.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env sh +# This script can be used on the command line directly to configure several +# different build environments. +# This is called by `.travis.yml` via Travis CI. +# Travis supplies $TRAVIS_OS_NAME. +# http://docs.travis-ci.com/user/multi-os/ +# Our .travis.yml also defines: + +# - BUILD_TYPE=release/debug +# - LIB_TYPE=static/shared + +env_set=1 +if ${BUILD_TYPE+false}; then + echo "BUILD_TYPE not set in environment." + env_set=0 +fi +if ${LIB_TYPE+false}; then + echo "LIB_TYPE not set in environment." + env_set=0 +fi +if ${CXX+false}; then + echo "CXX not set in environment." + env_set=0 +fi + + +if [ ${env_set} -eq 0 ]; then + echo "USAGE: CXX=$(which clang++) BUILD_TYPE=[release|debug] LIB_TYPE=[static|shared] $0" + echo "" + echo "Examples:" + echo " CXX=$(which clang++) BUILD_TYPE=release LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=debug LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=release LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which clang++) BUILD_TYPE=debug LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" + + echo " CXX=$(which g++) BUILD_TYPE=release LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=debug LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=release LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" + echo " CXX=$(which g++) BUILD_TYPE=debug LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" + + exit -1 +fi + +if ${DESTDIR+false}; then + DESTDIR="/usr/local" +fi + +# -e: fail on error +# -v: show commands +# -x: show expanded commands +set -vex + + +env | sort + +which python3 +which meson +which ninja +echo ${CXX} +${CXX} --version +python3 --version +meson --version +ninja --version +_COMPILER_NAME=`basename ${CXX}` +_BUILD_DIR_NAME="build-${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}" +meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" +ninja -v -j 2 -C "${_BUILD_DIR_NAME}" +#ninja -v -j 2 -C "${_BUILD_DIR_NAME}" test +cd "${_BUILD_DIR_NAME}" + meson test --no-rebuild --print-errorlogs + + if [ "${DESTDIR}" != "/usr/local" ]; then + ninja install + fi +cd - + +if ${CLEANUP+false}; then + echo "Skipping cleanup: build directory will persist." +else + rm -r "${_BUILD_DIR_NAME}" +fi diff --git a/.travis_scripts/travis.install.linux.sh b/.travis_scripts/travis.install.linux.sh index a049f760c..84c3a6199 100644 --- a/.travis_scripts/travis.install.linux.sh +++ b/.travis_scripts/travis.install.linux.sh @@ -4,10 +4,6 @@ wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.z unzip -q ninja-linux.zip -d build pip3 install meson -# /usr/bin/gcc is 4.6 always, but gcc-X.Y is available. -if [[ $CXX = g++ ]]; then export CXX="g++-4.9" CC="gcc-4.9"; fi -# /usr/bin/clang has a conflict with gcc, so use clang-X.Y. -if [[ $CXX = clang++ ]]; then export CXX="clang++-3.5" CC="clang-3.5"; fi echo ${PATH} ls /usr/local ls /usr/local/bin diff --git a/.travis_scripts/travis.sh b/.travis_scripts/travis.sh deleted file mode 100755 index 769110074..000000000 --- a/.travis_scripts/travis.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env sh -# This is called by `.travis.yml` via Travis CI. -# Travis supplies $TRAVIS_OS_NAME. -# http://docs.travis-ci.com/user/multi-os/ -# Our .travis.yml also defines: -# - SHARED_LIB=ON/OFF -# - STATIC_LIB=ON/OFF -# - CMAKE_PKG=ON/OFF -# - BUILD_TYPE=release/debug -# - VERBOSE_MAKE=false/true -# - VERBOSE (set or not) - -# -e: fail on error -# -v: show commands -# -x: show expanded commands -set -vex - -env | sort - -which python3 -which meson -which ninja -echo ${CXX} -${CXX} --version -python3 --version -meson --version -ninja --version -meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} -ninja -v -C build-${LIB_TYPE} -#ninja -v -C build-${LIB_TYPE} test -cd build-${LIB_TYPE} -meson test --no-rebuild --print-errorlogs -cd - -rm -r build-${LIB_TYPE} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a6e8dc51..145a77c15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,8 +70,6 @@ set( JSONCPP_VERSION ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") set( JSONCPP_SOVERSION 19 ) -enable_testing() - option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) option(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) @@ -175,8 +173,14 @@ if(JSONCPP_WITH_CMAKE_PACKAGE) FILE jsoncppConfig.cmake) endif() +if(JSONCPP_WITH_TESTS) + enable_testing() + include(CTest) +endif() + # Build the different applications add_subdirectory( src ) #install the includes add_subdirectory( include ) + diff --git a/CTestConfig.cmake b/CTestConfig.cmake new file mode 100644 index 000000000..b8fc6d55b --- /dev/null +++ b/CTestConfig.cmake @@ -0,0 +1,15 @@ +## This file should be placed in the root directory of your project. +## Then modify the CMakeLists.txt file in the root directory of your +## project to incorporate the testing dashboard. +## +## # The following are required to submit to the CDash dashboard: +## ENABLE_TESTING() +## INCLUDE(CTest) + +set(CTEST_PROJECT_NAME "jsoncpp") +set(CTEST_NIGHTLY_START_TIME "01:23:45 UTC") + +set(CTEST_DROP_METHOD "https") +set(CTEST_DROP_SITE "my.cdash.org") +set(CTEST_DROP_LOCATION "/submit.php?project=jsoncpp") +set(CTEST_DROP_SITE_CDASH TRUE) diff --git a/README.md b/README.md index 3edee800c..8f825949f 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,11 @@ format to store user input files. ## Contributing to JsonCpp ### Building and testing with Meson/Ninja -Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use [meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build for debugging, as well as for continuous integration (see [`travis.sh`](travis.sh) ). Other systems may work, but minor things like version strings might break. +Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use +[meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build +for debugging, as well as for continuous integration (see +[`./travis_scripts/meson_builder.sh`](./travis_scripts/meson_builder.sh) ). Other systems may work, but minor +things like version strings might break. First, install both meson (which requires Python3) and ninja. If you wish to install to a directory other than /usr/local, set an environment variable called DESTDIR with the desired path: diff --git a/appveyor.yml b/appveyor.yml index a723fca2a..447a2121f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,11 @@ environment: build_script: - cmake --version - cd c:\projects\jsoncpp - - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX=%CD:\=/%/install -DBUILD_SHARED_LIBS=ON . + - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX:PATH=%CD:\=/%/install -DBUILD_SHARED_LIBS:BOOL=ON . + # Use ctest to make a dashboard build ctest -D Experimental(Start|Update|Configure|Build|Test|Coverage|MemCheck|Submit) + #NOTE Testing on window is not yet finished - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalTest -D ExperimentalSubmit + - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalSubmit + # Final step is to verify that installation succeeds - cmake --build . --config Release --target install deploy: diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 9862399a8..4ca09094d 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -15,9 +15,22 @@ if(PYTHONINTERP_FOUND) # Run end to end parser/writer tests set(TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../test) set(RUNJSONTESTS_PATH ${TEST_DIR}/runjsontests.py) + + # Run unit tests in post-build + # (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) add_custom_target(jsoncpp_readerwriter_tests "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" DEPENDS jsontestrunner_exe jsoncpp_test ) add_custom_target(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) + + ## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp + add_test(NAME jsoncpp_readerwriter + COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" + WORKING_DIRECTORY "${TEST_DIR}/data" + ) + add_test(NAME jsoncpp_readerwriter_json_checker + COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $ "${TEST_DIR}/data" + WORKING_DIRECTORY "${TEST_DIR}/data" + ) endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 7c7b6afe7..8a3970fc0 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -1,6 +1,6 @@ # vim: et ts=4 sts=4 sw=4 tw=0 -add_executable( jsoncpp_test +add_executable( jsoncpp_test jsontest.cpp jsontest.h main.cpp @@ -31,6 +31,10 @@ if(JSONCPP_WITH_POST_BUILD_UNITTEST) POST_BUILD COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) endif() + ## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp + add_test(NAME jsoncpp_test + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + ) endif() -set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) +set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) diff --git a/test/runjsontests.py b/test/runjsontests.py index 48cfe8235..dfdeca3ea 100644 --- a/test/runjsontests.py +++ b/test/runjsontests.py @@ -55,7 +55,7 @@ def safeGetLine(lines, index): """ % (message, diff_line, safeGetLine(expected,diff_line), safeGetLine(actual,diff_line)) - + def safeReadFile(path): try: return open(path, 'rt', encoding = 'utf-8').read() @@ -69,7 +69,43 @@ def runAllTests(jsontest_executable_path, input_dir = None, input_dir = os.path.join(os.getcwd(), 'data') tests = glob(os.path.join(input_dir, '*.json')) if with_json_checker: - test_jsonchecker = glob(os.path.join(input_dir, '../jsonchecker', '*.json')) + all_test_jsonchecker = glob(os.path.join(input_dir, '../jsonchecker', '*.json')) + # These tests fail with strict json support, but pass with jsoncpp extra lieniency + """ + Failure details: + * Test ../jsonchecker/fail25.json + Parsing should have failed: + [" tab character in string "] + + * Test ../jsonchecker/fail13.json + Parsing should have failed: + {"Numbers cannot have leading zeroes": 013} + + * Test ../jsonchecker/fail18.json + Parsing should have failed: + [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] + + * Test ../jsonchecker/fail8.json + Parsing should have failed: + ["Extra close"]] + + * Test ../jsonchecker/fail7.json + Parsing should have failed: + ["Comma after the close"], + + * Test ../jsonchecker/fail10.json + Parsing should have failed: + {"Extra value after close": true} "misplaced quoted value" + + * Test ../jsonchecker/fail27.json + Parsing should have failed: + ["line + break"] + """ + known_differences_withjsonchecker = [ "fail25.json", "fail13.json", "fail18.json", "fail8.json", + "fail7.json", "fail10.json", "fail27.json" ] + test_jsonchecker = [ test for test in all_test_jsonchecker if os.path.basename(test) not in known_differences_withjsonchecker ] + else: test_jsonchecker = [] failed_tests = [] From 8b31c6f0fdf9de5b5295f395c5cec55aedbfa0a8 Mon Sep 17 00:00:00 2001 From: terrycz126 Date: Wed, 7 Nov 2018 23:54:34 +0800 Subject: [PATCH 085/410] Fix redefined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) warning --- src/lib_json/json_reader.cpp | 11 ++++++----- src/lib_json/json_writer.cpp | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index ad7e15d6f..65bfad375 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -19,19 +19,20 @@ #include #include -#if __cplusplus >= 201103L #include +#if __cplusplus >= 201103L #if !defined(sscanf) #define sscanf std::sscanf #endif -#else -#include + +#endif //__cplusplus #if defined(_MSC_VER) +#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#endif -#endif +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif //_MSC_VER #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 2197efba6..36cf055a7 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -42,8 +42,11 @@ #define isfinite _finite #endif +#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#endif +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES + +#endif //_MSC_VER #if defined(__sun) && defined(__SVR4) // Solaris #if !defined(isfinite) From 2853b1cdacece137194abc5dc55e9ccbf23534f9 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 11 Jan 2019 13:58:53 -0600 Subject: [PATCH 086/410] COMP: Use C++11 override directly The override support in C++11 is required so avoid aliasing this feature. Compilers that do not support the override keyword are no longer supported. --- include/json/config.h | 5 +---- include/json/reader.h | 4 ++-- include/json/value.h | 4 ++-- include/json/writer.h | 12 ++++++------ src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_writer.cpp | 2 +- src/test_lib_json/jsontest.h | 4 ++-- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index a36ca1555..5049c7321 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -89,12 +89,11 @@ // In c++11 the override keyword allows you to explicitly define that a function // is intended to override the base-class version. This makes the code more // manageable and fixes a set of common hard-to-find bugs. +#define JSONCPP_OVERRIDE override // Define maintained for backwards compatibility of external tools. C++11 should be used directly in JSONCPP #if __cplusplus >= 201103L -#define JSONCPP_OVERRIDE override #define JSONCPP_NOEXCEPT noexcept #define JSONCPP_OP_EXPLICIT explicit #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 -#define JSONCPP_OVERRIDE override #define JSONCPP_NOEXCEPT throw() #if _MSC_VER >= 1800 // MSVC 2013 #define JSONCPP_OP_EXPLICIT explicit @@ -102,11 +101,9 @@ #define JSONCPP_OP_EXPLICIT #endif #elif defined(_MSC_VER) && _MSC_VER >= 1900 -#define JSONCPP_OVERRIDE override #define JSONCPP_NOEXCEPT noexcept #define JSONCPP_OP_EXPLICIT explicit #else -#define JSONCPP_OVERRIDE #define JSONCPP_NOEXCEPT throw() #define JSONCPP_OP_EXPLICIT #endif diff --git a/include/json/reader.h b/include/json/reader.h index 9a7fba220..58cb58b57 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -347,9 +347,9 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { Json::Value settings_; CharReaderBuilder(); - ~CharReaderBuilder() JSONCPP_OVERRIDE; + ~CharReaderBuilder() override; - CharReader* newCharReader() const JSONCPP_OVERRIDE; + CharReader* newCharReader() const override; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. diff --git a/include/json/value.h b/include/json/value.h index 3d765ec1f..3fdd88437 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -55,8 +55,8 @@ namespace Json { class JSON_API Exception : public std::exception { public: Exception(JSONCPP_STRING const& msg); - ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; - char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE; + ~Exception() JSONCPP_NOEXCEPT override; + char const* what() const JSONCPP_NOEXCEPT override; protected: JSONCPP_STRING msg_; diff --git a/include/json/writer.h b/include/json/writer.h index d70ca1c8b..7faaa0241 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -119,12 +119,12 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { Json::Value settings_; StreamWriterBuilder(); - ~StreamWriterBuilder() JSONCPP_OVERRIDE; + ~StreamWriterBuilder() override; /** * \throw std::exception if something goes wrong (e.g. invalid settings) */ - StreamWriter* newStreamWriter() const JSONCPP_OVERRIDE; + StreamWriter* newStreamWriter() const override; /** \return true if 'settings' are legal and consistent; * otherwise, indicate bad settings via 'invalid'. @@ -169,7 +169,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { public: FastWriter(); - ~FastWriter() JSONCPP_OVERRIDE {} + ~FastWriter() override {} void enableYAMLCompatibility(); @@ -183,7 +183,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void omitEndingLineFeed(); public: // overridden from Writer - JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; + JSONCPP_STRING write(const Value& root) override; private: void writeValue(const Value& value); @@ -229,14 +229,14 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { public: StyledWriter(); - ~StyledWriter() JSONCPP_OVERRIDE {} + ~StyledWriter() override {} public: // overridden from Writer /** \brief Serialize a Value in JSON format. * \param root Value to serialize. * \return String containing the JSON document that represents the root value. */ - JSONCPP_STRING write(const Value& root) JSONCPP_OVERRIDE; + JSONCPP_STRING write(const Value& root) override; private: void writeValue(const Value& value); diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 65bfad375..d024c22d7 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1907,7 +1907,7 @@ class OurCharReader : public CharReader { bool parse(char const* beginDoc, char const* endDoc, Value* root, - JSONCPP_STRING* errs) JSONCPP_OVERRIDE { + JSONCPP_STRING* errs) override { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { *errs = reader_.getFormattedErrorMessages(); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 36cf055a7..748b7e821 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -880,7 +880,7 @@ struct BuiltStyledStreamWriter : public StreamWriter { bool useSpecialFloats, unsigned int precision, PrecisionType precisionType); - int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE; + int write(Value const& root, JSONCPP_OSTREAM* sout) override; private: void writeValue(Value const& value); diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 48761c56b..e508282b6 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -262,10 +262,10 @@ TestResult& checkStringEqual(TestResult& result, } \ \ public: /* overridden from TestCase */ \ - const char* testName() const JSONCPP_OVERRIDE { \ + const char* testName() const override { \ return #FixtureType "/" #name; \ } \ - void runTestCase() JSONCPP_OVERRIDE; \ + void runTestCase() override; \ }; \ \ void Test##FixtureType##name::runTestCase() From 31d65711d695498929d9f6f4bd396ca4188de814 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 11 Jan 2019 14:13:08 -0600 Subject: [PATCH 087/410] ENH: Remove conditionals for unsupported VS compilers Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities See: https://blogs.msdn.microsoft.com/vcblog/2013/12/02/c1114-core-language-features-in-vs-2013-and-the-nov-2013-ctp/ for details related to language features supported. --- doc/doxyfile.in | 2 +- doc/web_doxyfile.in | 2 +- include/json/config.h | 29 +++++++---------------------- src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 2 +- 6 files changed, 12 insertions(+), 27 deletions(-) diff --git a/doc/doxyfile.in b/doc/doxyfile.in index baf04c19a..dcf514ea3 100644 --- a/doc/doxyfile.in +++ b/doc/doxyfile.in @@ -1944,7 +1944,7 @@ INCLUDE_FILE_PATTERNS = *.h # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = "_MSC_VER=1400" \ +PREDEFINED = "_MSC_VER=1800" \ _CPPRTTI \ _WIN32 \ JSONCPP_DOC_EXCLUDE_IMPLEMENTATION diff --git a/doc/web_doxyfile.in b/doc/web_doxyfile.in index 938ecd125..df09dccae 100644 --- a/doc/web_doxyfile.in +++ b/doc/web_doxyfile.in @@ -1932,7 +1932,7 @@ INCLUDE_FILE_PATTERNS = *.h # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = "_MSC_VER=1400" \ +PREDEFINED = "_MSC_VER=1800" \ _CPPRTTI \ _WIN32 \ JSONCPP_DOC_EXCLUDE_IMPLEMENTATION diff --git a/include/json/config.h b/include/json/config.h index 5049c7321..84384282c 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -54,6 +54,10 @@ #define JSON_API #endif +#if defined(_MSC_VER) && _MSC_VER < 1800 + #error "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" +#endif + #if defined(_MSC_VER) && _MSC_VER < 1900 // As recommended at https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 extern JSON_API int msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...); @@ -68,22 +72,7 @@ // #define JSON_NO_INT64 1 #if defined(_MSC_VER) // MSVC -#if _MSC_VER <= 1200 // MSVC 6 -// Microsoft Visual Studio 6 only support conversion from __int64 to double -// (no conversion from unsigned __int64). -#define JSON_USE_INT64_DOUBLE_CONVERSION 1 -// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255' -// characters in the debug information) -// All projects I've ever seen with VS6 were using this globally (not bothering -// with pragma push/pop). -#pragma warning(disable : 4786) -#endif // MSVC 6 - -#if _MSC_VER >= 1500 // MSVC 2008 - /// Indicates that the following function is deprecated. #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) -#endif - #endif // defined(_MSC_VER) // In c++11 the override keyword allows you to explicitly define that a function @@ -93,13 +82,9 @@ #if __cplusplus >= 201103L #define JSONCPP_NOEXCEPT noexcept #define JSONCPP_OP_EXPLICIT explicit -#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900 +#elif defined(_MSC_VER) && _MSC_VER < 1900 #define JSONCPP_NOEXCEPT throw() -#if _MSC_VER >= 1800 // MSVC 2013 #define JSONCPP_OP_EXPLICIT explicit -#else -#define JSONCPP_OP_EXPLICIT -#endif #elif defined(_MSC_VER) && _MSC_VER >= 1900 #define JSONCPP_NOEXCEPT noexcept #define JSONCPP_OP_EXPLICIT explicit @@ -110,9 +95,9 @@ #ifndef JSON_HAS_RVALUE_REFERENCES -#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010 +#if defined(_MSC_VER) #define JSON_HAS_RVALUE_REFERENCES 1 -#endif // MSVC >= 2010 +#endif // MSVC >= 2013 #ifdef __clang__ #if __has_feature(cxx_rvalue_references) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index d024c22d7..fe796349b 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -34,7 +34,7 @@ #endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #endif //_MSC_VER -#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +#if defined(_MSC_VER) // Disable warning about strdup being deprecated. #pragma warning(disable : 4996) #endif diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 81640ea42..1aec87fd0 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -43,7 +43,7 @@ int JSON_API msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *fo #endif // Disable warning C4702 : unreachable code -#if defined(_MSC_VER) && _MSC_VER >= 1800 // VC++ 12.0 and above +#if defined(_MSC_VER) #pragma warning(disable : 4702) #endif diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 748b7e821..4f7712116 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -76,7 +76,7 @@ #endif #endif -#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 +#if defined(_MSC_VER) // Disable warning about strdup being deprecated. #pragma warning(disable : 4996) #endif From 4e8b4e313f26f1dd4838f28d5c3e88a2ed7ac140 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 27 Nov 2018 19:40:20 -0800 Subject: [PATCH 088/410] Add support for VS2017 --- makefiles/msvc2017/jsoncpp.sln | 43 +++++++ makefiles/msvc2017/jsontest.vcxproj | 101 +++++++++++++++ makefiles/msvc2017/lib_json.vcxproj | 153 +++++++++++++++++++++++ makefiles/msvc2017/test_lib_json.vcxproj | 114 +++++++++++++++++ 4 files changed, 411 insertions(+) create mode 100644 makefiles/msvc2017/jsoncpp.sln create mode 100644 makefiles/msvc2017/jsontest.vcxproj create mode 100644 makefiles/msvc2017/lib_json.vcxproj create mode 100644 makefiles/msvc2017/test_lib_json.vcxproj diff --git a/makefiles/msvc2017/jsoncpp.sln b/makefiles/msvc2017/jsoncpp.sln new file mode 100644 index 000000000..c1c37985e --- /dev/null +++ b/makefiles/msvc2017/jsoncpp.sln @@ -0,0 +1,43 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcxproj", "{B84F7231-16CE-41D8-8C08-7B523FF4225B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcxproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcxproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + dummy|x86 = dummy|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.ActiveCfg = Debug|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.Build.0 = Debug|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.ActiveCfg = dummy|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.Build.0 = dummy|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.ActiveCfg = Release|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.Build.0 = Release|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.ActiveCfg = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.Build.0 = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.ActiveCfg = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.Build.0 = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.ActiveCfg = Release|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.Build.0 = Release|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.ActiveCfg = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.Build.0 = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.ActiveCfg = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.Build.0 = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.ActiveCfg = Release|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4EE0C79B-26FE-4FB3-B025-AA18203D1636} + EndGlobalSection +EndGlobal diff --git a/makefiles/msvc2017/jsontest.vcxproj b/makefiles/msvc2017/jsontest.vcxproj new file mode 100644 index 000000000..e38401ea5 --- /dev/null +++ b/makefiles/msvc2017/jsontest.vcxproj @@ -0,0 +1,101 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {25AF2DD2-D396-4668-B188-488C33B8E620} + Win32Proj + + + + Application + v141 + MultiByte + + + Application + v141 + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + + + ../../build/vs71/debug/jsontest\ + ../../build/vs71/debug/jsontest\ + true + + + ../../build/vs71/release/jsontest\ + ../../build/vs71/release/jsontest\ + false + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + Level3 + EditAndContinue + + + $(OutDir)jsontest.exe + true + $(OutDir)jsontest.pdb + Console + MachineX86 + + + + + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + Level3 + ProgramDatabase + + + $(OutDir)jsontest.exe + true + Console + true + true + MachineX86 + + + + + + + + {b84f7231-16ce-41d8-8c08-7b523ff4225b} + false + + + + + + \ No newline at end of file diff --git a/makefiles/msvc2017/lib_json.vcxproj b/makefiles/msvc2017/lib_json.vcxproj new file mode 100644 index 000000000..c13655db0 --- /dev/null +++ b/makefiles/msvc2017/lib_json.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + dummy + Win32 + + + Release + Win32 + + + + {B84F7231-16CE-41D8-8C08-7B523FF4225B} + Win32Proj + + + + DynamicLibrary + v141 + MultiByte + true + + + StaticLibrary + v141 + MultiByte + true + + + StaticLibrary + v141 + MultiByte + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + + + ../../build/vs71/debug/lib_json\ + ../../build/vs71/debug/lib_json\ + + + ../../build/vs71/release/lib_json\ + ../../build/vs71/release/lib_json\ + + + $(Configuration)\ + $(Configuration)\ + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + true + EnableFastChecks + MultiThreadedDebug + true + true + false + true + + Level3 + EditAndContinue + + + $(OutDir)json_vc71_libmtd.lib + + + + + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + false + true + + AssemblyAndSourceCode + Level3 + ProgramDatabase + + + $(OutDir)json_vc71_libmt.lib + + + + + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + false + true + + AssemblyAndSourceCode + Level3 + ProgramDatabase + + + true + Windows + true + true + MachineX86 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/makefiles/msvc2017/test_lib_json.vcxproj b/makefiles/msvc2017/test_lib_json.vcxproj new file mode 100644 index 000000000..75ea7715c --- /dev/null +++ b/makefiles/msvc2017/test_lib_json.vcxproj @@ -0,0 +1,114 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D} + test_lib_json + Win32Proj + + + + Application + v141 + MultiByte + + + Application + v141 + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + + + ../../build/vs71/debug/test_lib_json\ + ../../build/vs71/debug/test_lib_json\ + true + + + ../../build/vs71/release/test_lib_json\ + ../../build/vs71/release/test_lib_json\ + false + + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + Level3 + EditAndContinue + + + $(OutDir)test_lib_json.exe + true + $(OutDir)test_lib_json.pdb + Console + MachineX86 + + + Running all unit tests + $(TargetPath) + + + + + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + Level3 + ProgramDatabase + + + $(OutDir)test_lib_json.exe + true + Console + true + true + MachineX86 + + + Running all unit tests + $(TargetPath) + + + + + + + + + + + + {b84f7231-16ce-41d8-8c08-7b523ff4225b} + false + + + + + + \ No newline at end of file From fdc0824505ac890241062eca5e06c7cf0c11284c Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 27 Nov 2018 19:42:53 -0800 Subject: [PATCH 089/410] Add amd64 support --- makefiles/msvc2017/jsoncpp.sln | 21 +++++ makefiles/msvc2017/jsontest.vcxproj | 67 +++++++++++++++ makefiles/msvc2017/lib_json.vcxproj | 105 +++++++++++++++++++++++ makefiles/msvc2017/test_lib_json.vcxproj | 75 ++++++++++++++++ 4 files changed, 268 insertions(+) diff --git a/makefiles/msvc2017/jsoncpp.sln b/makefiles/msvc2017/jsoncpp.sln index c1c37985e..cf77ce01d 100644 --- a/makefiles/msvc2017/jsoncpp.sln +++ b/makefiles/msvc2017/jsoncpp.sln @@ -10,27 +10,48 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_j EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 + dummy|x64 = dummy|x64 dummy|x86 = dummy|x86 + Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x64.ActiveCfg = Debug|x64 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x64.Build.0 = Debug|x64 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.ActiveCfg = Debug|Win32 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.Build.0 = Debug|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x64.ActiveCfg = dummy|x64 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x64.Build.0 = dummy|x64 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.ActiveCfg = dummy|Win32 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.Build.0 = dummy|Win32 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x64.ActiveCfg = Release|x64 + {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x64.Build.0 = Release|x64 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.ActiveCfg = Release|Win32 {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.Build.0 = Release|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.ActiveCfg = Debug|x64 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.Build.0 = Debug|x64 {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.ActiveCfg = Debug|Win32 {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.Build.0 = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x64.ActiveCfg = Debug|x64 + {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x64.Build.0 = Debug|x64 {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.ActiveCfg = Debug|Win32 {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.Build.0 = Debug|Win32 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.ActiveCfg = Release|x64 + {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.Build.0 = Release|x64 {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.ActiveCfg = Release|Win32 {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.Build.0 = Release|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.ActiveCfg = Debug|x64 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.Build.0 = Debug|x64 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.ActiveCfg = Debug|Win32 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.Build.0 = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x64.ActiveCfg = Debug|x64 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x64.Build.0 = Debug|x64 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.ActiveCfg = Debug|Win32 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.Build.0 = Debug|Win32 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.ActiveCfg = Release|x64 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.Build.0 = Release|x64 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.ActiveCfg = Release|Win32 {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.Build.0 = Release|Win32 EndGlobalSection diff --git a/makefiles/msvc2017/jsontest.vcxproj b/makefiles/msvc2017/jsontest.vcxproj index e38401ea5..de43cfee9 100644 --- a/makefiles/msvc2017/jsontest.vcxproj +++ b/makefiles/msvc2017/jsontest.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {25AF2DD2-D396-4668-B188-488C33B8E620} @@ -20,20 +28,36 @@ v141 MultiByte + + Application + v141 + MultiByte + Application v141 MultiByte + + Application + v141 + MultiByte + + + + + + + <_ProjectFileVersion>15.0.28127.55 @@ -43,11 +67,17 @@ ../../build/vs71/debug/jsontest\ true + + true + ../../build/vs71/release/jsontest\ ../../build/vs71/release/jsontest\ false + + false + Disabled @@ -68,6 +98,25 @@ MachineX86 + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + $(OutDir)jsontest.exe + true + $(OutDir)jsontest.pdb + Console + + ../../include;%(AdditionalIncludeDirectories) @@ -86,6 +135,24 @@ MachineX86 + + + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)jsontest.exe + true + Console + true + true + + diff --git a/makefiles/msvc2017/lib_json.vcxproj b/makefiles/msvc2017/lib_json.vcxproj index c13655db0..b40683e2c 100644 --- a/makefiles/msvc2017/lib_json.vcxproj +++ b/makefiles/msvc2017/lib_json.vcxproj @@ -5,14 +5,26 @@ Debug Win32 + + Debug + x64 + dummy Win32 + + dummy + x64 + Release Win32 + + Release + x64 + {B84F7231-16CE-41D8-8C08-7B523FF4225B} @@ -25,29 +37,55 @@ MultiByte true + + DynamicLibrary + v141 + MultiByte + true + StaticLibrary v141 MultiByte true + + StaticLibrary + v141 + MultiByte + true + StaticLibrary v141 MultiByte + + StaticLibrary + v141 + MultiByte + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 @@ -56,6 +94,7 @@ ../../build/vs71/debug/lib_json\ ../../build/vs71/debug/lib_json\ + ../../build/vs71/release/lib_json\ ../../build/vs71/release/lib_json\ @@ -85,6 +124,27 @@ $(OutDir)json_vc71_libmtd.lib + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + false + true + + + Level3 + ProgramDatabase + + + $(OutDir)json_vc71_libmtd.lib + + true @@ -105,6 +165,27 @@ $(OutDir)json_vc71_libmt.lib + + + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + false + true + + + AssemblyAndSourceCode + Level3 + ProgramDatabase + + + $(OutDir)json_vc71_libmt.lib + + true @@ -129,6 +210,30 @@ MachineX86 + + + true + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + false + true + + + AssemblyAndSourceCode + Level3 + ProgramDatabase + + + true + Windows + true + true + + diff --git a/makefiles/msvc2017/test_lib_json.vcxproj b/makefiles/msvc2017/test_lib_json.vcxproj index 75ea7715c..89a336f80 100644 --- a/makefiles/msvc2017/test_lib_json.vcxproj +++ b/makefiles/msvc2017/test_lib_json.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D} @@ -21,20 +29,36 @@ v141 MultiByte + + Application + v141 + MultiByte + Application v141 MultiByte + + Application + v141 + MultiByte + + + + + + + <_ProjectFileVersion>15.0.28127.55 @@ -44,11 +68,17 @@ ../../build/vs71/debug/test_lib_json\ true + + true + ../../build/vs71/release/test_lib_json\ ../../build/vs71/release/test_lib_json\ false + + false + Disabled @@ -73,6 +103,29 @@ $(TargetPath) + + + Disabled + ../../include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + $(OutDir)test_lib_json.exe + true + $(OutDir)test_lib_json.pdb + Console + + + Running all unit tests + $(TargetPath) + + ../../include;%(AdditionalIncludeDirectories) @@ -95,6 +148,28 @@ $(TargetPath) + + + ../../include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)test_lib_json.exe + true + Console + true + true + + + Running all unit tests + $(TargetPath) + + From 908383abebfd9d135904ab99c879d0430330b4b5 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 29 Nov 2018 22:44:56 -0800 Subject: [PATCH 090/410] Fix bogus asm setting --- makefiles/msvc2017/lib_json.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefiles/msvc2017/lib_json.vcxproj b/makefiles/msvc2017/lib_json.vcxproj index b40683e2c..d6d0f4a81 100644 --- a/makefiles/msvc2017/lib_json.vcxproj +++ b/makefiles/msvc2017/lib_json.vcxproj @@ -178,7 +178,7 @@ true - AssemblyAndSourceCode + NoListing Level3 ProgramDatabase From d3d2e17b648c513203fafe8ade7b247ce7152272 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 9 Dec 2018 07:39:19 -0800 Subject: [PATCH 091/410] Switch to the VCPP dll --- makefiles/msvc2017/lib_json.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/makefiles/msvc2017/lib_json.vcxproj b/makefiles/msvc2017/lib_json.vcxproj index d6d0f4a81..092bd29c9 100644 --- a/makefiles/msvc2017/lib_json.vcxproj +++ b/makefiles/msvc2017/lib_json.vcxproj @@ -131,7 +131,7 @@ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) true EnableFastChecks - MultiThreadedDebug + MultiThreadedDebugDLL true true false @@ -171,7 +171,7 @@ ../../include;%(AdditionalIncludeDirectories) WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) true - MultiThreaded + MultiThreadedDLL true true false From 3beadff472f1a33aac2891c07aed168565dbd408 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:08:51 -0600 Subject: [PATCH 092/410] PERF: readability container size empty The emptiness of a container should be checked using the empty() method instead of the size() method. It is not guaranteed that size() is a constant-time function, and it is generally more efficient and also shows clearer intent to use empty(). Furthermore some containers may implement the empty() method but not implement the size() method. Using empty() whenever possible makes it easier to switch to another container in the future. SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,readability-container-size-empty -header-filter=.* -fix --- src/lib_json/json_reader.cpp | 6 +++--- src/lib_json/json_value.cpp | 4 ++-- src/lib_json/json_writer.cpp | 8 ++++---- src/test_lib_json/main.cpp | 28 ++++++++++++++-------------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index fe796349b..aa5156f0c 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -880,7 +880,7 @@ bool Reader::pushError(const Value& value, return true; } -bool Reader::good() const { return !errors_.size(); } +bool Reader::good() const { return errors_.empty(); } // exact copy of Features class OurFeatures { @@ -1895,7 +1895,7 @@ bool OurReader::pushError(const Value& value, return true; } -bool OurReader::good() const { return !errors_.size(); } +bool OurReader::good() const { return errors_.empty(); } class OurCharReader : public CharReader { bool const collectComments_; @@ -1961,7 +1961,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const { inv[key] = settings_[key]; } } - return 0u == inv.size(); + return inv.empty(); } Value& CharReaderBuilder::operator[](const JSONCPP_STRING& key) { return settings_[key]; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 1aec87fd0..c7fcfa413 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -889,8 +889,8 @@ bool Value::isConvertibleTo(ValueType other) const { return (isNumeric() && asDouble() == 0.0) || (type_ == booleanValue && value_.bool_ == false) || (type_ == stringValue && asString().empty()) || - (type_ == arrayValue && value_.map_->size() == 0) || - (type_ == objectValue && value_.map_->size() == 0) || + (type_ == arrayValue && value_.map_->empty()) || + (type_ == objectValue && value_.map_->empty()) || type_ == nullValue; case intValue: return isInt() || diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 4f7712116..7138b7a7b 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -551,7 +551,7 @@ bool StyledWriter::isMultilineArray(const Value& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + !childValue.empty()); } if (!isMultiLine) // check if line length > max line length { @@ -774,7 +774,7 @@ bool StyledStreamWriter::isMultilineArray(const Value& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + !childValue.empty()); } if (!isMultiLine) // check if line length > max line length { @@ -1059,7 +1059,7 @@ bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) { for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { Value const& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + !childValue.empty()); } if (!isMultiLine) // check if line length > max line length { @@ -1226,7 +1226,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { inv[key] = settings_[key]; } } - return 0u == inv.size(); + return inv.empty(); } Value& StreamWriterBuilder::operator[](const JSONCPP_STRING& key) { return settings_[key]; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 23da4b3a3..4dfca7538 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1818,7 +1818,7 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { b.settings_["dropNullPlaceholders"] = false; JSONTEST_ASSERT(Json::writeString(b, nullValue) == "null"); b.settings_["dropNullPlaceholders"] = true; - JSONTEST_ASSERT(Json::writeString(b, nullValue) == ""); + JSONTEST_ASSERT(Json::writeString(b, nullValue).empty()); } JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { @@ -1850,8 +1850,8 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) { Json::Value root; bool ok = reader.parse("{ \"property\" : \"value\" }", root); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0); - JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0); + JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); + JSONTEST_ASSERT(reader.getStructuredErrors().empty()); } JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) { @@ -1862,8 +1862,8 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) { "null, \"false\" : false }", root); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().size() == 0); - JSONTEST_ASSERT(reader.getStructuredErrors().size() == 0); + JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); + JSONTEST_ASSERT(reader.getStructuredErrors().empty()); JSONTEST_ASSERT(root["property"].getOffsetStart() == 15); JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34); JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16); @@ -1944,7 +1944,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { char const doc[] = "{ \"property\" : \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.size() == 0); + JSONTEST_ASSERT(errs.empty()); delete reader; } @@ -1958,7 +1958,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { "null, \"false\" : false }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.size() == 0); + JSONTEST_ASSERT(errs.empty()); delete reader; } @@ -2014,7 +2014,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { JSONCPP_STRING errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("value", root["property"]); delete reader; } @@ -2061,7 +2061,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { JSONCPP_STRING errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("property", root); delete reader; } @@ -2176,7 +2176,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { char const doc[] = "[]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(0u, root.size()); JSONTEST_ASSERT_EQUAL(Json::arrayValue, root); } @@ -2184,7 +2184,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { char const doc[] = "[null]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(1u, root.size()); } { @@ -2212,7 +2212,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { char const doc[] = "[,null]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(2u, root.size()); } { @@ -2240,7 +2240,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { char const doc[] = "[,,null]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(3u, root.size()); } { @@ -2263,7 +2263,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { char const doc[] = "[,,,[]]"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs == ""); + JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[3u]); } From cbeed7b0769a1a519a2e827480b96cf0d17e791d Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:12 -0600 Subject: [PATCH 093/410] STYLE: Use range-based loops from C++11 C++11 Range based for loops can be used in Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container, in the forward direction.. Range based loopes are more explicit for only computing the end location once for containers. SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-loop-convert -header-filter=.* -fix --- src/jsontestrunner/main.cpp | 4 +--- src/lib_json/json_reader.cpp | 16 ++++------------ src/lib_json/json_value.cpp | 9 +++------ src/test_lib_json/jsontest.cpp | 7 ++----- src/test_lib_json/main.cpp | 3 +-- 5 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 28691a2de..544929932 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -110,9 +110,7 @@ static void printValueTree(FILE* fout, Json::Value::Members members(value.getMemberNames()); std::sort(members.begin(), members.end()); JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : "."; - for (Json::Value::Members::iterator it = members.begin(); - it != members.end(); ++it) { - const JSONCPP_STRING name = *it; + for (auto name : members) { printValueTree(fout, value[name], path + suffix + name); } } break; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index aa5156f0c..077da1be8 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -818,9 +818,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const { JSONCPP_STRING Reader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); ++itError) { - const ErrorInfo& error = *itError; + for (const auto & error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -833,9 +831,7 @@ JSONCPP_STRING Reader::getFormattedErrorMessages() const { std::vector Reader::getStructuredErrors() const { std::vector allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); ++itError) { - const ErrorInfo& error = *itError; + for (const auto & error : errors_) { Reader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; @@ -1833,9 +1829,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { JSONCPP_STRING OurReader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); ++itError) { - const ErrorInfo& error = *itError; + for (const auto & error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -1848,9 +1842,7 @@ JSONCPP_STRING OurReader::getFormattedErrorMessages() const { std::vector OurReader::getStructuredErrors() const { std::vector allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); ++itError) { - const ErrorInfo& error = *itError; + for (const auto & error : errors_) { OurReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index c7fcfa413..5e832392b 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1655,8 +1655,7 @@ void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) { const Value& Path::resolve(const Value& root) const { const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; + for (const auto & arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) { // Error: unable to resolve path (array value expected at position... @@ -1681,8 +1680,7 @@ const Value& Path::resolve(const Value& root) const { Value Path::resolve(const Value& root, const Value& defaultValue) const { const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; + for (const auto & arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) return defaultValue; @@ -1700,8 +1698,7 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const { Value& Path::make(Value& root) const { Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { - const PathArgument& arg = *it; + for (const auto & arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray()) { // Error: node is not an array at position ... diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 5e04aa434..f66150587 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -150,9 +150,7 @@ void TestResult::printFailure(bool printTestName) const { } // Print in reverse to display the callstack in the right order - Failures::const_iterator itEnd = failures_.end(); - for (Failures::const_iterator it = failures_.begin(); it != itEnd; ++it) { - const Failure& failure = *it; + for (const auto & failure : failures_ ) { JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); @@ -275,8 +273,7 @@ bool Runner::runAllTest(bool printSummary) const { } return true; } else { - for (unsigned int index = 0; index < failures.size(); ++index) { - TestResult& result = failures[index]; + for (auto & result : failures) { result.printFailure(count > 1); } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 4dfca7538..8b2154739 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2365,8 +2365,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { { __LINE__, false, "{\"a\":.Infinity}" }, { __LINE__, false, "{\"a\":_Infinity}" }, { __LINE__, false, "{\"a\":_nfinity}" }, { __LINE__, true, "{\"a\":-Infinity}" } }; - for (size_t tdi = 0; tdi < sizeof(test_data) / sizeof(*test_data); ++tdi) { - const TestData& td = test_data[tdi]; + for (const auto& td : test_data) { bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), &root, &errs); JSONTEST_ASSERT(td.ok == ok) << "line:" << td.line << "\n" From 1fc3de7ca12fbaf67b887b53d6546c2ac35ab305 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:15 -0600 Subject: [PATCH 094/410] STYLE: Use auto for variable type matches the type of the initializer expression This check is responsible for using the auto type specifier for variable declarations to improve code readability and maintainability. The auto type specifier will only be introduced in situations where the variable type matches the type of the initializer expression. In other words auto should deduce the same type that was originally spelled in the source SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-auto -header-filter = .* -fix --- src/jsontestrunner/main.cpp | 2 +- src/lib_json/json_reader.cpp | 6 +++--- src/lib_json/json_value.cpp | 14 +++++++------- src/lib_json/json_writer.cpp | 10 +++++----- src/test_lib_json/jsontest.cpp | 2 +- src/test_lib_json/main.cpp | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 544929932..6e0c0049a 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -56,7 +56,7 @@ static JSONCPP_STRING readInputTestFile(const char* path) { return JSONCPP_STRING(""); fseek(file, 0, SEEK_END); long const size = ftell(file); - unsigned long const usize = static_cast(size); + size_t const usize = static_cast(size); fseek(file, 0, SEEK_SET); JSONCPP_STRING text; char* buffer = new char[size + 1]; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 077da1be8..ce4aac446 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -577,7 +577,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - Value::UInt digit(static_cast(c - '0')); + auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, b) this is the last digit, and @@ -1569,7 +1569,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - Value::UInt digit(static_cast(c - '0')); + auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, b) this is the last digit, and @@ -1611,7 +1611,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { if (length < 0) { return addError("Unable to parse token length", token); } - size_t const ulength = static_cast(length); + auto const ulength = static_cast(length); // Avoid using a string constant for the format control string given to // sscanf, as this can cause hard to debug crashes on OS X. See here for more diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 5e832392b..ef9511788 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -990,7 +990,7 @@ Value& Value::operator[](ArrayIndex index) { if (type_ == nullValue) *this = Value(arrayValue); CZString key(index); - ObjectValues::iterator it = value_.map_->lower_bound(key); + auto it = value_.map_->lower_bound(key); if (it != value_.map_->end() && (*it).first == key) return (*it).second; @@ -1113,7 +1113,7 @@ Value& Value::resolveReference(const char* key) { *this = Value(objectValue); CZString actualKey(key, static_cast(strlen(key)), CZString::noDuplication); // NOTE! - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); + auto it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1132,7 +1132,7 @@ Value& Value::resolveReference(char const* key, char const* end) { *this = Value(objectValue); CZString actualKey(key, static_cast(end - key), CZString::duplicateOnCopy); - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); + auto it = value_.map_->lower_bound(actualKey); if (it != value_.map_->end() && (*it).first == actualKey) return (*it).second; @@ -1226,7 +1226,7 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) { } CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); - ObjectValues::iterator it = value_.map_->find(actualKey); + auto it = value_.map_->find(actualKey); if (it == value_.map_->end()) return false; if (removed) @@ -1262,7 +1262,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { return false; } CZString key(index); - ObjectValues::iterator it = value_.map_->find(key); + auto it = value_.map_->find(key); if (it == value_.map_->end()) { return false; } @@ -1276,7 +1276,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { } // erase the last one ("leftover") CZString keyLast(oldSize - 1); - ObjectValues::iterator itLast = value_.map_->find(keyLast); + auto itLast = value_.map_->find(keyLast); value_.map_->erase(itLast); return true; } @@ -1608,7 +1608,7 @@ Path::Path(const JSONCPP_STRING& path, void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { const char* current = path.c_str(); const char* end = current + path.length(); - InArgs::const_iterator itInArg = in.begin(); + auto itInArg = in.begin(); while (current != end) { if (*current == '[') { ++current; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 7138b7a7b..993001ca1 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -147,7 +147,7 @@ JSONCPP_STRING valueToString(double value, (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f", precision, value); assert(len >= 0); - size_t wouldPrint = static_cast(len); + auto wouldPrint = static_cast(len); if (wouldPrint >= buffer.size()) { buffer.resize(wouldPrint + 1); continue; @@ -409,7 +409,7 @@ void FastWriter::writeValue(const Value& value) { case objectValue: { Value::Members members(value.getMemberNames()); document_ += '{'; - for (Value::Members::iterator it = members.begin(); it != members.end(); + for (auto it = members.begin(); it != members.end(); ++it) { const JSONCPP_STRING& name = *it; if (it != members.begin()) @@ -479,7 +479,7 @@ void StyledWriter::writeValue(const Value& value) { else { writeWithIndent("{"); indent(); - Value::Members::iterator it = members.begin(); + auto it = members.begin(); for (;;) { const JSONCPP_STRING& name = *it; const Value& childValue = value[name]; @@ -699,7 +699,7 @@ void StyledStreamWriter::writeValue(const Value& value) { else { writeWithIndent("{"); indent(); - Value::Members::iterator it = members.begin(); + auto it = members.begin(); for (;;) { const JSONCPP_STRING& name = *it; const Value& childValue = value[name]; @@ -979,7 +979,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { else { writeWithIndent("{"); indent(); - Value::Members::iterator it = members.begin(); + auto it = members.begin(); for (;;) { JSONCPP_STRING const& name = *it; Value const& childValue = value[name]; diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index f66150587..03703c9c4 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -278,7 +278,7 @@ bool Runner::runAllTest(bool printSummary) const { } if (printSummary) { - unsigned int failedCount = static_cast(failures.size()); + auto failedCount = static_cast(failures.size()); unsigned int passedCount = count - failedCount; printf("%u/%u tests passed (%u failure(s))\n", passedCount, count, failedCount); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 8b2154739..d0315d7b2 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1036,7 +1036,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { normalizeFloatingPointStr(JsonTest::ToJsonString(val.asString()))); // 10^19 - const Json::UInt64 ten_to_19 = static_cast(1e19); + const auto ten_to_19 = static_cast(1e19); val = Json::Value(Json::UInt64(ten_to_19)); JSONTEST_ASSERT_EQUAL(Json::uintValue, val.type()); From b5093e8122acd97d19267be1b6798c7232fae371 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:19 -0600 Subject: [PATCH 095/410] PERF: Allow compiler to choose best way to construct a copy With move semantics added to the language and the standard library updated with move constructors added for many types it is now interesting to take an argument directly by value, instead of by const-reference, and then copy. This check allows the compiler to take care of choosing the best way to construct the copy. The transformation is usually beneficial when the calling code passes an rvalue and assumes the move construction is a cheap operation. This short example illustrates how the construction of the value happens: SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-pass-by-value -header-filter=.* -fix --- include/json/value.h | 2 +- include/json/writer.h | 4 ++-- src/lib_json/json_reader.cpp | 5 ++--- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_writer.cpp | 26 +++++++++++++------------- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 3fdd88437..71bc65c0b 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -54,7 +54,7 @@ namespace Json { */ class JSON_API Exception : public std::exception { public: - Exception(JSONCPP_STRING const& msg); + Exception(JSONCPP_STRING msg); ~Exception() JSONCPP_NOEXCEPT override; char const* what() const JSONCPP_NOEXCEPT override; diff --git a/include/json/writer.h b/include/json/writer.h index 7faaa0241..34e71edac 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -300,8 +300,8 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API /** * \param indentation Each level will be indented by this amount extra. */ - StyledStreamWriter(const JSONCPP_STRING& indentation = "\t"); - ~StyledStreamWriter() {} + StyledStreamWriter(JSONCPP_STRING indentation = "\t"); + ~StyledStreamWriter() = default; public: /** \brief Serialize a Value in JSON format. diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index ce4aac446..c5af01468 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -88,9 +88,8 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // ////////////////////////////////////////////////////////////////// Reader::Reader() - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(Features::all()), - collectComments_() {} + : errors_(), document_(), commentsBefore_(), features_(Features::all()) + {} Reader::Reader(const Features& features) : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index ef9511788..2445d31a8 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -213,7 +213,7 @@ static inline void releaseStringValue(char* value, unsigned) { free(value); } namespace Json { -Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) {} +Exception::Exception(JSONCPP_STRING msg) : msg_(std::move(msg)) {} Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {} diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 993001ca1..54fcb4fa1 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -642,8 +642,8 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// -StyledStreamWriter::StyledStreamWriter(const JSONCPP_STRING& indentation) - : document_(nullptr), rightMargin_(74), indentation_(indentation), +StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) + : document_(nullptr), indentation_(std::move(indentation)), addChildValues_(), indented_(false) {} void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { @@ -872,11 +872,11 @@ struct CommentStyle { }; struct BuiltStyledStreamWriter : public StreamWriter { - BuiltStyledStreamWriter(JSONCPP_STRING const& indentation, + BuiltStyledStreamWriter(JSONCPP_STRING indentation, CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, + JSONCPP_STRING colonSymbol, + JSONCPP_STRING nullSymbol, + JSONCPP_STRING endingLineFeedSymbol, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType); @@ -912,17 +912,17 @@ struct BuiltStyledStreamWriter : public StreamWriter { PrecisionType precisionType_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( - JSONCPP_STRING const& indentation, + JSONCPP_STRING indentation, CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, + JSONCPP_STRING colonSymbol, + JSONCPP_STRING nullSymbol, + JSONCPP_STRING endingLineFeedSymbol, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType) - : rightMargin_(74), indentation_(indentation), cs_(cs), - colonSymbol_(colonSymbol), nullSymbol_(nullSymbol), - endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false), + : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), + colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), + endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), addChildValues_(false), indented_(false), useSpecialFloats_(useSpecialFloats), precision_(precision), precisionType_(precisionType) {} int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { From e817e4fc25d1a4a99c1f27ab430154f57fdd0831 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:22 -0600 Subject: [PATCH 096/410] STYLE: Use default member initialization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converts a default constructor’s member initializers into the new default member initializers in C++11. Other member initializers that match the default member initializer are removed. This can reduce repeated code or allow use of ‘= default’. SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-default-member-init -header-filter=.* -fix --- include/json/features.h | 8 ++++---- include/json/reader.h | 12 +++++------ include/json/value.h | 8 ++++---- include/json/writer.h | 14 ++++++------- src/lib_json/json_reader.cpp | 3 +-- src/lib_json/json_value.cpp | 4 ++-- src/lib_json/json_valueiterator.inl | 2 +- src/lib_json/json_writer.cpp | 6 +++--- src/test_lib_json/jsontest.cpp | 4 ++-- src/test_lib_json/jsontest.h | 8 ++++---- src/test_lib_json/main.cpp | 32 ++++++++++++++--------------- 11 files changed, 49 insertions(+), 52 deletions(-) diff --git a/include/json/features.h b/include/json/features.h index 72eb6a8a0..ba25e8da6 100644 --- a/include/json/features.h +++ b/include/json/features.h @@ -41,17 +41,17 @@ class JSON_API Features { Features(); /// \c true if comments are allowed. Default: \c true. - bool allowComments_; + bool allowComments_{true}; /// \c true if root must be either an array or an object value. Default: \c /// false. - bool strictRoot_; + bool strictRoot_{false}; /// \c true if dropped null placeholders are allowed. Default: \c false. - bool allowDroppedNullPlaceholders_; + bool allowDroppedNullPlaceholders_{false}; /// \c true if numeric object key are allowed. Default: \c false. - bool allowNumericKeys_; + bool allowNumericKeys_{false}; }; } // namespace Json diff --git a/include/json/reader.h b/include/json/reader.h index 58cb58b57..1af5cb0dd 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -242,14 +242,14 @@ class JSON_API Reader { Nodes nodes_; Errors errors_; JSONCPP_STRING document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value* lastValue_; + Location begin_{}; + Location end_{}; + Location current_{}; + Location lastValueEnd_{}; + Value* lastValue_{}; JSONCPP_STRING commentsBefore_; Features features_; - bool collectComments_; + bool collectComments_{}; }; // Reader /** Interface for reading JSON from a char array. diff --git a/include/json/value.h b/include/json/value.h index 71bc65c0b..8321de7bf 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -630,7 +630,7 @@ Json::Value obj_value(Json::objectValue); // {} void setComment(const char* text, size_t len); - char* comment_; + char* comment_{nullptr}; }; // struct MemberNamesTransform @@ -678,8 +678,8 @@ class JSON_API PathArgument { private: enum Kind { kindNone = 0, kindIndex, kindKey }; JSONCPP_STRING key_; - ArrayIndex index_; - Kind kind_; + ArrayIndex index_{}; + Kind kind_{kindNone}; }; /** \brief Experimental and untested: represents a "path" to access a node. @@ -780,7 +780,7 @@ class JSON_API ValueIteratorBase { private: Value::ObjectValues::iterator current_; // Indicates that iterator is for a null value. - bool isNull_; + bool isNull_{true}; public: // For some reason, BORLAND needs these at the end, rather diff --git a/include/json/writer.h b/include/json/writer.h index 34e71edac..165326060 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -189,9 +189,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void writeValue(const Value& value); JSONCPP_STRING document_; - bool yamlCompatibilityEnabled_; - bool dropNullPlaceholders_; - bool omitEndingLineFeed_; + bool yamlCompatibilityEnabled_{false}; + bool dropNullPlaceholders_{false}; + bool omitEndingLineFeed_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -257,9 +257,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; JSONCPP_STRING document_; JSONCPP_STRING indentString_; - unsigned int rightMargin_; - unsigned int indentSize_; - bool addChildValues_; + unsigned int rightMargin_{74}; + unsigned int indentSize_{3}; + bool addChildValues_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -331,7 +331,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; JSONCPP_OSTREAM* document_; JSONCPP_STRING indentString_; - unsigned int rightMargin_; + unsigned int rightMargin_{74}; JSONCPP_STRING indentation_; bool addChildValues_ : 1; bool indented_ : 1; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index c5af01468..e1dc21237 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -60,8 +60,7 @@ typedef std::auto_ptr CharReaderPtr; // //////////////////////////////// Features::Features() - : allowComments_(true), strictRoot_(false), - allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} + {} Features Features::all() { return {}; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 2445d31a8..76c14a29d 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -233,7 +233,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() : comment_(nullptr) {} +Value::CommentInfo::CommentInfo() {} Value::CommentInfo::~CommentInfo() { if (comment_) @@ -1575,7 +1575,7 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} +PathArgument::PathArgument() : key_() {} PathArgument::PathArgument(ArrayIndex index) : key_(), index_(index), kind_(kindIndex) {} diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 7cc379227..4a2fc2e65 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -16,7 +16,7 @@ namespace Json { // ////////////////////////////////////////////////////////////////// ValueIteratorBase::ValueIteratorBase() - : current_(), isNull_(true) { + : current_() { } ValueIteratorBase::ValueIteratorBase( diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 54fcb4fa1..02d9a74f4 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -352,8 +352,8 @@ Writer::~Writer() {} // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - : yamlCompatibilityEnabled_(false), dropNullPlaceholders_(false), - omitEndingLineFeed_(false) {} + + {} void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } @@ -428,7 +428,7 @@ void FastWriter::writeValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledWriter::StyledWriter() - : rightMargin_(74), indentSize_(3), addChildValues_(false) {} + {} JSONCPP_STRING StyledWriter::write(const Value& root) { document_.clear(); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 03703c9c4..0329eeab9 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -74,7 +74,7 @@ namespace JsonTest { // ////////////////////////////////////////////////////////////////// TestResult::TestResult() - : predicateId_(1), lastUsedPredicateId_(0), messageTarget_(nullptr) { + { // The root predicate has id 0 rootPredicateNode_.id_ = 0; rootPredicateNode_.next_ = nullptr; @@ -205,7 +205,7 @@ TestResult& TestResult::operator<<(bool value) { // class TestCase // ////////////////////////////////////////////////////////////////// -TestCase::TestCase() : result_(nullptr) {} +TestCase::TestCase() {} TestCase::~TestCase() {} diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index e508282b6..76504228e 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -60,7 +60,7 @@ class TestResult { /// Not encapsulated to prevent step into when debugging failed assertions /// Incremented by one on assertion predicate entry, decreased by one /// by addPredicateContext(). - PredicateContext::Id predicateId_; + PredicateContext::Id predicateId_{1}; /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; @@ -109,9 +109,9 @@ class TestResult { Failures failures_; JSONCPP_STRING name_; PredicateContext rootPredicateNode_; - PredicateContext::Id lastUsedPredicateId_; + PredicateContext::Id lastUsedPredicateId_{0}; /// Failure which is the target of the messages added using operator << - Failure* messageTarget_; + Failure* messageTarget_{nullptr}; }; class TestCase { @@ -125,7 +125,7 @@ class TestCase { virtual const char* testName() const = 0; protected: - TestResult* result_; + TestResult* result_{nullptr}; private: virtual void runTestCase() = 0; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index d0315d7b2..b4f3f597a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -82,19 +82,19 @@ struct ValueTest : JsonTest::TestCase { /// Initialize all checks to \c false by default. IsCheck(); - bool isObject_; - bool isArray_; - bool isBool_; - bool isString_; - bool isNull_; - - bool isInt_; - bool isInt64_; - bool isUInt_; - bool isUInt64_; - bool isIntegral_; - bool isDouble_; - bool isNumeric_; + bool isObject_{false}; + bool isArray_{false}; + bool isBool_{false}; + bool isString_{false}; + bool isNull_{false}; + + bool isInt_{false}; + bool isInt64_{false}; + bool isUInt_{false}; + bool isUInt64_{false}; + bool isIntegral_{false}; + bool isDouble_{false}; + bool isNumeric_{false}; }; void checkConstMemberCount(const Json::Value& value, @@ -1331,10 +1331,8 @@ void ValueTest::checkMemberCount(Json::Value& value, } ValueTest::IsCheck::IsCheck() - : isObject_(false), isArray_(false), isBool_(false), isString_(false), - isNull_(false), isInt_(false), isInt64_(false), isUInt_(false), - isUInt64_(false), isIntegral_(false), isDouble_(false), - isNumeric_(false) {} + + {} void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); From e3e05c70859570152172e1f51940ad7468a78d4f Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:26 -0600 Subject: [PATCH 097/410] STYLE: Pefer = default to explicitly trivial implementations This check replaces default bodies of special member functions with = default;. The explicitly defaulted function declarations enable more opportunities in optimization, because the compiler might treat explicitly defaulted functions as trivial. Additionally, the C++11 use of = default more clearly expreses the intent for the special member functions. SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-equals-default -header-filter=.* -fix --- include/json/reader.h | 4 ++-- include/json/writer.h | 4 ++-- src/lib_json/json_reader.cpp | 4 ++-- src/lib_json/json_value.cpp | 2 +- src/lib_json/json_valueiterator.inl | 6 +++--- src/lib_json/json_writer.cpp | 12 ++++++------ src/test_lib_json/jsontest.cpp | 6 +++--- src/test_lib_json/main.cpp | 2 +- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index 1af5cb0dd..ac8b7bd80 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -256,7 +256,7 @@ class JSON_API Reader { */ class JSON_API CharReader { public: - virtual ~CharReader() {} + virtual ~CharReader() = default; /** \brief Read a Value from a JSON document. * The document must be a UTF-8 encoded string containing the document to @@ -282,7 +282,7 @@ class JSON_API CharReader { class JSON_API Factory { public: - virtual ~Factory() {} + virtual ~Factory() = default; /** \brief Allocate a CharReader via operator new(). * \throw std::exception if something goes wrong (e.g. invalid settings) */ diff --git a/include/json/writer.h b/include/json/writer.h index 165326060..10a1c8e11 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -169,7 +169,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { public: FastWriter(); - ~FastWriter() override {} + ~FastWriter() override = default; void enableYAMLCompatibility(); @@ -229,7 +229,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API StyledWriter : public Writer { public: StyledWriter(); - ~StyledWriter() override {} + ~StyledWriter() override = default; public: // overridden from Writer /** \brief Serialize a Value in JSON format. diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index e1dc21237..fc6b1397d 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -60,7 +60,7 @@ typedef std::auto_ptr CharReaderPtr; // //////////////////////////////// Features::Features() - {} + = default; Features Features::all() { return {}; } @@ -1907,7 +1907,7 @@ class OurCharReader : public CharReader { }; CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } -CharReaderBuilder::~CharReaderBuilder() {} +CharReaderBuilder::~CharReaderBuilder() = default; CharReader* CharReaderBuilder::newCharReader() const { bool collectComments = settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 76c14a29d..f05d7ae0e 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -233,7 +233,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() {} +Value::CommentInfo::CommentInfo() = default; Value::CommentInfo::~CommentInfo() { if (comment_) diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 4a2fc2e65..21d0611de 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -123,7 +123,7 @@ char const* ValueIteratorBase::memberName(char const** end) const { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueConstIterator::ValueConstIterator() {} +ValueConstIterator::ValueConstIterator() = default; ValueConstIterator::ValueConstIterator( const Value::ObjectValues::iterator& current) @@ -146,7 +146,7 @@ operator=(const ValueIteratorBase& other) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueIterator::ValueIterator() {} +ValueIterator::ValueIterator() = default; ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current) : ValueIteratorBase(current) {} @@ -157,7 +157,7 @@ ValueIterator::ValueIterator(const ValueConstIterator& other) } ValueIterator::ValueIterator(const ValueIterator& other) - : ValueIteratorBase(other) {} + = default; ValueIterator& ValueIterator::operator=(const SelfType& other) { copy(other); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 02d9a74f4..406d4bc26 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -346,14 +346,14 @@ JSONCPP_STRING valueToQuotedString(const char* value) { // Class Writer // ////////////////////////////////////////////////////////////////// -Writer::~Writer() {} +Writer::~Writer() = default; // Class FastWriter // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - {} + = default; void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } @@ -428,7 +428,7 @@ void FastWriter::writeValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledWriter::StyledWriter() - {} + = default; JSONCPP_STRING StyledWriter::write(const Value& root) { document_.clear(); @@ -1156,10 +1156,10 @@ bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { // StreamWriter StreamWriter::StreamWriter() : sout_(nullptr) {} -StreamWriter::~StreamWriter() {} -StreamWriter::Factory::~Factory() {} +StreamWriter::~StreamWriter() = default; +StreamWriter::Factory::~Factory() = default; StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } -StreamWriterBuilder::~StreamWriterBuilder() {} +StreamWriterBuilder::~StreamWriterBuilder() = default; StreamWriter* StreamWriterBuilder::newStreamWriter() const { JSONCPP_STRING indentation = settings_["indentation"].asString(); JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 0329eeab9..369ca9fce 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -205,9 +205,9 @@ TestResult& TestResult::operator<<(bool value) { // class TestCase // ////////////////////////////////////////////////////////////////// -TestCase::TestCase() {} +TestCase::TestCase() = default; -TestCase::~TestCase() {} +TestCase::~TestCase() = default; void TestCase::run(TestResult& result) { result_ = &result; @@ -217,7 +217,7 @@ void TestCase::run(TestResult& result) { // class Runner // ////////////////////////////////////////////////////////////////// -Runner::Runner() {} +Runner::Runner() = default; Runner& Runner::add(TestCaseFactory factory) { tests_.push_back(factory); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index b4f3f597a..b787a98a0 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1332,7 +1332,7 @@ void ValueTest::checkMemberCount(Json::Value& value, ValueTest::IsCheck::IsCheck() - {} + = default; void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); From d11732043ab12e0fbd9fa71cb546c8ac14ebf93a Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 17:09:29 -0600 Subject: [PATCH 098/410] STYLE: Pefer = delete to explicitly trivial implementations This check replaces undefined special member functions with = delete;. The explicitly deleted function declarations enable more opportunities in optimization, because the compiler might treat explicitly delted functions as noops. Additionally, the C++11 use of = delete more clearly expreses the intent for the special member functions. SRCDIR=/Users/johnsonhj/src/jsoncpp/ #My local SRC BLDDIR=/Users/johnsonhj/src/jsoncpp/cmake-build-debug/ #My local BLD cd /Users/johnsonhj/src/jsoncpp/cmake-build-debug/ run-clang-tidy.py -extra-arg=-D__clang__ -checks=-*,modernize-use-equals-delete -header-filter=.* -fix --- src/test_lib_json/jsontest.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 76504228e..85952a580 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -162,8 +162,8 @@ class Runner { static void printUsage(const char* appName); private: // prevents copy construction and assignment - Runner(const Runner& other); - Runner& operator=(const Runner& other); + Runner(const Runner& other) = delete; + Runner& operator=(const Runner& other) = delete; private: void listTests() const; From 21a418563406acb42484eff33da0a354a671effc Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 14 Jan 2019 19:02:40 -0600 Subject: [PATCH 099/410] STYLE: Avoid unnecessary conversions from size_t to unsigned int Make the index values consistent with size_t. --- src/lib_json/json_reader.cpp | 10 +++++++--- src/test_lib_json/jsontest.cpp | 34 +++++++++++++++++----------------- src/test_lib_json/jsontest.h | 8 ++++---- 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index fc6b1397d..56acc6ae3 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -888,7 +888,7 @@ class OurFeatures { bool failIfExtra_; bool rejectDupKeys_; bool allowSpecialFloats_; - int stackLimit_; + size_t stackLimit_; }; // OurFeatures // exact copy of Implementation of class Features @@ -1087,7 +1087,7 @@ bool OurReader::parse(const char* beginDoc, bool OurReader::readValue() { // To preserve the old behaviour we cast size_t to int. - if (static_cast(nodes_.size()) > features_.stackLimit_) + if (nodes_.size() > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; skipCommentTokens(token); @@ -1917,7 +1917,11 @@ CharReader* CharReaderBuilder::newCharReader() const { settings_["allowDroppedNullPlaceholders"].asBool(); features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); - features.stackLimit_ = settings_["stackLimit"].asInt(); +#if defined(JSON_HAS_INT64) + features.stackLimit_ = settings_["stackLimit"].asUInt64(); +#else + features.stackLimit_ = settings_["stackLimit"].asUInt(); +#endif features.failIfExtra_ = settings_["failIfExtra"].asBool(); features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 369ca9fce..1545e0333 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -224,18 +224,18 @@ Runner& Runner::add(TestCaseFactory factory) { return *this; } -unsigned int Runner::testCount() const { - return static_cast(tests_.size()); +size_t Runner::testCount() const { + return tests_.size(); } -JSONCPP_STRING Runner::testNameAt(unsigned int index) const { +JSONCPP_STRING Runner::testNameAt(size_t index) const { TestCase* test = tests_[index](); JSONCPP_STRING name = test->testName(); delete test; return name; } -void Runner::runTestAt(unsigned int index, TestResult& result) const { +void Runner::runTestAt(size_t index, TestResult& result) const { TestCase* test = tests_[index](); result.setTestName(test->testName()); printf("Testing %s: ", test->testName()); @@ -257,9 +257,9 @@ void Runner::runTestAt(unsigned int index, TestResult& result) const { } bool Runner::runAllTest(bool printSummary) const { - unsigned int count = testCount(); + size_t const count = testCount(); std::deque failures; - for (unsigned int index = 0; index < count; ++index) { + for (size_t index = 0; index < count; ++index) { TestResult result; runTestAt(index, result); if (result.failed()) { @@ -269,7 +269,7 @@ bool Runner::runAllTest(bool printSummary) const { if (failures.empty()) { if (printSummary) { - printf("All %u tests passed\n", count); + printf("All %zu tests passed\n", count); } return true; } else { @@ -278,19 +278,19 @@ bool Runner::runAllTest(bool printSummary) const { } if (printSummary) { - auto failedCount = static_cast(failures.size()); - unsigned int passedCount = count - failedCount; - printf("%u/%u tests passed (%u failure(s))\n", passedCount, count, - failedCount); + size_t const failedCount = failures.size(); + size_t const passedCount = count - failedCount; + printf("%zu/%zu tests passed (%zu failure(s))\n", + passedCount, count, failedCount); } return false; } } bool Runner::testIndex(const JSONCPP_STRING& testName, - unsigned int& indexOut) const { - unsigned int count = testCount(); - for (unsigned int index = 0; index < count; ++index) { + size_t& indexOut) const { + const size_t count = testCount(); + for (size_t index = 0; index < count; ++index) { if (testNameAt(index) == testName) { indexOut = index; return true; @@ -300,8 +300,8 @@ bool Runner::testIndex(const JSONCPP_STRING& testName, } void Runner::listTests() const { - unsigned int count = testCount(); - for (unsigned int index = 0; index < count; ++index) { + const size_t count = testCount(); + for (size_t index = 0; index < count; ++index) { printf("%s\n", testNameAt(index).c_str()); } } @@ -319,7 +319,7 @@ int Runner::runCommandLine(int argc, const char* argv[]) const { } else if (opt == "--test") { ++index; if (index < argc) { - unsigned int testNameIndex; + size_t testNameIndex; if (testIndex(argv[index], testNameIndex)) { subrunner.add(tests_[testNameIndex]); } else { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 85952a580..57d42ba6e 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -151,13 +151,13 @@ class Runner { bool runAllTest(bool printSummary) const; /// Returns the number of test case in the suite - unsigned int testCount() const; + size_t testCount() const; /// Returns the name of the test case at the specified index - JSONCPP_STRING testNameAt(unsigned int index) const; + JSONCPP_STRING testNameAt(size_t index) const; /// Runs the test case at the specified index using the specified TestResult - void runTestAt(unsigned int index, TestResult& result) const; + void runTestAt(size_t index, TestResult& result) const; static void printUsage(const char* appName); @@ -167,7 +167,7 @@ class Runner { private: void listTests() const; - bool testIndex(const JSONCPP_STRING& testName, unsigned int& indexOut) const; + bool testIndex(const JSONCPP_STRING& testName, size_t& indexOut) const; static void preventDialogOnCrash(); private: From dc4a7f9b613ce47d472c9fb90d07632dc1d2313a Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 17 Jan 2019 11:07:53 -0500 Subject: [PATCH 100/410] Reapply clang-format. $ clang-format -i -style=file \ $(find . | egrep '.*\.(h|cpp|inl)$') --- include/json/assertions.h | 2 +- include/json/config.h | 23 +++++++----- include/json/features.h | 8 ++-- include/json/reader.h | 5 ++- include/json/value.h | 6 +-- include/json/writer.h | 14 +++---- src/jsontestrunner/main.cpp | 2 +- src/lib_json/json_reader.cpp | 23 ++++++------ src/lib_json/json_value.cpp | 58 +++++++++++++++-------------- src/lib_json/json_valueiterator.inl | 22 ++++------- src/lib_json/json_writer.cpp | 19 +++++----- src/test_lib_json/jsontest.cpp | 20 ++++------ src/test_lib_json/jsontest.h | 14 +++---- src/test_lib_json/main.cpp | 54 +++++++++++++++------------ 14 files changed, 135 insertions(+), 135 deletions(-) diff --git a/include/json/assertions.h b/include/json/assertions.h index 9bf076f9a..b72254820 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -6,8 +6,8 @@ #ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED #define CPPTL_JSON_ASSERTIONS_H_INCLUDED -#include #include +#include #if !defined(JSON_IS_AMALGAMATION) #include "config.h" diff --git a/include/json/config.h b/include/json/config.h index 84384282c..f04d544fd 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -7,7 +7,7 @@ #define JSON_CONFIG_H_INCLUDED #include #include //typedef int64_t, uint64_t -#include //typedef String +#include //typedef String /// If defined, indicates that json library is embedded in CppTL library. //# define JSON_IN_CPPTL 1 @@ -55,15 +55,18 @@ #endif #if defined(_MSC_VER) && _MSC_VER < 1800 - #error "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" +#error \ + "ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities" #endif #if defined(_MSC_VER) && _MSC_VER < 1900 -// As recommended at https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 - extern JSON_API int msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...); -# define jsoncpp_snprintf msvc_pre1900_c99_snprintf +// As recommended at +// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 +extern JSON_API int +msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); +#define jsoncpp_snprintf msvc_pre1900_c99_snprintf #else -# define jsoncpp_snprintf std::snprintf +#define jsoncpp_snprintf std::snprintf #endif // If JSON_NO_INT64 is defined, then Json only support C++ "int" type for @@ -75,10 +78,10 @@ #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) #endif // defined(_MSC_VER) -// In c++11 the override keyword allows you to explicitly define that a function -// is intended to override the base-class version. This makes the code more -// manageable and fixes a set of common hard-to-find bugs. -#define JSONCPP_OVERRIDE override // Define maintained for backwards compatibility of external tools. C++11 should be used directly in JSONCPP +// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. +// C++11 should be used directly in JSONCPP. +#define JSONCPP_OVERRIDE override + #if __cplusplus >= 201103L #define JSONCPP_NOEXCEPT noexcept #define JSONCPP_OP_EXPLICIT explicit diff --git a/include/json/features.h b/include/json/features.h index ba25e8da6..8cbe172d4 100644 --- a/include/json/features.h +++ b/include/json/features.h @@ -41,17 +41,17 @@ class JSON_API Features { Features(); /// \c true if comments are allowed. Default: \c true. - bool allowComments_{true}; + bool allowComments_{ true }; /// \c true if root must be either an array or an object value. Default: \c /// false. - bool strictRoot_{false}; + bool strictRoot_{ false }; /// \c true if dropped null placeholders are allowed. Default: \c false. - bool allowDroppedNullPlaceholders_{false}; + bool allowDroppedNullPlaceholders_{ false }; /// \c true if numeric object key are allowed. Default: \c false. - bool allowNumericKeys_{false}; + bool allowNumericKeys_{ false }; }; } // namespace Json diff --git a/include/json/reader.h b/include/json/reader.h index ac8b7bd80..bde5f3fd8 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -220,8 +220,9 @@ class JSON_API Reader { Location& current, Location end, unsigned int& unicode); - bool - addError(const JSONCPP_STRING& message, Token& token, Location extra = nullptr); + bool addError(const JSONCPP_STRING& message, + Token& token, + Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, diff --git a/include/json/value.h b/include/json/value.h index 8321de7bf..8e6b615aa 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -630,7 +630,7 @@ Json::Value obj_value(Json::objectValue); // {} void setComment(const char* text, size_t len); - char* comment_{nullptr}; + char* comment_{ nullptr }; }; // struct MemberNamesTransform @@ -679,7 +679,7 @@ class JSON_API PathArgument { enum Kind { kindNone = 0, kindIndex, kindKey }; JSONCPP_STRING key_; ArrayIndex index_{}; - Kind kind_{kindNone}; + Kind kind_{ kindNone }; }; /** \brief Experimental and untested: represents a "path" to access a node. @@ -780,7 +780,7 @@ class JSON_API ValueIteratorBase { private: Value::ObjectValues::iterator current_; // Indicates that iterator is for a null value. - bool isNull_{true}; + bool isNull_{ true }; public: // For some reason, BORLAND needs these at the end, rather diff --git a/include/json/writer.h b/include/json/writer.h index 10a1c8e11..cf6f0c653 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -189,9 +189,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void writeValue(const Value& value); JSONCPP_STRING document_; - bool yamlCompatibilityEnabled_{false}; - bool dropNullPlaceholders_{false}; - bool omitEndingLineFeed_{false}; + bool yamlCompatibilityEnabled_{ false }; + bool dropNullPlaceholders_{ false }; + bool omitEndingLineFeed_{ false }; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -257,9 +257,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; JSONCPP_STRING document_; JSONCPP_STRING indentString_; - unsigned int rightMargin_{74}; - unsigned int indentSize_{3}; - bool addChildValues_{false}; + unsigned int rightMargin_{ 74 }; + unsigned int indentSize_{ 3 }; + bool addChildValues_{ false }; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -331,7 +331,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; JSONCPP_OSTREAM* document_; JSONCPP_STRING indentString_; - unsigned int rightMargin_{74}; + unsigned int rightMargin_{ 74 }; JSONCPP_STRING indentation_; bool addChildValues_ : 1; bool indented_ : 1; diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 6e0c0049a..a0ef94cc4 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -14,9 +14,9 @@ */ #include // sort +#include #include #include -#include struct Options { JSONCPP_STRING path; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 56acc6ae3..dfe76348f 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -31,8 +31,8 @@ #if defined(_MSC_VER) #if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES -#endif //_MSC_VER +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif //_MSC_VER #if defined(_MSC_VER) // Disable warning about strdup being deprecated. @@ -59,8 +59,7 @@ typedef std::auto_ptr CharReaderPtr; // Implementation of class Features // //////////////////////////////// -Features::Features() - = default; +Features::Features() = default; Features Features::all() { return {}; } @@ -87,8 +86,7 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // ////////////////////////////////////////////////////////////////// Reader::Reader() - : errors_(), document_(), commentsBefore_(), features_(Features::all()) - {} + : errors_(), document_(), commentsBefore_(), features_(Features::all()) {} Reader::Reader(const Features& features) : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), @@ -816,7 +814,7 @@ JSONCPP_STRING Reader::getFormatedErrorMessages() const { JSONCPP_STRING Reader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (const auto & error : errors_) { + for (const auto& error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -829,7 +827,7 @@ JSONCPP_STRING Reader::getFormattedErrorMessages() const { std::vector Reader::getStructuredErrors() const { std::vector allErrors; - for (const auto & error : errors_) { + for (const auto& error : errors_) { Reader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; @@ -989,8 +987,9 @@ class OurReader { Location& current, Location end, unsigned int& unicode); - bool - addError(const JSONCPP_STRING& message, Token& token, Location extra = nullptr); + bool addError(const JSONCPP_STRING& message, + Token& token, + Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, @@ -1827,7 +1826,7 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { JSONCPP_STRING OurReader::getFormattedErrorMessages() const { JSONCPP_STRING formattedMessage; - for (const auto & error : errors_) { + for (const auto& error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; @@ -1840,7 +1839,7 @@ JSONCPP_STRING OurReader::getFormattedErrorMessages() const { std::vector OurReader::getStructuredErrors() const { std::vector allErrors; - for (const auto & error : errors_) { + for (const auto& error : errors_) { OurReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index f05d7ae0e..574b1e909 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -9,8 +9,8 @@ #include #endif // if !defined(JSON_IS_AMALGAMATION) #include -#include #include +#include #include #include #ifdef JSON_USE_CPPTL @@ -21,24 +21,28 @@ // Provide implementation equivalent of std::snprintf for older _MSC compilers #if defined(_MSC_VER) && _MSC_VER < 1900 -#include -static int msvc_pre1900_c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) -{ - int count = -1; - if (size != 0) - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - if (count == -1) - count = _vscprintf(format, ap); - return count; -} - -int JSON_API msvc_pre1900_c99_snprintf(char *outBuf, size_t size, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap); - va_end(ap); - return count; +#include +static int msvc_pre1900_c99_vsnprintf(char* outBuf, + size_t size, + const char* format, + va_list ap) { + int count = -1; + if (size != 0) + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + return count; +} + +int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, + size_t size, + const char* format, + ...) { + va_list ap; + va_start(ap, format); + const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap); + va_end(ap); + return count; } #endif @@ -213,7 +217,7 @@ static inline void releaseStringValue(char* value, unsigned) { free(value); } namespace Json { -Exception::Exception(JSONCPP_STRING msg) : msg_(std::move(msg)) {} +Exception::Exception(JSONCPP_STRING msg) : msg_(std::move(msg)) {} Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {} @@ -233,7 +237,7 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() = default; +Value::CommentInfo::CommentInfo() = default; Value::CommentInfo::~CommentInfo() { if (comment_) @@ -436,7 +440,8 @@ Value::Value(double value) { Value::Value(const char* value) { initBasic(stringValue, true); - JSON_ASSERT_MESSAGE(value != nullptr, "Null Value Passed to Value Constructor"); + JSON_ASSERT_MESSAGE(value != nullptr, + "Null Value Passed to Value Constructor"); value_.string_ = duplicateAndPrefixStringValue( value, static_cast(strlen(value))); } @@ -890,8 +895,7 @@ bool Value::isConvertibleTo(ValueType other) const { (type_ == booleanValue && value_.bool_ == false) || (type_ == stringValue && asString().empty()) || (type_ == arrayValue && value_.map_->empty()) || - (type_ == objectValue && value_.map_->empty()) || - type_ == nullValue; + (type_ == objectValue && value_.map_->empty()) || type_ == nullValue; case intValue: return isInt() || (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || @@ -1655,7 +1659,7 @@ void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) { const Value& Path::resolve(const Value& root) const { const Value* node = &root; - for (const auto & arg : args_) { + for (const auto& arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) { // Error: unable to resolve path (array value expected at position... @@ -1680,7 +1684,7 @@ const Value& Path::resolve(const Value& root) const { Value Path::resolve(const Value& root, const Value& defaultValue) const { const Value* node = &root; - for (const auto & arg : args_) { + for (const auto& arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) return defaultValue; @@ -1698,7 +1702,7 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const { Value& Path::make(Value& root) const { Value* node = &root; - for (const auto & arg : args_) { + for (const auto& arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray()) { // Error: node is not an array at position ... diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 21d0611de..d1e2d3d1b 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -15,25 +15,17 @@ namespace Json { // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -ValueIteratorBase::ValueIteratorBase() - : current_() { -} +ValueIteratorBase::ValueIteratorBase() : current_() {} ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator& current) : current_(current), isNull_(false) {} -Value& ValueIteratorBase::deref() const { - return current_->second; -} +Value& ValueIteratorBase::deref() const { return current_->second; } -void ValueIteratorBase::increment() { - ++current_; -} +void ValueIteratorBase::increment() { ++current_; } -void ValueIteratorBase::decrement() { - --current_; -} +void ValueIteratorBase::decrement() { --current_; } ValueIteratorBase::difference_type ValueIteratorBase::computeDistance(const SelfType& other) const { @@ -96,7 +88,8 @@ JSONCPP_STRING ValueIteratorBase::name() const { char const* keey; char const* end; keey = memberName(&end); - if (!keey) return JSONCPP_STRING(); + if (!keey) + return JSONCPP_STRING(); return JSONCPP_STRING(keey, end); } @@ -156,8 +149,7 @@ ValueIterator::ValueIterator(const ValueConstIterator& other) throwRuntimeError("ConstIterator to Iterator should never be allowed."); } -ValueIterator::ValueIterator(const ValueIterator& other) - = default; +ValueIterator::ValueIterator(const ValueIterator& other) = default; ValueIterator& ValueIterator::operator=(const SelfType& other) { copy(other); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 406d4bc26..c1c482b8c 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -44,7 +44,7 @@ #if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #endif //_MSC_VER @@ -352,8 +352,8 @@ Writer::~Writer() = default; // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - - = default; + + = default; void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; } @@ -409,8 +409,7 @@ void FastWriter::writeValue(const Value& value) { case objectValue: { Value::Members members(value.getMemberNames()); document_ += '{'; - for (auto it = members.begin(); it != members.end(); - ++it) { + for (auto it = members.begin(); it != members.end(); ++it) { const JSONCPP_STRING& name = *it; if (it != members.begin()) document_ += ','; @@ -427,8 +426,7 @@ void FastWriter::writeValue(const Value& value) { // Class StyledWriter // ////////////////////////////////////////////////////////////////// -StyledWriter::StyledWriter() - = default; +StyledWriter::StyledWriter() = default; JSONCPP_STRING StyledWriter::write(const Value& root) { document_.clear(); @@ -922,9 +920,10 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter( PrecisionType precisionType) : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), - endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), addChildValues_(false), - indented_(false), useSpecialFloats_(useSpecialFloats), - precision_(precision), precisionType_(precisionType) {} + endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), + addChildValues_(false), indented_(false), + useSpecialFloats_(useSpecialFloats), precision_(precision), + precisionType_(precisionType) {} int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { sout_ = sout; addChildValues_ = false; diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 1545e0333..e8f09bc16 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -73,8 +73,7 @@ namespace JsonTest { // class TestResult // ////////////////////////////////////////////////////////////////// -TestResult::TestResult() - { +TestResult::TestResult() { // The root predicate has id 0 rootPredicateNode_.id_ = 0; rootPredicateNode_.next_ = nullptr; @@ -150,7 +149,7 @@ void TestResult::printFailure(bool printTestName) const { } // Print in reverse to display the callstack in the right order - for (const auto & failure : failures_ ) { + for (const auto& failure : failures_) { JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); @@ -205,7 +204,7 @@ TestResult& TestResult::operator<<(bool value) { // class TestCase // ////////////////////////////////////////////////////////////////// -TestCase::TestCase() = default; +TestCase::TestCase() = default; TestCase::~TestCase() = default; @@ -224,9 +223,7 @@ Runner& Runner::add(TestCaseFactory factory) { return *this; } -size_t Runner::testCount() const { - return tests_.size(); -} +size_t Runner::testCount() const { return tests_.size(); } JSONCPP_STRING Runner::testNameAt(size_t index) const { TestCase* test = tests_[index](); @@ -273,22 +270,21 @@ bool Runner::runAllTest(bool printSummary) const { } return true; } else { - for (auto & result : failures) { + for (auto& result : failures) { result.printFailure(count > 1); } if (printSummary) { size_t const failedCount = failures.size(); size_t const passedCount = count - failedCount; - printf("%zu/%zu tests passed (%zu failure(s))\n", - passedCount, count, failedCount); + printf("%zu/%zu tests passed (%zu failure(s))\n", passedCount, count, + failedCount); } return false; } } -bool Runner::testIndex(const JSONCPP_STRING& testName, - size_t& indexOut) const { +bool Runner::testIndex(const JSONCPP_STRING& testName, size_t& indexOut) const { const size_t count = testCount(); for (size_t index = 0; index < count; ++index) { if (testNameAt(index) == testName) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 57d42ba6e..36cfd1ae6 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -6,12 +6,12 @@ #ifndef JSONTEST_H_INCLUDED #define JSONTEST_H_INCLUDED +#include #include #include #include #include #include -#include #include // ////////////////////////////////////////////////////////////////// @@ -60,7 +60,7 @@ class TestResult { /// Not encapsulated to prevent step into when debugging failed assertions /// Incremented by one on assertion predicate entry, decreased by one /// by addPredicateContext(). - PredicateContext::Id predicateId_{1}; + PredicateContext::Id predicateId_{ 1 }; /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; @@ -109,9 +109,9 @@ class TestResult { Failures failures_; JSONCPP_STRING name_; PredicateContext rootPredicateNode_; - PredicateContext::Id lastUsedPredicateId_{0}; + PredicateContext::Id lastUsedPredicateId_{ 0 }; /// Failure which is the target of the messages added using operator << - Failure* messageTarget_{nullptr}; + Failure* messageTarget_{ nullptr }; }; class TestCase { @@ -125,7 +125,7 @@ class TestCase { virtual const char* testName() const = 0; protected: - TestResult* result_{nullptr}; + TestResult* result_{ nullptr }; private: virtual void runTestCase() = 0; @@ -262,9 +262,7 @@ TestResult& checkStringEqual(TestResult& result, } \ \ public: /* overridden from TestCase */ \ - const char* testName() const override { \ - return #FixtureType "/" #name; \ - } \ + const char* testName() const override { return #FixtureType "/" #name; } \ void runTestCase() override; \ }; \ \ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index b787a98a0..4c0319795 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -82,19 +82,19 @@ struct ValueTest : JsonTest::TestCase { /// Initialize all checks to \c false by default. IsCheck(); - bool isObject_{false}; - bool isArray_{false}; - bool isBool_{false}; - bool isString_{false}; - bool isNull_{false}; - - bool isInt_{false}; - bool isInt64_{false}; - bool isUInt_{false}; - bool isUInt64_{false}; - bool isIntegral_{false}; - bool isDouble_{false}; - bool isNumeric_{false}; + bool isObject_{ false }; + bool isArray_{ false }; + bool isBool_{ false }; + bool isString_{ false }; + bool isNull_{ false }; + + bool isInt_{ false }; + bool isInt64_{ false }; + bool isUInt_{ false }; + bool isUInt64_{ false }; + bool isIntegral_{ false }; + bool isDouble_{ false }; + bool isNumeric_{ false }; }; void checkConstMemberCount(const Json::Value& value, @@ -1331,8 +1331,8 @@ void ValueTest::checkMemberCount(Json::Value& value, } ValueTest::IsCheck::IsCheck() - - = default; + + = default; void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); @@ -2354,14 +2354,22 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { JSONCPP_STRING in; }; const TestData test_data[] = { - { __LINE__, true, "{\"a\":9}" }, { __LINE__, false, "{\"a\":0Infinity}" }, - { __LINE__, false, "{\"a\":1Infinity}" }, { __LINE__, false, "{\"a\":9Infinity}" }, - { __LINE__, false, "{\"a\":0nfinity}" }, { __LINE__, false, "{\"a\":1nfinity}" }, - { __LINE__, false, "{\"a\":9nfinity}" }, { __LINE__, false, "{\"a\":nfinity}" }, - { __LINE__, false, "{\"a\":.nfinity}" }, { __LINE__, false, "{\"a\":9nfinity}" }, - { __LINE__, false, "{\"a\":-nfinity}" }, { __LINE__, true, "{\"a\":Infinity}" }, - { __LINE__, false, "{\"a\":.Infinity}" }, { __LINE__, false, "{\"a\":_Infinity}" }, - { __LINE__, false, "{\"a\":_nfinity}" }, { __LINE__, true, "{\"a\":-Infinity}" } + { __LINE__, true, "{\"a\":9}" }, // + { __LINE__, false, "{\"a\":0Infinity}" }, // + { __LINE__, false, "{\"a\":1Infinity}" }, // + { __LINE__, false, "{\"a\":9Infinity}" }, // + { __LINE__, false, "{\"a\":0nfinity}" }, // + { __LINE__, false, "{\"a\":1nfinity}" }, // + { __LINE__, false, "{\"a\":9nfinity}" }, // + { __LINE__, false, "{\"a\":nfinity}" }, // + { __LINE__, false, "{\"a\":.nfinity}" }, // + { __LINE__, false, "{\"a\":9nfinity}" }, // + { __LINE__, false, "{\"a\":-nfinity}" }, // + { __LINE__, true, "{\"a\":Infinity}" }, // + { __LINE__, false, "{\"a\":.Infinity}" }, // + { __LINE__, false, "{\"a\":_Infinity}" }, // + { __LINE__, false, "{\"a\":_nfinity}" }, // + { __LINE__, true, "{\"a\":-Infinity}" } // }; for (const auto& td : test_data) { bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), From 1c2ed7a10f6dc98d8ca0947356c78b785bd6e00a Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 17 Jan 2019 16:35:29 -0500 Subject: [PATCH 101/410] convert JSONCPP_STRING etc from macros to typedefs --- include/json/assertions.h | 4 +- include/json/config.h | 56 +++++----- include/json/reader.h | 42 ++++---- include/json/value.h | 58 +++++----- include/json/writer.h | 64 +++++------ src/jsontestrunner/main.cpp | 89 ++++++++------- src/lib_json/json_reader.cpp | 135 +++++++++++------------ src/lib_json/json_tool.h | 4 +- src/lib_json/json_value.cpp | 53 +++++---- src/lib_json/json_valueiterator.inl | 6 +- src/lib_json/json_writer.cpp | 162 +++++++++++++--------------- src/test_lib_json/jsontest.cpp | 43 ++++---- src/test_lib_json/jsontest.h | 29 +++-- src/test_lib_json/main.cpp | 115 ++++++++++---------- 14 files changed, 416 insertions(+), 444 deletions(-) diff --git a/include/json/assertions.h b/include/json/assertions.h index b72254820..20716b067 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -29,7 +29,7 @@ #define JSON_FAIL_MESSAGE(message) \ { \ - JSONCPP_OSTRINGSTREAM oss; \ + OStringStream oss; \ oss << message; \ Json::throwLogicError(oss.str()); \ abort(); \ @@ -43,7 +43,7 @@ // release builds we abort, for a core-dump or debugger. #define JSON_FAIL_MESSAGE(message) \ { \ - JSONCPP_OSTRINGSTREAM oss; \ + OStringStream oss; \ oss << message; \ assert(false && oss.str().c_str()); \ abort(); \ diff --git a/include/json/config.h b/include/json/config.h index f04d544fd..2b603769e 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -6,8 +6,13 @@ #ifndef JSON_CONFIG_H_INCLUDED #define JSON_CONFIG_H_INCLUDED #include -#include //typedef int64_t, uint64_t -#include //typedef String +#include +#include +#include +#include +#include +#include +#include /// If defined, indicates that json library is embedded in CppTL library. //# define JSON_IN_CPPTL 1 @@ -142,12 +147,9 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #if !defined(JSON_IS_AMALGAMATION) +#include "allocator.h" #include "version.h" -#if JSONCPP_USING_SECURE_MEMORY -#include "allocator.h" //typedef Allocator -#endif - #endif // if !defined(JSON_IS_AMALGAMATION) namespace Json { @@ -170,24 +172,28 @@ typedef Int64 LargestInt; typedef UInt64 LargestUInt; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) -#if JSONCPP_USING_SECURE_MEMORY -#define JSONCPP_STRING \ - std::basic_string, Json::SecureAllocator > -#define JSONCPP_OSTRINGSTREAM \ - std::basic_ostringstream, \ - Json::SecureAllocator > -#define JSONCPP_OSTREAM std::basic_ostream > -#define JSONCPP_ISTRINGSTREAM \ - std::basic_istringstream, \ - Json::SecureAllocator > -#define JSONCPP_ISTREAM std::istream -#else -#define JSONCPP_STRING std::string -#define JSONCPP_OSTRINGSTREAM std::ostringstream -#define JSONCPP_OSTREAM std::ostream -#define JSONCPP_ISTRINGSTREAM std::istringstream -#define JSONCPP_ISTREAM std::istream -#endif // if JSONCPP_USING_SECURE_MEMORY -} // end namespace Json + +template +using Allocator = typename std::conditional, + std::allocator >::type; +using String = + std::basic_string, Allocator >; +using IStringStream = std::basic_istringstream; +using OStringStream = std::basic_ostringstream; +using IStream = std::istream; +using OStream = std::ostream; +} // namespace Json + +// Legacy names (formerly macros). +using JSONCPP_STRING = Json::String; +using JSONCPP_ISTRINGSTREAM = Json::IStringStream; +using JSONCPP_OSTRINGSTREAM = Json::OStringStream; +using JSONCPP_ISTREAM = Json::IStream; +using JSONCPP_OSTREAM = Json::OStream; #endif // JSON_CONFIG_H_INCLUDED diff --git a/include/json/reader.h b/include/json/reader.h index bde5f3fd8..111e5dd98 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -46,7 +46,7 @@ class JSON_API Reader { struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; - JSONCPP_STRING message; + String message; }; /** \brief Constructs a Reader allowing all features @@ -103,7 +103,7 @@ class JSON_API Reader { /// \brief Parse from input stream. /// \see Json::operator>>(std::istream&, Json::Value&). - bool parse(JSONCPP_ISTREAM& is, Value& root, bool collectComments = true); + bool parse(IStream& is, Value& root, bool collectComments = true); /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -115,7 +115,7 @@ class JSON_API Reader { * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") - JSONCPP_STRING getFormatedErrorMessages() const; + String getFormatedErrorMessages() const; /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -125,7 +125,7 @@ class JSON_API Reader { * occurred * during parsing. */ - JSONCPP_STRING getFormattedErrorMessages() const; + String getFormattedErrorMessages() const; /** \brief Returns a vector of structured erros encounted while parsing. * \return A (possibly empty) vector of StructuredError objects. Currently @@ -142,7 +142,7 @@ class JSON_API Reader { * \return \c true if the error was successfully added, \c false if the * Value offset exceeds the document size. */ - bool pushError(const Value& value, const JSONCPP_STRING& message); + bool pushError(const Value& value, const String& message); /** \brief Add a semantic error message with extra context. * \param value JSON Value location associated with the error @@ -151,9 +151,7 @@ class JSON_API Reader { * \return \c true if the error was successfully added, \c false if either * Value offset exceeds the document size. */ - bool pushError(const Value& value, - const JSONCPP_STRING& message, - const Value& extra); + bool pushError(const Value& value, const String& message, const Value& extra); /** \brief Return whether there are any errors. * \return \c true if there are no errors to report \c false if @@ -189,7 +187,7 @@ class JSON_API Reader { class ErrorInfo { public: Token token_; - JSONCPP_STRING message_; + String message_; Location extra_; }; @@ -209,7 +207,7 @@ class JSON_API Reader { bool decodeNumber(Token& token); bool decodeNumber(Token& token, Value& decoded); bool decodeString(Token& token); - bool decodeString(Token& token, JSONCPP_STRING& decoded); + bool decodeString(Token& token, String& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); bool decodeUnicodeCodePoint(Token& token, @@ -220,11 +218,9 @@ class JSON_API Reader { Location& current, Location end, unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, - Token& token, - Location extra = nullptr); + bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const JSONCPP_STRING& message, + bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); @@ -232,23 +228,23 @@ class JSON_API Reader { Char getNextChar(); void getLocationLineAndColumn(Location location, int& line, int& column) const; - JSONCPP_STRING getLocationLineAndColumn(Location location) const; + String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); static bool containsNewLine(Location begin, Location end); - static JSONCPP_STRING normalizeEOL(Location begin, Location end); + static String normalizeEOL(Location begin, Location end); typedef std::stack Nodes; Nodes nodes_; Errors errors_; - JSONCPP_STRING document_; + String document_; Location begin_{}; Location end_{}; Location current_{}; Location lastValueEnd_{}; Value* lastValue_{}; - JSONCPP_STRING commentsBefore_; + String commentsBefore_; Features features_; bool collectComments_{}; }; // Reader @@ -279,7 +275,7 @@ class JSON_API CharReader { virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, - JSONCPP_STRING* errs) = 0; + String* errs) = 0; class JSON_API Factory { public: @@ -299,7 +295,7 @@ class JSON_API CharReader { CharReaderBuilder builder; builder["collectComments"] = false; Value value; - JSONCPP_STRING errs; + String errs; bool ok = parseFromStream(builder, std::cin, &value, &errs); \endcode */ @@ -359,7 +355,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { /** A simple way to update a specific setting. */ - Value& operator[](const JSONCPP_STRING& key); + Value& operator[](const String& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) @@ -380,7 +376,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * is convenient. */ bool JSON_API parseFromStream(CharReader::Factory const&, - JSONCPP_ISTREAM&, + IStream&, Value* root, std::string* errs); @@ -408,7 +404,7 @@ bool JSON_API parseFromStream(CharReader::Factory const&, \throw std::exception on parse error. \see Json::operator<<() */ -JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&); +JSON_API IStream& operator>>(IStream&, Value&); } // namespace Json diff --git a/include/json/value.h b/include/json/value.h index 8e6b615aa..9df8a3b6c 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -54,12 +54,12 @@ namespace Json { */ class JSON_API Exception : public std::exception { public: - Exception(JSONCPP_STRING msg); + Exception(String msg); ~Exception() JSONCPP_NOEXCEPT override; char const* what() const JSONCPP_NOEXCEPT override; protected: - JSONCPP_STRING msg_; + String msg_; }; /** Exceptions which the user cannot easily avoid. @@ -70,7 +70,7 @@ class JSON_API Exception : public std::exception { */ class JSON_API RuntimeError : public Exception { public: - RuntimeError(JSONCPP_STRING const& msg); + RuntimeError(String const& msg); }; /** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros. @@ -81,13 +81,13 @@ class JSON_API RuntimeError : public Exception { */ class JSON_API LogicError : public Exception { public: - LogicError(JSONCPP_STRING const& msg); + LogicError(String const& msg); }; /// used internally -JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg); +JSONCPP_NORETURN void throwRuntimeError(String const& msg); /// used internally -JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg); +JSONCPP_NORETURN void throwLogicError(String const& msg); /** \brief Type of the value held by a Value object. */ @@ -186,7 +186,7 @@ class JSON_API Value { friend class ValueIteratorBase; public: - typedef std::vector Members; + typedef std::vector Members; typedef ValueIterator iterator; typedef ValueConstIterator const_iterator; typedef Json::UInt UInt; @@ -332,8 +332,8 @@ Json::Value obj_value(Json::objectValue); // {} * \endcode */ Value(const StaticString& value); - Value(const JSONCPP_STRING& value); ///< Copy data() til size(). Embedded - ///< zeroes too. + Value(const String& value); ///< Copy data() til size(). Embedded + ///< zeroes too. #ifdef JSON_USE_CPPTL Value(const CppTL::ConstString& value); #endif @@ -377,7 +377,7 @@ Json::Value obj_value(Json::objectValue); // {} unsigned getCStringLength() const; // Allows you to understand the length of // the CString #endif - JSONCPP_STRING asString() const; ///< Embedded zeroes are possible. + String asString() const; ///< Embedded zeroes are possible. /** Get raw char* of string-value. * \return false if !string. (Seg-fault if str or end are NULL.) */ @@ -484,11 +484,11 @@ Json::Value obj_value(Json::objectValue); // {} const Value& operator[](const char* key) const; /// Access an object value by name, create a null member if it does not exist. /// \param key may contain embedded nulls. - Value& operator[](const JSONCPP_STRING& key); + Value& operator[](const String& key); /// Access an object value by name, returns null if there is no member with /// that name. /// \param key may contain embedded nulls. - const Value& operator[](const JSONCPP_STRING& key) const; + const Value& operator[](const String& key) const; /** \brief Access an object value by name, create a null member if it does not exist. @@ -521,7 +521,7 @@ Json::Value obj_value(Json::objectValue); // {} /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \param key may contain embedded nulls. - Value get(const JSONCPP_STRING& key, const Value& defaultValue) const; + Value get(const String& key, const Value& defaultValue) const; #ifdef JSON_USE_CPPTL /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy @@ -543,7 +543,7 @@ Json::Value obj_value(Json::objectValue); // {} void removeMember(const char* key); /// Same as removeMember(const char*) /// \param key may contain embedded nulls. - void removeMember(const JSONCPP_STRING& key); + void removeMember(const String& key); /// Same as removeMember(const char* begin, const char* end, Value* removed), /// but 'key' is null-terminated. bool removeMember(const char* key, Value* removed); @@ -553,8 +553,8 @@ Json::Value obj_value(Json::objectValue); // {} \param key may contain embedded nulls. \return true iff removed (no exceptions) */ - bool removeMember(JSONCPP_STRING const& key, Value* removed); - /// Same as removeMember(JSONCPP_STRING const& key, Value* removed) + bool removeMember(String const& key, Value* removed); + /// Same as removeMember(String const& key, Value* removed) bool removeMember(const char* begin, const char* end, Value* removed); /** \brief Remove the indexed array element. @@ -569,8 +569,8 @@ Json::Value obj_value(Json::objectValue); // {} bool isMember(const char* key) const; /// Return true if the object has a member named key. /// \param key may contain embedded nulls. - bool isMember(const JSONCPP_STRING& key) const; - /// Same as isMember(JSONCPP_STRING const& key)const + bool isMember(const String& key) const; + /// Same as isMember(String const& key)const bool isMember(const char* begin, const char* end) const; #ifdef JSON_USE_CPPTL /// Return true if the object has a member named key. @@ -590,17 +590,17 @@ Json::Value obj_value(Json::objectValue); // {} //# endif /// \deprecated Always pass len. - JSONCPP_DEPRECATED("Use setComment(JSONCPP_STRING const&) instead.") + JSONCPP_DEPRECATED("Use setComment(String const&) instead.") void setComment(const char* comment, CommentPlacement placement); /// Comments must be //... or /* ... */ void setComment(const char* comment, size_t len, CommentPlacement placement); /// Comments must be //... or /* ... */ - void setComment(const JSONCPP_STRING& comment, CommentPlacement placement); + void setComment(const String& comment, CommentPlacement placement); bool hasComment(CommentPlacement placement) const; /// Include delimiters and embedded newlines. - JSONCPP_STRING getComment(CommentPlacement placement) const; + String getComment(CommentPlacement placement) const; - JSONCPP_STRING toStyledString() const; + String toStyledString() const; const_iterator begin() const; const_iterator end() const; @@ -673,11 +673,11 @@ class JSON_API PathArgument { PathArgument(); PathArgument(ArrayIndex index); PathArgument(const char* key); - PathArgument(const JSONCPP_STRING& key); + PathArgument(const String& key); private: enum Kind { kindNone = 0, kindIndex, kindKey }; - JSONCPP_STRING key_; + String key_; ArrayIndex index_{}; Kind kind_{ kindNone }; }; @@ -695,7 +695,7 @@ class JSON_API PathArgument { */ class JSON_API Path { public: - Path(const JSONCPP_STRING& path, + Path(const String& path, const PathArgument& a1 = PathArgument(), const PathArgument& a2 = PathArgument(), const PathArgument& a3 = PathArgument(), @@ -712,12 +712,12 @@ class JSON_API Path { typedef std::vector InArgs; typedef std::vector Args; - void makePath(const JSONCPP_STRING& path, const InArgs& in); - void addPathInArg(const JSONCPP_STRING& path, + void makePath(const String& path, const InArgs& in); + void addPathInArg(const String& path, const InArgs& in, InArgs::const_iterator& itInArg, PathArgument::Kind kind); - static void invalidPath(const JSONCPP_STRING& path, int location); + static void invalidPath(const String& path, int location); Args args_; }; @@ -751,7 +751,7 @@ class JSON_API ValueIteratorBase { /// Return the member name of the referenced Value, or "" if it is not an /// objectValue. /// \note Avoid `c_str()` on result, as embedded zeroes are possible. - JSONCPP_STRING name() const; + String name() const; /// Return the member name of the referenced Value. "" if it is not an /// objectValue. diff --git a/include/json/writer.h b/include/json/writer.h index cf6f0c653..b8094839d 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -41,7 +41,7 @@ class Value; */ class JSON_API StreamWriter { protected: - JSONCPP_OSTREAM* sout_; // not owned; will not delete + OStream* sout_; // not owned; will not delete public: StreamWriter(); virtual ~StreamWriter(); @@ -51,7 +51,7 @@ class JSON_API StreamWriter { \return zero on success (For now, we always return zero, so check the stream instead.) \throw std::exception possibly, depending on configuration */ - virtual int write(Value const& root, JSONCPP_OSTREAM* sout) = 0; + virtual int write(Value const& root, OStream* sout) = 0; /** \brief A simple abstract factory. */ @@ -68,8 +68,8 @@ class JSON_API StreamWriter { /** \brief Write into stringstream, then return string, for convenience. * A StreamWriter will be created from the factory, used, and then deleted. */ -JSONCPP_STRING JSON_API writeString(StreamWriter::Factory const& factory, - Value const& root); +String JSON_API writeString(StreamWriter::Factory const& factory, + Value const& root); /** \brief Build a StreamWriter implementation. @@ -132,7 +132,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { bool validate(Json::Value* invalid) const; /** A simple way to update a specific setting. */ - Value& operator[](const JSONCPP_STRING& key); + Value& operator[](const String& key); /** Called by ctor, but you can use this to reset settings_. * \pre 'settings' != NULL (but Json::null is fine) @@ -149,7 +149,7 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { public: virtual ~Writer(); - virtual JSONCPP_STRING write(const Value& root) = 0; + virtual String write(const Value& root) = 0; }; /** \brief Outputs a Value in JSON format @@ -183,12 +183,12 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void omitEndingLineFeed(); public: // overridden from Writer - JSONCPP_STRING write(const Value& root) override; + String write(const Value& root) override; private: void writeValue(const Value& value); - JSONCPP_STRING document_; + String document_; bool yamlCompatibilityEnabled_{ false }; bool dropNullPlaceholders_{ false }; bool omitEndingLineFeed_{ false }; @@ -236,27 +236,27 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API * \param root Value to serialize. * \return String containing the JSON document that represents the root value. */ - JSONCPP_STRING write(const Value& root) override; + String write(const Value& root) override; private: void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultilineArray(const Value& value); - void pushValue(const JSONCPP_STRING& value); + void pushValue(const String& value); void writeIndent(); - void writeWithIndent(const JSONCPP_STRING& value); + void writeWithIndent(const String& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); static bool hasCommentForValue(const Value& value); - static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); + static String normalizeEOL(const String& text); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; - JSONCPP_STRING document_; - JSONCPP_STRING indentString_; + String document_; + String indentString_; unsigned int rightMargin_{ 74 }; unsigned int indentSize_{ 3 }; bool addChildValues_{ false }; @@ -300,7 +300,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API /** * \param indentation Each level will be indented by this amount extra. */ - StyledStreamWriter(JSONCPP_STRING indentation = "\t"); + StyledStreamWriter(String indentation = "\t"); ~StyledStreamWriter() = default; public: @@ -310,29 +310,29 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API * \note There is no point in deriving from Writer, since write() should not * return a value. */ - void write(JSONCPP_OSTREAM& out, const Value& root); + void write(OStream& out, const Value& root); private: void writeValue(const Value& value); void writeArrayValue(const Value& value); bool isMultilineArray(const Value& value); - void pushValue(const JSONCPP_STRING& value); + void pushValue(const String& value); void writeIndent(); - void writeWithIndent(const JSONCPP_STRING& value); + void writeWithIndent(const String& value); void indent(); void unindent(); void writeCommentBeforeValue(const Value& root); void writeCommentAfterValueOnSameLine(const Value& root); static bool hasCommentForValue(const Value& value); - static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING& text); + static String normalizeEOL(const String& text); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; - JSONCPP_OSTREAM* document_; - JSONCPP_STRING indentString_; + OStream* document_; + String indentString_; unsigned int rightMargin_{ 74 }; - JSONCPP_STRING indentation_; + String indentation_; bool addChildValues_ : 1; bool indented_ : 1; }; @@ -341,21 +341,21 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API #endif #if defined(JSON_HAS_INT64) -JSONCPP_STRING JSON_API valueToString(Int value); -JSONCPP_STRING JSON_API valueToString(UInt value); +String JSON_API valueToString(Int value); +String JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) -JSONCPP_STRING JSON_API valueToString(LargestInt value); -JSONCPP_STRING JSON_API valueToString(LargestUInt value); -JSONCPP_STRING JSON_API +String JSON_API valueToString(LargestInt value); +String JSON_API valueToString(LargestUInt value); +String JSON_API valueToString(double value, unsigned int precision = Value::defaultRealPrecision, PrecisionType precisionType = PrecisionType::significantDigits); -JSONCPP_STRING JSON_API valueToString(bool value); -JSONCPP_STRING JSON_API valueToQuotedString(const char* value); +String JSON_API valueToString(bool value); +String JSON_API valueToQuotedString(const char* value); /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() -JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root); +JSON_API OStream& operator<<(OStream&, const Value& root); } // namespace Json diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index a0ef94cc4..855f9c761 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -19,29 +19,28 @@ #include struct Options { - JSONCPP_STRING path; + Json::String path; Json::Features features; bool parseOnly; - typedef JSONCPP_STRING (*writeFuncType)(Json::Value const&); + using writeFuncType = Json::String(*)(Json::Value const&); writeFuncType write; }; -static JSONCPP_STRING normalizeFloatingPointStr(double value) { +static Json::String normalizeFloatingPointStr(double value) { char buffer[32]; jsoncpp_snprintf(buffer, sizeof(buffer), "%.16g", value); buffer[sizeof(buffer) - 1] = 0; - JSONCPP_STRING s(buffer); - JSONCPP_STRING::size_type index = s.find_last_of("eE"); - if (index != JSONCPP_STRING::npos) { - JSONCPP_STRING::size_type hasSign = + Json::String s(buffer); + Json::String::size_type index = s.find_last_of("eE"); + if (index != Json::String::npos) { + Json::String::size_type hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign; - JSONCPP_STRING normalized = s.substr(0, exponentStartIndex); - JSONCPP_STRING::size_type indexDigit = - s.find_first_not_of('0', exponentStartIndex); - JSONCPP_STRING exponent = "0"; - if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different - // from 0 + Json::String::size_type exponentStartIndex = index + 1 + hasSign; + Json::String normalized = s.substr(0, exponentStartIndex); + Json::String::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); + Json::String exponent = "0"; + if (indexDigit != Json::String::npos) // There is an exponent different + // from 0 { exponent = s.substr(indexDigit); } @@ -50,17 +49,17 @@ static JSONCPP_STRING normalizeFloatingPointStr(double value) { return s; } -static JSONCPP_STRING readInputTestFile(const char* path) { +static Json::String readInputTestFile(const char* path) { FILE* file = fopen(path, "rb"); if (!file) - return JSONCPP_STRING(""); + return ""; fseek(file, 0, SEEK_END); long const size = ftell(file); size_t const usize = static_cast(size); fseek(file, 0, SEEK_SET); - JSONCPP_STRING text; char* buffer = new char[size + 1]; buffer[size] = 0; + Json::String text; if (fread(buffer, 1, usize, file) == usize) text = buffer; fclose(file); @@ -68,9 +67,8 @@ static JSONCPP_STRING readInputTestFile(const char* path) { return text; } -static void printValueTree(FILE* fout, - Json::Value& value, - const JSONCPP_STRING& path = ".") { +static void +printValueTree(FILE* fout, Json::Value& value, const Json::String& path = ".") { if (value.hasComment(Json::commentBefore)) { fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); } @@ -109,7 +107,7 @@ static void printValueTree(FILE* fout, fprintf(fout, "%s={}\n", path.c_str()); Json::Value::Members members(value.getMemberNames()); std::sort(members.begin(), members.end()); - JSONCPP_STRING suffix = *(path.end() - 1) == '.' ? "" : "."; + Json::String suffix = *(path.end() - 1) == '.' ? "" : "."; for (auto name : members) { printValueTree(fout, value[name], path + suffix + name); } @@ -123,9 +121,9 @@ static void printValueTree(FILE* fout, } } -static int parseAndSaveValueTree(const JSONCPP_STRING& input, - const JSONCPP_STRING& actual, - const JSONCPP_STRING& kind, +static int parseAndSaveValueTree(const Json::String& input, + const Json::String& actual, + const Json::String& kind, const Json::Features& features, bool parseOnly, Json::Value* root) { @@ -148,29 +146,29 @@ static int parseAndSaveValueTree(const JSONCPP_STRING& input, } return 0; } -// static JSONCPP_STRING useFastWriter(Json::Value const& root) { +// static Json::String useFastWriter(Json::Value const& root) { // Json::FastWriter writer; // writer.enableYAMLCompatibility(); // return writer.write(root); // } -static JSONCPP_STRING useStyledWriter(Json::Value const& root) { +static Json::String useStyledWriter(Json::Value const& root) { Json::StyledWriter writer; return writer.write(root); } -static JSONCPP_STRING useStyledStreamWriter(Json::Value const& root) { +static Json::String useStyledStreamWriter(Json::Value const& root) { Json::StyledStreamWriter writer; - JSONCPP_OSTRINGSTREAM sout; + Json::OStringStream sout; writer.write(sout, root); return sout.str(); } -static JSONCPP_STRING useBuiltStyledStreamWriter(Json::Value const& root) { +static Json::String useBuiltStyledStreamWriter(Json::Value const& root) { Json::StreamWriterBuilder builder; return Json::writeString(builder, root); } -static int rewriteValueTree(const JSONCPP_STRING& rewritePath, +static int rewriteValueTree(const Json::String& rewritePath, const Json::Value& root, Options::writeFuncType write, - JSONCPP_STRING* rewrite) { + Json::String* rewrite) { *rewrite = write(root); FILE* fout = fopen(rewritePath.c_str(), "wt"); if (!fout) { @@ -182,13 +180,12 @@ static int rewriteValueTree(const JSONCPP_STRING& rewritePath, return 0; } -static JSONCPP_STRING removeSuffix(const JSONCPP_STRING& path, - const JSONCPP_STRING& extension) { +static Json::String removeSuffix(const Json::String& path, const Json::String& extension) { if (extension.length() >= path.length()) - return JSONCPP_STRING(""); - JSONCPP_STRING suffix = path.substr(path.length() - extension.length()); + return Json::String(""); + Json::String suffix = path.substr(path.length() - extension.length()); if (suffix != extension) - return JSONCPP_STRING(""); + return Json::String(""); return path.substr(0, path.length() - extension.length()); } @@ -213,18 +210,18 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) { return printUsage(argv); } int index = 1; - if (JSONCPP_STRING(argv[index]) == "--json-checker") { + if (Json::String(argv[index]) == "--json-checker") { opts->features = Json::Features::strictMode(); opts->parseOnly = true; ++index; } - if (JSONCPP_STRING(argv[index]) == "--json-config") { + if (Json::String(argv[index]) == "--json-config") { printConfig(); return 3; } - if (JSONCPP_STRING(argv[index]) == "--json-writer") { + if (Json::String(argv[index]) == "--json-writer") { ++index; - JSONCPP_STRING const writerName(argv[index++]); + Json::String const writerName(argv[index++]); if (writerName == "StyledWriter") { opts->write = &useStyledWriter; } else if (writerName == "StyledStreamWriter") { @@ -245,22 +242,22 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) { static int runTest(Options const& opts) { int exitCode = 0; - JSONCPP_STRING input = readInputTestFile(opts.path.c_str()); + Json::String input = readInputTestFile(opts.path.c_str()); if (input.empty()) { printf("Failed to read input or empty input: %s\n", opts.path.c_str()); return 3; } - JSONCPP_STRING basePath = removeSuffix(opts.path, ".json"); + Json::String basePath = removeSuffix(opts.path, ".json"); if (!opts.parseOnly && basePath.empty()) { printf("Bad input path. Path does not end with '.expected':\n%s\n", opts.path.c_str()); return 3; } - JSONCPP_STRING const actualPath = basePath + ".actual"; - JSONCPP_STRING const rewritePath = basePath + ".rewrite"; - JSONCPP_STRING const rewriteActualPath = basePath + ".actual-rewrite"; + Json::String const actualPath = basePath + ".actual"; + Json::String const rewritePath = basePath + ".rewrite"; + Json::String const rewriteActualPath = basePath + ".actual-rewrite"; Json::Value root; exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features, @@ -268,7 +265,7 @@ static int runTest(Options const& opts) { if (exitCode || opts.parseOnly) { return exitCode; } - JSONCPP_STRING rewrite; + Json::String rewrite; exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite); if (exitCode) { return exitCode; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index dfe76348f..05b238a90 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -108,9 +108,9 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { // Those would allow streamed input from a file, if parse() were a // template function. - // Since JSONCPP_STRING is reference-counted, this at least does not + // Since String is reference-counted, this at least does not // create an extra copy. - JSONCPP_STRING doc; + String doc; std::getline(is, doc, (char)EOF); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } @@ -358,9 +358,8 @@ bool Reader::readComment() { return true; } -JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, - Reader::Location end) { - JSONCPP_STRING normalized; +String Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { + String normalized; normalized.reserve(static_cast(end - begin)); Reader::Location current = begin; while (current != end) { @@ -382,7 +381,7 @@ void Reader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); - const JSONCPP_STRING& normalized = normalizeEOL(begin, end); + const String& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { assert(lastValue_ != nullptr); lastValue_->setComment(normalized, placement); @@ -452,7 +451,7 @@ bool Reader::readString() { bool Reader::readObject(Token& token) { Token tokenName; - JSONCPP_STRING name; + String name; Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); @@ -472,7 +471,7 @@ bool Reader::readObject(Token& token) { Value numberName; if (!decodeNumber(tokenName, numberName)) return recoverFromError(tokenObjectEnd); - name = JSONCPP_STRING(numberName.asCString()); + name = String(numberName.asCString()); } else { break; } @@ -609,18 +608,17 @@ bool Reader::decodeDouble(Token& token) { bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; - JSONCPP_STRING buffer(token.start_, token.end_); - JSONCPP_ISTRINGSTREAM is(buffer); + String buffer(token.start_, token.end_); + IStringStream is(buffer); if (!(is >> value)) - return addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); decoded = value; return true; } bool Reader::decodeString(Token& token) { - JSONCPP_STRING decoded_string; + String decoded_string; if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); @@ -630,7 +628,7 @@ bool Reader::decodeString(Token& token) { return true; } -bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { +bool Reader::decodeString(Token& token, String& decoded) { decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -737,9 +735,7 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, return true; } -bool Reader::addError(const JSONCPP_STRING& message, - Token& token, - Location extra) { +bool Reader::addError(const String& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -761,7 +757,7 @@ bool Reader::recoverFromError(TokenType skipUntilToken) { return false; } -bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, +bool Reader::addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken) { addError(message, token); @@ -799,7 +795,7 @@ void Reader::getLocationLineAndColumn(Location location, ++line; } -JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { +String Reader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; @@ -808,12 +804,12 @@ JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { } // Deprecated. Preserved for backward compatibility -JSONCPP_STRING Reader::getFormatedErrorMessages() const { +String Reader::getFormatedErrorMessages() const { return getFormattedErrorMessages(); } -JSONCPP_STRING Reader::getFormattedErrorMessages() const { - JSONCPP_STRING formattedMessage; +String Reader::getFormattedErrorMessages() const { + String formattedMessage; for (const auto& error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; @@ -837,7 +833,7 @@ std::vector Reader::getStructuredErrors() const { return allErrors; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { +bool Reader::pushError(const Value& value, const String& message) { ptrdiff_t const length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; @@ -854,7 +850,7 @@ bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { } bool Reader::pushError(const Value& value, - const JSONCPP_STRING& message, + const String& message, const Value& extra) { ptrdiff_t const length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length || @@ -905,7 +901,7 @@ class OurReader { struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; - JSONCPP_STRING message; + String message; }; OurReader(OurFeatures const& features); @@ -913,12 +909,10 @@ class OurReader { const char* endDoc, Value& root, bool collectComments = true); - JSONCPP_STRING getFormattedErrorMessages() const; + String getFormattedErrorMessages() const; std::vector getStructuredErrors() const; - bool pushError(const Value& value, const JSONCPP_STRING& message); - bool pushError(const Value& value, - const JSONCPP_STRING& message, - const Value& extra); + bool pushError(const Value& value, const String& message); + bool pushError(const Value& value, const String& message, const Value& extra); bool good() const; private: @@ -955,7 +949,7 @@ class OurReader { class ErrorInfo { public: Token token_; - JSONCPP_STRING message_; + String message_; Location extra_; }; @@ -976,7 +970,7 @@ class OurReader { bool decodeNumber(Token& token); bool decodeNumber(Token& token, Value& decoded); bool decodeString(Token& token); - bool decodeString(Token& token, JSONCPP_STRING& decoded); + bool decodeString(Token& token, String& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); bool decodeUnicodeCodePoint(Token& token, @@ -987,11 +981,9 @@ class OurReader { Location& current, Location end, unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, - Token& token, - Location extra = nullptr); + bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const JSONCPP_STRING& message, + bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); @@ -999,23 +991,23 @@ class OurReader { Char getNextChar(); void getLocationLineAndColumn(Location location, int& line, int& column) const; - JSONCPP_STRING getLocationLineAndColumn(Location location) const; + String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); - static JSONCPP_STRING normalizeEOL(Location begin, Location end); + static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); typedef std::stack Nodes; Nodes nodes_; Errors errors_; - JSONCPP_STRING document_; + String document_; Location begin_; Location end_; Location current_; Location lastValueEnd_; Value* lastValue_; - JSONCPP_STRING commentsBefore_; + String commentsBefore_; OurFeatures const features_; bool collectComments_; @@ -1329,9 +1321,9 @@ bool OurReader::readComment() { return true; } -JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, - OurReader::Location end) { - JSONCPP_STRING normalized; +String OurReader::normalizeEOL(OurReader::Location begin, + OurReader::Location end) { + String normalized; normalized.reserve(static_cast(end - begin)); OurReader::Location current = begin; while (current != end) { @@ -1353,7 +1345,7 @@ void OurReader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); - const JSONCPP_STRING& normalized = normalizeEOL(begin, end); + const String& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { assert(lastValue_ != nullptr); lastValue_->setComment(normalized, placement); @@ -1439,7 +1431,7 @@ bool OurReader::readStringSingleQuote() { bool OurReader::readObject(Token& token) { Token tokenName; - JSONCPP_STRING name; + String name; Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); @@ -1472,7 +1464,7 @@ bool OurReader::readObject(Token& token) { if (name.length() >= (1U << 30)) throwRuntimeError("keylength >= 2^30"); if (features_.rejectDupKeys_ && currentValue().isMember(name)) { - JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; + String msg = "Duplicate key: '" + name + "'"; return addErrorAndRecover(msg, tokenName, tokenObjectEnd); } Value& value = currentValue()[name]; @@ -1624,20 +1616,19 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { fixNumericLocaleInput(buffer, buffer + length); count = sscanf(buffer, format, &value); } else { - JSONCPP_STRING buffer(token.start_, token.end_); + String buffer(token.start_, token.end_); count = sscanf(buffer.c_str(), format, &value); } if (count != 1) - return addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return addError( + "'" + String(token.start_, token.end_) + "' is not a number.", token); decoded = value; return true; } bool OurReader::decodeString(Token& token) { - JSONCPP_STRING decoded_string; + String decoded_string; if (!decodeString(token, decoded_string)) return false; Value decoded(decoded_string); @@ -1647,7 +1638,7 @@ bool OurReader::decodeString(Token& token) { return true; } -bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { +bool OurReader::decodeString(Token& token, String& decoded) { decoded.reserve(static_cast(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -1754,9 +1745,7 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, return true; } -bool OurReader::addError(const JSONCPP_STRING& message, - Token& token, - Location extra) { +bool OurReader::addError(const String& message, Token& token, Location extra) { ErrorInfo info; info.token_ = token; info.message_ = message; @@ -1778,7 +1767,7 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) { return false; } -bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, +bool OurReader::addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken) { addError(message, token); @@ -1816,7 +1805,7 @@ void OurReader::getLocationLineAndColumn(Location location, ++line; } -JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { +String OurReader::getLocationLineAndColumn(Location location) const { int line, column; getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; @@ -1824,8 +1813,8 @@ JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { return buffer; } -JSONCPP_STRING OurReader::getFormattedErrorMessages() const { - JSONCPP_STRING formattedMessage; +String OurReader::getFormattedErrorMessages() const { + String formattedMessage; for (const auto& error : errors_) { formattedMessage += "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; @@ -1849,7 +1838,7 @@ std::vector OurReader::getStructuredErrors() const { return allErrors; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { +bool OurReader::pushError(const Value& value, const String& message) { ptrdiff_t length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; @@ -1866,7 +1855,7 @@ bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { } bool OurReader::pushError(const Value& value, - const JSONCPP_STRING& message, + const String& message, const Value& extra) { ptrdiff_t length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length || @@ -1896,7 +1885,7 @@ class OurCharReader : public CharReader { bool parse(char const* beginDoc, char const* endDoc, Value* root, - JSONCPP_STRING* errs) override { + String* errs) override { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { *errs = reader_.getFormattedErrorMessages(); @@ -1926,7 +1915,7 @@ CharReader* CharReaderBuilder::newCharReader() const { features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); return new OurCharReader(collectComments, features); } -static void getValidReaderKeys(std::set* valid_keys) { +static void getValidReaderKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("collectComments"); valid_keys->insert("allowComments"); @@ -1944,19 +1933,19 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const { if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; - std::set valid_keys; + std::set valid_keys; getValidReaderKeys(&valid_keys); Value::Members keys = settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { - JSONCPP_STRING const& key = keys[i]; + String const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { inv[key] = settings_[key]; } } return inv.empty(); } -Value& CharReaderBuilder::operator[](const JSONCPP_STRING& key) { +Value& CharReaderBuilder::operator[](const String& key) { return settings_[key]; } // static @@ -1993,12 +1982,12 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { // global functions bool parseFromStream(CharReader::Factory const& fact, - JSONCPP_ISTREAM& sin, + IStream& sin, Value* root, - JSONCPP_STRING* errs) { - JSONCPP_OSTRINGSTREAM ssin; + String* errs) { + OStringStream ssin; ssin << sin.rdbuf(); - JSONCPP_STRING doc = ssin.str(); + String doc = ssin.str(); char const* begin = doc.data(); char const* end = begin + doc.size(); // Note that we do not actually need a null-terminator. @@ -2006,9 +1995,9 @@ bool parseFromStream(CharReader::Factory const& fact, return reader->parse(begin, end, root, errs); } -JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) { +IStream& operator>>(IStream& sin, Value& root) { CharReaderBuilder b; - JSONCPP_STRING errs; + String errs; bool ok = parseFromStream(b, sin, &root, &errs); if (!ok) { throwRuntimeError(errs); diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 855f6d7dd..5c13f1fed 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -36,8 +36,8 @@ static inline char getDecimalPoint() { } /// Converts a unicode code-point to UTF-8. -static inline JSONCPP_STRING codePointToUTF8(unsigned int cp) { - JSONCPP_STRING result; +static inline String codePointToUTF8(unsigned int cp) { + String result; // based on description from http://en.wikipedia.org/wiki/UTF-8 diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 574b1e909..9050e6cea 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -217,15 +217,15 @@ static inline void releaseStringValue(char* value, unsigned) { free(value); } namespace Json { -Exception::Exception(JSONCPP_STRING msg) : msg_(std::move(msg)) {} +Exception::Exception(String msg) : msg_(std::move(msg)) {} Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } -RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) {} -LogicError::LogicError(JSONCPP_STRING const& msg) : Exception(msg) {} -JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) { +RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} +LogicError::LogicError(String const& msg) : Exception(msg) {} +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { throw RuntimeError(msg); } -JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) { +JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } @@ -452,7 +452,7 @@ Value::Value(const char* begin, const char* end) { duplicateAndPrefixStringValue(begin, static_cast(end - begin)); } -Value::Value(const JSONCPP_STRING& value) { +Value::Value(const String& value) { initBasic(stringValue, true); value_.string_ = duplicateAndPrefixStringValue( value.data(), static_cast(value.length())); @@ -684,7 +684,7 @@ bool Value::getString(char const** begin, char const** end) const { return true; } -JSONCPP_STRING Value::asString() const { +String Value::asString() const { switch (type_) { case nullValue: return ""; @@ -695,7 +695,7 @@ JSONCPP_STRING Value::asString() const { char const* this_str; decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - return JSONCPP_STRING(this_str, this_len); + return String(this_str, this_len); } case booleanValue: return value_.bool_ ? "true" : "false"; @@ -1172,7 +1172,7 @@ const Value& Value::operator[](const char* key) const { return nullSingleton(); return *found; } -Value const& Value::operator[](const JSONCPP_STRING& key) const { +Value const& Value::operator[](const String& key) const { Value const* found = find(key.data(), key.data() + key.length()); if (!found) return nullSingleton(); @@ -1183,7 +1183,7 @@ Value& Value::operator[](const char* key) { return resolveReference(key, key + strlen(key)); } -Value& Value::operator[](const JSONCPP_STRING& key) { +Value& Value::operator[](const String& key) { return resolveReference(key.data(), key.data() + key.length()); } @@ -1220,7 +1220,7 @@ Value Value::get(char const* begin, Value Value::get(char const* key, Value const& defaultValue) const { return get(key, key + strlen(key), defaultValue); } -Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const { +Value Value::get(String const& key, Value const& defaultValue) const { return get(key.data(), key.data() + key.length(), defaultValue); } @@ -1245,7 +1245,7 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) { bool Value::removeMember(const char* key, Value* removed) { return removeMember(key, key + strlen(key), removed); } -bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) { +bool Value::removeMember(String const& key, Value* removed) { return removeMember(key.data(), key.data() + key.length(), removed); } void Value::removeMember(const char* key) { @@ -1257,9 +1257,7 @@ void Value::removeMember(const char* key) { CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); value_.map_->erase(actualKey); } -void Value::removeMember(const JSONCPP_STRING& key) { - removeMember(key.c_str()); -} +void Value::removeMember(const String& key) { removeMember(key.c_str()); } bool Value::removeIndex(ArrayIndex index, Value* removed) { if (type_ != arrayValue) { @@ -1299,7 +1297,7 @@ bool Value::isMember(char const* begin, char const* end) const { bool Value::isMember(char const* key) const { return isMember(key, key + strlen(key)); } -bool Value::isMember(JSONCPP_STRING const& key) const { +bool Value::isMember(String const& key) const { return isMember(key.data(), key.data() + key.length()); } @@ -1320,7 +1318,7 @@ Value::Members Value::getMemberNames() const { ObjectValues::const_iterator it = value_.map_->begin(); ObjectValues::const_iterator itEnd = value_.map_->end(); for (; it != itEnd; ++it) { - members.push_back(JSONCPP_STRING((*it).first.data(), (*it).first.length())); + members.push_back(String((*it).first.data(), (*it).first.length())); } return members; } @@ -1491,8 +1489,7 @@ void Value::setComment(const char* comment, CommentPlacement placement) { setComment(comment, strlen(comment), placement); } -void Value::setComment(const JSONCPP_STRING& comment, - CommentPlacement placement) { +void Value::setComment(const String& comment, CommentPlacement placement) { setComment(comment.c_str(), comment.length(), placement); } @@ -1500,7 +1497,7 @@ bool Value::hasComment(CommentPlacement placement) const { return comments_ != nullptr && comments_[placement].comment_ != nullptr; } -JSONCPP_STRING Value::getComment(CommentPlacement placement) const { +String Value::getComment(CommentPlacement placement) const { if (hasComment(placement)) return comments_[placement].comment_; return ""; @@ -1514,10 +1511,10 @@ ptrdiff_t Value::getOffsetStart() const { return start_; } ptrdiff_t Value::getOffsetLimit() const { return limit_; } -JSONCPP_STRING Value::toStyledString() const { +String Value::toStyledString() const { StreamWriterBuilder builder; - JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : ""; + String out = this->hasComment(commentBefore) ? "\n" : ""; out += Json::writeString(builder, *this); out += '\n'; @@ -1587,13 +1584,13 @@ PathArgument::PathArgument(ArrayIndex index) PathArgument::PathArgument(const char* key) : key_(key), index_(), kind_(kindKey) {} -PathArgument::PathArgument(const JSONCPP_STRING& key) +PathArgument::PathArgument(const String& key) : key_(key.c_str()), index_(), kind_(kindKey) {} // class Path // ////////////////////////////////////////////////////////////////// -Path::Path(const JSONCPP_STRING& path, +Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2, const PathArgument& a3, @@ -1609,7 +1606,7 @@ Path::Path(const JSONCPP_STRING& path, makePath(path, in); } -void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { +void Path::makePath(const String& path, const InArgs& in) { const char* current = path.c_str(); const char* end = current + path.length(); auto itInArg = in.begin(); @@ -1635,12 +1632,12 @@ void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { const char* beginName = current; while (current != end && !strchr("[.", *current)) ++current; - args_.push_back(JSONCPP_STRING(beginName, current)); + args_.push_back(String(beginName, current)); } } } -void Path::addPathInArg(const JSONCPP_STRING& /*path*/, +void Path::addPathInArg(const String& /*path*/, const InArgs& in, InArgs::const_iterator& itInArg, PathArgument::Kind kind) { @@ -1653,7 +1650,7 @@ void Path::addPathInArg(const JSONCPP_STRING& /*path*/, } } -void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) { +void Path::invalidPath(const String& /*path*/, int /*location*/) { // Error: invalid path. } diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index d1e2d3d1b..4a3d210de 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -84,13 +84,13 @@ UInt ValueIteratorBase::index() const { return Value::UInt(-1); } -JSONCPP_STRING ValueIteratorBase::name() const { +String ValueIteratorBase::name() const { char const* keey; char const* end; keey = memberName(&end); if (!keey) - return JSONCPP_STRING(); - return JSONCPP_STRING(keey, end); + return String(); + return String(keey, end); } char const* ValueIteratorBase::memberName() const { diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index c1c482b8c..34cc6fdab 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -89,7 +89,7 @@ typedef std::unique_ptr StreamWriterPtr; typedef std::auto_ptr StreamWriterPtr; #endif -JSONCPP_STRING valueToString(LargestInt value) { +String valueToString(LargestInt value) { UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); if (value == Value::minLargestInt) { @@ -105,7 +105,7 @@ JSONCPP_STRING valueToString(LargestInt value) { return current; } -JSONCPP_STRING valueToString(LargestUInt value) { +String valueToString(LargestUInt value) { UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); uintToString(value, current); @@ -115,21 +115,17 @@ JSONCPP_STRING valueToString(LargestUInt value) { #if defined(JSON_HAS_INT64) -JSONCPP_STRING valueToString(Int value) { - return valueToString(LargestInt(value)); -} +String valueToString(Int value) { return valueToString(LargestInt(value)); } -JSONCPP_STRING valueToString(UInt value) { - return valueToString(LargestUInt(value)); -} +String valueToString(UInt value) { return valueToString(LargestUInt(value)); } #endif // # if defined(JSON_HAS_INT64) namespace { -JSONCPP_STRING valueToString(double value, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType) { +String valueToString(double value, + bool useSpecialFloats, + unsigned int precision, + PrecisionType precisionType) { // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. @@ -140,7 +136,7 @@ JSONCPP_STRING valueToString(double value, [isnan(value) ? 0 : (value < 0) ? 1 : 2]; } - JSONCPP_STRING buffer(size_t(36), '\0'); + String buffer(size_t(36), '\0'); while (true) { int len = jsoncpp_snprintf( &*buffer.begin(), buffer.size(), @@ -172,13 +168,13 @@ JSONCPP_STRING valueToString(double value, } } // namespace -JSONCPP_STRING valueToString(double value, - unsigned int precision, - PrecisionType precisionType) { +String valueToString(double value, + unsigned int precision, + PrecisionType precisionType) { return valueToString(value, false, precision, precisionType); } -JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; } +String valueToString(bool value) { return value ? "true" : "false"; } static bool isAnyCharRequiredQuoting(char const* s, size_t n) { assert(s || !n); @@ -260,10 +256,10 @@ static const char hex2[] = "000102030405060708090a0b0c0d0e0f" "e0e1e2e3e4e5e6e7e8e9eaebecedeeef" "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"; -static JSONCPP_STRING toHex16Bit(unsigned int x) { +static String toHex16Bit(unsigned int x) { const unsigned int hi = (x >> 8) & 0xff; const unsigned int lo = x & 0xff; - JSONCPP_STRING result(4, ' '); + String result(4, ' '); result[0] = hex2[2 * hi]; result[1] = hex2[2 * hi + 1]; result[2] = hex2[2 * lo]; @@ -271,17 +267,17 @@ static JSONCPP_STRING toHex16Bit(unsigned int x) { return result; } -static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { +static String valueToQuotedStringN(const char* value, unsigned length) { if (value == nullptr) return ""; if (!isAnyCharRequiredQuoting(value, length)) - return JSONCPP_STRING("\"") + value + "\""; + return String("\"") + value + "\""; // We have to walk value and escape any special characters. - // Appending to JSONCPP_STRING is not efficient, but this should be rare. + // Appending to String is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL - JSONCPP_STRING result; + String::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL + String result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; char const* end = value + length; @@ -340,7 +336,7 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { return result; } -JSONCPP_STRING valueToQuotedString(const char* value) { +String valueToQuotedString(const char* value) { return valueToQuotedStringN(value, static_cast(strlen(value))); } @@ -361,7 +357,7 @@ void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } -JSONCPP_STRING FastWriter::write(const Value& root) { +String FastWriter::write(const Value& root) { document_.clear(); writeValue(root); if (!omitEndingLineFeed_) @@ -410,7 +406,7 @@ void FastWriter::writeValue(const Value& value) { Value::Members members(value.getMemberNames()); document_ += '{'; for (auto it = members.begin(); it != members.end(); ++it) { - const JSONCPP_STRING& name = *it; + const String& name = *it; if (it != members.begin()) document_ += ','; document_ += valueToQuotedStringN(name.data(), @@ -428,7 +424,7 @@ void FastWriter::writeValue(const Value& value) { StyledWriter::StyledWriter() = default; -JSONCPP_STRING StyledWriter::write(const Value& root) { +String StyledWriter::write(const Value& root) { document_.clear(); addChildValues_ = false; indentString_.clear(); @@ -479,7 +475,7 @@ void StyledWriter::writeValue(const Value& value) { indent(); auto it = members.begin(); for (;;) { - const JSONCPP_STRING& name = *it; + const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedString(name.c_str())); @@ -569,7 +565,7 @@ bool StyledWriter::isMultilineArray(const Value& value) { return isMultiLine; } -void StyledWriter::pushValue(const JSONCPP_STRING& value) { +void StyledWriter::pushValue(const String& value) { if (addChildValues_) childValues_.push_back(value); else @@ -587,14 +583,12 @@ void StyledWriter::writeIndent() { document_ += indentString_; } -void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) { +void StyledWriter::writeWithIndent(const String& value) { writeIndent(); document_ += value; } -void StyledWriter::indent() { - indentString_ += JSONCPP_STRING(indentSize_, ' '); -} +void StyledWriter::indent() { indentString_ += String(indentSize_, ' '); } void StyledWriter::unindent() { assert(indentString_.size() >= indentSize_); @@ -607,8 +601,8 @@ void StyledWriter::writeCommentBeforeValue(const Value& root) { document_ += '\n'; writeIndent(); - const JSONCPP_STRING& comment = root.getComment(commentBefore); - JSONCPP_STRING::const_iterator iter = comment.begin(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); while (iter != comment.end()) { document_ += *iter; if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) @@ -640,11 +634,11 @@ bool StyledWriter::hasCommentForValue(const Value& value) { // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// -StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) +StyledStreamWriter::StyledStreamWriter(String indentation) : document_(nullptr), indentation_(std::move(indentation)), addChildValues_(), indented_(false) {} -void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { +void StyledStreamWriter::write(OStream& out, const Value& root) { document_ = &out; addChildValues_ = false; indentString_.clear(); @@ -699,7 +693,7 @@ void StyledStreamWriter::writeValue(const Value& value) { indent(); auto it = members.begin(); for (;;) { - const JSONCPP_STRING& name = *it; + const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedString(name.c_str())); @@ -792,7 +786,7 @@ bool StyledStreamWriter::isMultilineArray(const Value& value) { return isMultiLine; } -void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) { +void StyledStreamWriter::pushValue(const String& value) { if (addChildValues_) childValues_.push_back(value); else @@ -807,7 +801,7 @@ void StyledStreamWriter::writeIndent() { *document_ << '\n' << indentString_; } -void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) { +void StyledStreamWriter::writeWithIndent(const String& value) { if (!indented_) writeIndent(); *document_ << value; @@ -827,8 +821,8 @@ void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { if (!indented_) writeIndent(); - const JSONCPP_STRING& comment = root.getComment(commentBefore); - JSONCPP_STRING::const_iterator iter = comment.begin(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); while (iter != comment.end()) { *document_ << *iter; if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) @@ -870,61 +864,60 @@ struct CommentStyle { }; struct BuiltStyledStreamWriter : public StreamWriter { - BuiltStyledStreamWriter(JSONCPP_STRING indentation, + BuiltStyledStreamWriter(String indentation, CommentStyle::Enum cs, - JSONCPP_STRING colonSymbol, - JSONCPP_STRING nullSymbol, - JSONCPP_STRING endingLineFeedSymbol, + String colonSymbol, + String nullSymbol, + String endingLineFeedSymbol, bool useSpecialFloats, unsigned int precision, PrecisionType precisionType); - int write(Value const& root, JSONCPP_OSTREAM* sout) override; + int write(Value const& root, OStream* sout) override; private: void writeValue(Value const& value); void writeArrayValue(Value const& value); bool isMultilineArray(Value const& value); - void pushValue(JSONCPP_STRING const& value); + void pushValue(String const& value); void writeIndent(); - void writeWithIndent(JSONCPP_STRING const& value); + void writeWithIndent(String const& value); void indent(); void unindent(); void writeCommentBeforeValue(Value const& root); void writeCommentAfterValueOnSameLine(Value const& root); static bool hasCommentForValue(const Value& value); - typedef std::vector ChildValues; + typedef std::vector ChildValues; ChildValues childValues_; - JSONCPP_STRING indentString_; + String indentString_; unsigned int rightMargin_; - JSONCPP_STRING indentation_; + String indentation_; CommentStyle::Enum cs_; - JSONCPP_STRING colonSymbol_; - JSONCPP_STRING nullSymbol_; - JSONCPP_STRING endingLineFeedSymbol_; + String colonSymbol_; + String nullSymbol_; + String endingLineFeedSymbol_; bool addChildValues_ : 1; bool indented_ : 1; bool useSpecialFloats_ : 1; unsigned int precision_; PrecisionType precisionType_; }; -BuiltStyledStreamWriter::BuiltStyledStreamWriter( - JSONCPP_STRING indentation, - CommentStyle::Enum cs, - JSONCPP_STRING colonSymbol, - JSONCPP_STRING nullSymbol, - JSONCPP_STRING endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType) +BuiltStyledStreamWriter::BuiltStyledStreamWriter(String indentation, + CommentStyle::Enum cs, + String colonSymbol, + String nullSymbol, + String endingLineFeedSymbol, + bool useSpecialFloats, + unsigned int precision, + PrecisionType precisionType) : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), addChildValues_(false), indented_(false), useSpecialFloats_(useSpecialFloats), precision_(precision), precisionType_(precisionType) {} -int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { +int BuiltStyledStreamWriter::write(Value const& root, OStream* sout) { sout_ = sout; addChildValues_ = false; indented_ = true; @@ -980,7 +973,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { indent(); auto it = members.begin(); for (;;) { - JSONCPP_STRING const& name = *it; + String const& name = *it; Value const& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedStringN( @@ -1078,7 +1071,7 @@ bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) { return isMultiLine; } -void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) { +void BuiltStyledStreamWriter::pushValue(String const& value) { if (addChildValues_) childValues_.push_back(value); else @@ -1097,7 +1090,7 @@ void BuiltStyledStreamWriter::writeIndent() { } } -void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) { +void BuiltStyledStreamWriter::writeWithIndent(String const& value) { if (!indented_) writeIndent(); *sout_ << value; @@ -1119,8 +1112,8 @@ void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { if (!indented_) writeIndent(); - const JSONCPP_STRING& comment = root.getComment(commentBefore); - JSONCPP_STRING::const_iterator iter = comment.begin(); + const String& comment = root.getComment(commentBefore); + String::const_iterator iter = comment.begin(); while (iter != comment.end()) { *sout_ << *iter; if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/')) @@ -1160,9 +1153,9 @@ StreamWriter::Factory::~Factory() = default; StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } StreamWriterBuilder::~StreamWriterBuilder() = default; StreamWriter* StreamWriterBuilder::newStreamWriter() const { - JSONCPP_STRING indentation = settings_["indentation"].asString(); - JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); - JSONCPP_STRING pt_str = settings_["precisionType"].asString(); + String indentation = settings_["indentation"].asString(); + String cs_str = settings_["commentStyle"].asString(); + String pt_str = settings_["precisionType"].asString(); bool eyc = settings_["enableYAMLCompatibility"].asBool(); bool dnp = settings_["dropNullPlaceholders"].asBool(); bool usf = settings_["useSpecialFloats"].asBool(); @@ -1183,24 +1176,24 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { } else { throwRuntimeError("precisionType must be 'significant' or 'decimal'"); } - JSONCPP_STRING colonSymbol = " : "; + String colonSymbol = " : "; if (eyc) { colonSymbol = ": "; } else if (indentation.empty()) { colonSymbol = ":"; } - JSONCPP_STRING nullSymbol = "null"; + String nullSymbol = "null"; if (dnp) { nullSymbol.clear(); } if (pre > 17) pre = 17; - JSONCPP_STRING endingLineFeedSymbol; + String endingLineFeedSymbol; return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre, precisionType); } -static void getValidWriterKeys(std::set* valid_keys) { +static void getValidWriterKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("indentation"); valid_keys->insert("commentStyle"); @@ -1215,19 +1208,19 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; - std::set valid_keys; + std::set valid_keys; getValidWriterKeys(&valid_keys); Value::Members keys = settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { - JSONCPP_STRING const& key = keys[i]; + String const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { inv[key] = settings_[key]; } } return inv.empty(); } -Value& StreamWriterBuilder::operator[](const JSONCPP_STRING& key) { +Value& StreamWriterBuilder::operator[](const String& key) { return settings_[key]; } // static @@ -1243,15 +1236,14 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) { //! [StreamWriterBuilderDefaults] } -JSONCPP_STRING writeString(StreamWriter::Factory const& factory, - Value const& root) { - JSONCPP_OSTRINGSTREAM sout; +String writeString(StreamWriter::Factory const& factory, Value const& root) { + OStringStream sout; StreamWriterPtr const writer(factory.newStreamWriter()); writer->write(root, &sout); return sout.str(); } -JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) { +OStream& operator<<(OStream& sout, Value const& root) { StreamWriterBuilder builder; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index e8f09bc16..873952f5d 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -80,7 +80,7 @@ TestResult::TestResult() { predicateStackTail_ = &rootPredicateNode_; } -void TestResult::setTestName(const JSONCPP_STRING& name) { name_ = name; } +void TestResult::setTestName(const Json::String& name) { name_ = name; } TestResult& TestResult::addFailure(const char* file, unsigned int line, const char* expr) { @@ -150,7 +150,7 @@ void TestResult::printFailure(bool printTestName) const { // Print in reverse to display the callstack in the right order for (const auto& failure : failures_) { - JSONCPP_STRING indent(failure.nestingLevel_ * 2, ' '); + Json::String indent(failure.nestingLevel_ * 2, ' '); if (failure.file_) { printf("%s%s(%u): ", indent.c_str(), failure.file_, failure.line_); } @@ -160,19 +160,18 @@ void TestResult::printFailure(bool printTestName) const { printf("\n"); } if (!failure.message_.empty()) { - JSONCPP_STRING reindented = indentText(failure.message_, indent + " "); + Json::String reindented = indentText(failure.message_, indent + " "); printf("%s\n", reindented.c_str()); } } } -JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text, - const JSONCPP_STRING& indent) { - JSONCPP_STRING reindented; - JSONCPP_STRING::size_type lastIndex = 0; +Json::String TestResult::indentText(const Json::String& text, const Json::String& indent) { + Json::String reindented; + Json::String::size_type lastIndex = 0; while (lastIndex < text.size()) { - JSONCPP_STRING::size_type nextIndex = text.find('\n', lastIndex); - if (nextIndex == JSONCPP_STRING::npos) { + Json::String::size_type nextIndex = text.find('\n', lastIndex); + if (nextIndex == Json::String::npos) { nextIndex = text.size() - 1; } reindented += indent; @@ -182,7 +181,7 @@ JSONCPP_STRING TestResult::indentText(const JSONCPP_STRING& text, return reindented; } -TestResult& TestResult::addToLastFailure(const JSONCPP_STRING& message) { +TestResult& TestResult::addToLastFailure(const Json::String& message) { if (messageTarget_ != nullptr) { messageTarget_->message_ += message; } @@ -225,9 +224,9 @@ Runner& Runner::add(TestCaseFactory factory) { size_t Runner::testCount() const { return tests_.size(); } -JSONCPP_STRING Runner::testNameAt(size_t index) const { +Json::String Runner::testNameAt(size_t index) const { TestCase* test = tests_[index](); - JSONCPP_STRING name = test->testName(); + Json::String name = test->testName(); delete test; return name; } @@ -284,7 +283,7 @@ bool Runner::runAllTest(bool printSummary) const { } } -bool Runner::testIndex(const JSONCPP_STRING& testName, size_t& indexOut) const { +bool Runner::testIndex(const Json::String& testName, size_t& indexOut) const { const size_t count = testCount(); for (size_t index = 0; index < count; ++index) { if (testNameAt(index) == testName) { @@ -303,10 +302,10 @@ void Runner::listTests() const { } int Runner::runCommandLine(int argc, const char* argv[]) const { - // typedef std::deque TestNames; + // typedef std::deque TestNames; Runner subrunner; for (int index = 1; index < argc; ++index) { - JSONCPP_STRING opt = argv[index]; + Json::String opt = argv[index]; if (opt == "--list-tests") { listTests(); return 0; @@ -406,21 +405,19 @@ void Runner::printUsage(const char* appName) { // Assertion functions // ////////////////////////////////////////////////////////////////// -JSONCPP_STRING ToJsonString(const char* toConvert) { - return JSONCPP_STRING(toConvert); -} +Json::String ToJsonString(const char* toConvert) { return Json::String(toConvert); } -JSONCPP_STRING ToJsonString(JSONCPP_STRING in) { return in; } +Json::String ToJsonString(Json::String in) { return in; } #if JSONCPP_USING_SECURE_MEMORY -JSONCPP_STRING ToJsonString(std::string in) { - return JSONCPP_STRING(in.data(), in.data() + in.length()); +Json::String ToJsonString(std::string in) { + return Json::String(in.data(), in.data() + in.length()); } #endif TestResult& checkStringEqual(TestResult& result, - const JSONCPP_STRING& expected, - const JSONCPP_STRING& actual, + const Json::String& expected, + const Json::String& actual, const char* file, unsigned int line, const char* expr) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 36cfd1ae6..9821cb03f 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -32,8 +32,8 @@ class Failure { public: const char* file_; unsigned int line_; - JSONCPP_STRING expr_; - JSONCPP_STRING message_; + Json::String expr_; + Json::String message_; unsigned int nestingLevel_; }; @@ -65,7 +65,7 @@ class TestResult { /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; - void setTestName(const JSONCPP_STRING& name); + void setTestName(const Json::String& name); /// Adds an assertion failure. TestResult& @@ -82,7 +82,7 @@ class TestResult { // Generic operator that will work with anything ostream can deal with. template TestResult& operator<<(const T& value) { - JSONCPP_OSTRINGSTREAM oss; + Json::OStringStream oss; oss.precision(16); oss.setf(std::ios_base::floatfield); oss << value; @@ -96,18 +96,17 @@ class TestResult { TestResult& operator<<(Json::UInt64 value); private: - TestResult& addToLastFailure(const JSONCPP_STRING& message); + TestResult& addToLastFailure(const Json::String& message); /// Adds a failure or a predicate context void addFailureInfo(const char* file, unsigned int line, const char* expr, unsigned int nestingLevel); - static JSONCPP_STRING indentText(const JSONCPP_STRING& text, - const JSONCPP_STRING& indent); + static Json::String indentText(const Json::String& text, const Json::String& indent); typedef std::deque Failures; Failures failures_; - JSONCPP_STRING name_; + Json::String name_; PredicateContext rootPredicateNode_; PredicateContext::Id lastUsedPredicateId_{ 0 }; /// Failure which is the target of the messages added using operator << @@ -154,7 +153,7 @@ class Runner { size_t testCount() const; /// Returns the name of the test case at the specified index - JSONCPP_STRING testNameAt(size_t index) const; + Json::String testNameAt(size_t index) const; /// Runs the test case at the specified index using the specified TestResult void runTestAt(size_t index, TestResult& result) const; @@ -167,7 +166,7 @@ class Runner { private: void listTests() const; - bool testIndex(const JSONCPP_STRING& testName, size_t& indexOut) const; + bool testIndex(const Json::String& testName, size_t& indexOut) const; static void preventDialogOnCrash(); private: @@ -190,15 +189,15 @@ TestResult& checkEqual(TestResult& result, return result; } -JSONCPP_STRING ToJsonString(const char* toConvert); -JSONCPP_STRING ToJsonString(JSONCPP_STRING in); +Json::String ToJsonString(const char* toConvert); +Json::String ToJsonString(Json::String in); #if JSONCPP_USING_SECURE_MEMORY -JSONCPP_STRING ToJsonString(std::string in); +Json::String ToJsonString(std::string in); #endif TestResult& checkStringEqual(TestResult& result, - const JSONCPP_STRING& expected, - const JSONCPP_STRING& actual, + const Json::String& expected, + const Json::String& actual, const char* file, unsigned int line, const char* expr); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 4c0319795..0c4d21d31 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -110,21 +110,20 @@ struct ValueTest : JsonTest::TestCase { /// Normalize the representation of floating-point number by stripped leading /// 0 in exponent. - static JSONCPP_STRING normalizeFloatingPointStr(const JSONCPP_STRING& s); + static Json::String normalizeFloatingPointStr(const Json::String& s); }; -JSONCPP_STRING ValueTest::normalizeFloatingPointStr(const JSONCPP_STRING& s) { - JSONCPP_STRING::size_type index = s.find_last_of("eE"); - if (index != JSONCPP_STRING::npos) { - JSONCPP_STRING::size_type hasSign = +Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { + Json::String::size_type index = s.find_last_of("eE"); + if (index != Json::String::npos) { + Json::String::size_type hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - JSONCPP_STRING::size_type exponentStartIndex = index + 1 + hasSign; - JSONCPP_STRING normalized = s.substr(0, exponentStartIndex); - JSONCPP_STRING::size_type indexDigit = - s.find_first_not_of('0', exponentStartIndex); - JSONCPP_STRING exponent = "0"; - if (indexDigit != JSONCPP_STRING::npos) // There is an exponent different - // from 0 + Json::String::size_type exponentStartIndex = index + 1 + hasSign; + Json::String normalized = s.substr(0, exponentStartIndex); + Json::String::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); + Json::String exponent = "0"; + if (indexDigit != Json::String::npos) // There is an exponent different + // from 0 { exponent = s.substr(indexDigit); } @@ -1601,7 +1600,7 @@ JSONTEST_FIXTURE(ValueTest, offsetAccessors) { JSONTEST_FIXTURE(ValueTest, StaticString) { char mutant[] = "hello"; Json::StaticString ss(mutant); - JSONCPP_STRING regular(mutant); + Json::String regular(mutant); mutant[1] = 'a'; JSONTEST_ASSERT_STRING_EQUAL("hallo", ss.c_str()); JSONTEST_ASSERT_STRING_EQUAL("hello", regular.c_str()); @@ -1623,16 +1622,16 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { JSONTEST_FIXTURE(ValueTest, CommentBefore) { Json::Value val; // fill val - val.setComment(JSONCPP_STRING("// this comment should appear before"), + val.setComment(Json::String("// this comment should appear before"), Json::commentBefore); Json::StreamWriterBuilder wbuilder; wbuilder.settings_["commentStyle"] = "All"; { char const expected[] = "// this comment should appear before\nnull"; - JSONCPP_STRING result = Json::writeString(wbuilder, val); + Json::String result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - JSONCPP_STRING res2 = val.toStyledString(); - JSONCPP_STRING exp2 = "\n"; + Json::String res2 = val.toStyledString(); + Json::String exp2 = "\n"; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1641,10 +1640,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { val.swapPayload(other); { char const expected[] = "// this comment should appear before\n\"hello\""; - JSONCPP_STRING result = Json::writeString(wbuilder, val); + Json::String result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - JSONCPP_STRING res2 = val.toStyledString(); - JSONCPP_STRING exp2 = "\n"; + Json::String res2 = val.toStyledString(); + Json::String exp2 = "\n"; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1655,10 +1654,10 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { // Json::CommentPlacement::commentBefore); Assignment over-writes comments. { char const expected[] = "\"hello\""; - JSONCPP_STRING result = Json::writeString(wbuilder, val); + Json::String result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); - JSONCPP_STRING res2 = val.toStyledString(); - JSONCPP_STRING exp2 = ""; + Json::String res2 = val.toStyledString(); + Json::String exp2 = ""; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -1667,7 +1666,7 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { JSONTEST_FIXTURE(ValueTest, zeroes) { char const cstr[] = "h\0i"; - JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 + Json::String binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); Json::StreamWriterBuilder b; { @@ -1693,7 +1692,7 @@ JSONTEST_FIXTURE(ValueTest, zeroes) { JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { char const cstr[] = "h\0i"; - JSONCPP_STRING binary(cstr, sizeof(cstr)); // include trailing 0 + Json::String binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); { Json::Value root; @@ -1724,8 +1723,8 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) { b.settings_["useSpecialFloats"] = true; Json::Value v = std::numeric_limits::quiet_NaN(); - JSONCPP_STRING expected = "NaN"; - JSONCPP_STRING result = Json::writeString(b, v); + Json::String expected = "NaN"; + Json::String result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); v = std::numeric_limits::infinity(); @@ -1744,8 +1743,8 @@ JSONTEST_FIXTURE(ValueTest, precision) { b.settings_["precision"] = 5; Json::Value v = 100.0 / 3; - JSONCPP_STRING expected = "33.333"; - JSONCPP_STRING result = Json::writeString(b, v); + Json::String expected = "33.333"; + Json::String result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); v = 0.25000000; @@ -1820,15 +1819,15 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { } JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { - JSONCPP_STRING binary("hi", 3); // include trailing 0 + Json::String binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); - JSONCPP_STRING expected("\"hi\\u0000\""); // unicoded zero + Json::String expected("\"hi\\u0000\""); // unicoded zero Json::StreamWriterBuilder b; { Json::Value root; root = binary; JSONTEST_ASSERT_STRING_EQUAL(binary, root.asString()); - JSONCPP_STRING out = Json::writeString(b, root); + Json::String out = Json::writeString(b, root); JSONTEST_ASSERT_EQUAL(expected.size(), out.size()); JSONTEST_ASSERT_STRING_EQUAL(expected, out); } @@ -1836,7 +1835,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { Json::Value root; root["top"] = binary; JSONTEST_ASSERT_STRING_EQUAL(binary, root["top"].asString()); - JSONCPP_STRING out = Json::writeString(b, root["top"]); + Json::String out = Json::writeString(b, root["top"]); JSONTEST_ASSERT_STRING_EQUAL(expected, out); } } @@ -1937,7 +1936,7 @@ struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -1949,7 +1948,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " @@ -1963,7 +1962,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; Json::Value root; char const doc[] = "{ \"property\" :: \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -1977,7 +1976,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; Json::Value root; char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -1991,7 +1990,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : \"v\\alue\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -2009,7 +2008,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { { b.settings_["stackLimit"] = 2; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); @@ -2019,7 +2018,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { { b.settings_["stackLimit"] = 1; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; JSONTEST_ASSERT_THROWS( reader->parse(doc, doc + std::strlen(doc), &root, &errs)); delete reader; @@ -2036,7 +2035,7 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { { b.strictMode(&b.settings_); Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 41\n" @@ -2056,7 +2055,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { { b.settings_["failIfExtra"] = false; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); @@ -2066,7 +2065,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { { b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT_STRING_EQUAL(errs, @@ -2079,7 +2078,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { b.settings_["failIfExtra"] = false; b.strictMode(&b.settings_); Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT_STRING_EQUAL(errs, @@ -2096,7 +2095,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { char const doc[] = "1:2:3"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 2\n" @@ -2112,7 +2111,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { char const doc[] = "{ \"property\" : \"value\" } //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -2126,7 +2125,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -2139,7 +2138,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { char const doc[] = " true /*trailing\ncomment*/"; b.settings_["failIfExtra"] = true; Json::CharReader* reader(b.newCharReader()); - JSONCPP_STRING errs; + Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -2152,7 +2151,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { Json::CharReaderBuilder b; b.settings_["allowDroppedNullPlaceholders"] = true; Json::Value root; - JSONCPP_STRING errs; + Json::String errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":,\"b\":true}"; @@ -2274,7 +2273,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; - JSONCPP_STRING errs; + Json::String errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; @@ -2303,7 +2302,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; - JSONCPP_STRING errs; + Json::String errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; @@ -2332,7 +2331,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::CharReaderBuilder b; b.settings_["allowSpecialFloats"] = true; Json::Value root; - JSONCPP_STRING errs; + Json::String errs; Json::CharReader* reader(b.newCharReader()); { char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}"; @@ -2351,7 +2350,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { struct TestData { int line; bool ok; - JSONCPP_STRING in; + Json::String in; }; const TestData test_data[] = { { __LINE__, true, "{\"a\":9}" }, // @@ -2426,7 +2425,7 @@ JSONTEST_FIXTURE(IteratorTest, distance) { json["k1"] = "a"; json["k2"] = "b"; int dist = 0; - JSONCPP_STRING str; + Json::String str; for (Json::ValueIterator it = json.begin(); it != json.end(); ++it) { dist = it - json.begin(); str = it->asString().c_str(); @@ -2480,19 +2479,19 @@ JSONTEST_FIXTURE(IteratorTest, const) { Json::Value value; for (int i = 9; i < 12; ++i) { - JSONCPP_OSTRINGSTREAM out; + Json::OStringStream out; out << std::setw(2) << i; - JSONCPP_STRING str = out.str(); + Json::String str = out.str(); value[str] = str; } - JSONCPP_OSTRINGSTREAM out; + Json::OStringStream out; // in old code, this will get a compile error Json::Value::const_iterator iter = value.begin(); for (; iter != value.end(); ++iter) { out << *iter << ','; } - JSONCPP_STRING expected = "\" 9\",\"10\",\"11\","; + Json::String expected = "\" 9\",\"10\",\"11\","; JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); } From b9ed29a2216a801b43aac23d617afe88db3007fb Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 17 Jan 2019 23:26:28 -0500 Subject: [PATCH 102/410] Jsoncpp aliases 2 (#868) convert JSONCPP_STRING etc from macros to typedefs From deb6cca21421c8b29741101e38989fb62f176115 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 17 Jan 2019 19:21:12 -0600 Subject: [PATCH 103/410] STYLE: FATAL_ERROR ignored in cmake_required_minimum since 2.6.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 145a77c15..185385f13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ # set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.1.0") set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.1") -cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION} FATAL_ERROR) +cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION}) if("${CMAKE_VERSION}" VERSION_LESS_EQUAL "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") #Set and use the newest available cmake policies that are validated to work set(JSONCPP_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") From 2c257590a16a51ee5c0c3aefbfd4db70d24c7944 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 17 Jan 2019 19:25:06 -0600 Subject: [PATCH 104/410] BUG: VERSION_LESS_EQUAL introduced in cmake 3.7 Older versions of cmake, according to documentation: https://cmake.org/cmake/help/v3.5/command/if.html , do not know VERSION_LESS_EQUAL, just VERSION_LESS. This leads to errors: CMake Error at somewhere/jsoncpp/CMakeLists.txt:18 (if): if given arguments: "3.5.1" "VERSION_LESS_EQUAL" "3.13.1" Unknown arguments specified Resolves: #866 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 185385f13..2de402472 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,9 @@ # continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:" # set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.1.0") -set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.1") +set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2") cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION}) -if("${CMAKE_VERSION}" VERSION_LESS_EQUAL "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") +if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") #Set and use the newest available cmake policies that are validated to work set(JSONCPP_CMAKE_POLICY_VERSION "${CMAKE_VERSION}") else() From 756a08fbbdd018bc2c14be65d229262ad576a9e2 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 18 Jan 2019 03:45:27 -0500 Subject: [PATCH 105/410] switch .clang-format to C++11 --- .clang-format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index dd51247d5..2a372fc5b 100644 --- a/.clang-format +++ b/.clang-format @@ -29,8 +29,8 @@ PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerBindsToType: true SpacesBeforeTrailingComments: 1 -Cpp11BracedListStyle: false -Standard: Cpp03 +Cpp11BracedListStyle: true +Standard: Cpp11 IndentWidth: 2 TabWidth: 8 UseTab: Never From 2b593a9da837337c8520507de38f8122b879eb68 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 18 Jan 2019 03:46:57 -0500 Subject: [PATCH 106/410] apply the C++11 style change in .clang-format --- include/json/config.h | 5 ++- include/json/features.h | 8 ++--- include/json/value.h | 6 ++-- include/json/writer.h | 14 ++++---- src/jsontestrunner/main.cpp | 10 +++--- src/lib_json/json_writer.cpp | 4 +-- src/test_lib_json/jsontest.cpp | 7 ++-- src/test_lib_json/jsontest.h | 14 ++++---- src/test_lib_json/main.cpp | 63 +++++++++++++++++----------------- 9 files changed, 68 insertions(+), 63 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 2b603769e..1af868122 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -176,9 +176,8 @@ typedef UInt64 LargestUInt; template using Allocator = typename std::conditional, - std::allocator >::type; -using String = - std::basic_string, Allocator >; + std::allocator>::type; +using String = std::basic_string, Allocator>; using IStringStream = std::basic_istringstream; diff --git a/include/json/features.h b/include/json/features.h index 8cbe172d4..ba25e8da6 100644 --- a/include/json/features.h +++ b/include/json/features.h @@ -41,17 +41,17 @@ class JSON_API Features { Features(); /// \c true if comments are allowed. Default: \c true. - bool allowComments_{ true }; + bool allowComments_{true}; /// \c true if root must be either an array or an object value. Default: \c /// false. - bool strictRoot_{ false }; + bool strictRoot_{false}; /// \c true if dropped null placeholders are allowed. Default: \c false. - bool allowDroppedNullPlaceholders_{ false }; + bool allowDroppedNullPlaceholders_{false}; /// \c true if numeric object key are allowed. Default: \c false. - bool allowNumericKeys_{ false }; + bool allowNumericKeys_{false}; }; } // namespace Json diff --git a/include/json/value.h b/include/json/value.h index 9df8a3b6c..1036d3260 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -630,7 +630,7 @@ Json::Value obj_value(Json::objectValue); // {} void setComment(const char* text, size_t len); - char* comment_{ nullptr }; + char* comment_{nullptr}; }; // struct MemberNamesTransform @@ -679,7 +679,7 @@ class JSON_API PathArgument { enum Kind { kindNone = 0, kindIndex, kindKey }; String key_; ArrayIndex index_{}; - Kind kind_{ kindNone }; + Kind kind_{kindNone}; }; /** \brief Experimental and untested: represents a "path" to access a node. @@ -780,7 +780,7 @@ class JSON_API ValueIteratorBase { private: Value::ObjectValues::iterator current_; // Indicates that iterator is for a null value. - bool isNull_{ true }; + bool isNull_{true}; public: // For some reason, BORLAND needs these at the end, rather diff --git a/include/json/writer.h b/include/json/writer.h index b8094839d..12fd36a7a 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -189,9 +189,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter void writeValue(const Value& value); String document_; - bool yamlCompatibilityEnabled_{ false }; - bool dropNullPlaceholders_{ false }; - bool omitEndingLineFeed_{ false }; + bool yamlCompatibilityEnabled_{false}; + bool dropNullPlaceholders_{false}; + bool omitEndingLineFeed_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -257,9 +257,9 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; String document_; String indentString_; - unsigned int rightMargin_{ 74 }; - unsigned int indentSize_{ 3 }; - bool addChildValues_{ false }; + unsigned int rightMargin_{74}; + unsigned int indentSize_{3}; + bool addChildValues_{false}; }; #if defined(_MSC_VER) #pragma warning(pop) @@ -331,7 +331,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API ChildValues childValues_; OStream* document_; String indentString_; - unsigned int rightMargin_{ 74 }; + unsigned int rightMargin_{74}; String indentation_; bool addChildValues_ : 1; bool indented_ : 1; diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 855f9c761..d2d41aa5f 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -22,7 +22,7 @@ struct Options { Json::String path; Json::Features features; bool parseOnly; - using writeFuncType = Json::String(*)(Json::Value const&); + using writeFuncType = Json::String (*)(Json::Value const&); writeFuncType write; }; @@ -37,10 +37,11 @@ static Json::String normalizeFloatingPointStr(double value) { (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; Json::String::size_type exponentStartIndex = index + 1 + hasSign; Json::String normalized = s.substr(0, exponentStartIndex); - Json::String::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); + Json::String::size_type indexDigit = + s.find_first_not_of('0', exponentStartIndex); Json::String exponent = "0"; if (indexDigit != Json::String::npos) // There is an exponent different - // from 0 + // from 0 { exponent = s.substr(indexDigit); } @@ -180,7 +181,8 @@ static int rewriteValueTree(const Json::String& rewritePath, return 0; } -static Json::String removeSuffix(const Json::String& path, const Json::String& extension) { +static Json::String removeSuffix(const Json::String& path, + const Json::String& extension) { if (extension.length() >= path.length()) return Json::String(""); Json::String suffix = path.substr(path.length() - extension.length()); diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 34cc6fdab..41dfd8cf6 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -130,8 +130,8 @@ String valueToString(double value, // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. if (!isfinite(value)) { - static const char* const reps[2][3] = { { "NaN", "-Infinity", "Infinity" }, - { "null", "-1e+9999", "1e+9999" } }; + static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"}, + {"null", "-1e+9999", "1e+9999"}}; return reps[useSpecialFloats ? 0 : 1] [isnan(value) ? 0 : (value < 0) ? 1 : 2]; } diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 873952f5d..c0b5296d9 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -166,7 +166,8 @@ void TestResult::printFailure(bool printTestName) const { } } -Json::String TestResult::indentText(const Json::String& text, const Json::String& indent) { +Json::String TestResult::indentText(const Json::String& text, + const Json::String& indent) { Json::String reindented; Json::String::size_type lastIndex = 0; while (lastIndex < text.size()) { @@ -405,7 +406,9 @@ void Runner::printUsage(const char* appName) { // Assertion functions // ////////////////////////////////////////////////////////////////// -Json::String ToJsonString(const char* toConvert) { return Json::String(toConvert); } +Json::String ToJsonString(const char* toConvert) { + return Json::String(toConvert); +} Json::String ToJsonString(Json::String in) { return in; } diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 9821cb03f..e9c11a470 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -60,7 +60,7 @@ class TestResult { /// Not encapsulated to prevent step into when debugging failed assertions /// Incremented by one on assertion predicate entry, decreased by one /// by addPredicateContext(). - PredicateContext::Id predicateId_{ 1 }; + PredicateContext::Id predicateId_{1}; /// \internal Implementation detail for predicate macros PredicateContext* predicateStackTail_; @@ -102,15 +102,16 @@ class TestResult { unsigned int line, const char* expr, unsigned int nestingLevel); - static Json::String indentText(const Json::String& text, const Json::String& indent); + static Json::String indentText(const Json::String& text, + const Json::String& indent); typedef std::deque Failures; Failures failures_; Json::String name_; PredicateContext rootPredicateNode_; - PredicateContext::Id lastUsedPredicateId_{ 0 }; + PredicateContext::Id lastUsedPredicateId_{0}; /// Failure which is the target of the messages added using operator << - Failure* messageTarget_{ nullptr }; + Failure* messageTarget_{nullptr}; }; class TestCase { @@ -124,7 +125,7 @@ class TestCase { virtual const char* testName() const = 0; protected: - TestResult* result_{ nullptr }; + TestResult* result_{nullptr}; private: virtual void runTestCase() = 0; @@ -218,8 +219,7 @@ TestResult& checkStringEqual(TestResult& result, #define JSONTEST_ASSERT_PRED(expr) \ { \ JsonTest::PredicateContext _minitest_Context = { \ - result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL \ - }; \ + result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL}; \ result_->predicateStackTail_->next_ = &_minitest_Context; \ result_->predicateId_ += 1; \ result_->predicateStackTail_ = &_minitest_Context; \ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 0c4d21d31..27fb4a273 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -82,19 +82,19 @@ struct ValueTest : JsonTest::TestCase { /// Initialize all checks to \c false by default. IsCheck(); - bool isObject_{ false }; - bool isArray_{ false }; - bool isBool_{ false }; - bool isString_{ false }; - bool isNull_{ false }; - - bool isInt_{ false }; - bool isInt64_{ false }; - bool isUInt_{ false }; - bool isUInt64_{ false }; - bool isIntegral_{ false }; - bool isDouble_{ false }; - bool isNumeric_{ false }; + bool isObject_{false}; + bool isArray_{false}; + bool isBool_{false}; + bool isString_{false}; + bool isNull_{false}; + + bool isInt_{false}; + bool isInt64_{false}; + bool isUInt_{false}; + bool isUInt64_{false}; + bool isIntegral_{false}; + bool isDouble_{false}; + bool isNumeric_{false}; }; void checkConstMemberCount(const Json::Value& value, @@ -120,10 +120,11 @@ Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; Json::String::size_type exponentStartIndex = index + 1 + hasSign; Json::String normalized = s.substr(0, exponentStartIndex); - Json::String::size_type indexDigit = s.find_first_not_of('0', exponentStartIndex); + Json::String::size_type indexDigit = + s.find_first_not_of('0', exponentStartIndex); Json::String exponent = "0"; if (indexDigit != Json::String::npos) // There is an exponent different - // from 0 + // from 0 { exponent = s.substr(indexDigit); } @@ -2353,22 +2354,22 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::String in; }; const TestData test_data[] = { - { __LINE__, true, "{\"a\":9}" }, // - { __LINE__, false, "{\"a\":0Infinity}" }, // - { __LINE__, false, "{\"a\":1Infinity}" }, // - { __LINE__, false, "{\"a\":9Infinity}" }, // - { __LINE__, false, "{\"a\":0nfinity}" }, // - { __LINE__, false, "{\"a\":1nfinity}" }, // - { __LINE__, false, "{\"a\":9nfinity}" }, // - { __LINE__, false, "{\"a\":nfinity}" }, // - { __LINE__, false, "{\"a\":.nfinity}" }, // - { __LINE__, false, "{\"a\":9nfinity}" }, // - { __LINE__, false, "{\"a\":-nfinity}" }, // - { __LINE__, true, "{\"a\":Infinity}" }, // - { __LINE__, false, "{\"a\":.Infinity}" }, // - { __LINE__, false, "{\"a\":_Infinity}" }, // - { __LINE__, false, "{\"a\":_nfinity}" }, // - { __LINE__, true, "{\"a\":-Infinity}" } // + {__LINE__, true, "{\"a\":9}"}, // + {__LINE__, false, "{\"a\":0Infinity}"}, // + {__LINE__, false, "{\"a\":1Infinity}"}, // + {__LINE__, false, "{\"a\":9Infinity}"}, // + {__LINE__, false, "{\"a\":0nfinity}"}, // + {__LINE__, false, "{\"a\":1nfinity}"}, // + {__LINE__, false, "{\"a\":9nfinity}"}, // + {__LINE__, false, "{\"a\":nfinity}"}, // + {__LINE__, false, "{\"a\":.nfinity}"}, // + {__LINE__, false, "{\"a\":9nfinity}"}, // + {__LINE__, false, "{\"a\":-nfinity}"}, // + {__LINE__, true, "{\"a\":Infinity}"}, // + {__LINE__, false, "{\"a\":.Infinity}"}, // + {__LINE__, false, "{\"a\":_Infinity}"}, // + {__LINE__, false, "{\"a\":_nfinity}"}, // + {__LINE__, true, "{\"a\":-Infinity}"} // }; for (const auto& td : test_data) { bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), From d85d75045cdd7e76998e382a435bced9f34b966c Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sat, 19 Jan 2019 22:58:02 -0500 Subject: [PATCH 107/410] Issue #872: add json/allocator.h in the amalgamated header. I don't know why we didn't include this before. It seems to work fine. --- amalgamate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amalgamate.py b/amalgamate.py index f4bff4da3..c12215a8b 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -67,7 +67,7 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") header.add_file("include/json/version.h") - #header.add_file("include/json/allocator.h") # Not available here. + header.add_file("include/json/allocator.h") header.add_file("include/json/config.h") header.add_file("include/json/forwards.h") header.add_file("include/json/features.h") From 0c1cc6e1a373dc58e2599ec7dd68b2e6b863990a Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 20 Jan 2019 23:59:16 -0500 Subject: [PATCH 108/410] pack the {type,allocated} bitfield (#876) * pack the {type,allocated} bitfield (Issue#873) This allows special functions to be implemented more easily. --- include/json/value.h | 29 ++--- src/lib_json/json_value.cpp | 207 ++++++++++++++++++------------------ 2 files changed, 117 insertions(+), 119 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 1036d3260..4e031d27b 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -338,18 +338,14 @@ Json::Value obj_value(Json::objectValue); // {} Value(const CppTL::ConstString& value); #endif Value(bool value); - /// Deep copy. Value(const Value& other); -#if JSON_HAS_RVALUE_REFERENCES - /// Move constructor Value(Value&& other); -#endif ~Value(); - /// Deep copy, then swap(other). - /// \note Over-write existing comments. To preserve comments, use + /// \note Overwrite existing comments. To preserve comments, use /// #swapPayload(). - Value& operator=(Value other); + Value& operator=(const Value& other); + Value& operator=(Value&& other); /// Swap everything. void swap(Value& other); @@ -616,6 +612,10 @@ Json::Value obj_value(Json::objectValue); // {} ptrdiff_t getOffsetLimit() const; private: + void setType(ValueType v) { bits_.value_type_ = v; } + bool isAllocated() const { return bits_.allocated_; } + void setIsAllocated(bool v) { bits_.allocated_ = v; } + void initBasic(ValueType type, bool allocated = false); void dupPayload(const Value& other); void releasePayload(); @@ -647,14 +647,17 @@ Json::Value obj_value(Json::objectValue); // {} LargestUInt uint_; double real_; bool bool_; - char* string_; // actually ptr to unsigned, followed by str, unless - // !allocated_ + char* string_; // if allocated_, ptr to { unsigned, char[] }. ObjectValues* map_; } value_; - ValueType type_ : 8; - unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is - // useless. If not allocated_, string_ must be - // null-terminated. + + struct { + // Really a ValueType, but types should agree for bitfield packing. + unsigned int value_type_ : 8; + // Unless allocated_, string_ must be null-terminated. + unsigned int allocated_ : 1; + } bits_; + CommentInfo* comments_; // [start, limit) byte offsets in the source JSON text from which this Value diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 9050e6cea..eec536fb2 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -481,35 +481,30 @@ Value::Value(const Value& other) { dupMeta(other); } -#if JSON_HAS_RVALUE_REFERENCES -// Move constructor Value::Value(Value&& other) { initBasic(nullValue); swap(other); } -#endif Value::~Value() { releasePayload(); - delete[] comments_; - value_.uint_ = 0; } -Value& Value::operator=(Value other) { - swap(other); +Value& Value::operator=(const Value& other) { + Value(other).swap(*this); + return *this; +} + +Value& Value::operator=(Value&& other) { + other.swap(*this); return *this; } void Value::swapPayload(Value& other) { - ValueType temp = type_; - type_ = other.type_; - other.type_ = temp; + std::swap(bits_, other.bits_); std::swap(value_, other.value_); - int temp2 = allocated_; - allocated_ = other.allocated_; - other.allocated_ = temp2 & 0x1; } void Value::copyPayload(const Value& other) { @@ -530,7 +525,9 @@ void Value::copy(const Value& other) { dupMeta(other); } -ValueType Value::type() const { return type_; } +ValueType Value::type() const { + return static_cast(bits_.value_type_); +} int Value::compare(const Value& other) const { if (*this < other) @@ -541,10 +538,10 @@ int Value::compare(const Value& other) const { } bool Value::operator<(const Value& other) const { - int typeDelta = type_ - other.type_; + int typeDelta = type() - other.type(); if (typeDelta) return typeDelta < 0 ? true : false; - switch (type_) { + switch (type()) { case nullValue: return false; case intValue: @@ -566,9 +563,9 @@ bool Value::operator<(const Value& other) const { unsigned other_len; char const* this_str; char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len, &other_str); unsigned min_len = std::min(this_len, other_len); JSON_ASSERT(this_str && other_str); @@ -599,14 +596,9 @@ bool Value::operator>=(const Value& other) const { return !(*this < other); } bool Value::operator>(const Value& other) const { return other < *this; } bool Value::operator==(const Value& other) const { - // if ( type_ != other.type_ ) - // GCC 2.95.3 says: - // attempt to take address of bit-field structure member `Json::Value::type_' - // Beats me, but a temp solves the problem. - int temp = other.type_; - if (type_ != temp) + if (type() != other.type()) return false; - switch (type_) { + switch (type()) { case nullValue: return true; case intValue: @@ -625,9 +617,9 @@ bool Value::operator==(const Value& other) const { unsigned other_len; char const* this_str; char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len, &other_str); if (this_len != other_len) return false; @@ -648,44 +640,45 @@ bool Value::operator==(const Value& other) const { bool Value::operator!=(const Value& other) const { return !(*this == other); } const char* Value::asCString() const { - JSON_ASSERT_MESSAGE(type_ == stringValue, + JSON_ASSERT_MESSAGE(type() == stringValue, "in Json::Value::asCString(): requires stringValue"); if (value_.string_ == nullptr) return nullptr; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, &this_str); return this_str; } #if JSONCPP_USING_SECURE_MEMORY unsigned Value::getCStringLength() const { - JSON_ASSERT_MESSAGE(type_ == stringValue, + JSON_ASSERT_MESSAGE(type() == stringValue, "in Json::Value::asCString(): requires stringValue"); if (value_.string_ == 0) return 0; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, &this_str); return this_len; } #endif bool Value::getString(char const** begin, char const** end) const { - if (type_ != stringValue) + if (type() != stringValue) return false; if (value_.string_ == nullptr) return false; unsigned length; - decodePrefixedString(this->allocated_, this->value_.string_, &length, begin); + decodePrefixedString(this->isAllocated(), this->value_.string_, &length, + begin); *end = *begin + length; return true; } String Value::asString() const { - switch (type_) { + switch (type()) { case nullValue: return ""; case stringValue: { @@ -693,7 +686,7 @@ String Value::asString() const { return ""; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len, &this_str); return String(this_str, this_len); } @@ -714,13 +707,13 @@ String Value::asString() const { CppTL::ConstString Value::asConstString() const { unsigned len; char const* str; - decodePrefixedString(allocated_, value_.string_, &len, &str); + decodePrefixedString(isAllocated(), value_.string_, &len, &str); return CppTL::ConstString(str, len); } #endif Value::Int Value::asInt() const { - switch (type_) { + switch (type()) { case intValue: JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); return Int(value_.int_); @@ -742,7 +735,7 @@ Value::Int Value::asInt() const { } Value::UInt Value::asUInt() const { - switch (type_) { + switch (type()) { case intValue: JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); return UInt(value_.int_); @@ -766,7 +759,7 @@ Value::UInt Value::asUInt() const { #if defined(JSON_HAS_INT64) Value::Int64 Value::asInt64() const { - switch (type_) { + switch (type()) { case intValue: return Int64(value_.int_); case uintValue: @@ -787,7 +780,7 @@ Value::Int64 Value::asInt64() const { } Value::UInt64 Value::asUInt64() const { - switch (type_) { + switch (type()) { case intValue: JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); return UInt64(value_.int_); @@ -825,7 +818,7 @@ LargestUInt Value::asLargestUInt() const { } double Value::asDouble() const { - switch (type_) { + switch (type()) { case intValue: return static_cast(value_.int_); case uintValue: @@ -847,7 +840,7 @@ double Value::asDouble() const { } float Value::asFloat() const { - switch (type_) { + switch (type()) { case intValue: return static_cast(value_.int_); case uintValue: @@ -870,7 +863,7 @@ float Value::asFloat() const { } bool Value::asBool() const { - switch (type_) { + switch (type()) { case booleanValue: return value_.bool_; case nullValue: @@ -892,29 +885,30 @@ bool Value::isConvertibleTo(ValueType other) const { switch (other) { case nullValue: return (isNumeric() && asDouble() == 0.0) || - (type_ == booleanValue && value_.bool_ == false) || - (type_ == stringValue && asString().empty()) || - (type_ == arrayValue && value_.map_->empty()) || - (type_ == objectValue && value_.map_->empty()) || type_ == nullValue; + (type() == booleanValue && value_.bool_ == false) || + (type() == stringValue && asString().empty()) || + (type() == arrayValue && value_.map_->empty()) || + (type() == objectValue && value_.map_->empty()) || + type() == nullValue; case intValue: return isInt() || - (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || - type_ == booleanValue || type_ == nullValue; + (type() == realValue && InRange(value_.real_, minInt, maxInt)) || + type() == booleanValue || type() == nullValue; case uintValue: return isUInt() || - (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || - type_ == booleanValue || type_ == nullValue; + (type() == realValue && InRange(value_.real_, 0, maxUInt)) || + type() == booleanValue || type() == nullValue; case realValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; + return isNumeric() || type() == booleanValue || type() == nullValue; case booleanValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; + return isNumeric() || type() == booleanValue || type() == nullValue; case stringValue: - return isNumeric() || type_ == booleanValue || type_ == stringValue || - type_ == nullValue; + return isNumeric() || type() == booleanValue || type() == stringValue || + type() == nullValue; case arrayValue: - return type_ == arrayValue || type_ == nullValue; + return type() == arrayValue || type() == nullValue; case objectValue: - return type_ == objectValue || type_ == nullValue; + return type() == objectValue || type() == nullValue; } JSON_ASSERT_UNREACHABLE; return false; @@ -922,7 +916,7 @@ bool Value::isConvertibleTo(ValueType other) const { /// Number of values in array or object ArrayIndex Value::size() const { - switch (type_) { + switch (type()) { case nullValue: case intValue: case uintValue: @@ -954,12 +948,12 @@ bool Value::empty() const { Value::operator bool() const { return !isNull(); } void Value::clear() { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || - type_ == objectValue, + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue || + type() == objectValue, "in Json::Value::clear(): requires complex value"); start_ = 0; limit_ = 0; - switch (type_) { + switch (type()) { case arrayValue: case objectValue: value_.map_->clear(); @@ -970,9 +964,9 @@ void Value::clear() { } void Value::resize(ArrayIndex newSize) { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, "in Json::Value::resize(): requires arrayValue"); - if (type_ == nullValue) + if (type() == nullValue) *this = Value(arrayValue); ArrayIndex oldSize = size(); if (newSize == 0) @@ -989,9 +983,9 @@ void Value::resize(ArrayIndex newSize) { Value& Value::operator[](ArrayIndex index) { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, + type() == nullValue || type() == arrayValue, "in Json::Value::operator[](ArrayIndex): requires arrayValue"); - if (type_ == nullValue) + if (type() == nullValue) *this = Value(arrayValue); CZString key(index); auto it = value_.map_->lower_bound(key); @@ -1012,9 +1006,9 @@ Value& Value::operator[](int index) { const Value& Value::operator[](ArrayIndex index) const { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, + type() == nullValue || type() == arrayValue, "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); - if (type_ == nullValue) + if (type() == nullValue) return nullSingleton(); CZString key(index); ObjectValues::const_iterator it = value_.map_->find(key); @@ -1031,17 +1025,17 @@ const Value& Value::operator[](int index) const { } void Value::initBasic(ValueType type, bool allocated) { - type_ = type; - allocated_ = allocated; + setType(type); + setIsAllocated(allocated); comments_ = nullptr; start_ = 0; limit_ = 0; } void Value::dupPayload(const Value& other) { - type_ = other.type_; - allocated_ = false; - switch (type_) { + setType(other.type()); + setIsAllocated(false); + switch (type()) { case nullValue: case intValue: case uintValue: @@ -1050,12 +1044,13 @@ void Value::dupPayload(const Value& other) { value_ = other.value_; break; case stringValue: - if (other.value_.string_ && other.allocated_) { + if (other.value_.string_ && other.isAllocated()) { unsigned len; char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, &len, &str); + decodePrefixedString(other.isAllocated(), other.value_.string_, &len, + &str); value_.string_ = duplicateAndPrefixStringValue(str, len); - allocated_ = true; + setIsAllocated(true); } else { value_.string_ = other.value_.string_; } @@ -1070,7 +1065,7 @@ void Value::dupPayload(const Value& other) { } void Value::releasePayload() { - switch (type_) { + switch (type()) { case nullValue: case intValue: case uintValue: @@ -1078,7 +1073,7 @@ void Value::releasePayload() { case booleanValue: break; case stringValue: - if (allocated_) + if (isAllocated()) releasePrefixedStringValue(value_.string_); break; case arrayValue: @@ -1111,9 +1106,9 @@ void Value::dupMeta(const Value& other) { // @param key is null-terminated. Value& Value::resolveReference(const char* key) { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, + type() == nullValue || type() == objectValue, "in Json::Value::resolveReference(): requires objectValue"); - if (type_ == nullValue) + if (type() == nullValue) *this = Value(objectValue); CZString actualKey(key, static_cast(strlen(key)), CZString::noDuplication); // NOTE! @@ -1130,9 +1125,9 @@ Value& Value::resolveReference(const char* key) { // @param key is not null-terminated. Value& Value::resolveReference(char const* key, char const* end) { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, + type() == nullValue || type() == objectValue, "in Json::Value::resolveReference(key, end): requires objectValue"); - if (type_ == nullValue) + if (type() == nullValue) *this = Value(objectValue); CZString actualKey(key, static_cast(end - key), CZString::duplicateOnCopy); @@ -1154,10 +1149,10 @@ Value Value::get(ArrayIndex index, const Value& defaultValue) const { bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } Value const* Value::find(char const* begin, char const* end) const { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::find(key, end, found): requires " "objectValue or nullValue"); - if (type_ == nullValue) + if (type() == nullValue) return nullptr; CZString actualKey(begin, static_cast(end - begin), CZString::noDuplication); @@ -1225,7 +1220,7 @@ Value Value::get(String const& key, Value const& defaultValue) const { } bool Value::removeMember(const char* begin, const char* end, Value* removed) { - if (type_ != objectValue) { + if (type() != objectValue) { return false; } CZString actualKey(begin, static_cast(end - begin), @@ -1249,9 +1244,9 @@ bool Value::removeMember(String const& key, Value* removed) { return removeMember(key.data(), key.data() + key.length(), removed); } void Value::removeMember(const char* key) { - JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::removeMember(): requires objectValue"); - if (type_ == nullValue) + if (type() == nullValue) return; CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication); @@ -1260,7 +1255,7 @@ void Value::removeMember(const char* key) { void Value::removeMember(const String& key) { removeMember(key.c_str()); } bool Value::removeIndex(ArrayIndex index, Value* removed) { - if (type_ != arrayValue) { + if (type() != arrayValue) { return false; } CZString key(index); @@ -1309,9 +1304,9 @@ bool Value::isMember(const CppTL::ConstString& key) const { Value::Members Value::getMemberNames() const { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, + type() == nullValue || type() == objectValue, "in Json::Value::getMemberNames(), value must be objectValue"); - if (type_ == nullValue) + if (type() == nullValue) return Value::Members(); Members members; members.reserve(value_.map_->size()); @@ -1327,7 +1322,7 @@ Value::Members Value::getMemberNames() const { // EnumMemberNames // Value::enumMemberNames() const //{ -// if ( type_ == objectValue ) +// if ( type() == objectValue ) // { // return CppTL::Enum::any( CppTL::Enum::transform( // CppTL::Enum::keys( *(value_.map_), CppTL::Type() ), @@ -1340,7 +1335,7 @@ Value::Members Value::getMemberNames() const { // EnumValues // Value::enumValues() const //{ -// if ( type_ == objectValue || type_ == arrayValue ) +// if ( type() == objectValue || type() == arrayValue ) // return CppTL::Enum::anyValues( *(value_.map_), // CppTL::Type() ); // return EnumValues(); @@ -1353,12 +1348,12 @@ static bool IsIntegral(double d) { return modf(d, &integral_part) == 0.0; } -bool Value::isNull() const { return type_ == nullValue; } +bool Value::isNull() const { return type() == nullValue; } -bool Value::isBool() const { return type_ == booleanValue; } +bool Value::isBool() const { return type() == booleanValue; } bool Value::isInt() const { - switch (type_) { + switch (type()) { case intValue: #if defined(JSON_HAS_INT64) return value_.int_ >= minInt && value_.int_ <= maxInt; @@ -1377,7 +1372,7 @@ bool Value::isInt() const { } bool Value::isUInt() const { - switch (type_) { + switch (type()) { case intValue: #if defined(JSON_HAS_INT64) return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); @@ -1401,7 +1396,7 @@ bool Value::isUInt() const { bool Value::isInt64() const { #if defined(JSON_HAS_INT64) - switch (type_) { + switch (type()) { case intValue: return true; case uintValue: @@ -1421,7 +1416,7 @@ bool Value::isInt64() const { bool Value::isUInt64() const { #if defined(JSON_HAS_INT64) - switch (type_) { + switch (type()) { case intValue: return value_.int_ >= 0; case uintValue: @@ -1440,7 +1435,7 @@ bool Value::isUInt64() const { } bool Value::isIntegral() const { - switch (type_) { + switch (type()) { case intValue: case uintValue: return true; @@ -1462,16 +1457,16 @@ bool Value::isIntegral() const { } bool Value::isDouble() const { - return type_ == intValue || type_ == uintValue || type_ == realValue; + return type() == intValue || type() == uintValue || type() == realValue; } bool Value::isNumeric() const { return isDouble(); } -bool Value::isString() const { return type_ == stringValue; } +bool Value::isString() const { return type() == stringValue; } -bool Value::isArray() const { return type_ == arrayValue; } +bool Value::isArray() const { return type() == arrayValue; } -bool Value::isObject() const { return type_ == objectValue; } +bool Value::isObject() const { return type() == objectValue; } void Value::setComment(const char* comment, size_t len, @@ -1522,7 +1517,7 @@ String Value::toStyledString() const { } Value::const_iterator Value::begin() const { - switch (type_) { + switch (type()) { case arrayValue: case objectValue: if (value_.map_) @@ -1535,7 +1530,7 @@ Value::const_iterator Value::begin() const { } Value::const_iterator Value::end() const { - switch (type_) { + switch (type()) { case arrayValue: case objectValue: if (value_.map_) @@ -1548,7 +1543,7 @@ Value::const_iterator Value::end() const { } Value::iterator Value::begin() { - switch (type_) { + switch (type()) { case arrayValue: case objectValue: if (value_.map_) @@ -1561,7 +1556,7 @@ Value::iterator Value::begin() { } Value::iterator Value::end() { - switch (type_) { + switch (type()) { case arrayValue: case objectValue: if (value_.map_) From b4ca2db5ff1494cb0c15c06bb1699048298c98b6 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 24 Jan 2019 09:00:55 -0600 Subject: [PATCH 109/410] COMP: Remove build files for unsupported IDE's The msvc2010 and vs71 IDE's do not support sufficient C++11 feature sets for jsoncpp. Remove these build environments. resolves: #882 --- makefiles/msvc2010/jsoncpp.sln | 42 ---- makefiles/msvc2010/jsontest.vcxproj | 96 -------- makefiles/msvc2010/jsontest.vcxproj.filters | 13 -- makefiles/msvc2010/lib_json.vcxproj | 143 ------------ makefiles/msvc2010/lib_json.vcxproj.filters | 33 --- makefiles/msvc2010/test_lib_json.vcxproj | 109 ---------- .../msvc2010/test_lib_json.vcxproj.filters | 24 -- makefiles/vs71/jsoncpp.sln | 46 ---- makefiles/vs71/jsontest.vcproj | 119 ---------- makefiles/vs71/lib_json.vcproj | 205 ------------------ makefiles/vs71/test_lib_json.vcproj | 130 ----------- 11 files changed, 960 deletions(-) delete mode 100644 makefiles/msvc2010/jsoncpp.sln delete mode 100644 makefiles/msvc2010/jsontest.vcxproj delete mode 100644 makefiles/msvc2010/jsontest.vcxproj.filters delete mode 100644 makefiles/msvc2010/lib_json.vcxproj delete mode 100644 makefiles/msvc2010/lib_json.vcxproj.filters delete mode 100644 makefiles/msvc2010/test_lib_json.vcxproj delete mode 100644 makefiles/msvc2010/test_lib_json.vcxproj.filters delete mode 100644 makefiles/vs71/jsoncpp.sln delete mode 100644 makefiles/vs71/jsontest.vcproj delete mode 100644 makefiles/vs71/lib_json.vcproj delete mode 100644 makefiles/vs71/test_lib_json.vcproj diff --git a/makefiles/msvc2010/jsoncpp.sln b/makefiles/msvc2010/jsoncpp.sln deleted file mode 100644 index c4ecb9070..000000000 --- a/makefiles/msvc2010/jsoncpp.sln +++ /dev/null @@ -1,42 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcxproj", "{1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcxproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcxproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|Win32.ActiveCfg = Debug|Win32 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|Win32.Build.0 = Debug|Win32 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|x64.ActiveCfg = Debug|x64 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Debug|x64.Build.0 = Debug|x64 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|Win32.ActiveCfg = Release|Win32 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|Win32.Build.0 = Release|Win32 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|x64.ActiveCfg = Release|x64 - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89}.Release|x64.Build.0 = Release|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|Win32.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|Win32.Build.0 = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|Win32.ActiveCfg = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|Win32.Build.0 = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.ActiveCfg = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|Win32.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|Win32.Build.0 = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|Win32.ActiveCfg = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|Win32.Build.0 = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/makefiles/msvc2010/jsontest.vcxproj b/makefiles/msvc2010/jsontest.vcxproj deleted file mode 100644 index 939d440dd..000000000 --- a/makefiles/msvc2010/jsontest.vcxproj +++ /dev/null @@ -1,96 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {25AF2DD2-D396-4668-B188-488C33B8E620} - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - ../../build/vs71/debug/jsontest\ - ../../build/vs71/debug/jsontest\ - true - ../../build/vs71/release/jsontest\ - ../../build/vs71/release/jsontest\ - false - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - EditAndContinue - - - $(OutDir)jsontest.exe - true - $(OutDir)jsontest.pdb - Console - MachineX86 - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)jsontest.exe - true - Console - true - true - MachineX86 - - - - - - - - {1e6c2c1c-6453-4129-ae3f-0ee8e6599c89} - - - - - - \ No newline at end of file diff --git a/makefiles/msvc2010/jsontest.vcxproj.filters b/makefiles/msvc2010/jsontest.vcxproj.filters deleted file mode 100644 index 610b540ea..000000000 --- a/makefiles/msvc2010/jsontest.vcxproj.filters +++ /dev/null @@ -1,13 +0,0 @@ - - - - - {903591b3-ade3-4ce4-b1f9-1e175e62b014} - - - - - Source Files - - - \ No newline at end of file diff --git a/makefiles/msvc2010/lib_json.vcxproj b/makefiles/msvc2010/lib_json.vcxproj deleted file mode 100644 index 3cfd0f936..000000000 --- a/makefiles/msvc2010/lib_json.vcxproj +++ /dev/null @@ -1,143 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - {1E6C2C1C-6453-4129-AE3F-0EE8E6599C89} - Win32Proj - jsoncpp - - - - StaticLibrary - true - Unicode - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ../../include - MultiThreadedDebug - - - Windows - true - - - - - NotUsing - Level3 - Disabled - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - ../../include - MultiThreadedDebug - - - Windows - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ../../include - MultiThreaded - - - Windows - true - true - true - - - - - Level3 - NotUsing - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - ../../include - MultiThreaded - - - Windows - true - true - true - - - - - - \ No newline at end of file diff --git a/makefiles/msvc2010/lib_json.vcxproj.filters b/makefiles/msvc2010/lib_json.vcxproj.filters deleted file mode 100644 index 63c740331..000000000 --- a/makefiles/msvc2010/lib_json.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ - - - - - {c110bc57-c46e-476c-97ea-84d8014f431c} - - - {ed718592-5acf-47b5-8f2b-b8224590da6a} - - - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/makefiles/msvc2010/test_lib_json.vcxproj b/makefiles/msvc2010/test_lib_json.vcxproj deleted file mode 100644 index 068af613e..000000000 --- a/makefiles/msvc2010/test_lib_json.vcxproj +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D} - test_lib_json - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - ../../build/vs71/debug/test_lib_json\ - ../../build/vs71/debug/test_lib_json\ - true - ../../build/vs71/release/test_lib_json\ - ../../build/vs71/release/test_lib_json\ - false - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - EditAndContinue - - - $(OutDir)test_lib_json.exe - true - $(OutDir)test_lib_json.pdb - Console - MachineX86 - - - Running all unit tests - $(TargetPath) - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)test_lib_json.exe - true - Console - true - true - MachineX86 - - - Running all unit tests - $(TargetPath) - - - - - - - - - - - - {1e6c2c1c-6453-4129-ae3f-0ee8e6599c89} - - - - - - \ No newline at end of file diff --git a/makefiles/msvc2010/test_lib_json.vcxproj.filters b/makefiles/msvc2010/test_lib_json.vcxproj.filters deleted file mode 100644 index 8f0a17b99..000000000 --- a/makefiles/msvc2010/test_lib_json.vcxproj.filters +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Source Filter - - - Source Filter - - - - - {bf40cbfc-8e98-40b4-b9f3-7e8d579cbae2} - - - {5fd39074-89e6-4939-aa3f-694fefd296b1} - - - - - Header Files - - - \ No newline at end of file diff --git a/makefiles/vs71/jsoncpp.sln b/makefiles/vs71/jsoncpp.sln deleted file mode 100644 index dd2f91b44..000000000 --- a/makefiles/vs71/jsoncpp.sln +++ /dev/null @@ -1,46 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcproj", "{B84F7231-16CE-41D8-8C08-7B523FF4225B}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}" - ProjectSection(ProjectDependencies) = postProject - {B84F7231-16CE-41D8-8C08-7B523FF4225B} = {B84F7231-16CE-41D8-8C08-7B523FF4225B} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}" - ProjectSection(ProjectDependencies) = postProject - {B84F7231-16CE-41D8-8C08-7B523FF4225B} = {B84F7231-16CE-41D8-8C08-7B523FF4225B} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - dummy = dummy - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug.ActiveCfg = Debug|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug.Build.0 = Debug|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy.ActiveCfg = dummy|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy.Build.0 = dummy|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release.ActiveCfg = Release|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release.Build.0 = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug.Build.0 = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy.Build.0 = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release.ActiveCfg = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release.Build.0 = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug.Build.0 = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy.Build.0 = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release.ActiveCfg = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/makefiles/vs71/jsontest.vcproj b/makefiles/vs71/jsontest.vcproj deleted file mode 100644 index 562c71f61..000000000 --- a/makefiles/vs71/jsontest.vcproj +++ /dev/null @@ -1,119 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/makefiles/vs71/lib_json.vcproj b/makefiles/vs71/lib_json.vcproj deleted file mode 100644 index 24c5dd411..000000000 --- a/makefiles/vs71/lib_json.vcproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/makefiles/vs71/test_lib_json.vcproj b/makefiles/vs71/test_lib_json.vcproj deleted file mode 100644 index 9ebb986a6..000000000 --- a/makefiles/vs71/test_lib_json.vcproj +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 2ab1d634806a817d838ddd93f06b9aa1a686197a Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 24 Jan 2019 09:57:56 -0600 Subject: [PATCH 110/410] COMP: Remove visual studio specialization in favor of meson or cmake More robust build environments can be generated from meson or cmake rather than including those files in every download. --- README.md | 7 + makefiles/msvc2017/jsoncpp.sln | 64 ------ makefiles/msvc2017/jsontest.vcxproj | 168 --------------- makefiles/msvc2017/lib_json.vcxproj | 258 ----------------------- makefiles/msvc2017/test_lib_json.vcxproj | 189 ----------------- 5 files changed, 7 insertions(+), 679 deletions(-) delete mode 100644 makefiles/msvc2017/jsoncpp.sln delete mode 100644 makefiles/msvc2017/jsontest.vcxproj delete mode 100644 makefiles/msvc2017/lib_json.vcxproj delete mode 100644 makefiles/msvc2017/test_lib_json.vcxproj diff --git a/README.md b/README.md index 8f825949f..9d71b4f11 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,13 @@ format to store user input files. ## Contributing to JsonCpp +### Building + +Both CMake and Meson tools are capable of generating a variety of build environments for you preferred development environment. +Using cmake or meson you can generate an XCode, Visual Studio, Unix Makefile, Ninja, or other environment that fits your needs. + +An example of a common Meson/Ninja environment is described next. + ### Building and testing with Meson/Ninja Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use [meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build diff --git a/makefiles/msvc2017/jsoncpp.sln b/makefiles/msvc2017/jsoncpp.sln deleted file mode 100644 index cf77ce01d..000000000 --- a/makefiles/msvc2017/jsoncpp.sln +++ /dev/null @@ -1,64 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.102 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_json", "lib_json.vcxproj", "{B84F7231-16CE-41D8-8C08-7B523FF4225B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jsontest", "jsontest.vcxproj", "{25AF2DD2-D396-4668-B188-488C33B8E620}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_json", "test_lib_json.vcxproj", "{B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - dummy|x64 = dummy|x64 - dummy|x86 = dummy|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x64.ActiveCfg = Debug|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x64.Build.0 = Debug|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.ActiveCfg = Debug|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Debug|x86.Build.0 = Debug|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x64.ActiveCfg = dummy|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x64.Build.0 = dummy|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.ActiveCfg = dummy|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.dummy|x86.Build.0 = dummy|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x64.ActiveCfg = Release|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x64.Build.0 = Release|x64 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.ActiveCfg = Release|Win32 - {B84F7231-16CE-41D8-8C08-7B523FF4225B}.Release|x86.Build.0 = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.ActiveCfg = Debug|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x64.Build.0 = Debug|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Debug|x86.Build.0 = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x64.ActiveCfg = Debug|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x64.Build.0 = Debug|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.ActiveCfg = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.dummy|x86.Build.0 = Debug|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.ActiveCfg = Release|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x64.Build.0 = Release|x64 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.ActiveCfg = Release|Win32 - {25AF2DD2-D396-4668-B188-488C33B8E620}.Release|x86.Build.0 = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.ActiveCfg = Debug|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x64.Build.0 = Debug|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Debug|x86.Build.0 = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x64.ActiveCfg = Debug|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x64.Build.0 = Debug|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.ActiveCfg = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.dummy|x86.Build.0 = Debug|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.ActiveCfg = Release|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x64.Build.0 = Release|x64 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.ActiveCfg = Release|Win32 - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {4EE0C79B-26FE-4FB3-B025-AA18203D1636} - EndGlobalSection -EndGlobal diff --git a/makefiles/msvc2017/jsontest.vcxproj b/makefiles/msvc2017/jsontest.vcxproj deleted file mode 100644 index de43cfee9..000000000 --- a/makefiles/msvc2017/jsontest.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {25AF2DD2-D396-4668-B188-488C33B8E620} - Win32Proj - - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.28127.55 - - - ../../build/vs71/debug/jsontest\ - ../../build/vs71/debug/jsontest\ - true - - - true - - - ../../build/vs71/release/jsontest\ - ../../build/vs71/release/jsontest\ - false - - - false - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - Level3 - EditAndContinue - - - $(OutDir)jsontest.exe - true - $(OutDir)jsontest.pdb - Console - MachineX86 - - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - Level3 - ProgramDatabase - - - $(OutDir)jsontest.exe - true - $(OutDir)jsontest.pdb - Console - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - ProgramDatabase - - - $(OutDir)jsontest.exe - true - Console - true - true - MachineX86 - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)jsontest.exe - true - Console - true - true - - - - - - - - {b84f7231-16ce-41d8-8c08-7b523ff4225b} - false - - - - - - \ No newline at end of file diff --git a/makefiles/msvc2017/lib_json.vcxproj b/makefiles/msvc2017/lib_json.vcxproj deleted file mode 100644 index 092bd29c9..000000000 --- a/makefiles/msvc2017/lib_json.vcxproj +++ /dev/null @@ -1,258 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - dummy - Win32 - - - dummy - x64 - - - Release - Win32 - - - Release - x64 - - - - {B84F7231-16CE-41D8-8C08-7B523FF4225B} - Win32Proj - - - - DynamicLibrary - v141 - MultiByte - true - - - DynamicLibrary - v141 - MultiByte - true - - - StaticLibrary - v141 - MultiByte - true - - - StaticLibrary - v141 - MultiByte - true - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.28127.55 - - - ../../build/vs71/debug/lib_json\ - ../../build/vs71/debug/lib_json\ - - - - ../../build/vs71/release/lib_json\ - ../../build/vs71/release/lib_json\ - - - $(Configuration)\ - $(Configuration)\ - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - true - EnableFastChecks - MultiThreadedDebug - true - true - false - true - - Level3 - EditAndContinue - - - $(OutDir)json_vc71_libmtd.lib - - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - true - false - true - - - Level3 - ProgramDatabase - - - $(OutDir)json_vc71_libmtd.lib - - - - - true - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - true - true - false - true - - AssemblyAndSourceCode - Level3 - ProgramDatabase - - - $(OutDir)json_vc71_libmt.lib - - - - - true - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreadedDLL - true - true - false - true - - - NoListing - Level3 - ProgramDatabase - - - $(OutDir)json_vc71_libmt.lib - - - - - true - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - true - true - false - true - - AssemblyAndSourceCode - Level3 - ProgramDatabase - - - true - Windows - true - true - MachineX86 - - - - - true - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - true - MultiThreaded - true - true - false - true - - - AssemblyAndSourceCode - Level3 - ProgramDatabase - - - true - Windows - true - true - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/makefiles/msvc2017/test_lib_json.vcxproj b/makefiles/msvc2017/test_lib_json.vcxproj deleted file mode 100644 index 89a336f80..000000000 --- a/makefiles/msvc2017/test_lib_json.vcxproj +++ /dev/null @@ -1,189 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {B7A96B78-2782-40D2-8F37-A2DEF2B9C26D} - test_lib_json - Win32Proj - - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - Application - v141 - MultiByte - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.28127.55 - - - ../../build/vs71/debug/test_lib_json\ - ../../build/vs71/debug/test_lib_json\ - true - - - true - - - ../../build/vs71/release/test_lib_json\ - ../../build/vs71/release/test_lib_json\ - false - - - false - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - Level3 - EditAndContinue - - - $(OutDir)test_lib_json.exe - true - $(OutDir)test_lib_json.pdb - Console - MachineX86 - - - Running all unit tests - $(TargetPath) - - - - - Disabled - ../../include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - EnableFastChecks - MultiThreadedDebug - - - Level3 - ProgramDatabase - - - $(OutDir)test_lib_json.exe - true - $(OutDir)test_lib_json.pdb - Console - - - Running all unit tests - $(TargetPath) - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - ProgramDatabase - - - $(OutDir)test_lib_json.exe - true - Console - true - true - MachineX86 - - - Running all unit tests - $(TargetPath) - - - - - ../../include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)test_lib_json.exe - true - Console - true - true - - - Running all unit tests - $(TargetPath) - - - - - - - - - - - - {b84f7231-16ce-41d8-8c08-7b523ff4225b} - false - - - - - - \ No newline at end of file From 36d8cfd768606751a163297af49fb4cf1731eb31 Mon Sep 17 00:00:00 2001 From: Marcel Raad Date: Mon, 25 Feb 2019 15:24:03 +0100 Subject: [PATCH 111/410] Fix macro redefinition warning with clang-cl clang-cl defines _MSC_VER by default, so JSONCPP_DEPRECATED was first defined for MSVC and then redefined for clang. Integrate the MSVC definition into the block with clang and GCC's JSONCPP_DEPRECATED definitions to fix this. --- include/json/config.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 1af868122..541d168b0 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -79,10 +79,6 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); // Storages, and 64 bits integer support is disabled. // #define JSON_NO_INT64 1 -#if defined(_MSC_VER) // MSVC -#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) -#endif // defined(_MSC_VER) - // JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools. // C++11 should be used directly in JSONCPP. #define JSONCPP_OVERRIDE override @@ -135,7 +131,9 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) #endif // GNUC version -#endif // __clang__ || __GNUC__ +#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates MSVC) +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif // __clang__ || __GNUC__ || _MSC_VER #if !defined(JSONCPP_DEPRECATED) #define JSONCPP_DEPRECATED(message) From 433107f1d9d639243a075e31ac2f45db0c7d47ee Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 20 Jan 2019 21:53:01 -0500 Subject: [PATCH 112/410] refactor comments_ into a class --- include/json/value.h | 38 ++++++++----- src/lib_json/json_value.cpp | 104 +++++++++++++++--------------------- 2 files changed, 69 insertions(+), 73 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 4e031d27b..9a2d10ddc 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -9,7 +9,9 @@ #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" #endif // if !defined(JSON_IS_AMALGAMATION) +#include #include +#include #include #include @@ -587,11 +589,15 @@ Json::Value obj_value(Json::objectValue); // {} /// \deprecated Always pass len. JSONCPP_DEPRECATED("Use setComment(String const&) instead.") - void setComment(const char* comment, CommentPlacement placement); + void setComment(const char* comment, CommentPlacement placement) { + setComment(String(comment, strlen(comment)), placement); + } /// Comments must be //... or /* ... */ - void setComment(const char* comment, size_t len, CommentPlacement placement); + void setComment(const char* comment, size_t len, CommentPlacement placement) { + setComment(String(comment, len), placement); + } /// Comments must be //... or /* ... */ - void setComment(const String& comment, CommentPlacement placement); + void setComment(String comment, CommentPlacement placement); bool hasComment(CommentPlacement placement) const; /// Include delimiters and embedded newlines. String getComment(CommentPlacement placement) const; @@ -624,15 +630,6 @@ Json::Value obj_value(Json::objectValue); // {} Value& resolveReference(const char* key); Value& resolveReference(const char* key, const char* end); - struct CommentInfo { - CommentInfo(); - ~CommentInfo(); - - void setComment(const char* text, size_t len); - - char* comment_{nullptr}; - }; - // struct MemberNamesTransform //{ // typedef const char *result_type; @@ -658,7 +655,22 @@ Json::Value obj_value(Json::objectValue); // {} unsigned int allocated_ : 1; } bits_; - CommentInfo* comments_; + class Comments { + public: + Comments() = default; + Comments(const Comments& that); + Comments(Comments&&) = default; + Comments& operator=(const Comments& that); + Comments& operator=(Comments&&) = default; + bool has(CommentPlacement slot) const; + String get(CommentPlacement slot) const; + void set(CommentPlacement slot, String s); + + private: + using Array = std::array; + std::unique_ptr ptr_; + }; + Comments comments_; // [start, limit) byte offsets in the source JSON text from which this Value // was extracted. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index eec536fb2..7102f8857 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -55,6 +55,15 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, namespace Json { +template +static std::unique_ptr cloneUnique(const std::unique_ptr& p) { + std::unique_ptr r; + if (p) { + r = std::unique_ptr(new T(*p)); + } + return r; +} + // This is a walkaround to avoid the static initialization of Value::null. // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of // 8 (instead of 4) as a bit of future-proofing. @@ -229,34 +238,6 @@ JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// class Value::CommentInfo -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// -// ////////////////////////////////////////////////////////////////// - -Value::CommentInfo::CommentInfo() = default; - -Value::CommentInfo::~CommentInfo() { - if (comment_) - releaseStringValue(comment_, 0u); -} - -void Value::CommentInfo::setComment(const char* text, size_t len) { - if (comment_) { - releaseStringValue(comment_, 0u); - comment_ = nullptr; - } - JSON_ASSERT(text != nullptr); - JSON_ASSERT_MESSAGE( - text[0] == '\0' || text[0] == '/', - "in Json::Value::setComment(): Comments must start with /"); - // It seems that /**/ style comments are acceptable as well. - comment_ = duplicateStringValue(text, len); -} - // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// @@ -488,7 +469,6 @@ Value::Value(Value&& other) { Value::~Value() { releasePayload(); - delete[] comments_; value_.uint_ = 0; } @@ -521,7 +501,6 @@ void Value::swap(Value& other) { void Value::copy(const Value& other) { copyPayload(other); - delete[] comments_; dupMeta(other); } @@ -1027,7 +1006,7 @@ const Value& Value::operator[](int index) const { void Value::initBasic(ValueType type, bool allocated) { setType(type); setIsAllocated(allocated); - comments_ = nullptr; + comments_ = Comments{}; start_ = 0; limit_ = 0; } @@ -1086,17 +1065,7 @@ void Value::releasePayload() { } void Value::dupMeta(const Value& other) { - if (other.comments_) { - comments_ = new CommentInfo[numberOfCommentPlacement]; - for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { - const CommentInfo& otherComment = other.comments_[comment]; - if (otherComment.comment_) - comments_[comment].setComment(otherComment.comment_, - strlen(otherComment.comment_)); - } - } else { - comments_ = nullptr; - } + comments_ = other.comments_; start_ = other.start_; limit_ = other.limit_; } @@ -1468,34 +1437,49 @@ bool Value::isArray() const { return type() == arrayValue; } bool Value::isObject() const { return type() == objectValue; } -void Value::setComment(const char* comment, - size_t len, - CommentPlacement placement) { - if (!comments_) - comments_ = new CommentInfo[numberOfCommentPlacement]; - if ((len > 0) && (comment[len - 1] == '\n')) { - // Always discard trailing newline, to aid indentation. - len -= 1; - } - comments_[placement].setComment(comment, len); +Value::Comments::Comments(const Comments& that) + : ptr_{cloneUnique(that.ptr_)} {} + +Value::Comments& Value::Comments::operator=(const Comments& that) { + ptr_ = cloneUnique(that.ptr_); + return *this; } -void Value::setComment(const char* comment, CommentPlacement placement) { - setComment(comment, strlen(comment), placement); +bool Value::Comments::has(CommentPlacement slot) const { + return ptr_ && !(*ptr_)[slot].empty(); } -void Value::setComment(const String& comment, CommentPlacement placement) { - setComment(comment.c_str(), comment.length(), placement); +String Value::Comments::get(CommentPlacement slot) const { + if (!ptr_) + return {}; + return (*ptr_)[slot]; +} + +void Value::Comments::set(CommentPlacement slot, String comment) { + if (!ptr_) { + ptr_ = std::unique_ptr(new Array()); + } + (*ptr_)[slot] = std::move(comment); +} + +void Value::setComment(String comment, CommentPlacement placement) { + if (!comment.empty() && (comment.back() == '\n')) { + // Always discard trailing newline, to aid indentation. + comment.pop_back(); + } + JSON_ASSERT(!comment.empty()); + JSON_ASSERT_MESSAGE( + comment[0] == '\0' || comment[0] == '/', + "in Json::Value::setComment(): Comments must start with /"); + comments_.set(placement, std::move(comment)); } bool Value::hasComment(CommentPlacement placement) const { - return comments_ != nullptr && comments_[placement].comment_ != nullptr; + return comments_.has(placement); } String Value::getComment(CommentPlacement placement) const { - if (hasComment(placement)) - return comments_[placement].comment_; - return ""; + return comments_.get(placement); } void Value::setOffsetStart(ptrdiff_t start) { start_ = start; } From 00558b38db535b6ee99185caa97efd50d0aa9d29 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 21 Jan 2019 16:42:25 -0500 Subject: [PATCH 113/410] VS2013 doesn't allow move ops to be =default --- include/json/value.h | 4 ++-- src/lib_json/json_value.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 9a2d10ddc..a62f4828b 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -659,9 +659,9 @@ Json::Value obj_value(Json::objectValue); // {} public: Comments() = default; Comments(const Comments& that); - Comments(Comments&&) = default; + Comments(Comments&& that); Comments& operator=(const Comments& that); - Comments& operator=(Comments&&) = default; + Comments& operator=(Comments&& that); bool has(CommentPlacement slot) const; String get(CommentPlacement slot) const; void set(CommentPlacement slot, String s); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 7102f8857..5ce007998 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1440,11 +1440,19 @@ bool Value::isObject() const { return type() == objectValue; } Value::Comments::Comments(const Comments& that) : ptr_{cloneUnique(that.ptr_)} {} +Value::Comments::Comments(Comments&& that) + : ptr_{std::move(that.ptr_)} {} + Value::Comments& Value::Comments::operator=(const Comments& that) { ptr_ = cloneUnique(that.ptr_); return *this; } +Value::Comments& Value::Comments::operator=(Comments&& that) { + ptr_ = std::move(that.ptr_); + return *this; +} + bool Value::Comments::has(CommentPlacement slot) const { return ptr_ && !(*ptr_)[slot].empty(); } From 9a55d22d3dbb75753696611c8688b9ac9928d244 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 21 Jan 2019 12:32:31 -0500 Subject: [PATCH 114/410] remove JSON_HAS_RVALUE_REFERENCES --- include/json/config.h | 24 ------------------------ include/json/value.h | 8 -------- src/lib_json/json_value.cpp | 10 ---------- src/test_lib_json/main.cpp | 2 -- 4 files changed, 44 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 541d168b0..8c6050815 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -97,30 +97,6 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_OP_EXPLICIT #endif -#ifndef JSON_HAS_RVALUE_REFERENCES - -#if defined(_MSC_VER) -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // MSVC >= 2013 - -#ifdef __clang__ -#if __has_feature(cxx_rvalue_references) -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // has_feature - -#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) -#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) -#define JSON_HAS_RVALUE_REFERENCES 1 -#endif // GXX_EXPERIMENTAL - -#endif // __clang__ || __GNUC__ - -#endif // not defined JSON_HAS_RVALUE_REFERENCES - -#ifndef JSON_HAS_RVALUE_REFERENCES -#define JSON_HAS_RVALUE_REFERENCES 0 -#endif - #ifdef __clang__ #if __has_extension(attribute_deprecated_with_message) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) diff --git a/include/json/value.h b/include/json/value.h index a62f4828b..69a0ed2ab 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -251,15 +251,10 @@ class JSON_API Value { CZString(ArrayIndex index); CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(CZString const& other); -#if JSON_HAS_RVALUE_REFERENCES CZString(CZString&& other); -#endif ~CZString(); CZString& operator=(const CZString& other); - -#if JSON_HAS_RVALUE_REFERENCES CZString& operator=(CZString&& other); -#endif bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; @@ -468,10 +463,7 @@ Json::Value obj_value(Json::objectValue); // {} /// /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); - -#if JSON_HAS_RVALUE_REFERENCES Value& append(Value&& value); -#endif /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 5ce007998..fe5d8b36f 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -276,12 +276,10 @@ Value::CZString::CZString(const CZString& other) { storage_.length_ = other.storage_.length_; } -#if JSON_HAS_RVALUE_REFERENCES Value::CZString::CZString(CZString&& other) : cstr_(other.cstr_), index_(other.index_) { other.cstr_ = nullptr; } -#endif Value::CZString::~CZString() { if (cstr_ && storage_.policy_ == duplicate) { @@ -304,14 +302,12 @@ Value::CZString& Value::CZString::operator=(const CZString& other) { return *this; } -#if JSON_HAS_RVALUE_REFERENCES Value::CZString& Value::CZString::operator=(CZString&& other) { cstr_ = other.cstr_; index_ = other.index_; other.cstr_ = nullptr; return *this; } -#endif bool Value::CZString::operator<(const CZString& other) const { if (!cstr_) @@ -1169,11 +1165,9 @@ Value const& Value::operator[](CppTL::ConstString const& key) const { Value& Value::append(const Value& value) { return (*this)[size()] = value; } -#if JSON_HAS_RVALUE_REFERENCES Value& Value::append(Value&& value) { return (*this)[size()] = std::move(value); } -#endif Value Value::get(char const* begin, char const* end, @@ -1198,11 +1192,7 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) { if (it == value_.map_->end()) return false; if (removed) -#if JSON_HAS_RVALUE_REFERENCES *removed = std::move(it->second); -#else - *removed = it->second; -#endif value_.map_->erase(it); return true; } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 27fb4a273..2df51b5a0 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2499,7 +2499,6 @@ JSONTEST_FIXTURE(IteratorTest, const) { struct RValueTest : JsonTest::TestCase {}; JSONTEST_FIXTURE(RValueTest, moveConstruction) { -#if JSON_HAS_RVALUE_REFERENCES Json::Value json; json["key"] = "value"; Json::Value moved = std::move(json); @@ -2507,7 +2506,6 @@ JSONTEST_FIXTURE(RValueTest, moveConstruction) { // equal. JSONTEST_ASSERT_EQUAL(Json::objectValue, moved.type()); JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); -#endif } int main(int argc, const char* argv[]) { From 863aa36165acfdbaf22447f4934f5adc327692a0 Mon Sep 17 00:00:00 2001 From: Willem Date: Mon, 18 Mar 2019 14:02:50 +0100 Subject: [PATCH 115/410] Update README.md Update the link to the conan page, as https://conan.io/source/jsoncpp/1.8.0/theirix/ci returns a 404. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d71b4f11..2e6409291 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # JsonCpp -[![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](http://www.conan.io/source/jsoncpp/1.8.0/theirix/ci) +[![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](https://bintray.com/theirix/conan-repo/jsoncpp%3Atheirix) [JSON][json-org] is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value From 0adb053294045adcba5643d82983ed90e9816d1e Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 14:16:13 +0100 Subject: [PATCH 116/410] tests: Add small checks for find() --- src/test_lib_json/main.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 2df51b5a0..c2d0f2e71 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -204,6 +204,16 @@ JSONTEST_FIXTURE(ValueTest, objects) { JSONTEST_ASSERT_EQUAL(Json::Value(1234), constObject["id"]); JSONTEST_ASSERT_EQUAL(Json::Value(), constObject["unknown id"]); + // Access through find() + const char idKey[] = "id"; + const Json::Value* foundId = object1_.find(idKey, idKey + strlen(idKey)); + JSONTEST_ASSERT(foundId != nullptr); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId); + + const char unknownIdKey[] = "unknown id"; + const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); + JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); + // Access through non-const reference JSONTEST_ASSERT_EQUAL(Json::Value(1234), object1_["id"]); JSONTEST_ASSERT_EQUAL(Json::Value(), object1_["unknown id"]); From eb7bd9546e3107215fdaaf6f6c9d2b41f1635446 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 14:32:00 +0100 Subject: [PATCH 117/410] Value::find(): Fix assert message --- src/lib_json/json_value.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index fe5d8b36f..f21b2311f 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1115,7 +1115,7 @@ bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } Value const* Value::find(char const* begin, char const* end) const { JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, - "in Json::Value::find(key, end, found): requires " + "in Json::Value::find(begin, end): requires " "objectValue or nullValue"); if (type() == nullValue) return nullptr; From d76fe5687dd448a1b466bcf73729147e6046c31e Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 14:31:06 +0100 Subject: [PATCH 118/410] Implement Value::demand() --- include/json/value.h | 2 +- src/lib_json/json_value.cpp | 6 ++++++ src/test_lib_json/main.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/json/value.h b/include/json/value.h index 69a0ed2ab..277cd451d 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -524,7 +524,7 @@ Json::Value obj_value(Json::objectValue); // {} /// Most general and efficient version of object-mutators. /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. - Value const* demand(char const* begin, char const* end); + Value* demand(char const* begin, char const* end); /// \brief Remove and return the named member. /// /// Do nothing if it did not exist. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index f21b2311f..b046c1939 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1126,6 +1126,12 @@ Value const* Value::find(char const* begin, char const* end) const { return nullptr; return &(*it).second; } +Value* Value::demand(char const* begin, char const* end) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, + "in Json::Value::demand(begin, end): requires " + "objectValue or nullValue"); + return &resolveReference(begin, end); +} const Value& Value::operator[](const char* key) const { Value const* found = find(key, key + strlen(key)); if (!found) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c2d0f2e71..1a337bc7e 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -214,6 +214,15 @@ JSONTEST_FIXTURE(ValueTest, objects) { const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); + const char yetAnotherIdKey[] = "yet another id"; + const Json::Value* foundYetAnotherId = object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); + JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId); + Json::Value* demandedYetAnotherId = object1_.demand(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); + JSONTEST_ASSERT(demandedYetAnotherId != nullptr); + *demandedYetAnotherId = "baz"; + + JSONTEST_ASSERT_EQUAL(Json::Value("baz"), object1_["yet another id"]); + // Access through non-const reference JSONTEST_ASSERT_EQUAL(Json::Value(1234), object1_["id"]); JSONTEST_ASSERT_EQUAL(Json::Value(), object1_["unknown id"]); From 9a629bc5e1fd00f959316afa2ceb3575e8f3ea5e Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 14:39:59 +0100 Subject: [PATCH 119/410] tests: Add a comment --- src/test_lib_json/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 1a337bc7e..280f7eac6 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -214,6 +214,7 @@ JSONTEST_FIXTURE(ValueTest, objects) { const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); + // Access through demand() const char yetAnotherIdKey[] = "yet another id"; const Json::Value* foundYetAnotherId = object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId); From 99a99d4032ca1607ad0b9b985b49935bef3713f0 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 15:04:30 +0100 Subject: [PATCH 120/410] Cast to unsigned char in Value::setType() to appease gcc (issue #888) --- include/json/value.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/json/value.h b/include/json/value.h index 69a0ed2ab..2e94b37c7 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -610,7 +610,7 @@ Json::Value obj_value(Json::objectValue); // {} ptrdiff_t getOffsetLimit() const; private: - void setType(ValueType v) { bits_.value_type_ = v; } + void setType(ValueType v) { bits_.value_type_ = static_cast (v); } bool isAllocated() const { return bits_.allocated_; } void setIsAllocated(bool v) { bits_.allocated_ = v; } From 69402d1fbb893c85a3bfc603e66c618d423be94e Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Sat, 23 Mar 2019 21:03:30 +0100 Subject: [PATCH 121/410] Bump minor version, SOVERSION --- CMakeLists.txt | 4 ++-- meson.build | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2de402472..a99243798 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,12 +63,12 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) endif() project(JSONCPP - VERSION 1.8.4 # [.[.[.]]] + VERSION 1.9.0 # [.[.[.]]] LANGUAGES CXX) set( JSONCPP_VERSION ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH} ) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set( JSONCPP_SOVERSION 19 ) +set( JSONCPP_SOVERSION 21 ) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) diff --git a/meson.build b/meson.build index a338cc0dd..106e17f6a 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'jsoncpp', 'cpp', - version : '1.8.4', + version : '1.9.0', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -62,7 +62,7 @@ jsoncpp_lib = library( 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp'], - soversion : 20, + soversion : 21, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) From b16abf8ce1e78d0c77bcd6e458afe6048c855b6a Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Fri, 22 Mar 2019 10:15:08 +0100 Subject: [PATCH 122/410] Explicitly set JSON_API to 'default' visibility on clang & gcc --- include/json/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/json/config.h b/include/json/config.h index 8c6050815..cba610293 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -48,6 +48,8 @@ #if defined(_MSC_VER) || defined(__MINGW32__) #define JSON_API __declspec(dllexport) #define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#elif defined(__GNUC__) || defined(__clang__) +#define JSON_API __attribute__((visibility("default"))) #endif // if defined(_MSC_VER) #elif defined(JSON_DLL) #if defined(_MSC_VER) || defined(__MINGW32__) From 27b950168360616b3b20213e3c5a1ec34386844c Mon Sep 17 00:00:00 2001 From: David Demelier Date: Thu, 18 Apr 2019 16:32:13 +0200 Subject: [PATCH 123/410] Fix build with libc++, closes #910 --- version => version.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename version => version.md (100%) diff --git a/version b/version.md similarity index 100% rename from version rename to version.md From 27290cf81db1e25f53b839ff240c019c317cff5f Mon Sep 17 00:00:00 2001 From: David Demelier Date: Tue, 23 Apr 2019 11:02:28 +0200 Subject: [PATCH 124/410] Use version.md in dev.makefile --- dev.makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev.makefile b/dev.makefile index 7e4b3fb78..159af172a 100644 --- a/dev.makefile +++ b/dev.makefile @@ -1,6 +1,6 @@ # This is only for jsoncpp developers/contributors. # We use this to sign releases, generate documentation, etc. -VER?=$(shell cat version) +VER?=$(shell cat version.md) default: @echo "VER=${VER}" From 5b91551f3944d69e0090d6b6528852207de78078 Mon Sep 17 00:00:00 2001 From: David Demelier Date: Tue, 23 Apr 2019 11:12:23 +0200 Subject: [PATCH 125/410] Rename version.md to version.txt --- dev.makefile | 2 +- version.md => version.txt | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename version.md => version.txt (100%) diff --git a/dev.makefile b/dev.makefile index 159af172a..1a4be6a91 100644 --- a/dev.makefile +++ b/dev.makefile @@ -1,6 +1,6 @@ # This is only for jsoncpp developers/contributors. # We use this to sign releases, generate documentation, etc. -VER?=$(shell cat version.md) +VER?=$(shell cat version.txt) default: @echo "VER=${VER}" diff --git a/version.md b/version.txt similarity index 100% rename from version.md rename to version.txt From 0155f38b5b6b8e8d2b5806df0729cb3663ee1070 Mon Sep 17 00:00:00 2001 From: Olivier LIESS Date: Mon, 3 Jun 2019 12:39:50 +0200 Subject: [PATCH 126/410] added cmake config version file for proper cmake delivery --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a99243798..4c910af85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,9 +168,15 @@ if(JSONCPP_WITH_PKGCONFIG_SUPPORT) endif() if(JSONCPP_WITH_CMAKE_PACKAGE) + include (CMakePackageConfigHelpers) install(EXPORT jsoncpp DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp FILE jsoncppConfig.cmake) + write_basic_package_version_file ("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) endif() if(JSONCPP_WITH_TESTS) From 8d2095af3c503f009d8f447e40ae1e2dbdec1408 Mon Sep 17 00:00:00 2001 From: Olivier LIESS Date: Mon, 3 Jun 2019 12:35:14 +0200 Subject: [PATCH 127/410] cmake fixes --- CMakeLists.txt | 28 +++++++++++----------------- src/jsontestrunner/CMakeLists.txt | 2 +- src/lib_json/CMakeLists.txt | 4 ++-- src/lib_json/version.h.in | 14 +++++++------- src/test_lib_json/CMakeLists.txt | 2 +- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a99243798..c8bd6a101 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,6 @@ project(JSONCPP VERSION 1.9.0 # [.[.[.]]] LANGUAGES CXX) -set( JSONCPP_VERSION ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH} ) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") set( JSONCPP_SOVERSION 21 ) @@ -88,12 +87,7 @@ include(GNUInstallDirs) set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build") -# Set variable named ${VAR_NAME} to value ${VALUE} -function(set_using_dynamic_name VAR_NAME VALUE) - set( "${VAR_NAME}" "${VALUE}" PARENT_SCOPE) -endfunction() - -set( JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) +set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) # File version.h is only regenerated on CMake configure step configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" @@ -107,11 +101,11 @@ macro(UseCompilationWarningAsError) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # warnings when compiled in release configuration. - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") + add_compile_options($<$:/WX>) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + add_compile_options(-Werror) if(JSONCPP_WITH_STRICT_ISO) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") + add_compile_options(-pedantic-errors) endif() endif() endmacro() @@ -122,29 +116,29 @@ include_directories( ${jsoncpp_SOURCE_DIR}/include ) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") + add_compile_options($<$:/W4>) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") + add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") + add_compile_options(-Wall -Wconversion -Wshadow -Wextra) # not yet ready for -Wsign-conversion if(JSONCPP_WITH_STRICT_ISO) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + add_compile_options(-pedantic) endif() if(JSONCPP_WITH_WARNING_AS_ERROR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") + add_compile_options(-Werror=conversion) endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") + add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + add_compile_options(-pedantic) endif() endif() diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 4ca09094d..cb8ce50eb 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -5,7 +5,7 @@ add_executable(jsontestrunner_exe ) if(BUILD_SHARED_LIBS) - add_definitions( -DJSON_DLL ) + add_compile_definitions( -DJSON_DLL ) endif() target_link_libraries(jsontestrunner_exe jsoncpp_lib) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index fc4e7a08f..a8d07331f 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -34,7 +34,7 @@ endif() if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) message(WARNING "Locale functionality is not supported") - add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) + add_compile_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) endif() set( JSONCPP_INCLUDE_DIR ../../include ) @@ -68,7 +68,7 @@ else(JSONCPP_WITH_CMAKE_PACKAGE) endif() if(BUILD_SHARED_LIBS) - add_definitions( -DJSON_DLL_BUILD ) + add_compile_definitions( -DJSON_DLL_BUILD ) endif() diff --git a/src/lib_json/version.h.in b/src/lib_json/version.h.in index 47aac69bd..911a66bba 100644 --- a/src/lib_json/version.h.in +++ b/src/lib_json/version.h.in @@ -1,14 +1,14 @@ // DO NOT EDIT. This file (and "version") is generated by CMake. // Run CMake configure step to update it. #ifndef JSON_VERSION_H_INCLUDED -# define JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED -# define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" -# define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ -# define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ -# define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ -# define JSONCPP_VERSION_QUALIFIER -# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) +#define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" +#define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ +#define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ +#define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) #ifdef JSONCPP_USING_SECURE_MEMORY #undef JSONCPP_USING_SECURE_MEMORY diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 8a3970fc0..999d3e8b5 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable( jsoncpp_test if(BUILD_SHARED_LIBS) - add_definitions( -DJSON_DLL ) + add_compile_definitions( -DJSON_DLL ) endif() target_link_libraries(jsoncpp_test jsoncpp_lib) From 1234f4227b8c5068100d60bdb6ab10c858cbed2b Mon Sep 17 00:00:00 2001 From: Abigail Bunyan Date: Mon, 3 Jun 2019 15:04:01 +0100 Subject: [PATCH 128/410] Add missing classes to forwards.h Fixes #904. --- include/json/forwards.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/json/forwards.h b/include/json/forwards.h index 70bbe191c..958b5bcc8 100644 --- a/include/json/forwards.h +++ b/include/json/forwards.h @@ -13,11 +13,17 @@ namespace Json { // writer.h +class StreamWriter; +class StreamWriterBuilder; +class Writer; class FastWriter; class StyledWriter; +class StyledStreamWriter; // reader.h class Reader; +class CharReader; +class CharReaderBuilder; // features.h class Features; From 85f5b1c8f90cda5afd15cdcd01c825815e7fbe04 Mon Sep 17 00:00:00 2001 From: Olivier LIESS Date: Mon, 3 Jun 2019 16:28:56 +0200 Subject: [PATCH 129/410] fixed typos --- src/jsontestrunner/CMakeLists.txt | 2 +- src/lib_json/CMakeLists.txt | 4 ++-- src/test_lib_json/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index cb8ce50eb..023a44e64 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -5,7 +5,7 @@ add_executable(jsontestrunner_exe ) if(BUILD_SHARED_LIBS) - add_compile_definitions( -DJSON_DLL ) + add_compile_definitions( JSON_DLL ) endif() target_link_libraries(jsontestrunner_exe jsoncpp_lib) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index a8d07331f..034f43864 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -34,7 +34,7 @@ endif() if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) message(WARNING "Locale functionality is not supported") - add_compile_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) + add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT) endif() set( JSONCPP_INCLUDE_DIR ../../include ) @@ -68,7 +68,7 @@ else(JSONCPP_WITH_CMAKE_PACKAGE) endif() if(BUILD_SHARED_LIBS) - add_compile_definitions( -DJSON_DLL_BUILD ) + add_compile_definitions( JSON_DLL_BUILD ) endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 999d3e8b5..a8740daee 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable( jsoncpp_test if(BUILD_SHARED_LIBS) - add_compile_definitions( -DJSON_DLL ) + add_compile_definitions( JSON_DLL ) endif() target_link_libraries(jsoncpp_test jsoncpp_lib) From 83cc92161be96d7f2113a3ec9f62109d828e1eec Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 6 Jun 2019 13:41:47 -0700 Subject: [PATCH 130/410] Fix JSON_USE_EXCEPTION=0 use case This patch fixes the JSON_USE_EXCEPTION flag. Currently, due to the throwRuntimeError and throwLogicError methods implemented in json_value, even if JSON_USE_EXCEPTION is set to 0 jsoncpp will still throw. This breaks integration into projects with -fno-exceptions set, such as Chromium. --- include/json/value.h | 2 ++ src/lib_json/json_value.cpp | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 5f8d21444..06d89ae39 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -50,6 +50,7 @@ */ namespace Json { +#if JSON_USE_EXCEPTION /** Base class for all exceptions we throw. * * We use nothing but these internally. Of course, STL can throw others. @@ -85,6 +86,7 @@ class JSON_API LogicError : public Exception { public: LogicError(String const& msg); }; +#endif /// used internally JSONCPP_NORETURN void throwRuntimeError(String const& msg); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index b046c1939..cc92d444a 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -226,6 +226,7 @@ static inline void releaseStringValue(char* value, unsigned) { free(value); } namespace Json { +#if JSON_USE_EXCEPTION Exception::Exception(String msg) : msg_(std::move(msg)) {} Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } @@ -237,6 +238,14 @@ JSONCPP_NORETURN void throwRuntimeError(String const& msg) { JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } +# else // !JSON_USE_EXCEPTION +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { + abort(); +} +JSONCPP_NORETURN void throwLogicError(String const& msg) { + abort(); +} +#endif // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// From 518875d2ea71db4f9d6f3418dd5218dd1ae04f01 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 13:32:20 -0700 Subject: [PATCH 131/410] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 5747e61c1..77c1d2d94 100644 --- a/AUTHORS +++ b/AUTHORS @@ -57,6 +57,7 @@ Iñaki Baz Castillo Jacco Jean-Christophe Fillion-Robin Jonas Platte +Jordan Bayles Jörg Krause Keith Lea Kevin Grant From 185dfd592d92d523971ea059edc6c34a9be9b5e3 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 13:38:00 -0700 Subject: [PATCH 132/410] Update meson build requirement Currently, we have a build type warning due to listing a requirement for meson build version that doesn't implement features we use in our build file. The minimum meson build version required is actually 0.50.0, so this PR updates our meson.build file to depend on 0.50.0. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 106e17f6a..ece8aa4d5 100644 --- a/meson.build +++ b/meson.build @@ -7,7 +7,7 @@ project( 'cpp_std=c++11', 'warning_level=1'], license : 'Public Domain', - meson_version : '>= 0.41.1') + meson_version : '>= 0.50.0') jsoncpp_ver_arr = meson.project_version().split('.') jsoncpp_major_version = jsoncpp_ver_arr[0] From 12461e5bf1ccc9886f95d58aac211c3e9404bcac Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 13:53:55 -0700 Subject: [PATCH 133/410] Create CONTRIBUTING.md --- CONTRIBUTING.md | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..40090df91 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,113 @@ +# Contributing to JsonCpp + +## Building + +Both CMake and Meson tools are capable of generating a variety of build environments for you preferred development environment. +Using cmake or meson you can generate an XCode, Visual Studio, Unix Makefile, Ninja, or other environment that fits your needs. + +An example of a common Meson/Ninja environment is described next. + +## Building and testing with Meson/Ninja +Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use +[meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build +for debugging, as well as for continuous integration (see +[`./travis_scripts/meson_builder.sh`](./travis_scripts/meson_builder.sh) ). Other systems may work, but minor +things like version strings might break. + +First, install both meson (which requires Python3) and ninja. +If you wish to install to a directory other than /usr/local, set an environment variable called DESTDIR with the desired path: + DESTDIR=/path/to/install/dir + +Then, + + cd jsoncpp/ + BUILD_TYPE=debug + #BUILD_TYPE=release + LIB_TYPE=shared + #LIB_TYPE=static + meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} + #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. + ninja -v -C build-${LIB_TYPE} + cd build-${LIB_TYPE} + meson test --no-rebuild --print-errorlogs + sudo ninja install + +## Building and testing with other build systems +See https://github.com/open-source-parsers/jsoncpp/wiki/Building + +## Running the tests manually + +You need to run tests manually only if you are troubleshooting an issue. + +In the instructions below, replace `path/to/jsontest` with the path of the +`jsontest` executable that was compiled on your platform. + + cd test + # This will run the Reader/Writer tests + python runjsontests.py path/to/jsontest + + # This will run the Reader/Writer tests, using JSONChecker test suite + # (http://www.json.org/JSON_checker/). + # Notes: not all tests pass: JsonCpp is too lenient (for example, + # it allows an integer to start with '0'). The goal is to improve + # strict mode parsing to get all tests to pass. + python runjsontests.py --with-json-checker path/to/jsontest + + # This will run the unit tests (mostly Value) + python rununittests.py path/to/test_lib_json + + # You can run the tests using valgrind: + python rununittests.py --valgrind path/to/test_lib_json + +## Building the documentation + +Run the Python script `doxybuild.py` from the top directory: + + python doxybuild.py --doxygen=$(which doxygen) --open --with-dot + +See `doxybuild.py --help` for options. + +## Adding a reader/writer test + +To add a test, you need to create two files in test/data: + +* a `TESTNAME.json` file, that contains the input document in JSON format. +* a `TESTNAME.expected` file, that contains a flatened representation of the + input document. + +The `TESTNAME.expected` file format is as follows: + +* Each line represents a JSON element of the element tree represented by the + input document. +* Each line has two parts: the path to access the element separated from the + element value by `=`. Array and object values are always empty (i.e. + represented by either `[]` or `{}`). +* Element path `.` represents the root element, and is used to separate object + members. `[N]` is used to specify the value of an array element at index `N`. + +See the examples `test_complex_01.json` and `test_complex_01.expected` to better understand element paths. + +## Understanding reader/writer test output + +When a test is run, output files are generated beside the input test files. Below is a short description of the content of each file: + +* `test_complex_01.json`: input JSON document. +* `test_complex_01.expected`: flattened JSON element tree used to check if + parsing was corrected. +* `test_complex_01.actual`: flattened JSON element tree produced by `jsontest` + from reading `test_complex_01.json`. +* `test_complex_01.rewrite`: JSON document written by `jsontest` using the + `Json::Value` parsed from `test_complex_01.json` and serialized using + `Json::StyledWritter`. +* `test_complex_01.actual-rewrite`: flattened JSON element tree produced by + `jsontest` from reading `test_complex_01.rewrite`. +* `test_complex_01.process-output`: `jsontest` output, typically useful for + understanding parsing errors. + +## Versioning rules + +Consumers of this library require a strict approach to incrementing versioning of the JsonCpp library. Currently, we follow the below set of rules: + +* Any new public symbols require a minor version bump. +* Any alteration or removal of public symbols requires a major version bump, including changing the size of a class. This is necessary for +consumers to do dependency injection properly. From be4dc51c1fb270a014ab75b4fdbf4a791ee4af1a Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 13:54:28 -0700 Subject: [PATCH 134/410] Update README.md Separate contributing guidelines into their own separate documentation. --- README.md | 105 ------------------------------------------------------ 1 file changed, 105 deletions(-) diff --git a/README.md b/README.md index 2e6409291..8c8587060 100644 --- a/README.md +++ b/README.md @@ -28,111 +28,6 @@ format to store user input files. * `0.y.z` can be used with older compilers. * Major versions maintain binary-compatibility. -## Contributing to JsonCpp - -### Building - -Both CMake and Meson tools are capable of generating a variety of build environments for you preferred development environment. -Using cmake or meson you can generate an XCode, Visual Studio, Unix Makefile, Ninja, or other environment that fits your needs. - -An example of a common Meson/Ninja environment is described next. - -### Building and testing with Meson/Ninja -Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use -[meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build -for debugging, as well as for continuous integration (see -[`./travis_scripts/meson_builder.sh`](./travis_scripts/meson_builder.sh) ). Other systems may work, but minor -things like version strings might break. - -First, install both meson (which requires Python3) and ninja. -If you wish to install to a directory other than /usr/local, set an environment variable called DESTDIR with the desired path: - DESTDIR=/path/to/install/dir - -Then, - - cd jsoncpp/ - BUILD_TYPE=debug - #BUILD_TYPE=release - LIB_TYPE=shared - #LIB_TYPE=static - meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} - #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. - ninja -v -C build-${LIB_TYPE} - cd build-${LIB_TYPE} - meson test --no-rebuild --print-errorlogs - sudo ninja install - -### Building and testing with other build systems -See https://github.com/open-source-parsers/jsoncpp/wiki/Building - -### Running the tests manually - -You need to run tests manually only if you are troubleshooting an issue. - -In the instructions below, replace `path/to/jsontest` with the path of the -`jsontest` executable that was compiled on your platform. - - cd test - # This will run the Reader/Writer tests - python runjsontests.py path/to/jsontest - - # This will run the Reader/Writer tests, using JSONChecker test suite - # (http://www.json.org/JSON_checker/). - # Notes: not all tests pass: JsonCpp is too lenient (for example, - # it allows an integer to start with '0'). The goal is to improve - # strict mode parsing to get all tests to pass. - python runjsontests.py --with-json-checker path/to/jsontest - - # This will run the unit tests (mostly Value) - python rununittests.py path/to/test_lib_json - - # You can run the tests using valgrind: - python rununittests.py --valgrind path/to/test_lib_json - -### Building the documentation - -Run the Python script `doxybuild.py` from the top directory: - - python doxybuild.py --doxygen=$(which doxygen) --open --with-dot - -See `doxybuild.py --help` for options. - -### Adding a reader/writer test - -To add a test, you need to create two files in test/data: - -* a `TESTNAME.json` file, that contains the input document in JSON format. -* a `TESTNAME.expected` file, that contains a flatened representation of the - input document. - -The `TESTNAME.expected` file format is as follows: - -* Each line represents a JSON element of the element tree represented by the - input document. -* Each line has two parts: the path to access the element separated from the - element value by `=`. Array and object values are always empty (i.e. - represented by either `[]` or `{}`). -* Element path `.` represents the root element, and is used to separate object - members. `[N]` is used to specify the value of an array element at index `N`. - -See the examples `test_complex_01.json` and `test_complex_01.expected` to better understand element paths. - -### Understanding reader/writer test output - -When a test is run, output files are generated beside the input test files. Below is a short description of the content of each file: - -* `test_complex_01.json`: input JSON document. -* `test_complex_01.expected`: flattened JSON element tree used to check if - parsing was corrected. -* `test_complex_01.actual`: flattened JSON element tree produced by `jsontest` - from reading `test_complex_01.json`. -* `test_complex_01.rewrite`: JSON document written by `jsontest` using the - `Json::Value` parsed from `test_complex_01.json` and serialized using - `Json::StyledWritter`. -* `test_complex_01.actual-rewrite`: flattened JSON element tree produced by - `jsontest` from reading `test_complex_01.rewrite`. -* `test_complex_01.process-output`: `jsontest` output, typically useful for - understanding parsing errors. ## Using JsonCpp in your project From f7182a0fdc72404a9722388f1d59adecef8d93d6 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 14:05:18 -0700 Subject: [PATCH 135/410] Update CONTRIBUTING.md Added style information. --- CONTRIBUTING.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 40090df91..b7e4ab7af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -111,3 +111,35 @@ Consumers of this library require a strict approach to incrementing versioning o * Any new public symbols require a minor version bump. * Any alteration or removal of public symbols requires a major version bump, including changing the size of a class. This is necessary for consumers to do dependency injection properly. + +## Preparing code for submission + +Generally, JsonCpp's style guide has been pretty relaxed, with the following common themes: + +* Variables and function names use lower camel case (E.g. parseValue or collectComments). +* Class use camel case (e.g. OurReader) +* Member variables have a trailing underscore +* Prefer `nullptr` over `NULL`. +* Passing by non-const reference is allowed. +* Single statement if blocks may omit brackets. +* Generally prefer less space over more space. + +For an example: + +```c++ +bool Reader::decodeNumber(Token& token) { + Value decoded; + if (!decodeNumber(token, decoded)) + return false; + currentValue().swapPayload(decoded); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} +``` + +Before submitting your code, ensure that you meet the versioning requirements above, follow the style guide of the file you are modifying (or the above rules for new files), and run clang format. Meson exposes clang format with the following command: + +``` +ninja -v -C build-${LIB_TYPE}/ clang-format +``` From d5bd1a771631950264f65a01b9c4255f0f2324a6 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 14:06:45 -0700 Subject: [PATCH 136/410] Run clang format Clang format hasn't been run on some recent checkins. This patch updates the repository with clang format properly run on all files. --- include/json/config.h | 5 +++-- include/json/value.h | 4 +++- src/lib_json/json_value.cpp | 13 ++++--------- src/test_lib_json/main.cpp | 9 ++++++--- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index cba610293..eca9e8c45 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -108,8 +108,9 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) -#endif // GNUC version -#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates MSVC) +#endif // GNUC version +#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates + // MSVC) #define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) #endif // __clang__ || __GNUC__ || _MSC_VER diff --git a/include/json/value.h b/include/json/value.h index 06d89ae39..59bae07da 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -612,7 +612,9 @@ Json::Value obj_value(Json::objectValue); // {} ptrdiff_t getOffsetLimit() const; private: - void setType(ValueType v) { bits_.value_type_ = static_cast (v); } + void setType(ValueType v) { + bits_.value_type_ = static_cast(v); + } bool isAllocated() const { return bits_.allocated_; } void setIsAllocated(bool v) { bits_.allocated_ = v; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index cc92d444a..c0840ebc7 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -238,13 +238,9 @@ JSONCPP_NORETURN void throwRuntimeError(String const& msg) { JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } -# else // !JSON_USE_EXCEPTION -JSONCPP_NORETURN void throwRuntimeError(String const& msg) { - abort(); -} -JSONCPP_NORETURN void throwLogicError(String const& msg) { - abort(); -} +#else // !JSON_USE_EXCEPTION +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { abort(); } +JSONCPP_NORETURN void throwLogicError(String const& msg) { abort(); } #endif // ////////////////////////////////////////////////////////////////// @@ -1445,8 +1441,7 @@ bool Value::isObject() const { return type() == objectValue; } Value::Comments::Comments(const Comments& that) : ptr_{cloneUnique(that.ptr_)} {} -Value::Comments::Comments(Comments&& that) - : ptr_{std::move(that.ptr_)} {} +Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {} Value::Comments& Value::Comments::operator=(const Comments& that) { ptr_ = cloneUnique(that.ptr_); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 280f7eac6..10e1ca9fc 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -211,14 +211,17 @@ JSONTEST_FIXTURE(ValueTest, objects) { JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId); const char unknownIdKey[] = "unknown id"; - const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); + const Json::Value* foundUnknownId = + object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); // Access through demand() const char yetAnotherIdKey[] = "yet another id"; - const Json::Value* foundYetAnotherId = object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); + const Json::Value* foundYetAnotherId = + object1_.find(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundYetAnotherId); - Json::Value* demandedYetAnotherId = object1_.demand(yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); + Json::Value* demandedYetAnotherId = object1_.demand( + yetAnotherIdKey, yetAnotherIdKey + strlen(yetAnotherIdKey)); JSONTEST_ASSERT(demandedYetAnotherId != nullptr); *demandedYetAnotherId = "baz"; From 18e51e23fd4dcbdfb6e348d93548e03bcdd4c7ba Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 14:38:38 -0700 Subject: [PATCH 137/410] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..dd84ea782 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..bbcbbe7d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 2d211de06e387c9c4f30f602c00ba6c6fac3d376 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 14:40:08 -0700 Subject: [PATCH 138/410] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea782..35477097a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -12,27 +12,15 @@ A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error +1. **Expected behavior** A clear and concise description of what you expected to happen. -**Screenshots** -If applicable, add screenshots to help explain your problem. - **Desktop (please complete the following information):** - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] + - Meson version + - Ninja version **Additional context** Add any other context about the problem here. From 408b466b57f4cf0744c2ab3de1c700dc83fc24fc Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Tue, 25 Jun 2019 14:27:26 -0700 Subject: [PATCH 139/410] Modernize Travis and Appveyor configs This PR updates the Travis and Appveyor configs to use more recent toolchain versions, allowing for better C++11 compliance. --- .travis.yml | 50 +++++++++++++++++++------------------------------- appveyor.yml | 12 +++++++----- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/.travis.yml b/.travis.yml index fe71962ae..13f32cc18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,9 @@ # Build matrix / environment variables are explained on: # http://about.travis-ci.org/docs/user/build-configuration/ -# This file can be validated on: -# http://lint.travis-ci.org/ -# See also -# http://stackoverflow.com/questions/22111549/travis-ci-with-clang-3-4-and-c11/30925448#30925448 -# to allow C++11, though we are not yet building with -std=c++11 +# This file can be validated on: http://www.yamllint.com/ +# Or using the Ruby based travel command line tool: +# gem install travis --no-rdoc --no-ri +# travis lint .travis.yml language: cpp sudo: false addons: @@ -15,12 +14,10 @@ addons: update: false # do not update homebrew by default apt: sources: - #- ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.5 + - ubuntu-toolchain-r-test + - llvm-toolchain-xenial-8 packages: - #- gcc-4.9 - #- g++-4.9 - - clang-3.5 + - clang-8 - valgrind matrix: allow_failures: @@ -28,21 +25,21 @@ matrix: include: - name: Mac clang meson static release testing os: osx - osx_image: xcode9.4 + osx_image: xcode10.2 compiler: clang - env: - CXX="clang++-3.5" - CC="clang-3.5" + env: + CXX="clang++" + CC="clang" LIB_TYPE=static BUILD_TYPE=release script: ./.travis_scripts/meson_builder.sh - - name: trusty clang meson static release testing + - name: xenial clang meson static release testing os: linux - dist: trusty + dist: xenial compiler: clang - env: - CXX="clang++-3.5" - CC="clang-3.5" + env: + CXX="clang++" + CC="clang" LIB_TYPE=static BUILD_TYPE=release # before_install and install steps only needed for linux meson builds @@ -55,23 +52,14 @@ matrix: os: linux dist: xenial compiler: gcc - env: + env: CXX=g++ CC=gcc DO_Coverage=ON BUILD_TOOL="Unix Makefiles" - BUILD_TYPE=Debug - LIB_TYPE=shared + BUILD_TYPE=Debug + LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp script: ./.travis_scripts/cmake_builder.sh -# Valgrind has too many false positives from the python wrapping. Need a good suppression file -# - name: xenial gcc cmake coverage -# os: linux -# dist: xenial -# compiler: gcc -# env: DO_MemCheck=ON CXX=/usr/bin/g++ BUILD_TOOL="Unix Makefiles" BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp -# script: ./.travis_scripts/cmake_builder.sh notifications: email: false - - diff --git a/appveyor.yml b/appveyor.yml index 447a2121f..daaaeefad 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,19 +2,21 @@ clone_folder: c:\projects\jsoncpp environment: matrix: - - CMAKE_GENERATOR: Visual Studio 12 2013 - - CMAKE_GENERATOR: Visual Studio 12 2013 Win64 - CMAKE_GENERATOR: Visual Studio 14 2015 - CMAKE_GENERATOR: Visual Studio 14 2015 Win64 + - CMAKE_GENERATOR: Visual Studio 15 2017 + - CMAKE_GENERATOR: Visual Studio 15 2017 Win64 build_script: - cmake --version - cd c:\projects\jsoncpp - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX:PATH=%CD:\=/%/install -DBUILD_SHARED_LIBS:BOOL=ON . - # Use ctest to make a dashboard build ctest -D Experimental(Start|Update|Configure|Build|Test|Coverage|MemCheck|Submit) - #NOTE Testing on window is not yet finished - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalTest -D ExperimentalSubmit + # Use ctest to make a dashboard build: + # - ctest -D Experimental(Start|Update|Configure|Build|Test|Coverage|MemCheck|Submit) + # NOTE: Testing on window is not yet finished: + # - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalTest -D ExperimentalSubmit - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalSubmit - # Final step is to verify that installation succeeds + # Final step is to verify that installation succeeds - cmake --build . --config Release --target install deploy: From c84f2e19c9514c22dfcb3e52c004b62ccb77deb9 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Tue, 25 Jun 2019 14:40:55 -0700 Subject: [PATCH 140/410] Update travis scripts --- .travis_scripts/cmake_builder.sh | 12 ++++++------ .travis_scripts/travis.before_install.linux.sh | 9 +++++---- .travis_scripts/travis.before_install.osx.sh | 4 ---- .travis_scripts/travis.install.linux.sh | 2 +- .travis_scripts/travis.install.osx.sh | 4 ---- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/.travis_scripts/cmake_builder.sh b/.travis_scripts/cmake_builder.sh index c0118782c..ccb33312e 100755 --- a/.travis_scripts/cmake_builder.sh +++ b/.travis_scripts/cmake_builder.sh @@ -12,10 +12,10 @@ # Optional environmental variables # - DESTDIR <- used for setting the install prefix # - BUILD_TOOL=["Unix Makefile"|"Ninja"] -# - BUILDNAME <-- how to identify this build on the dashboard +# - BUILDNAME <- how to identify this build on the dashboard # - DO_MemCheck <- if set, try to use valgrind -# - DO_Coverage <- if set, try to do dashboard coverage testing -# +# - DO_Coverage <- if set, try to do dashboard coverage testing +# env_set=1 if ${BUILD_TYPE+false}; then @@ -78,7 +78,7 @@ if ! ${DO_MemCheck+false}; then valgrind --version CTEST_TESTING_OPTION="-D ExperimentalMemCheck" else -# - DO_Coverage <- if set, try to do dashboard coverage testing +# - DO_Coverage <- if set, try to do dashboard coverage testing if ! ${DO_Coverage+false}; then export CXXFLAGS="-fprofile-arcs -ftest-coverage" export LDFLAGS="-fprofile-arcs -ftest-coverage" @@ -117,14 +117,14 @@ cd "${_BUILD_DIR_NAME}" ctest -C ${BUILD_TYPE} -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild ${CTEST_TESTING_OPTION} -D ExperimentalSubmit # Final step is to verify that installation succeeds cmake --build . --config ${BUILD_TYPE} --target install - + if [ "${DESTDIR}" != "/usr/local" ]; then ${_BUILD_EXE} install fi cd - if ${CLEANUP+false}; then - echo "Skipping cleanup: build directory will persist." + echo "Skipping cleanup: build directory will persist." else rm -r "${_BUILD_DIR_NAME}" fi diff --git a/.travis_scripts/travis.before_install.linux.sh b/.travis_scripts/travis.before_install.linux.sh index 18e019d84..9b556de15 100644 --- a/.travis_scripts/travis.before_install.linux.sh +++ b/.travis_scripts/travis.before_install.linux.sh @@ -1,7 +1,8 @@ set -vex -#before_install: pyenv install 3.5.4 && pyenv global 3.5.4 -#before_install: pyenv global 3.6 + +# Preinstalled versions of python are dependent on which Ubuntu distribution +# you are running. The below version needs to be updated whenever we roll +# the Ubuntu version used in Travis. # https://docs.travis-ci.com/user/languages/python/ -# "for Trusty, this means 2.7.6 and 3.4.3" -pyenv global 3.6 +pyenv global 3.7.1 diff --git a/.travis_scripts/travis.before_install.osx.sh b/.travis_scripts/travis.before_install.osx.sh index d7d11a54e..5d83c0c71 100644 --- a/.travis_scripts/travis.before_install.osx.sh +++ b/.travis_scripts/travis.before_install.osx.sh @@ -1,5 +1 @@ # NOTHING TO DO HERE -# set -vex - -#brew install pyenv -#which pyenv diff --git a/.travis_scripts/travis.install.linux.sh b/.travis_scripts/travis.install.linux.sh index 84c3a6199..7c5846f1a 100644 --- a/.travis_scripts/travis.install.linux.sh +++ b/.travis_scripts/travis.install.linux.sh @@ -1,6 +1,6 @@ set -vex -wget https://github.com/ninja-build/ninja/releases/download/v1.7.2/ninja-linux.zip +wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip unzip -q ninja-linux.zip -d build pip3 install meson diff --git a/.travis_scripts/travis.install.osx.sh b/.travis_scripts/travis.install.osx.sh index 1c6c6f0e1..5d83c0c71 100644 --- a/.travis_scripts/travis.install.osx.sh +++ b/.travis_scripts/travis.install.osx.sh @@ -1,5 +1 @@ # NOTHING TO DO HERE -# set -vex - -#python3 -m venv venv -#source venv/bin/activate From 2690bc9a9a9c7b3c80a886948321bc44cfde7654 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Tue, 25 Jun 2019 14:48:40 -0700 Subject: [PATCH 141/410] Update appveyor to use build images --- .travis.yml | 4 ++-- appveyor.yml | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 13f32cc18..b649b4633 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ matrix: LIB_TYPE=static BUILD_TYPE=release script: ./.travis_scripts/meson_builder.sh - - name: xenial clang meson static release testing + - name: Linux xenial clang meson static release testing os: linux dist: xenial compiler: clang @@ -48,7 +48,7 @@ matrix: install: - source ./.travis_scripts/travis.install.${TRAVIS_OS_NAME}.sh script: ./.travis_scripts/meson_builder.sh - - name: xenial gcc cmake coverage + - name: Linux xenial gcc cmake coverage os: linux dist: xenial compiler: gcc diff --git a/appveyor.yml b/appveyor.yml index daaaeefad..0b9c8fe3f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,10 +2,14 @@ clone_folder: c:\projects\jsoncpp environment: matrix: - - CMAKE_GENERATOR: Visual Studio 14 2015 - - CMAKE_GENERATOR: Visual Studio 14 2015 Win64 - - CMAKE_GENERATOR: Visual Studio 15 2017 - - CMAKE_GENERATOR: Visual Studio 15 2017 Win64 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + CMAKE_GENERATOR: Visual Studio 14 2015 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + CMAKE_GENERATOR: Visual Studio 14 2015 Win64 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + CMAKE_GENERATOR: Visual Studio 15 2017 + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + CMAKE_GENERATOR: Visual Studio 15 2017 Win64 build_script: - cmake --version From dd6921f479414ff1f63fc64f0c697afe3c5c3d9c Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 28 May 2018 12:45:01 -0400 Subject: [PATCH 142/410] Add WideString test for Issue #756 --- src/test_lib_json/main.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 10e1ca9fc..550b9c7e2 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -1644,6 +1646,28 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { } } +JSONTEST_FIXTURE(ValueTest, WideString) { + // https://github.com/open-source-parsers/jsoncpp/issues/756 + const std::string uni = u8"式,进"; // "\u5f0f\uff0c\u8fdb" + std::string styled; + { + Json::Value v; + v["abc"] = uni; + styled = v.toStyledString(); + } + Json::Value root; + { + JSONCPP_STRING errs; + std::istringstream iss(styled); + bool ok = parseFromStream(Json::CharReaderBuilder(), iss, &root, &errs); + JSONTEST_ASSERT(ok); + if (!ok) { + std::cerr << "errs: " << errs << std::endl; + } + } + JSONTEST_ASSERT_STRING_EQUAL(root["abc"].asString(), uni); +} + JSONTEST_FIXTURE(ValueTest, CommentBefore) { Json::Value val; // fill val val.setComment(Json::String("// this comment should appear before"), @@ -2556,6 +2580,7 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString); + JSONTEST_REGISTER_FIXTURE(runner, ValueTest, WideString); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore); // JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes); From d34479ec3465667600f82ae3be7c0d20e840c670 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 24 Jun 2019 14:48:59 -0700 Subject: [PATCH 143/410] Issue 920: Fix android build with casting fix This patch removes an unchecked conversion from a 64bit wide type to a 32bit wide type, fixing a compile error on some platforms. Issue:920 --- src/lib_json/json_reader.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 05b238a90..23167637a 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1905,11 +1905,10 @@ CharReader* CharReaderBuilder::newCharReader() const { settings_["allowDroppedNullPlaceholders"].asBool(); features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); -#if defined(JSON_HAS_INT64) - features.stackLimit_ = settings_["stackLimit"].asUInt64(); -#else - features.stackLimit_ = settings_["stackLimit"].asUInt(); -#endif + + // Stack limit is always a size_t, so we get this as an unsigned int + // regardless of it we have 64-bit integer support enabled. + features.stackLimit_ = static_cast(settings_["stackLimit"].asUInt()); features.failIfExtra_ = settings_["failIfExtra"].asBool(); features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); From 5510f14a71fab7d7307815c4097e30cfef84f329 Mon Sep 17 00:00:00 2001 From: chenguoping Date: Fri, 31 May 2019 14:16:48 +0800 Subject: [PATCH 144/410] repair a typo error --- src/lib_json/json_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 23167637a..abe3de9d8 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -840,7 +840,7 @@ bool Reader::pushError(const Value& value, const String& message) { Token token; token.type_ = tokenError; token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); + token.end_ = begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; @@ -1845,7 +1845,7 @@ bool OurReader::pushError(const Value& value, const String& message) { Token token; token.type_ = tokenError; token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); + token.end_ = begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; From b7feb2d493eade984f097d0e42cb190db542c1d0 Mon Sep 17 00:00:00 2001 From: cmlchen Date: Fri, 21 Jun 2019 09:40:33 +0800 Subject: [PATCH 145/410] use fpclassify to test a float number is zero or nan --- src/lib_json/json_value.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index c0840ebc7..6752fa2da 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -853,8 +853,8 @@ bool Value::asBool() const { case uintValue: return value_.uint_ ? true : false; case realValue: - // This is kind of strange. Not recommended. - return (value_.real_ != 0.0) ? true : false; + // According to JavaScript language zero or NaN is regarded as false + return std::fpclassify(value_.real_) != FP_ZERO && std::fpclassify(value_.real_) != FP_NAN default: break; } From 7c7ccbf9349066b930fd6f6d55b2f735ec5381bf Mon Sep 17 00:00:00 2001 From: cmlchen Date: Fri, 21 Jun 2019 10:23:20 +0800 Subject: [PATCH 146/410] fix compile problem --- src/lib_json/json_value.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6752fa2da..b6f41de34 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -854,7 +854,7 @@ bool Value::asBool() const { return value_.uint_ ? true : false; case realValue: // According to JavaScript language zero or NaN is regarded as false - return std::fpclassify(value_.real_) != FP_ZERO && std::fpclassify(value_.real_) != FP_NAN + return std::fpclassify(value_.real_) != FP_ZERO && std::fpclassify(value_.real_) != FP_NAN; default: break; } From c51d718ead5b8320dab84d15d5b57d887a7bc81a Mon Sep 17 00:00:00 2001 From: cmlchen Date: Tue, 25 Jun 2019 11:26:29 +0800 Subject: [PATCH 147/410] extract variable --- src/lib_json/json_value.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index b6f41de34..508f18ff7 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -852,9 +852,11 @@ bool Value::asBool() const { return value_.int_ ? true : false; case uintValue: return value_.uint_ ? true : false; - case realValue: - // According to JavaScript language zero or NaN is regarded as false - return std::fpclassify(value_.real_) != FP_ZERO && std::fpclassify(value_.real_) != FP_NAN; + case realValue: { + // According to JavaScript language zero or NaN is regarded as false + const auto value_classification = std::fpclassify(value_.real_); + return value_classification != FP_ZERO && value_classification != FP_NAN; + } default: break; } From 629a727b5f1330322c418457cd730cf459e3d05b Mon Sep 17 00:00:00 2001 From: Olivier LIESS Date: Mon, 3 Jun 2019 12:37:45 +0200 Subject: [PATCH 148/410] version.h : wrong file was deployed, added required include path and --- include/CMakeLists.txt | 6 +++++- include/json/version.h | 22 ---------------------- src/lib_json/CMakeLists.txt | 5 +++-- 3 files changed, 8 insertions(+), 25 deletions(-) delete mode 100644 include/json/version.h diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 7f1cb9822..facfab1c5 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,2 +1,6 @@ file(GLOB INCLUDE_FILES "json/*.h") -install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json) +install(FILES + ${INCLUDE_FILES} + ${PROJECT_BINARY_DIR}/include/json/version.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json) + diff --git a/include/json/version.h b/include/json/version.h deleted file mode 100644 index 027f73173..000000000 --- a/include/json/version.h +++ /dev/null @@ -1,22 +0,0 @@ -// DO NOT EDIT. This file (and "version") is generated by CMake. -// Run CMake configure step to update it. -#ifndef JSON_VERSION_H_INCLUDED -#define JSON_VERSION_H_INCLUDED - -#define JSONCPP_VERSION_STRING "1.8.4" -#define JSONCPP_VERSION_MAJOR 1 -#define JSONCPP_VERSION_MINOR 8 -#define JSONCPP_VERSION_PATCH 4 -#define JSONCPP_VERSION_QUALIFIER -#define JSONCPP_VERSION_HEXA \ - ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ - (JSONCPP_VERSION_PATCH << 8)) - -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif -#define JSONCPP_USING_SECURE_MEMORY 0 -// If non-zero, the library zeroes any memory that it has allocated before -// it frees its memory. - -#endif // JSON_VERSION_H_INCLUDED diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 034f43864..2392092af 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -47,7 +47,7 @@ set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/reader.h ${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h - ${JSONCPP_INCLUDE_DIR}/json/version.h + ${PROJECT_BINARY_DIR}/include/json/version.h ) source_group( "Public API" FILES ${PUBLIC_HEADERS} ) @@ -141,5 +141,6 @@ install( TARGETS jsoncpp_lib ${INSTALL_EXPORT} if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) target_include_directories( jsoncpp_lib PUBLIC $ - $) + $ + $) endif() From 786851819efe52c14114a857faf30b508e537c1b Mon Sep 17 00:00:00 2001 From: Autofuzz team Date: Wed, 12 Jun 2019 16:02:05 +0200 Subject: [PATCH 149/410] Add a simple fuzz test for jsoncpp. --- AUTHORS | 1 + src/test_lib_json/CMakeLists.txt | 2 ++ src/test_lib_json/fuzz.cpp | 49 ++++++++++++++++++++++++++++++++ src/test_lib_json/fuzz.h | 14 +++++++++ src/test_lib_json/main.cpp | 15 ++++++++++ 5 files changed, 81 insertions(+) create mode 100644 src/test_lib_json/fuzz.cpp create mode 100644 src/test_lib_json/fuzz.h diff --git a/AUTHORS b/AUTHORS index 77c1d2d94..3723d546a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -37,6 +37,7 @@ datadiode David Seifert David West dawesc +Devin Jeanpierre Dmitry Marakasov dominicpezzuto Don Milham diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index a8740daee..abb181361 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -3,6 +3,8 @@ add_executable( jsoncpp_test jsontest.cpp jsontest.h + fuzz.cpp + fuzz.h main.cpp ) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp new file mode 100644 index 000000000..8265a17bb --- /dev/null +++ b/src/test_lib_json/fuzz.cpp @@ -0,0 +1,49 @@ +// Copyright 2007-2010 The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#include "fuzz.h" + +#include +#include +#include +#include +#include +#include + +namespace Json { +class Exception; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + Json::CharReaderBuilder builder; + + if (size < sizeof(uint32_t)) { + return 0; + } + + uint32_t hash_settings = *(const uint32_t*)data; + data += sizeof(uint32_t); + + builder.settings_["failIfExtra"] = hash_settings & (1 << 0); + builder.settings_["allowComments_"] = hash_settings & (1 << 1); + builder.settings_["strictRoot_"] = hash_settings & (1 << 2); + builder.settings_["allowDroppedNullPlaceholders_"] = hash_settings & (1 << 3); + builder.settings_["allowNumericKeys_"] = hash_settings & (1 << 4); + builder.settings_["allowSingleQuotes_"] = hash_settings & (1 << 5); + builder.settings_["failIfExtra_"] = hash_settings & (1 << 6); + builder.settings_["rejectDupKeys_"] = hash_settings & (1 << 7); + builder.settings_["allowSpecialFloats_"] = hash_settings & (1 << 8); + + std::unique_ptr reader(builder.newCharReader()); + + Json::Value root; + const char* data_str = reinterpret_cast(data); + try { + reader->parse(data_str, data_str + size, &root, nullptr); + } catch (Json::Exception const&) { + } + // Whether it succeeded or not doesn't matter. + return 0; +} diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h new file mode 100644 index 000000000..f6504377b --- /dev/null +++ b/src/test_lib_json/fuzz.h @@ -0,0 +1,14 @@ +// Copyright 2007-2010 The JsonCpp Authors +// Distributed under MIT license, or public domain if desired and +// recognized in your jurisdiction. +// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE + +#ifndef FUZZ_H_INCLUDED +#define FUZZ_H_INCLUDED + +#include +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); + +#endif // ifndef FUZZ_H_INCLUDED diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 550b9c7e2..3fe7c01b4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -10,6 +10,7 @@ #pragma warning(disable : 4996) #endif +#include "fuzz.h" #include "jsontest.h" #include #include @@ -2555,6 +2556,18 @@ JSONTEST_FIXTURE(RValueTest, moveConstruction) { JSONTEST_ASSERT_EQUAL(Json::stringValue, moved["key"].type()); } +struct FuzzTest : JsonTest::TestCase {}; + +// Build and run the fuzz test without any fuzzer, so that it's guaranteed not +// go out of date, even if it's never run as an actual fuzz test. +JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { + const std::string example = "{}"; + JSONTEST_ASSERT_EQUAL( + 0, + LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), + example.size())); +} + int main(int argc, const char* argv[]) { JsonTest::Runner runner; JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr); @@ -2635,6 +2648,8 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction); + JSONTEST_REGISTER_FIXTURE(runner, FuzzTest, fuzzDoesntCrash); + return runner.runCommandLine(argc, argv); } From 0e3b22dd3ad15d1b4b6fed6ff0333ff28bb74a17 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 09:45:29 -0400 Subject: [PATCH 150/410] Updated header and fixed the bug --- src/test_lib_json/fuzz.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index 8265a17bb..f79f19ffe 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -1,11 +1,11 @@ -// Copyright 2007-2010 The JsonCpp Authors +// Copyright 2007-2019 The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE #include "fuzz.h" -#include +#include #include #include #include From 32472026767d377a6503fc8e676d34e99ea4471e Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 09:49:23 -0400 Subject: [PATCH 151/410] Updated fuzz.h --- src/test_lib_json/fuzz.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h index f6504377b..60897a4bc 100644 --- a/src/test_lib_json/fuzz.h +++ b/src/test_lib_json/fuzz.h @@ -6,9 +6,9 @@ #ifndef FUZZ_H_INCLUDED #define FUZZ_H_INCLUDED -#include -#include +#include +#include -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); #endif // ifndef FUZZ_H_INCLUDED From 29434414d762bc53278d474150ea146f5d1c0f65 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 09:50:09 -0400 Subject: [PATCH 152/410] Update fuzz.cpp --- src/test_lib_json/fuzz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index f79f19ffe..78d26ad33 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -16,7 +16,7 @@ namespace Json { class Exception; } -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { Json::CharReaderBuilder builder; if (size < sizeof(uint32_t)) { From 46d35659ef5c2738b20df0e9a46f7c97a867cdb4 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 09:50:41 -0400 Subject: [PATCH 153/410] Update fuzz.h --- src/test_lib_json/fuzz.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h index 60897a4bc..d5bc08ed1 100644 --- a/src/test_lib_json/fuzz.h +++ b/src/test_lib_json/fuzz.h @@ -7,7 +7,7 @@ #define FUZZ_H_INCLUDED #include -#include +#include int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); From 9d6db96f364021c5ed6b42db84e2d091a4e7137a Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:03:06 -0400 Subject: [PATCH 154/410] Update fuzz.h --- src/test_lib_json/fuzz.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h index d5bc08ed1..0816d2757 100644 --- a/src/test_lib_json/fuzz.h +++ b/src/test_lib_json/fuzz.h @@ -9,6 +9,6 @@ #include #include -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); #endif // ifndef FUZZ_H_INCLUDED From 576b271a044949950ed315da9ccd4eb6ab8d1894 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:03:26 -0400 Subject: [PATCH 155/410] Update fuzz.cpp --- src/test_lib_json/fuzz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index 78d26ad33..f79f19ffe 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -16,7 +16,7 @@ namespace Json { class Exception; } -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { Json::CharReaderBuilder builder; if (size < sizeof(uint32_t)) { From 9725530a4ffedb92d9cd588a0b3b1c1f00b66c44 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:25:29 -0400 Subject: [PATCH 156/410] Update fuzz.h --- src/test_lib_json/fuzz.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h index 0816d2757..d5bc08ed1 100644 --- a/src/test_lib_json/fuzz.h +++ b/src/test_lib_json/fuzz.h @@ -9,6 +9,6 @@ #include #include -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); #endif // ifndef FUZZ_H_INCLUDED From 2939d85b8411d019e48efaea461bac2b4cd910a1 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:26:01 -0400 Subject: [PATCH 157/410] Update fuzz.cpp --- src/test_lib_json/fuzz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index f79f19ffe..78d26ad33 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -16,7 +16,7 @@ namespace Json { class Exception; } -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { Json::CharReaderBuilder builder; if (size < sizeof(uint32_t)) { From d81a3caece868d21c97ced31b1395039242bbbde Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:32:37 -0400 Subject: [PATCH 158/410] Update fuzz.h --- src/test_lib_json/fuzz.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.h b/src/test_lib_json/fuzz.h index d5bc08ed1..0816d2757 100644 --- a/src/test_lib_json/fuzz.h +++ b/src/test_lib_json/fuzz.h @@ -9,6 +9,6 @@ #include #include -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); #endif // ifndef FUZZ_H_INCLUDED From 6d236e19481bc63aef9e952abedf48e0e242911b Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 10:32:52 -0400 Subject: [PATCH 159/410] Update fuzz.cpp --- src/test_lib_json/fuzz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index 78d26ad33..f79f19ffe 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -16,7 +16,7 @@ namespace Json { class Exception; } -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { Json::CharReaderBuilder builder; if (size < sizeof(uint32_t)) { From 8e01024ce37d7fe83d2667ed1ae65b82ab780fa5 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 11:20:37 -0400 Subject: [PATCH 160/410] fix llvm --- src/test_lib_json/main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3fe7c01b4..b8f297192 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2560,13 +2560,13 @@ struct FuzzTest : JsonTest::TestCase {}; // Build and run the fuzz test without any fuzzer, so that it's guaranteed not // go out of date, even if it's never run as an actual fuzz test. -JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { - const std::string example = "{}"; - JSONTEST_ASSERT_EQUAL( - 0, - LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), - example.size())); -} +//JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { +// const std::string example = "{}"; +// JSONTEST_ASSERT_EQUAL( +// 0, +// LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), +// example.size())); +//} int main(int argc, const char* argv[]) { JsonTest::Runner runner; From 7e69f15a6419003aa7e81e42ee7bb62444025602 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 11:34:16 -0400 Subject: [PATCH 161/410] added llvm --- src/test_lib_json/main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index b8f297192..3fe7c01b4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2560,13 +2560,13 @@ struct FuzzTest : JsonTest::TestCase {}; // Build and run the fuzz test without any fuzzer, so that it's guaranteed not // go out of date, even if it's never run as an actual fuzz test. -//JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { -// const std::string example = "{}"; -// JSONTEST_ASSERT_EQUAL( -// 0, -// LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), -// example.size())); -//} +JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { + const std::string example = "{}"; + JSONTEST_ASSERT_EQUAL( + 0, + LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), + example.size())); +} int main(int argc, const char* argv[]) { JsonTest::Runner runner; From 92cc77392e397bb32455c1874b301636b7a5107d Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 11:50:28 -0400 Subject: [PATCH 162/410] Added include fuzz.cpp --- src/test_lib_json/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3fe7c01b4..9d5886d96 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -11,6 +11,7 @@ #endif #include "fuzz.h" +#include "fuzz.cpp" #include "jsontest.h" #include #include From fdcd2fc2324df973dfec39e7cca08b1709d5dae1 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 12:23:05 -0400 Subject: [PATCH 163/410] Update main.cpp --- src/test_lib_json/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 9d5886d96..3fe7c01b4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -11,7 +11,6 @@ #endif #include "fuzz.h" -#include "fuzz.cpp" #include "jsontest.h" #include #include From caa2f3bf4224b585e811ca84f679f83a327b5a35 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 14:25:00 -0400 Subject: [PATCH 164/410] Update main.cpp --- src/test_lib_json/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3fe7c01b4..eb50b3051 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2564,7 +2564,7 @@ JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { const std::string example = "{}"; JSONTEST_ASSERT_EQUAL( 0, - LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), + fuzz::LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), example.size())); } From 13afd0e45500943ff48480d6f43d133b2a15ea7b Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 14:27:36 -0400 Subject: [PATCH 165/410] Update main.cpp --- src/test_lib_json/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index eb50b3051..3fe7c01b4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2564,7 +2564,7 @@ JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { const std::string example = "{}"; JSONTEST_ASSERT_EQUAL( 0, - fuzz::LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), + LLVMFuzzerTestOneInput(reinterpret_cast(example.c_str()), example.size())); } From 181f9eb129bd00ed24561c1e4bab4b8d84abc036 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 14:50:25 -0400 Subject: [PATCH 166/410] Update CMakeLists.txt --- src/test_lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index abb181361..e3e81a7d7 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -12,7 +12,7 @@ add_executable( jsoncpp_test if(BUILD_SHARED_LIBS) add_compile_definitions( JSON_DLL ) endif() -target_link_libraries(jsoncpp_test jsoncpp_lib) +target_link_libraries(jsoncpp_test jsoncpp_lib fuzz) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) From 400ec89811d975677a69039a52ef1d401c6daa1f Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 15:00:57 -0400 Subject: [PATCH 167/410] Update CMakeLists.txt --- src/test_lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index e3e81a7d7..abb181361 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -12,7 +12,7 @@ add_executable( jsoncpp_test if(BUILD_SHARED_LIBS) add_compile_definitions( JSON_DLL ) endif() -target_link_libraries(jsoncpp_test jsoncpp_lib fuzz) +target_link_libraries(jsoncpp_test jsoncpp_lib) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) From 336c300ca408900875d4d66bf30acb00b1a35d19 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 15:06:19 -0400 Subject: [PATCH 168/410] Update jsontest.cpp --- src/test_lib_json/jsontest.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index c0b5296d9..2bf4108d5 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -5,6 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #include "jsontest.h" +#inlcude "fuzz.h" #include #include From c4d1cb1cd15ba0e2cd659ae36bfe6eaefa69765f Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 15:07:31 -0400 Subject: [PATCH 169/410] Update jsontest.cpp --- src/test_lib_json/jsontest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 2bf4108d5..b23909404 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -5,7 +5,7 @@ #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #include "jsontest.h" -#inlcude "fuzz.h" +#include "fuzz.h" #include #include From bcc0472621982fa004455684fe90b62c09398eef Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 24 Jun 2019 15:13:53 -0400 Subject: [PATCH 170/410] Update jsontest.cpp --- src/test_lib_json/jsontest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index b23909404..c0b5296d9 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -5,7 +5,6 @@ #define _CRT_SECURE_NO_WARNINGS 1 // Prevents deprecation warning with MSVC #include "jsontest.h" -#include "fuzz.h" #include #include From d148e28b9bcd03a6269b82d6d6eb287871314179 Mon Sep 17 00:00:00 2001 From: Google-Autofuzz Date: Wed, 26 Jun 2019 17:19:42 -0400 Subject: [PATCH 171/410] added fuzz.cpp to macro in main.cpp --- src/test_lib_json/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3fe7c01b4..9d5886d96 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -11,6 +11,7 @@ #endif #include "fuzz.h" +#include "fuzz.cpp" #include "jsontest.h" #include #include From dc170e30e247d5ce8639ee876f70b685bab66a9e Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Wed, 26 Jun 2019 17:32:33 -0400 Subject: [PATCH 172/410] Update main.cpp --- src/test_lib_json/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 9d5886d96..3fe7c01b4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -11,7 +11,6 @@ #endif #include "fuzz.h" -#include "fuzz.cpp" #include "jsontest.h" #include #include From 879a5b80ce0f28cce4b859c57253f1e3c741e230 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Wed, 26 Jun 2019 17:40:59 -0400 Subject: [PATCH 173/410] Add fuzz.cpp to jsoncpp_test --- meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index ece8aa4d5..8de947c4c 100644 --- a/meson.build +++ b/meson.build @@ -88,7 +88,8 @@ jsoncpp_test = executable( 'jsoncpp_test', [ 'src/test_lib_json/jsontest.cpp', 'src/test_lib_json/jsontest.h', - 'src/test_lib_json/main.cpp'], + 'src/test_lib_json/main.cpp', + 'src/test_lib_json/fuzz.cpp'], include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, install : false, From ddc9e0fcd74fe478c575b12814bb9ce79b3db636 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 27 Jun 2019 12:01:43 -0700 Subject: [PATCH 174/410] Run clang-format on the repository We currently don't have any checks for clang formatting as part of our check-in process, this is an incremental patch to get things compliant. --- src/lib_json/json_value.cpp | 6 +++--- src/test_lib_json/main.cpp | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 508f18ff7..1cf482841 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -853,9 +853,9 @@ bool Value::asBool() const { case uintValue: return value_.uint_ ? true : false; case realValue: { - // According to JavaScript language zero or NaN is regarded as false - const auto value_classification = std::fpclassify(value_.real_); - return value_classification != FP_ZERO && value_classification != FP_NAN; + // According to JavaScript language zero or NaN is regarded as false + const auto value_classification = std::fpclassify(value_.real_); + return value_classification != FP_ZERO && value_classification != FP_NAN; } default: break; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 3fe7c01b4..fcda60e81 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -1649,7 +1648,7 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { JSONTEST_FIXTURE(ValueTest, WideString) { // https://github.com/open-source-parsers/jsoncpp/issues/756 - const std::string uni = u8"式,进"; // "\u5f0f\uff0c\u8fdb" + const std::string uni = u8"式,进"; // "\u5f0f\uff0c\u8fdb" std::string styled; { Json::Value v; From 44bc38f0a116d3ec3bd248a85da927839454c5bf Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 28 Jun 2019 09:34:16 -0700 Subject: [PATCH 175/410] Issue #633: Fix issue with maxInt This patch is a minor fix to Json::OurReader to properly check against maxLargestInt, not maxInt. Some cleanup in the decodeNumber method is included. --- src/lib_json/json_reader.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index abe3de9d8..7e1bca4fe 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1547,36 +1547,46 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of - // them. - Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(Value::minLargestInt) - : Value::maxLargestUInt; - Value::LargestUInt threshold = maxIntegerValue / 10; + + // TODO(issue #960): Change to constexpr + static const auto positive_threshold = Value::maxLargestUInt / 10; + static const auto positive_last_digit = Value::maxLargestUInt % 10; + static const auto negative_threshold = + Value::LargestUInt(Value::minLargestInt) / 10; + static const auto negative_last_digit = + Value::LargestUInt(Value::minLargestInt) % 10; + + const auto threshold = isNegative ? negative_threshold : positive_threshold; + const auto last_digit = + isNegative ? negative_last_digit : positive_last_digit; + Value::LargestUInt value = 0; while (current < token.end_) { Char c = *current++; if (c < '0' || c > '9') return decodeDouble(token, decoded); - auto digit(static_cast(c - '0')); + + const auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, b) this is the last digit, and + // a) we've only just touched the limit, meaing value == threshold, + // b) this is the last digit, or // c) it's small enough to fit in that rounding delta, we're okay. // Otherwise treat this number as a double to avoid overflow. - if (value > threshold || current != token.end_ || - digit > maxIntegerValue % 10) { + if (value > threshold || current != token.end_ || digit > last_digit) { return decodeDouble(token, decoded); } } value = value * 10 + digit; } + if (isNegative) decoded = -Value::LargestInt(value); - else if (value <= Value::LargestUInt(Value::maxInt)) + else if (value <= Value::LargestUInt(Value::maxLargestInt)) decoded = Value::LargestInt(value); else decoded = value; + return true; } From f8db40ff83ee8fa901e046ace396fa94a535b0d4 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 28 Jun 2019 10:11:58 -0700 Subject: [PATCH 176/410] Update minimum CMake version requirement --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 967a1e310..381d08b0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ # CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will # continue to generate policy warnings "CMake Warning (dev)...Policy CMP0XXX is not set:" # -set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.1.0") +set(JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION "3.8.0") set(JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION "3.13.2") cmake_minimum_required(VERSION ${JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION}) if("${CMAKE_VERSION}" VERSION_LESS "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") From 95b3092ce4b7156adc8a265907b2175ceff5a96f Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 28 Jun 2019 09:50:46 -0700 Subject: [PATCH 177/410] Fix comments on Json Reader There have been multiple discussions of the inaccurate comments in the Json Reader class. This patch just updates those comments. --- src/lib_json/json_reader.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 7e1bca4fe..bbff7efd8 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -870,7 +870,8 @@ bool Reader::pushError(const Value& value, bool Reader::good() const { return errors_.empty(); } -// exact copy of Features +// Originally copied from the Features class (now deprecated), used internally +// for features implementation. class OurFeatures { public: static OurFeatures all(); @@ -885,15 +886,13 @@ class OurFeatures { size_t stackLimit_; }; // OurFeatures -// exact copy of Implementation of class Features -// //////////////////////////////// - OurFeatures OurFeatures::all() { return {}; } // Implementation of class Reader // //////////////////////////////// -// exact copy of Reader, renamed to OurReader +// Originally copied from the Reader class (now deprecated), used internally +// for implementing JSON reading. class OurReader { public: typedef char Char; From 7924d3ff9713f1a130ed5fe234d52d7176ae4d09 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 1 Jul 2019 13:06:14 -0700 Subject: [PATCH 178/410] Update version.h.in header comments Currently, the comments in the version.h.in header file are incorrect. This tiny patch just updates them. --- src/lib_json/version.h.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib_json/version.h.in b/src/lib_json/version.h.in index 911a66bba..4cf439ccc 100644 --- a/src/lib_json/version.h.in +++ b/src/lib_json/version.h.in @@ -1,5 +1,5 @@ -// DO NOT EDIT. This file (and "version") is generated by CMake. -// Run CMake configure step to update it. +// DO NOT EDIT. This file (and "version") is a template used by the build system +// (either CMake or Meson) to generate a "version.h" header file. #ifndef JSON_VERSION_H_INCLUDED #define JSON_VERSION_H_INCLUDED @@ -8,7 +8,9 @@ #define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ #define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ #define JSONCPP_VERSION_QUALIFIER -#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) +#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) \ + | (JSONCPP_VERSION_MINOR << 16) \ + | (JSONCPP_VERSION_PATCH << 8)) #ifdef JSONCPP_USING_SECURE_MEMORY #undef JSONCPP_USING_SECURE_MEMORY From 3c32dca89214c03b107cc9d1c468000cff3f8127 Mon Sep 17 00:00:00 2001 From: lilinchao Date: Tue, 2 Jul 2019 21:15:11 +0800 Subject: [PATCH 179/410] adjust some codes position --- src/lib_json/json_reader.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index bbff7efd8..53b0b2ec6 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1454,18 +1454,18 @@ bool OurReader::readObject(Token& token) { } else { break; } - - Token colon; - if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover("Missing ':' after object member name", colon, - tokenObjectEnd); - } if (name.length() >= (1U << 30)) throwRuntimeError("keylength >= 2^30"); if (features_.rejectDupKeys_ && currentValue().isMember(name)) { String msg = "Duplicate key: '" + name + "'"; return addErrorAndRecover(msg, tokenName, tokenObjectEnd); } + + Token colon; + if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { + return addErrorAndRecover("Missing ':' after object member name", colon, + tokenObjectEnd); + } Value& value = currentValue()[name]; nodes_.push(&value); bool ok = readValue(); From 60ba071aace3d512131149f10f1fbf7ec284eb7a Mon Sep 17 00:00:00 2001 From: lilinchao Date: Tue, 2 Jul 2019 20:28:30 +0800 Subject: [PATCH 180/410] pop the root node after readValue() --- src/lib_json/json_reader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 53b0b2ec6..005ab2689 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1048,6 +1048,7 @@ bool OurReader::parse(const char* beginDoc, nodes_.push(&root); bool successful = readValue(); + nodes_.pop(); Token token; skipCommentTokens(token); if (features_.failIfExtra_) { From 9ef812a097fd49ecce470f68b1cb591b42adecb1 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Tue, 9 Jul 2019 15:03:39 -0700 Subject: [PATCH 181/410] \#964 Delete JSONCPP_NORETURN for [[noreturn]] This patch removes the custom JSONCPP_NORETURN macro in favor of the C++11 standard [[noreturn]] attribute. --- include/json/value.h | 17 ++--------------- src/lib_json/json_value.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 59bae07da..a9d9ea115 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -24,19 +24,6 @@ #include #endif -// Conditional NORETURN attribute on the throw functions would: -// a) suppress false positives from static code analysis -// b) possibly improve optimization opportunities. -#if !defined(JSONCPP_NORETURN) -#if defined(_MSC_VER) -#define JSONCPP_NORETURN __declspec(noreturn) -#elif defined(__GNUC__) -#define JSONCPP_NORETURN __attribute__((__noreturn__)) -#else -#define JSONCPP_NORETURN -#endif -#endif - // Disable warning C4251: : needs to have dll-interface to // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) @@ -89,9 +76,9 @@ class JSON_API LogicError : public Exception { #endif /// used internally -JSONCPP_NORETURN void throwRuntimeError(String const& msg); +[[noreturn]] void throwRuntimeError(String const& msg); /// used internally -JSONCPP_NORETURN void throwLogicError(String const& msg); +[[noreturn]] void throwLogicError(String const& msg); /** \brief Type of the value held by a Value object. */ diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 1cf482841..a702c56ca 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -232,15 +232,15 @@ Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} -JSONCPP_NORETURN void throwRuntimeError(String const& msg) { +[[noreturn]] void throwRuntimeError(String const& msg) { throw RuntimeError(msg); } -JSONCPP_NORETURN void throwLogicError(String const& msg) { +[[noreturn]] void throwLogicError(String const& msg) { throw LogicError(msg); } #else // !JSON_USE_EXCEPTION -JSONCPP_NORETURN void throwRuntimeError(String const& msg) { abort(); } -JSONCPP_NORETURN void throwLogicError(String const& msg) { abort(); } +[[noreturn]] void throwRuntimeError(String const& msg) { abort(); } +[[noreturn]] void throwLogicError(String const& msg) { abort(); } #endif // ////////////////////////////////////////////////////////////////// From 25c57812e2fbe818b4b3ae42b2321f47dd2249d7 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 11 Jul 2019 14:27:29 -0700 Subject: [PATCH 182/410] Add new JSON_USE_NULLREF flag This patch adds a new flag, JSON_USE_NULLREF, which removes the legacy singletons null, nullRef for consumers that require not having static initialized globals, like Chromium. --- include/json/config.h | 5 +++++ include/json/value.h | 13 ++++++++----- src/lib_json/json_value.cpp | 18 +++++++++--------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index eca9e8c45..8724ad95a 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -30,6 +30,11 @@ #define JSON_USE_EXCEPTION 1 #endif +// Temporary, tracked for removal with issue #982. +#ifndef JSON_USE_NULLREF +#define JSON_USE_NULLREF 1 +#endif + /// If defined, indicates that the source file is amalgamated /// to prevent private header inclusion. /// Remarks: it is automatically defined in the generated amalgamated header. diff --git a/include/json/value.h b/include/json/value.h index a9d9ea115..957f3f6f6 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -193,11 +193,14 @@ class JSON_API Value { // Required for boost integration, e. g. BOOST_TEST typedef std::string value_type; - static const Value& null; ///< We regret this reference to a global instance; - ///< prefer the simpler Value(). - static const Value& nullRef; ///< just a kludge for binary-compatibility; same - ///< as null - static Value const& nullSingleton(); ///< Prefer this to null or nullRef. +#if JSON_USE_NULLREF + // Binary compatibility kludges, do not use. + static const Value& null; + static const Value& nullRef; +#endif + + // null and nullRef are deprecated, use this instead. + static Value const& nullSingleton(); /// Minimum signed integer value that can be stored in a Json::Value. static const LargestInt minLargestInt; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index a702c56ca..d813c16a0 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -54,7 +54,6 @@ int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, #define JSON_ASSERT_UNREACHABLE assert(false) namespace Json { - template static std::unique_ptr cloneUnique(const std::unique_ptr& p) { std::unique_ptr r; @@ -72,10 +71,6 @@ static std::unique_ptr cloneUnique(const std::unique_ptr& p) { #else #define ALIGNAS(byte_alignment) #endif -// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; -// const unsigned char& kNullRef = kNull[0]; -// const Value& Value::null = reinterpret_cast(kNullRef); -// const Value& Value::nullRef = null; // static Value const& Value::nullSingleton() { @@ -83,10 +78,15 @@ Value const& Value::nullSingleton() { return nullStatic; } +#if JSON_USE_NULLREF // for backwards compatibility, we'll leave these global references around, but // DO NOT use them in JSONCPP library code any more! +// static Value const& Value::null = Value::nullSingleton(); + +// static Value const& Value::nullRef = Value::nullSingleton(); +#endif const Int Value::minInt = Int(~(UInt(-1) / 2)); const Int Value::maxInt = Int(UInt(-1) / 2); @@ -1648,20 +1648,20 @@ const Value& Path::resolve(const Value& root) const { for (const auto& arg : args_) { if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) { - // Error: unable to resolve path (array value expected at position... - return Value::null; + // Error: unable to resolve path (array value expected at position... ) + return Value::nullSingleton(); } node = &((*node)[arg.index_]); } else if (arg.kind_ == PathArgument::kindKey) { if (!node->isObject()) { // Error: unable to resolve path (object value expected at position...) - return Value::null; + return Value::nullSingleton(); } node = &((*node)[arg.key_]); if (node == &Value::nullSingleton()) { // Error: unable to resolve path (object has no member named '' at // position...) - return Value::null; + return Value::nullSingleton(); } } } From 645250b6690785be60ab6780ce4b58698d884d11 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Wed, 10 Jul 2019 18:56:30 -0700 Subject: [PATCH 183/410] \#979 Fix parseFromStream definition This patch fixes issue #979, where the parseFromStream definition in the header is different from the implementation. --- include/json/reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/json/reader.h b/include/json/reader.h index 111e5dd98..0f489d6ad 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -378,7 +378,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root, - std::string* errs); + String* errs); /** \brief Read from 'sin' into 'root'. From b3507948e2a1a79dfb1a8ac7b1e2dc1bea9f8360 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 12 Jul 2019 11:07:12 -0700 Subject: [PATCH 184/410] Fix definition check for GNUC --- include/json/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 8724ad95a..2f7052218 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -108,7 +108,7 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #if __has_extension(attribute_deprecated_with_message) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #endif -#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc) +#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) #elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) @@ -123,7 +123,7 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_DEPRECATED(message) #endif // if !defined(JSONCPP_DEPRECATED) -#if __GNUC__ >= 6 +#if defined(__GNUC__) && (__GNUC__ >= 6) #define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif From 483eba84a757d2e8ac61ae9345630fcbdbd03d5d Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 14 Jul 2019 18:41:48 -0400 Subject: [PATCH 185/410] Improve code comment formatting (Issue #985) --- include/json/reader.h | 265 ++++++++++++++++++------------------ include/json/value.h | 126 ++++++++--------- src/lib_json/json_value.cpp | 4 +- 3 files changed, 189 insertions(+), 206 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index 0f489d6ad..ce216a3dc 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -28,7 +28,7 @@ namespace Json { /** \brief Unserialize a JSON document into a - *Value. + * Value. * * \deprecated Use CharReader and CharReaderBuilder. */ @@ -41,7 +41,6 @@ class JSON_API Reader { * * The offsets give the [start, limit) range of bytes within the text. Note * that this is bytes, not codepoints. - * */ struct StructuredError { ptrdiff_t offset_start; @@ -49,29 +48,27 @@ class JSON_API Reader { String message; }; - /** \brief Constructs a Reader allowing all features - * for parsing. + /** \brief Constructs a Reader allowing all features for parsing. */ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); - /** \brief Constructs a Reader allowing the specified feature set - * for parsing. + /** \brief Constructs a Reader allowing the specified feature set for parsing. */ JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON * document. - * \param document UTF-8 encoded string containing the document to read. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them - * back during - * serialization, \c false to discard comments. - * This parameter is ignored if - * Features::allowComments_ - * is \c false. + * + * \param document UTF-8 encoded string containing the document + * to read. + * \param[out] root Contains the root value of the document if it + * was successfully parsed. + * \param collectComments \c true to collect comment and allow writing + * them back during serialization, \c false to + * discard comments. This parameter is ignored + * if Features::allowComments_ is \c false. * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ @@ -79,22 +76,20 @@ class JSON_API Reader { parse(const std::string& document, Value& root, bool collectComments = true); /** \brief Read a Value from a JSON - document. - * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the - document to read. - * \param endDoc Pointer on the end of the UTF-8 encoded string of the - document to read. - * Must be >= beginDoc. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param collectComments \c true to collect comment and allow writing them - back during - * serialization, \c false to discard comments. - * This parameter is ignored if - Features::allowComments_ - * is \c false. + * document. + * + * \param beginDoc Pointer on the beginning of the UTF-8 encoded + * string of the document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string + * of the document to read. Must be >= beginDoc. + * \param[out] root Contains the root value of the document if it + * was successfully parsed. + * \param collectComments \c true to collect comment and allow writing + * them back during serialization, \c false to + * discard comments. This parameter is ignored + * if Features::allowComments_ is \c false. * \return \c true if the document was successfully parsed, \c false if an - error occurred. + * error occurred. */ bool parse(const char* beginDoc, const char* endDoc, @@ -107,11 +102,10 @@ class JSON_API Reader { /** \brief Returns a user friendly string that list errors in the parsed * document. - * \return Formatted error message with the list of errors with their location - * in - * the parsed document. An empty string is returned if no error - * occurred - * during parsing. + * + * \return Formatted error message with the list of errors with their + * location in the parsed document. An empty string is returned if no error + * occurred during parsing. * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") @@ -119,43 +113,45 @@ class JSON_API Reader { /** \brief Returns a user friendly string that list errors in the parsed * document. - * \return Formatted error message with the list of errors with their location - * in - * the parsed document. An empty string is returned if no error - * occurred - * during parsing. + * + * \return Formatted error message with the list of errors with their + * location in the parsed document. An empty string is returned if no error + * occurred during parsing. */ String getFormattedErrorMessages() const; /** \brief Returns a vector of structured erros encounted while parsing. + * * \return A (possibly empty) vector of StructuredError objects. Currently - * only one error can be returned, but the caller should tolerate - * multiple - * errors. This can occur if the parser recovers from a non-fatal - * parse error and then encounters additional errors. + * only one error can be returned, but the caller should tolerate multiple + * errors. This can occur if the parser recovers from a non-fatal parse + * error and then encounters additional errors. */ std::vector getStructuredErrors() const; /** \brief Add a semantic error message. - * \param value JSON Value location associated with the error + * + * \param value JSON Value location associated with the error * \param message The error message. - * \return \c true if the error was successfully added, \c false if the - * Value offset exceeds the document size. + * \return \c true if the error was successfully added, \c false if the Value + * offset exceeds the document size. */ bool pushError(const Value& value, const String& message); /** \brief Add a semantic error message with extra context. - * \param value JSON Value location associated with the error + * + * \param value JSON Value location associated with the error * \param message The error message. - * \param extra Additional JSON Value location to contextualize the error + * \param extra Additional JSON Value location to contextualize the error * \return \c true if the error was successfully added, \c false if either * Value offset exceeds the document size. */ bool pushError(const Value& value, const String& message, const Value& extra); /** \brief Return whether there are any errors. - * \return \c true if there are no errors to report \c false if - * errors have occurred. + * + * \return \c true if there are no errors to report \c false if errors have + * occurred. */ bool good() const; @@ -255,22 +251,20 @@ class JSON_API CharReader { public: virtual ~CharReader() = default; /** \brief Read a Value from a JSON - document. - * The document must be a UTF-8 encoded string containing the document to - read. + * document. The document must be a UTF-8 encoded string containing the + * document to read. * - * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the - document to read. - * \param endDoc Pointer on the end of the UTF-8 encoded string of the - document to read. - * Must be >= beginDoc. - * \param root [out] Contains the root value of the document if it was - * successfully parsed. - * \param errs [out] Formatted error messages (if not NULL) - * a user friendly string that lists errors in the parsed - * document. + * \param beginDoc Pointer on the beginning of the UTF-8 encoded string + * of the document to read. + * \param endDoc Pointer on the end of the UTF-8 encoded string of the + * document to read. Must be >= beginDoc. + * \param[out] root Contains the root value of the document if it was + * successfully parsed. + * \param[out] errs Formatted error messages (if not NULL) a user + * friendly string that lists errors in the parsed + * document. * \return \c true if the document was successfully parsed, \c false if an - error occurred. + * error occurred. */ virtual bool parse(char const* beginDoc, char const* endDoc, @@ -288,59 +282,58 @@ class JSON_API CharReader { }; // CharReader /** \brief Build a CharReader implementation. - -Usage: -\code - using namespace Json; - CharReaderBuilder builder; - builder["collectComments"] = false; - Value value; - String errs; - bool ok = parseFromStream(builder, std::cin, &value, &errs); -\endcode -*/ + * + * Usage: + * \code + * using namespace Json; + * CharReaderBuilder builder; + * builder["collectComments"] = false; + * Value value; + * String errs; + * bool ok = parseFromStream(builder, std::cin, &value, &errs); + * \endcode + */ class JSON_API CharReaderBuilder : public CharReader::Factory { public: // Note: We use a Json::Value so that we can add data-members to this class // without a major version bump. /** Configuration of this builder. - These are case-sensitive. - Available settings (case-sensitive): - - `"collectComments": false or true` - - true to collect comment and allow writing them - back during serialization, false to discard comments. - This parameter is ignored if allowComments is false. - - `"allowComments": false or true` - - true if comments are allowed. - - `"strictRoot": false or true` - - true if root must be either an array or an object value - - `"allowDroppedNullPlaceholders": false or true` - - true if dropped null placeholders are allowed. (See - StreamWriterBuilder.) - - `"allowNumericKeys": false or true` - - true if numeric object keys are allowed. - - `"allowSingleQuotes": false or true` - - true if '' are allowed for strings (both keys and values) - - `"stackLimit": integer` - - Exceeding stackLimit (recursive depth of `readValue()`) will - cause an exception. - - This is a security issue (seg-faults caused by deeply nested JSON), - so the default is low. - - `"failIfExtra": false or true` - - If true, `parse()` returns false when extra non-whitespace trails - the JSON value in the input string. - - `"rejectDupKeys": false or true` - - If true, `parse()` returns false when a key is duplicated within an - object. - - `"allowSpecialFloats": false or true` - - If true, special float values (NaNs and infinities) are allowed - and their values are lossfree restorable. - - You can examine 'settings_` yourself - to see the defaults. You can also write and read them just like any - JSON Value. - \sa setDefaults() - */ + * These are case-sensitive. + * Available settings (case-sensitive): + * - `"collectComments": false or true` + * - true to collect comment and allow writing them back during + * serialization, false to discard comments. This parameter is ignored + * if allowComments is false. + * - `"allowComments": false or true` + * - true if comments are allowed. + * - `"strictRoot": false or true` + * - true if root must be either an array or an object value + * - `"allowDroppedNullPlaceholders": false or true` + * - true if dropped null placeholders are allowed. (See + * StreamWriterBuilder.) + * - `"allowNumericKeys": false or true` + * - true if numeric object keys are allowed. + * - `"allowSingleQuotes": false or true` + * - true if '' are allowed for strings (both keys and values) + * - `"stackLimit": integer` + * - Exceeding stackLimit (recursive depth of `readValue()`) will cause an + * exception. + * - This is a security issue (seg-faults caused by deeply nested JSON), so + * the default is low. + * - `"failIfExtra": false or true` + * - If true, `parse()` returns false when extra non-whitespace trails the + * JSON value in the input string. + * - `"rejectDupKeys": false or true` + * - If true, `parse()` returns false when a key is duplicated within an + * object. + * - `"allowSpecialFloats": false or true` + * - If true, special float values (NaNs and infinities) are allowed and + * their values are lossfree restorable. + * + * You can examine 'settings_` yourself to see the defaults. You can also + * write and read them just like any JSON Value. + * \sa setDefaults() + */ Json::Value settings_; CharReaderBuilder(); @@ -381,29 +374,29 @@ bool JSON_API parseFromStream(CharReader::Factory const&, String* errs); /** \brief Read from 'sin' into 'root'. - - Always keep comments from the input JSON. - - This can be used to read a file into a particular sub-object. - For example: - \code - Json::Value root; - cin >> root["dir"]["file"]; - cout << root; - \endcode - Result: - \verbatim - { - "dir": { - "file": { - // The input stream JSON would be nested here. - } - } - } - \endverbatim - \throw std::exception on parse error. - \see Json::operator<<() -*/ + * + * Always keep comments from the input JSON. + * + * This can be used to read a file into a particular sub-object. + * For example: + * \code + * Json::Value root; + * cin >> root["dir"]["file"]; + * cout << root; + * \endcode + * Result: + * \verbatim + * { + * "dir": { + * "file": { + * // The input stream JSON would be nested here. + * } + * } + * } + * \endverbatim + * \throw std::exception on parse error. + * \see Json::operator<<() + */ JSON_API IStream& operator>>(IStream&, Value&); } // namespace Json diff --git a/include/json/value.h b/include/json/value.h index 957f3f6f6..30ce89f5a 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -280,21 +280,22 @@ class JSON_API Value { #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION public: - /** \brief Create a default Value of the given type. - - This is a very useful constructor. - To create an empty array, pass arrayValue. - To create an empty object, pass objectValue. - Another Value can then be set to this one by assignment. -This is useful since clear() and resize() will not alter types. - - Examples: -\code -Json::Value null_value; // null -Json::Value arr_value(Json::arrayValue); // [] -Json::Value obj_value(Json::objectValue); // {} -\endcode - */ + /** + * \brief Create a default Value of the given type. + * + * This is a very useful constructor. + * To create an empty array, pass arrayValue. + * To create an empty object, pass objectValue. + * Another Value can then be set to this one by assignment. + * This is useful since clear() and resize() will not alter types. + * + * Examples: + * \code + * Json::Value null_value; // null + * Json::Value arr_value(Json::arrayValue); // [] + * Json::Value obj_value(Json::objectValue); // {} + * \endcode + */ Value(ValueType type = nullValue); Value(Int value); Value(UInt value); @@ -305,24 +306,25 @@ Json::Value obj_value(Json::objectValue); // {} Value(double value); Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.) Value(const char* begin, const char* end); ///< Copy all, incl zeroes. - /** \brief Constructs a value from a static string. - + /** + * \brief Constructs a value from a static string. + * * Like other value string constructor but do not duplicate the string for - * internal storage. The given string must remain alive after the call to this - * constructor. + * internal storage. The given string must remain alive after the call to + * this constructor. + * * \note This works only for null-terminated strings. (We cannot change the - * size of this class, so we have nowhere to store the length, - * which might be computed later for various operations.) + * size of this class, so we have nowhere to store the length, which might be + * computed later for various operations.) * * Example of usage: - * \code - * static StaticString foo("some text"); - * Json::Value aValue(foo); - * \endcode + * \code + * static StaticString foo("some text"); + * Json::Value aValue(foo); + * \endcode */ Value(const StaticString& value); - Value(const String& value); ///< Copy data() til size(). Embedded - ///< zeroes too. + Value(const String& value); #ifdef JSON_USE_CPPTL Value(const CppTL::ConstString& value); #endif @@ -419,35 +421,26 @@ Json::Value obj_value(Json::objectValue); // {} /// \post type() is arrayValue void resize(ArrayIndex newSize); - /// Access an array element (zero based index ). - /// If the array contains less than index element, then null value are - /// inserted - /// in the array so that its size is index+1. + //@{ + /// Access an array element (zero based index). If the array contains less + /// than index element, then null value are inserted in the array so that + /// its size is index+1. /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) + /// this from the operator[] which takes a string.) Value& operator[](ArrayIndex index); - - /// Access an array element (zero based index ). - /// If the array contains less than index element, then null value are - /// inserted - /// in the array so that its size is index+1. - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) Value& operator[](int index); + //@} - /// Access an array element (zero based index ) + //@{ + /// Access an array element (zero based index). /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) + /// this from the operator[] which takes a string.) const Value& operator[](ArrayIndex index) const; - - /// Access an array element (zero based index ) - /// (You may need to say 'value[0u]' to get your compiler to distinguish - /// this from the operator[] which takes a string.) const Value& operator[](int index) const; + //@} /// If the array contains at least index+1 elements, returns the element - /// value, - /// otherwise returns defaultValue. + /// value, otherwise returns defaultValue. Value get(ArrayIndex index, const Value& defaultValue) const; /// Return true if index < size(). bool isValidIndex(ArrayIndex index) const; @@ -459,7 +452,7 @@ Json::Value obj_value(Json::objectValue); // {} /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. - /// Exceeding that will cause an exception. + /// Exceeding that will cause an exception. Value& operator[](const char* key); /// Access an object value by name, returns null if there is no member with /// that name. @@ -472,17 +465,16 @@ Json::Value obj_value(Json::objectValue); // {} /// \param key may contain embedded nulls. const Value& operator[](const String& key) const; /** \brief Access an object value by name, create a null member if it does not - exist. - + * exist. + * * If the object has no entry for that name, then the member name used to - store - * the new entry is not duplicated. + * store the new entry is not duplicated. * Example of use: - * \code - * Json::Value object; - * static const StaticString code("code"); - * object[code] = 1234; - * \endcode + * \code + * Json::Value object; + * static const StaticString code("code"); + * object[code] = 1234; + * \endcode */ Value& operator[](const StaticString& key); #ifdef JSON_USE_CPPTL @@ -530,20 +522,20 @@ Json::Value obj_value(Json::objectValue); // {} /// but 'key' is null-terminated. bool removeMember(const char* key, Value* removed); /** \brief Remove the named map member. - - Update 'removed' iff removed. - \param key may contain embedded nulls. - \return true iff removed (no exceptions) - */ + * + * Update 'removed' iff removed. + * \param key may contain embedded nulls. + * \return true iff removed (no exceptions) + */ bool removeMember(String const& key, Value* removed); /// Same as removeMember(String const& key, Value* removed) bool removeMember(const char* begin, const char* end, Value* removed); /** \brief Remove the indexed array element. - - O(n) expensive operations. - Update 'removed' iff removed. - \return true if removed (no exceptions) - */ + * + * O(n) expensive operations. + * Update 'removed' iff removed. + * \return true if removed (no exceptions) + */ bool removeIndex(ArrayIndex index, Value* removed); /// Return true if the object has a member named key. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index d813c16a0..6024212f2 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -235,9 +235,7 @@ LogicError::LogicError(String const& msg) : Exception(msg) {} [[noreturn]] void throwRuntimeError(String const& msg) { throw RuntimeError(msg); } -[[noreturn]] void throwLogicError(String const& msg) { - throw LogicError(msg); -} +[[noreturn]] void throwLogicError(String const& msg) { throw LogicError(msg); } #else // !JSON_USE_EXCEPTION [[noreturn]] void throwRuntimeError(String const& msg) { abort(); } [[noreturn]] void throwLogicError(String const& msg) { abort(); } From b27c83f691a03f521a1b3b99eefa2973f8e2bfcd Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Thu, 18 Jul 2019 04:35:33 +0800 Subject: [PATCH 186/410] Delete JSONCPP_DEPRECATED, use [[deprecated]] instead. (#978) * delete JSONCPP_DEPRECATED, use [[deprecated]] * add pragma warning(disable:4996) * add error C2416 * update * update * update --- include/json/config.h | 19 ------------------- include/json/reader.h | 10 ++++++---- include/json/value.h | 4 ++-- include/json/writer.h | 8 ++++---- src/test_lib_json/jsontest.cpp | 4 ++-- src/test_lib_json/main.cpp | 2 +- 6 files changed, 15 insertions(+), 32 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 2f7052218..6426c3b29 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -104,25 +104,6 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_OP_EXPLICIT #endif -#ifdef __clang__ -#if __has_extension(attribute_deprecated_with_message) -#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) -#endif -#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) -#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) -#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) -#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) -#endif // GNUC version -#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates - // MSVC) -#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) -#endif // __clang__ || __GNUC__ || _MSC_VER - -#if !defined(JSONCPP_DEPRECATED) -#define JSONCPP_DEPRECATED(message) -#endif // if !defined(JSONCPP_DEPRECATED) - #if defined(__GNUC__) && (__GNUC__ >= 6) #define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif diff --git a/include/json/reader.h b/include/json/reader.h index ce216a3dc..f8158cfdb 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -25,6 +25,10 @@ #pragma pack(push, 8) +#if defined(_MSC_VER) +#pragma warning(disable : 4996) +#endif + namespace Json { /** \brief Unserialize a JSON document into a @@ -32,7 +36,7 @@ namespace Json { * * \deprecated Use CharReader and CharReaderBuilder. */ -class JSON_API Reader { +class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_API Reader { public: typedef char Char; typedef const Char* Location; @@ -50,12 +54,10 @@ class JSON_API Reader { /** \brief Constructs a Reader allowing all features for parsing. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON @@ -108,7 +110,7 @@ class JSON_API Reader { * occurred during parsing. * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ - JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") + [[deprecated("Use getFormattedErrorMessages() instead.")]] String getFormatedErrorMessages() const; /** \brief Returns a user friendly string that list errors in the parsed diff --git a/include/json/value.h b/include/json/value.h index 30ce89f5a..a47884854 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -564,7 +564,7 @@ class JSON_API Value { //# endif /// \deprecated Always pass len. - JSONCPP_DEPRECATED("Use setComment(String const&) instead.") + [[deprecated("Use setComment(String const&) instead.")]] void setComment(const char* comment, CommentPlacement placement) { setComment(String(comment, strlen(comment)), placement); } @@ -750,7 +750,7 @@ class JSON_API ValueIteratorBase { /// objectValue. /// \deprecated This cannot be used for UTF-8 strings, since there can be /// embedded nulls. - JSONCPP_DEPRECATED("Use `key = name();` instead.") + [[deprecated("Use `key = name();` instead.")]] char const* memberName() const; /// Return the member name of the referenced Value, or NULL if it is not an /// objectValue. diff --git a/include/json/writer.h b/include/json/writer.h index 12fd36a7a..328014166 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -145,7 +145,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { /** \brief Abstract class for writers. * \deprecated Use StreamWriter. (And really, this is an implementation detail.) */ -class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { +class [[deprecated("Use StreamWriter instead")]] JSON_API Writer { public: virtual ~Writer(); @@ -165,7 +165,7 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter +class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API FastWriter : public Writer { public: FastWriter(); @@ -225,7 +225,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API StyledWriter : public Writer { public: StyledWriter(); @@ -294,7 +294,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API StyledStreamWriter { public: /** diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index c0b5296d9..4c59d07b5 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -378,8 +378,8 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) - // @todo investigate this handler (for buffer overflow) - // _set_security_error_handler +// @todo investigate this handler (for buffer overflow) +// _set_security_error_handler #if defined(_WIN32) // Prevents the system from popping a dialog for debugging if the diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index fcda60e81..e700c3801 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2522,7 +2522,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( Json::Value::iterator it(v.begin()) // Compile, but throw. - ); + ); Json::Value value; From 12325b814f00cc31c6ccdb7a17d058c4dbc55aed Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 22 Jul 2019 15:25:23 -0700 Subject: [PATCH 187/410] Cleanup versioning strategy (#989) * Cleanup versioning strategy Currently, versioning is a mess. CMake and Meson have seperate build version number storage locations, with no way of knowing you need to have both. Plus, due to recent revisions the amalgamate script is broken unless you build first, and may still be broken afterwards. This PR fixes some issues with versioning, and adds comments clarifying what has to be done when doing a release. * Run clang format * Update SOVERSION.... --- CMakeLists.txt | 15 +++++++++------ CONTRIBUTING.md | 1 - amalgamate.py | 38 ++++++++++++++++++++----------------- include/json/reader.h | 2 +- include/json/version.h | 28 +++++++++++++++++++++++++++ meson.build | 37 +++++++++++++----------------------- src/lib_json/CMakeLists.txt | 5 ++--- src/lib_json/version.h.in | 22 --------------------- version.txt | 1 - 9 files changed, 74 insertions(+), 75 deletions(-) mode change 100644 => 100755 amalgamate.py create mode 100644 include/json/version.h delete mode 100644 src/lib_json/version.h.in delete mode 100644 version.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 381d08b0a..b4eb83039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,11 +63,18 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) endif() project(JSONCPP - VERSION 1.9.0 # [.[.[.]]] + # Note: version must be updated in three places when doing a release. This + # annoying process ensures that amalgamate, CMake, and meson all report the + # correct version. + # 1. /meson.build + # 2. /include/json/version.h + # 3. /CMakeLists.txt + # IMPORTANT: also update the SOVERSION!! + VERSION 1.9.2 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set( JSONCPP_SOVERSION 21 ) +set( JSONCPP_SOVERSION 22 ) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) @@ -89,10 +96,6 @@ set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the libra set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) -# File version.h is only regenerated on CMake configure step -configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" - "${PROJECT_BINARY_DIR}/include/json/version.h" - NEWLINE_STYLE UNIX ) configure_file( "${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_BINARY_DIR}/version" NEWLINE_STYLE UNIX ) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7e4ab7af..3e14b2b31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,6 @@ Then, LIB_TYPE=shared #LIB_TYPE=static meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} - #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. ninja -v -C build-${LIB_TYPE} cd build-${LIB_TYPE} meson test --no-rebuild --print-errorlogs diff --git a/amalgamate.py b/amalgamate.py old mode 100644 new mode 100755 index c12215a8b..7b41e2e5b --- a/amalgamate.py +++ b/amalgamate.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python + """Amalgamate json-cpp library sources into a single source and header file. Works with python2.6+ and python3.4+. @@ -9,6 +11,9 @@ import os.path import sys +INCLUDE_PATH = "include/json" +SRC_PATH = "src/lib_json" + class AmalgamationFile: def __init__(self, top_dir): self.top_dir = top_dir @@ -66,15 +71,15 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file("include/json/version.h") - header.add_file("include/json/allocator.h") - header.add_file("include/json/config.h") - header.add_file("include/json/forwards.h") - header.add_file("include/json/features.h") - header.add_file("include/json/value.h") - header.add_file("include/json/reader.h") - header.add_file("include/json/writer.h") - header.add_file("include/json/assertions.h") + header.add_file(os.path.join(INCLUDE_PATH, "version.h")) + header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) + header.add_file(os.path.join(INCLUDE_PATH, "config.h")) + header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) + header.add_file(os.path.join(INCLUDE_PATH, "features.h")) + header.add_file(os.path.join(INCLUDE_PATH, "value.h")) + header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) + header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) + header.add_file(os.path.join(INCLUDE_PATH, "assertions.h")) header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) @@ -94,8 +99,8 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file("include/json/config.h") - header.add_file("include/json/forwards.h") + header.add_file(os.path.join(INCLUDE_PATH, "config.h")) + header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") target_forward_header_path = os.path.join(os.path.dirname(target_source_path), @@ -116,12 +121,11 @@ def amalgamate_source(source_top_dir=None, #endif """) source.add_text("") - lib_json = "src/lib_json" - source.add_file(os.path.join(lib_json, "json_tool.h")) - source.add_file(os.path.join(lib_json, "json_reader.cpp")) - source.add_file(os.path.join(lib_json, "json_valueiterator.inl")) - source.add_file(os.path.join(lib_json, "json_value.cpp")) - source.add_file(os.path.join(lib_json, "json_writer.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_tool.h")) + source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) + source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) print("Writing amalgamated source to %r" % target_source_path) source.write_to(target_source_path) diff --git a/include/json/reader.h b/include/json/reader.h index f8158cfdb..adbe299bf 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -378,7 +378,7 @@ bool JSON_API parseFromStream(CharReader::Factory const&, /** \brief Read from 'sin' into 'root'. * * Always keep comments from the input JSON. - * + * * This can be used to read a file into a particular sub-object. * For example: * \code diff --git a/include/json/version.h b/include/json/version.h new file mode 100644 index 000000000..ff94372b0 --- /dev/null +++ b/include/json/version.h @@ -0,0 +1,28 @@ +#ifndef JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED + +// Note: version must be updated in three places when doing a release. This +// annoying process ensures that amalgamate, CMake, and meson all report the +// correct version. +// 1. /meson.build +// 2. /include/json/version.h +// 3. /CMakeLists.txt +// IMPORTANT: also update the SOVERSION!! + +#define JSONCPP_VERSION_STRING "1.9.2" +#define JSONCPP_VERSION_MAJOR 1 +#define JSONCPP_VERSION_MINOR 9 +#define JSONCPP_VERSION_PATCH 2 +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA \ + ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ + (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY 0 +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED diff --git a/meson.build b/meson.build index 8de947c4c..d1f49897a 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,15 @@ project( 'jsoncpp', 'cpp', - version : '1.9.0', + + # Note: version must be updated in three places when doing a release. This + # annoying process ensures that amalgamate, CMake, and meson all report the + # correct version. + # 1. /meson.build + # 2. /include/json/version.h + # 3. /CMakeLists.txt + # IMPORTANT: also update the SOVERSION!! + version : '1.9.2', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -9,25 +17,6 @@ project( license : 'Public Domain', meson_version : '>= 0.50.0') -jsoncpp_ver_arr = meson.project_version().split('.') -jsoncpp_major_version = jsoncpp_ver_arr[0] -jsoncpp_minor_version = jsoncpp_ver_arr[1] -jsoncpp_patch_version = jsoncpp_ver_arr[2] - -jsoncpp_cdata = configuration_data() -jsoncpp_cdata.set('JSONCPP_VERSION', meson.project_version()) -jsoncpp_cdata.set('JSONCPP_VERSION_MAJOR', jsoncpp_major_version) -jsoncpp_cdata.set('JSONCPP_VERSION_MINOR', jsoncpp_minor_version) -jsoncpp_cdata.set('JSONCPP_VERSION_PATCH', jsoncpp_patch_version) -jsoncpp_cdata.set('JSONCPP_USE_SECURE_MEMORY',0) - -jsoncpp_gen_sources = configure_file( - input : 'src/lib_json/version.h.in', - output : 'version.h', - configuration : jsoncpp_cdata, - install : true, - install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'json') -) jsoncpp_headers = [ 'include/json/allocator.h', @@ -39,6 +28,7 @@ jsoncpp_headers = [ 'include/json/json.h', 'include/json/reader.h', 'include/json/value.h', + 'include/json/version.h', 'include/json/writer.h'] jsoncpp_include_directories = include_directories('include') @@ -56,13 +46,12 @@ endif jsoncpp_lib = library( 'jsoncpp', - [ jsoncpp_gen_sources, - jsoncpp_headers, + [ jsoncpp_headers, 'src/lib_json/json_tool.h', 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp'], - soversion : 21, + soversion : 22, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) @@ -79,7 +68,7 @@ jsoncpp_dep = declare_dependency( include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, version : meson.project_version(), - sources : jsoncpp_gen_sources) + ) # tests python = import('python3').find_python() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 2392092af..0fa2f5953 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -45,9 +45,9 @@ set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/features.h ${JSONCPP_INCLUDE_DIR}/json/value.h ${JSONCPP_INCLUDE_DIR}/json/reader.h + ${JSONCPP_INCLUDE_DIR}/json/version.h ${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h - ${PROJECT_BINARY_DIR}/include/json/version.h ) source_group( "Public API" FILES ${PUBLIC_HEADERS} ) @@ -57,8 +57,7 @@ set(jsoncpp_sources json_reader.cpp json_valueiterator.inl json_value.cpp - json_writer.cpp - version.h.in) + json_writer.cpp) # Install instructions for this target if(JSONCPP_WITH_CMAKE_PACKAGE) diff --git a/src/lib_json/version.h.in b/src/lib_json/version.h.in deleted file mode 100644 index 4cf439ccc..000000000 --- a/src/lib_json/version.h.in +++ /dev/null @@ -1,22 +0,0 @@ -// DO NOT EDIT. This file (and "version") is a template used by the build system -// (either CMake or Meson) to generate a "version.h" header file. -#ifndef JSON_VERSION_H_INCLUDED -#define JSON_VERSION_H_INCLUDED - -#define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" -#define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ -#define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ -#define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ -#define JSONCPP_VERSION_QUALIFIER -#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) \ - | (JSONCPP_VERSION_MINOR << 16) \ - | (JSONCPP_VERSION_PATCH << 8)) - -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif -#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@ -// If non-zero, the library zeroes any memory that it has allocated before -// it frees its memory. - -#endif // JSON_VERSION_H_INCLUDED diff --git a/version.txt b/version.txt deleted file mode 100644 index bfa363e76..000000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -1.8.4 From 0d27381acfdd458e802ef59a1304fab356acd652 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Wed, 31 Jul 2019 11:26:48 -0700 Subject: [PATCH 188/410] Revert "Cleanup versioning strategy (#989)" (#996) This reverts commit 12325b814f00cc31c6ccdb7a17d058c4dbc55aed. --- CMakeLists.txt | 15 ++++++--------- CONTRIBUTING.md | 1 + amalgamate.py | 38 +++++++++++++++++-------------------- include/json/reader.h | 2 +- include/json/version.h | 28 --------------------------- meson.build | 37 +++++++++++++++++++++++------------- src/lib_json/CMakeLists.txt | 5 +++-- src/lib_json/version.h.in | 22 +++++++++++++++++++++ version.txt | 1 + 9 files changed, 75 insertions(+), 74 deletions(-) mode change 100755 => 100644 amalgamate.py delete mode 100644 include/json/version.h create mode 100644 src/lib_json/version.h.in create mode 100644 version.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index b4eb83039..381d08b0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,18 +63,11 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) endif() project(JSONCPP - # Note: version must be updated in three places when doing a release. This - # annoying process ensures that amalgamate, CMake, and meson all report the - # correct version. - # 1. /meson.build - # 2. /include/json/version.h - # 3. /CMakeLists.txt - # IMPORTANT: also update the SOVERSION!! - VERSION 1.9.2 # [.[.[.]]] + VERSION 1.9.0 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set( JSONCPP_SOVERSION 22 ) +set( JSONCPP_SOVERSION 21 ) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) @@ -96,6 +89,10 @@ set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the libra set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) +# File version.h is only regenerated on CMake configure step +configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" + "${PROJECT_BINARY_DIR}/include/json/version.h" + NEWLINE_STYLE UNIX ) configure_file( "${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_BINARY_DIR}/version" NEWLINE_STYLE UNIX ) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e14b2b31..b7e4ab7af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,6 +26,7 @@ Then, LIB_TYPE=shared #LIB_TYPE=static meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} + #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. ninja -v -C build-${LIB_TYPE} cd build-${LIB_TYPE} meson test --no-rebuild --print-errorlogs diff --git a/amalgamate.py b/amalgamate.py old mode 100755 new mode 100644 index 7b41e2e5b..c12215a8b --- a/amalgamate.py +++ b/amalgamate.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python - """Amalgamate json-cpp library sources into a single source and header file. Works with python2.6+ and python3.4+. @@ -11,9 +9,6 @@ import os.path import sys -INCLUDE_PATH = "include/json" -SRC_PATH = "src/lib_json" - class AmalgamationFile: def __init__(self, top_dir): self.top_dir = top_dir @@ -71,15 +66,15 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file(os.path.join(INCLUDE_PATH, "version.h")) - header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) - header.add_file(os.path.join(INCLUDE_PATH, "config.h")) - header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) - header.add_file(os.path.join(INCLUDE_PATH, "features.h")) - header.add_file(os.path.join(INCLUDE_PATH, "value.h")) - header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) - header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) - header.add_file(os.path.join(INCLUDE_PATH, "assertions.h")) + header.add_file("include/json/version.h") + header.add_file("include/json/allocator.h") + header.add_file("include/json/config.h") + header.add_file("include/json/forwards.h") + header.add_file("include/json/features.h") + header.add_file("include/json/value.h") + header.add_file("include/json/reader.h") + header.add_file("include/json/writer.h") + header.add_file("include/json/assertions.h") header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) @@ -99,8 +94,8 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file(os.path.join(INCLUDE_PATH, "config.h")) - header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) + header.add_file("include/json/config.h") + header.add_file("include/json/forwards.h") header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") target_forward_header_path = os.path.join(os.path.dirname(target_source_path), @@ -121,11 +116,12 @@ def amalgamate_source(source_top_dir=None, #endif """) source.add_text("") - source.add_file(os.path.join(SRC_PATH, "json_tool.h")) - source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) - source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) - source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) - source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) + lib_json = "src/lib_json" + source.add_file(os.path.join(lib_json, "json_tool.h")) + source.add_file(os.path.join(lib_json, "json_reader.cpp")) + source.add_file(os.path.join(lib_json, "json_valueiterator.inl")) + source.add_file(os.path.join(lib_json, "json_value.cpp")) + source.add_file(os.path.join(lib_json, "json_writer.cpp")) print("Writing amalgamated source to %r" % target_source_path) source.write_to(target_source_path) diff --git a/include/json/reader.h b/include/json/reader.h index adbe299bf..f8158cfdb 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -378,7 +378,7 @@ bool JSON_API parseFromStream(CharReader::Factory const&, /** \brief Read from 'sin' into 'root'. * * Always keep comments from the input JSON. - * + * * This can be used to read a file into a particular sub-object. * For example: * \code diff --git a/include/json/version.h b/include/json/version.h deleted file mode 100644 index ff94372b0..000000000 --- a/include/json/version.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef JSON_VERSION_H_INCLUDED -#define JSON_VERSION_H_INCLUDED - -// Note: version must be updated in three places when doing a release. This -// annoying process ensures that amalgamate, CMake, and meson all report the -// correct version. -// 1. /meson.build -// 2. /include/json/version.h -// 3. /CMakeLists.txt -// IMPORTANT: also update the SOVERSION!! - -#define JSONCPP_VERSION_STRING "1.9.2" -#define JSONCPP_VERSION_MAJOR 1 -#define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 2 -#define JSONCPP_VERSION_QUALIFIER -#define JSONCPP_VERSION_HEXA \ - ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ - (JSONCPP_VERSION_PATCH << 8)) - -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif -#define JSONCPP_USING_SECURE_MEMORY 0 -// If non-zero, the library zeroes any memory that it has allocated before -// it frees its memory. - -#endif // JSON_VERSION_H_INCLUDED diff --git a/meson.build b/meson.build index d1f49897a..8de947c4c 100644 --- a/meson.build +++ b/meson.build @@ -1,15 +1,7 @@ project( 'jsoncpp', 'cpp', - - # Note: version must be updated in three places when doing a release. This - # annoying process ensures that amalgamate, CMake, and meson all report the - # correct version. - # 1. /meson.build - # 2. /include/json/version.h - # 3. /CMakeLists.txt - # IMPORTANT: also update the SOVERSION!! - version : '1.9.2', + version : '1.9.0', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -17,6 +9,25 @@ project( license : 'Public Domain', meson_version : '>= 0.50.0') +jsoncpp_ver_arr = meson.project_version().split('.') +jsoncpp_major_version = jsoncpp_ver_arr[0] +jsoncpp_minor_version = jsoncpp_ver_arr[1] +jsoncpp_patch_version = jsoncpp_ver_arr[2] + +jsoncpp_cdata = configuration_data() +jsoncpp_cdata.set('JSONCPP_VERSION', meson.project_version()) +jsoncpp_cdata.set('JSONCPP_VERSION_MAJOR', jsoncpp_major_version) +jsoncpp_cdata.set('JSONCPP_VERSION_MINOR', jsoncpp_minor_version) +jsoncpp_cdata.set('JSONCPP_VERSION_PATCH', jsoncpp_patch_version) +jsoncpp_cdata.set('JSONCPP_USE_SECURE_MEMORY',0) + +jsoncpp_gen_sources = configure_file( + input : 'src/lib_json/version.h.in', + output : 'version.h', + configuration : jsoncpp_cdata, + install : true, + install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'json') +) jsoncpp_headers = [ 'include/json/allocator.h', @@ -28,7 +39,6 @@ jsoncpp_headers = [ 'include/json/json.h', 'include/json/reader.h', 'include/json/value.h', - 'include/json/version.h', 'include/json/writer.h'] jsoncpp_include_directories = include_directories('include') @@ -46,12 +56,13 @@ endif jsoncpp_lib = library( 'jsoncpp', - [ jsoncpp_headers, + [ jsoncpp_gen_sources, + jsoncpp_headers, 'src/lib_json/json_tool.h', 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp'], - soversion : 22, + soversion : 21, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) @@ -68,7 +79,7 @@ jsoncpp_dep = declare_dependency( include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, version : meson.project_version(), - ) + sources : jsoncpp_gen_sources) # tests python = import('python3').find_python() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 0fa2f5953..2392092af 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -45,9 +45,9 @@ set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/features.h ${JSONCPP_INCLUDE_DIR}/json/value.h ${JSONCPP_INCLUDE_DIR}/json/reader.h - ${JSONCPP_INCLUDE_DIR}/json/version.h ${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h + ${PROJECT_BINARY_DIR}/include/json/version.h ) source_group( "Public API" FILES ${PUBLIC_HEADERS} ) @@ -57,7 +57,8 @@ set(jsoncpp_sources json_reader.cpp json_valueiterator.inl json_value.cpp - json_writer.cpp) + json_writer.cpp + version.h.in) # Install instructions for this target if(JSONCPP_WITH_CMAKE_PACKAGE) diff --git a/src/lib_json/version.h.in b/src/lib_json/version.h.in new file mode 100644 index 000000000..4cf439ccc --- /dev/null +++ b/src/lib_json/version.h.in @@ -0,0 +1,22 @@ +// DO NOT EDIT. This file (and "version") is a template used by the build system +// (either CMake or Meson) to generate a "version.h" header file. +#ifndef JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED + +#define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" +#define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ +#define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ +#define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) \ + | (JSONCPP_VERSION_MINOR << 16) \ + | (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@ +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED diff --git a/version.txt b/version.txt new file mode 100644 index 000000000..bfa363e76 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +1.8.4 From 7b28698c5cd00c432cb1b981891b076dd81cd204 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Tue, 13 Aug 2019 22:41:43 -0700 Subject: [PATCH 189/410] Cleanup versioning strategy relanding (#989) (#997) * Cleanup versioning strategy Currently, versioning is a mess. CMake and Meson have seperate build version number storage locations, with no way of knowing you need to have both. Plus, due to recent revisions the amalgamate script is broken unless you build first, and may still be broken afterwards. This PR fixes some issues with versioning, and adds comments clarifying what has to be done when doing a release. * Run clang format * Update SOVERSION.... --- .gitignore | 2 -- CMakeLists.txt | 15 +++++++++------ CONTRIBUTING.md | 1 - amalgamate.py | 38 ++++++++++++++++++++----------------- doc/jsoncpp.dox | 14 +++++++------- include/CMakeLists.txt | 1 - include/json/reader.h | 2 +- include/json/version.h | 28 +++++++++++++++++++++++++++ meson.build | 37 +++++++++++++----------------------- src/lib_json/CMakeLists.txt | 5 ++--- src/lib_json/version.h.in | 22 --------------------- version.txt | 1 - 12 files changed, 81 insertions(+), 85 deletions(-) mode change 100644 => 100755 amalgamate.py create mode 100644 include/json/version.h delete mode 100644 src/lib_json/version.h.in delete mode 100644 version.txt diff --git a/.gitignore b/.gitignore index 7420697c2..91121c230 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,6 @@ /libs/ /doc/doxyfile /dist/ -#/version -#/include/json/version.h # MSVC project files: *.sln diff --git a/CMakeLists.txt b/CMakeLists.txt index 381d08b0a..b4eb83039 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,11 +63,18 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) endif() project(JSONCPP - VERSION 1.9.0 # [.[.[.]]] + # Note: version must be updated in three places when doing a release. This + # annoying process ensures that amalgamate, CMake, and meson all report the + # correct version. + # 1. /meson.build + # 2. /include/json/version.h + # 3. /CMakeLists.txt + # IMPORTANT: also update the SOVERSION!! + VERSION 1.9.2 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set( JSONCPP_SOVERSION 21 ) +set( JSONCPP_SOVERSION 22 ) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) @@ -89,10 +96,6 @@ set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the libra set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) -# File version.h is only regenerated on CMake configure step -configure_file( "${PROJECT_SOURCE_DIR}/src/lib_json/version.h.in" - "${PROJECT_BINARY_DIR}/include/json/version.h" - NEWLINE_STYLE UNIX ) configure_file( "${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_BINARY_DIR}/version" NEWLINE_STYLE UNIX ) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b7e4ab7af..3e14b2b31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,6 @@ Then, LIB_TYPE=shared #LIB_TYPE=static meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} - #ninja -v -C build-${LIB_TYPE} test # This stopped working on my Mac. ninja -v -C build-${LIB_TYPE} cd build-${LIB_TYPE} meson test --no-rebuild --print-errorlogs diff --git a/amalgamate.py b/amalgamate.py old mode 100644 new mode 100755 index c12215a8b..7b41e2e5b --- a/amalgamate.py +++ b/amalgamate.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python + """Amalgamate json-cpp library sources into a single source and header file. Works with python2.6+ and python3.4+. @@ -9,6 +11,9 @@ import os.path import sys +INCLUDE_PATH = "include/json" +SRC_PATH = "src/lib_json" + class AmalgamationFile: def __init__(self, top_dir): self.top_dir = top_dir @@ -66,15 +71,15 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file("include/json/version.h") - header.add_file("include/json/allocator.h") - header.add_file("include/json/config.h") - header.add_file("include/json/forwards.h") - header.add_file("include/json/features.h") - header.add_file("include/json/value.h") - header.add_file("include/json/reader.h") - header.add_file("include/json/writer.h") - header.add_file("include/json/assertions.h") + header.add_file(os.path.join(INCLUDE_PATH, "version.h")) + header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) + header.add_file(os.path.join(INCLUDE_PATH, "config.h")) + header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) + header.add_file(os.path.join(INCLUDE_PATH, "features.h")) + header.add_file(os.path.join(INCLUDE_PATH, "value.h")) + header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) + header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) + header.add_file(os.path.join(INCLUDE_PATH, "assertions.h")) header.add_text("#endif //ifndef JSON_AMALGAMATED_H_INCLUDED") target_header_path = os.path.join(os.path.dirname(target_source_path), header_include_path) @@ -94,8 +99,8 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") - header.add_file("include/json/config.h") - header.add_file("include/json/forwards.h") + header.add_file(os.path.join(INCLUDE_PATH, "config.h")) + header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") target_forward_header_path = os.path.join(os.path.dirname(target_source_path), @@ -116,12 +121,11 @@ def amalgamate_source(source_top_dir=None, #endif """) source.add_text("") - lib_json = "src/lib_json" - source.add_file(os.path.join(lib_json, "json_tool.h")) - source.add_file(os.path.join(lib_json, "json_reader.cpp")) - source.add_file(os.path.join(lib_json, "json_valueiterator.inl")) - source.add_file(os.path.join(lib_json, "json_value.cpp")) - source.add_file(os.path.join(lib_json, "json_writer.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_tool.h")) + source.add_file(os.path.join(SRC_PATH, "json_reader.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_valueiterator.inl")) + source.add_file(os.path.join(SRC_PATH, "json_value.cpp")) + source.add_file(os.path.join(SRC_PATH, "json_writer.cpp")) print("Writing amalgamated source to %r" % target_source_path) source.write_to(target_source_path) diff --git a/doc/jsoncpp.dox b/doc/jsoncpp.dox index 47efc8a35..f340591fd 100644 --- a/doc/jsoncpp.dox +++ b/doc/jsoncpp.dox @@ -3,7 +3,7 @@ \section _intro Introduction JSON (JavaScript Object Notation) - is a lightweight data-interchange format. + is a lightweight data-interchange format. Here is an example of JSON data: \verbatim @@ -23,14 +23,14 @@ Here is an example of JSON data: { // Default encoding for text "encoding" : "UTF-8", - + // Plug-ins loaded at start-up "plug-ins" : [ "python", "c++", // trailing comment "ruby" ], - + // Tab indent size // (multi-line comment) "indent" : { /*embedded comment*/ "length" : 3, "use_space": true } @@ -67,7 +67,7 @@ const Json::Value plugins = root["plug-ins"]; // Iterate over the sequence elements. for ( int index = 0; index < plugins.size(); ++index ) loadPlugIn( plugins[index].asString() ); - + // Try other datatypes. Some are auto-convertible to others. foo::setIndentLength( root["indent"].get("length", 3).asInt() ); foo::setIndentUseSpace( root["indent"].get("use_space", true).asBool() ); @@ -124,7 +124,7 @@ reader->parse(start, stop, &value2, &errs); \endcode \section _pbuild Build instructions -The build instructions are located in the file +The build instructions are located in the file README.md in the top-directory of the project. The latest version of the source is available in the project's GitHub repository: @@ -132,7 +132,7 @@ The latest version of the source is available in the project's GitHub repository jsoncpp \section _news What's New? -The description of latest changes can be found in +The description of latest changes can be found in the NEWS wiki . @@ -152,7 +152,7 @@ The description of latest changes can be found in \section _license License See file LICENSE in the top-directory of the project. -Basically JsonCpp is licensed under MIT license, or public domain if desired +Basically JsonCpp is licensed under MIT license, or public domain if desired and recognized in your jurisdiction. \author Baptiste Lepilleur (originator) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index facfab1c5..dc40d95e8 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,6 +1,5 @@ file(GLOB INCLUDE_FILES "json/*.h") install(FILES ${INCLUDE_FILES} - ${PROJECT_BINARY_DIR}/include/json/version.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/json) diff --git a/include/json/reader.h b/include/json/reader.h index f8158cfdb..adbe299bf 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -378,7 +378,7 @@ bool JSON_API parseFromStream(CharReader::Factory const&, /** \brief Read from 'sin' into 'root'. * * Always keep comments from the input JSON. - * + * * This can be used to read a file into a particular sub-object. * For example: * \code diff --git a/include/json/version.h b/include/json/version.h new file mode 100644 index 000000000..ff94372b0 --- /dev/null +++ b/include/json/version.h @@ -0,0 +1,28 @@ +#ifndef JSON_VERSION_H_INCLUDED +#define JSON_VERSION_H_INCLUDED + +// Note: version must be updated in three places when doing a release. This +// annoying process ensures that amalgamate, CMake, and meson all report the +// correct version. +// 1. /meson.build +// 2. /include/json/version.h +// 3. /CMakeLists.txt +// IMPORTANT: also update the SOVERSION!! + +#define JSONCPP_VERSION_STRING "1.9.2" +#define JSONCPP_VERSION_MAJOR 1 +#define JSONCPP_VERSION_MINOR 9 +#define JSONCPP_VERSION_PATCH 2 +#define JSONCPP_VERSION_QUALIFIER +#define JSONCPP_VERSION_HEXA \ + ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ + (JSONCPP_VERSION_PATCH << 8)) + +#ifdef JSONCPP_USING_SECURE_MEMORY +#undef JSONCPP_USING_SECURE_MEMORY +#endif +#define JSONCPP_USING_SECURE_MEMORY 0 +// If non-zero, the library zeroes any memory that it has allocated before +// it frees its memory. + +#endif // JSON_VERSION_H_INCLUDED diff --git a/meson.build b/meson.build index 8de947c4c..d1f49897a 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,15 @@ project( 'jsoncpp', 'cpp', - version : '1.9.0', + + # Note: version must be updated in three places when doing a release. This + # annoying process ensures that amalgamate, CMake, and meson all report the + # correct version. + # 1. /meson.build + # 2. /include/json/version.h + # 3. /CMakeLists.txt + # IMPORTANT: also update the SOVERSION!! + version : '1.9.2', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -9,25 +17,6 @@ project( license : 'Public Domain', meson_version : '>= 0.50.0') -jsoncpp_ver_arr = meson.project_version().split('.') -jsoncpp_major_version = jsoncpp_ver_arr[0] -jsoncpp_minor_version = jsoncpp_ver_arr[1] -jsoncpp_patch_version = jsoncpp_ver_arr[2] - -jsoncpp_cdata = configuration_data() -jsoncpp_cdata.set('JSONCPP_VERSION', meson.project_version()) -jsoncpp_cdata.set('JSONCPP_VERSION_MAJOR', jsoncpp_major_version) -jsoncpp_cdata.set('JSONCPP_VERSION_MINOR', jsoncpp_minor_version) -jsoncpp_cdata.set('JSONCPP_VERSION_PATCH', jsoncpp_patch_version) -jsoncpp_cdata.set('JSONCPP_USE_SECURE_MEMORY',0) - -jsoncpp_gen_sources = configure_file( - input : 'src/lib_json/version.h.in', - output : 'version.h', - configuration : jsoncpp_cdata, - install : true, - install_dir : join_paths(get_option('prefix'), get_option('includedir'), 'json') -) jsoncpp_headers = [ 'include/json/allocator.h', @@ -39,6 +28,7 @@ jsoncpp_headers = [ 'include/json/json.h', 'include/json/reader.h', 'include/json/value.h', + 'include/json/version.h', 'include/json/writer.h'] jsoncpp_include_directories = include_directories('include') @@ -56,13 +46,12 @@ endif jsoncpp_lib = library( 'jsoncpp', - [ jsoncpp_gen_sources, - jsoncpp_headers, + [ jsoncpp_headers, 'src/lib_json/json_tool.h', 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp'], - soversion : 21, + soversion : 22, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) @@ -79,7 +68,7 @@ jsoncpp_dep = declare_dependency( include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, version : meson.project_version(), - sources : jsoncpp_gen_sources) + ) # tests python = import('python3').find_python() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 2392092af..0fa2f5953 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -45,9 +45,9 @@ set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/features.h ${JSONCPP_INCLUDE_DIR}/json/value.h ${JSONCPP_INCLUDE_DIR}/json/reader.h + ${JSONCPP_INCLUDE_DIR}/json/version.h ${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h - ${PROJECT_BINARY_DIR}/include/json/version.h ) source_group( "Public API" FILES ${PUBLIC_HEADERS} ) @@ -57,8 +57,7 @@ set(jsoncpp_sources json_reader.cpp json_valueiterator.inl json_value.cpp - json_writer.cpp - version.h.in) + json_writer.cpp) # Install instructions for this target if(JSONCPP_WITH_CMAKE_PACKAGE) diff --git a/src/lib_json/version.h.in b/src/lib_json/version.h.in deleted file mode 100644 index 4cf439ccc..000000000 --- a/src/lib_json/version.h.in +++ /dev/null @@ -1,22 +0,0 @@ -// DO NOT EDIT. This file (and "version") is a template used by the build system -// (either CMake or Meson) to generate a "version.h" header file. -#ifndef JSON_VERSION_H_INCLUDED -#define JSON_VERSION_H_INCLUDED - -#define JSONCPP_VERSION_STRING "@JSONCPP_VERSION@" -#define JSONCPP_VERSION_MAJOR @JSONCPP_VERSION_MAJOR@ -#define JSONCPP_VERSION_MINOR @JSONCPP_VERSION_MINOR@ -#define JSONCPP_VERSION_PATCH @JSONCPP_VERSION_PATCH@ -#define JSONCPP_VERSION_QUALIFIER -#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) \ - | (JSONCPP_VERSION_MINOR << 16) \ - | (JSONCPP_VERSION_PATCH << 8)) - -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif -#define JSONCPP_USING_SECURE_MEMORY @JSONCPP_USE_SECURE_MEMORY@ -// If non-zero, the library zeroes any memory that it has allocated before -// it frees its memory. - -#endif // JSON_VERSION_H_INCLUDED diff --git a/version.txt b/version.txt deleted file mode 100644 index bfa363e76..000000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -1.8.4 From 2cf939e8c37494922ca2991902a0fe50baa2eaea Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Wed, 14 Aug 2019 13:42:10 +0800 Subject: [PATCH 190/410] change Value::null to Value::nullSingleton() (#1000) --- src/test_lib_json/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index e700c3801..d0baa867d 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -304,7 +304,7 @@ JSONTEST_FIXTURE(ValueTest, arrayIssue252) { int count = 5; Json::Value root; Json::Value item; - root["array"] = Json::Value::nullRef; + root["array"] = Json::Value::nullSingleton(); for (int i = 0; i < count; i++) { item["a"] = i; item["b"] = i; @@ -337,7 +337,7 @@ JSONTEST_FIXTURE(ValueTest, null) { JSONTEST_ASSERT_EQUAL(0.0, null_.asFloat()); JSONTEST_ASSERT_STRING_EQUAL("", null_.asString()); - JSONTEST_ASSERT_EQUAL(Json::Value::null, null_); + JSONTEST_ASSERT_EQUAL(Json::Value::nullSingleton(), null_); // Test using a Value in a boolean context (false iff null) JSONTEST_ASSERT_EQUAL(null_, false); @@ -1749,7 +1749,7 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { JSONTEST_ASSERT(!root.isMember("h")); JSONTEST_ASSERT(root.isMember(binary)); JSONTEST_ASSERT_STRING_EQUAL( - "there", root.get(binary, Json::Value::nullRef).asString()); + "there", root.get(binary, Json::Value::nullSingleton()).asString()); Json::Value removed; bool did; did = root.removeMember(binary.data(), binary.data() + binary.length(), @@ -1762,7 +1762,7 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { JSONTEST_ASSERT_STRING_EQUAL("there", removed.asString()); // still JSONTEST_ASSERT(!root.isMember(binary)); JSONTEST_ASSERT_STRING_EQUAL( - "", root.get(binary, Json::Value::nullRef).asString()); + "", root.get(binary, Json::Value::nullSingleton()).asString()); } } From b941149a37e3564ba215fd9ea1232649ec3525b5 Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Mon, 26 Aug 2019 21:36:27 +0200 Subject: [PATCH 191/410] tests: Improve CharReaderFailIfExtraTest (#1011) * There was a nonsensical change of 'failIfExtra' before calling strictMode(): the latter resets the former. Dealt with by having one test with pure strictMode and one with strictMode but failIfExtra=false. * The JSONTEST_ASSERT_STRING_EQUAL tests for the error strings swapped the 'expected' and 'actual' values. --- src/test_lib_json/main.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index d0baa867d..c6f2c5c74 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2116,22 +2116,34 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); + JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 13\n" + " Extra non-whitespace after JSON value.\n", + errs); + JSONTEST_ASSERT_EQUAL("property", root); + delete reader; + } + { + b.strictMode(&b.settings_); + Json::CharReader* reader(b.newCharReader()); + Json::String errs; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 13\n" + " Extra non-whitespace after JSON value.\n", + errs); JSONTEST_ASSERT_EQUAL("property", root); delete reader; } { - b.settings_["failIfExtra"] = false; b.strictMode(&b.settings_); + b.settings_["failIfExtra"] = false; Json::CharReader* reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL(errs, - "* Line 1, Column 13\n" - " Extra non-whitespace after JSON value.\n"); + JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 1\n" + " A valid JSON document must be either an array or an object value.\n", + errs); JSONTEST_ASSERT_EQUAL("property", root); delete reader; } From c92c87b47d7f2db163f58ac162432f1a9a60455a Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 27 Aug 2019 03:36:51 +0800 Subject: [PATCH 192/410] Add some test cases in ValueTest (#1010) * add some test cases in ValueTest * add some test cases in ValueTest --- src/test_lib_json/main.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c6f2c5c74..7de849198 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -141,9 +141,17 @@ JSONTEST_FIXTURE(ValueTest, checkNormalizeFloatingPointStr) { JSONTEST_ASSERT_STRING_EQUAL("1234.0", normalizeFloatingPointStr("1234.0")); JSONTEST_ASSERT_STRING_EQUAL("1234.0e0", normalizeFloatingPointStr("1234.0e0")); + JSONTEST_ASSERT_STRING_EQUAL("1234.0e-1", + normalizeFloatingPointStr("1234.0e-1")); JSONTEST_ASSERT_STRING_EQUAL("1234.0e+0", normalizeFloatingPointStr("1234.0e+0")); + JSONTEST_ASSERT_STRING_EQUAL("1234.0e+1", + normalizeFloatingPointStr("1234.0e+001")); JSONTEST_ASSERT_STRING_EQUAL("1234e-1", normalizeFloatingPointStr("1234e-1")); + JSONTEST_ASSERT_STRING_EQUAL("1234e+0", + normalizeFloatingPointStr("1234e+000")); + JSONTEST_ASSERT_STRING_EQUAL("1234e+1", + normalizeFloatingPointStr("1234e+001")); JSONTEST_ASSERT_STRING_EQUAL("1234e10", normalizeFloatingPointStr("1234e10")); JSONTEST_ASSERT_STRING_EQUAL("1234e10", normalizeFloatingPointStr("1234e010")); @@ -155,8 +163,6 @@ JSONTEST_FIXTURE(ValueTest, checkNormalizeFloatingPointStr) { normalizeFloatingPointStr("1234e+100")); JSONTEST_ASSERT_STRING_EQUAL("1234e-100", normalizeFloatingPointStr("1234e-100")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+1", - normalizeFloatingPointStr("1234e+001")); } JSONTEST_FIXTURE(ValueTest, memberCount) { @@ -172,6 +178,9 @@ JSONTEST_FIXTURE(ValueTest, memberCount) { JSONTEST_ASSERT_PRED(checkMemberCount(emptyString_, 0)); JSONTEST_ASSERT_PRED(checkMemberCount(string_, 0)); JSONTEST_ASSERT_PRED(checkMemberCount(true_, 0)); + JSONTEST_ASSERT_PRED(checkMemberCount(false_, 0)); + JSONTEST_ASSERT_PRED(checkMemberCount(string1_, 0)); + JSONTEST_ASSERT_PRED(checkMemberCount(float_, 0)); } JSONTEST_FIXTURE(ValueTest, objects) { From 472adb60eec34f9af430e099384e68772be86971 Mon Sep 17 00:00:00 2001 From: aliha Date: Mon, 26 Aug 2019 15:37:05 -0400 Subject: [PATCH 193/410] Fix a coupe of typos (#1007) --- include/json/reader.h | 2 +- include/json/value.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index adbe299bf..947fc0035 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -122,7 +122,7 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP */ String getFormattedErrorMessages() const; - /** \brief Returns a vector of structured erros encounted while parsing. + /** \brief Returns a vector of structured errors encountered while parsing. * * \return A (possibly empty) vector of StructuredError objects. Currently * only one error can be returned, but the caller should tolerate multiple diff --git a/include/json/value.h b/include/json/value.h index a47884854..e1340d62b 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -684,7 +684,7 @@ class JSON_API PathArgument { * - ".name1.name2.name3" * - ".[0][1][2].name1[3]" * - ".%" => member name is provided as parameter - * - ".[%]" => index is provied as parameter + * - ".[%]" => index is provided as parameter */ class JSON_API Path { public: From fd940255ced7773489f818e62d7074fbcfda81cc Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 27 Aug 2019 03:47:54 +0800 Subject: [PATCH 194/410] change the returned value (#1003) --- src/lib_json/json_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 005ab2689..1d614a4a1 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -311,7 +311,7 @@ bool Reader::readToken(Token& token) { if (!ok) token.type_ = tokenError; token.end_ = current_; - return true; + return ok; } void Reader::skipSpaces() { @@ -1274,7 +1274,7 @@ bool OurReader::readToken(Token& token) { if (!ok) token.type_ = tokenError; token.end_ = current_; - return true; + return ok; } void OurReader::skipSpaces() { From 21ab82916b00cf09673694c34fa8942b6b987bb9 Mon Sep 17 00:00:00 2001 From: Google AutoFuzz Team Date: Mon, 16 Sep 2019 10:30:59 -0700 Subject: [PATCH 195/410] Add dictionary for fuzzing (#1020) --- src/test_lib_json/fuzz.dict | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/test_lib_json/fuzz.dict diff --git a/src/test_lib_json/fuzz.dict b/src/test_lib_json/fuzz.dict new file mode 100644 index 000000000..725423d2f --- /dev/null +++ b/src/test_lib_json/fuzz.dict @@ -0,0 +1,54 @@ +# +# AFL dictionary for JSON +# ----------------------- +# +# Just the very basics. +# +# Inspired by a dictionary by Jakub Wilk +# +# https://github.com/rc0r/afl-fuzz/blob/master/dictionaries/json.dict +# + +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + +"\"\":0" +"//" +"/**/" From 3550a0a93940525bc32230fd851975631ed3f196 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 01:32:46 +0800 Subject: [PATCH 196/410] add some testcases: WriteTest, StreamWriterTest (#1015) --- src/test_lib_json/main.cpp | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 7de849198..cc5ebf2a2 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1864,6 +1864,27 @@ JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) { JSONTEST_ASSERT(writer.write(nullValue) == "\n"); } +JSONTEST_FIXTURE(WriterTest, enableYAMLCompatibility) { + Json::FastWriter writer; + Json::Value root; + root["hello"] = "world"; + + JSONTEST_ASSERT(writer.write(root) == "{\"hello\":\"world\"}\n"); + + writer.enableYAMLCompatibility(); + JSONTEST_ASSERT(writer.write(root) == "{\"hello\": \"world\"}\n"); +} + +JSONTEST_FIXTURE(WriterTest, omitEndingLineFeed) { + Json::FastWriter writer; + Json::Value nullValue; + + JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); + + writer.omitEndingLineFeed(); + JSONTEST_ASSERT(writer.write(nullValue) == "null"); +} + struct StreamWriterTest : JsonTest::TestCase {}; JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { @@ -1875,6 +1896,33 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { JSONTEST_ASSERT(Json::writeString(b, nullValue).empty()); } +JSONTEST_FIXTURE(StreamWriterTest, enableYAMLCompatibility) { + Json::StreamWriterBuilder b; + Json::Value root; + root["hello"] = "world"; + + b.settings_["indentation"] = ""; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); + + b.settings_["enableYAMLCompatibility"] = true; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\": \"world\"}"); + + b.settings_["enableYAMLCompatibility"] = false; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); +} + +JSONTEST_FIXTURE(StreamWriterTest, indentation) { + Json::StreamWriterBuilder b; + Json::Value root; + root["hello"] = "world"; + + b.settings_["indentation"] = ""; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); + + b.settings_["indentation"] = "\t"; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"hello\" : \"world\"\n}"); +} + JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { Json::String binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); @@ -2622,7 +2670,11 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, ValueTest, precision); JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders); + JSONTEST_REGISTER_FIXTURE(runner, WriterTest, enableYAMLCompatibility); + JSONTEST_REGISTER_FIXTURE(runner, WriterTest, omitEndingLineFeed); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, enableYAMLCompatibility); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, indentation); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes); JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors); From 7ef0f9fa5bc1e9dcd2cbba8202dac65fae083a03 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 01:33:47 +0800 Subject: [PATCH 197/410] [Language Conformance] Use constexpr restriction in jsoncpp (#1005) * use constexpr restriction in jsoncpp * remove TODO comment --- include/json/value.h | 26 ++++++++++++++------------ src/lib_json/json_reader.cpp | 9 ++++----- src/lib_json/json_value.cpp | 17 ----------------- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index e1340d62b..c9729241a 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -203,31 +203,33 @@ class JSON_API Value { static Value const& nullSingleton(); /// Minimum signed integer value that can be stored in a Json::Value. - static const LargestInt minLargestInt; + static constexpr LargestInt minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); /// Maximum signed integer value that can be stored in a Json::Value. - static const LargestInt maxLargestInt; + static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2); /// Maximum unsigned integer value that can be stored in a Json::Value. - static const LargestUInt maxLargestUInt; + static constexpr LargestUInt maxLargestUInt = LargestUInt(-1); /// Minimum signed int value that can be stored in a Json::Value. - static const Int minInt; + static constexpr Int minInt = Int(~(UInt(-1) / 2)); /// Maximum signed int value that can be stored in a Json::Value. - static const Int maxInt; + static constexpr Int maxInt = Int(UInt(-1) / 2); /// Maximum unsigned int value that can be stored in a Json::Value. - static const UInt maxUInt; + static constexpr UInt maxUInt = UInt(-1); #if defined(JSON_HAS_INT64) /// Minimum signed 64 bits int value that can be stored in a Json::Value. - static const Int64 minInt64; + static constexpr Int64 minInt64 = Int64(~(UInt64(-1) / 2)); /// Maximum signed 64 bits int value that can be stored in a Json::Value. - static const Int64 maxInt64; + static constexpr Int64 maxInt64 = Int64(UInt64(-1) / 2); /// Maximum unsigned 64 bits int value that can be stored in a Json::Value. - static const UInt64 maxUInt64; + static constexpr UInt64 maxUInt64 = UInt64(-1); #endif // defined(JSON_HAS_INT64) - /// Default precision for real value for string representation. - static const UInt defaultRealPrecision; - + static constexpr UInt defaultRealPrecision = 17; + // The constant is hard-coded because some compiler have trouble + // converting Value::maxUInt64 to a double correctly (AIX/xlC). + // Assumes that UInt64 is a 64 bits integer. + static constexpr double maxUInt64AsDouble = 18446744073709551615.0; // Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler // when using gcc and clang backend compilers. CZString // cannot be defined as private. See issue #486 diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 1d614a4a1..87e9c67db 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1548,12 +1548,11 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (isNegative) ++current; - // TODO(issue #960): Change to constexpr - static const auto positive_threshold = Value::maxLargestUInt / 10; - static const auto positive_last_digit = Value::maxLargestUInt % 10; - static const auto negative_threshold = + static constexpr auto positive_threshold = Value::maxLargestUInt / 10; + static constexpr auto positive_last_digit = Value::maxLargestUInt % 10; + static constexpr auto negative_threshold = Value::LargestUInt(Value::minLargestInt) / 10; - static const auto negative_last_digit = + static constexpr auto negative_last_digit = Value::LargestUInt(Value::minLargestInt) % 10; const auto threshold = isNegative ? negative_threshold : positive_threshold; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6024212f2..771c0dc99 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -88,23 +88,6 @@ Value const& Value::null = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton(); #endif -const Int Value::minInt = Int(~(UInt(-1) / 2)); -const Int Value::maxInt = Int(UInt(-1) / 2); -const UInt Value::maxUInt = UInt(-1); -#if defined(JSON_HAS_INT64) -const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2)); -const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2); -const UInt64 Value::maxUInt64 = UInt64(-1); -// The constant is hard-coded because some compiler have trouble -// converting Value::maxUInt64 to a double correctly (AIX/xlC). -// Assumes that UInt64 is a 64 bits integer. -static const double maxUInt64AsDouble = 18446744073709551615.0; -#endif // defined(JSON_HAS_INT64) -const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); -const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2); -const LargestUInt Value::maxLargestUInt = LargestUInt(-1); - -const UInt Value::defaultRealPrecision = 17; #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template From db61dba885bb2314b5626a716c1aa96f5221dfc7 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 01:35:48 +0800 Subject: [PATCH 198/410] Improving Code Readability (#1004) --- include/json/reader.h | 2 +- src/lib_json/json_reader.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index 947fc0035..b94b30724 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -193,7 +193,7 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP bool readToken(Token& token); void skipSpaces(); - bool match(Location pattern, int patternLength); + bool match(const Char* pattern, int patternLength); bool readComment(); bool readCStyleComment(); bool readCppStyleComment(); diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 87e9c67db..8cc4f43c3 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -324,7 +324,7 @@ void Reader::skipSpaces() { } } -bool Reader::match(Location pattern, int patternLength) { +bool Reader::match(const Char* pattern, int patternLength) { if (end_ - current_ < patternLength) return false; int index = patternLength; @@ -416,7 +416,7 @@ bool Reader::readCppStyleComment() { } void Reader::readNumber() { - const char* p = current_; + Location p = current_; char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') @@ -956,7 +956,7 @@ class OurReader { bool readToken(Token& token); void skipSpaces(); - bool match(Location pattern, int patternLength); + bool match(const Char* pattern, int patternLength); bool readComment(); bool readCStyleComment(); bool readCppStyleComment(); @@ -1287,7 +1287,7 @@ void OurReader::skipSpaces() { } } -bool OurReader::match(Location pattern, int patternLength) { +bool OurReader::match(const Char* pattern, int patternLength) { if (end_ - current_ < patternLength) return false; int index = patternLength; @@ -1380,7 +1380,7 @@ bool OurReader::readCppStyleComment() { } bool OurReader::readNumber(bool checkInf) { - const char* p = current_; + Location p = current_; if (checkInf && p != end_ && *p == 'I') { current_ = ++p; return false; From d622250c3e378484b572c26b2b1db98bfc8c4c9b Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 01:40:09 +0800 Subject: [PATCH 199/410] Check the comments array boundry. (#993) * check the comments array boundry * remove empty line --- src/lib_json/json_value.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 771c0dc99..730794d3d 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1450,7 +1450,10 @@ void Value::Comments::set(CommentPlacement slot, String comment) { if (!ptr_) { ptr_ = std::unique_ptr(new Array()); } - (*ptr_)[slot] = std::move(comment); + // check comments array boundry. + if (slot < CommentPlacement::numberOfCommentPlacement) { + (*ptr_)[slot] = std::move(comment); + } } void Value::setComment(String comment, CommentPlacement placement) { From abcd3f7b1fff42638a9848909611f21595bf820a Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 01:40:35 +0800 Subject: [PATCH 200/410] Modify code comments in write.h (#987) * modify code comments in write.h * update --- include/json/writer.h | 108 +++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/include/json/writer.h b/include/json/writer.h index 328014166..7eab29ef8 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -27,17 +27,17 @@ namespace Json { class Value; /** - -Usage: -\code - using namespace Json; - void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { - std::unique_ptr const writer( - factory.newStreamWriter()); - writer->write(value, &std::cout); - std::cout << std::endl; // add lf and flush - } -\endcode +* +* Usage: +* \code +* using namespace Json; +* void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { +* std::unique_ptr const writer( +* factory.newStreamWriter()); +* writer->write(value, &std::cout); +* std::cout << std::endl; // add lf and flush +* } +* \endcode */ class JSON_API StreamWriter { protected: @@ -45,12 +45,12 @@ class JSON_API StreamWriter { public: StreamWriter(); virtual ~StreamWriter(); - /** Write Value into document as configured in sub-class. - Do not take ownership of sout, but maintain a reference during function. - \pre sout != NULL - \return zero on success (For now, we always return zero, so check the - stream instead.) \throw std::exception possibly, depending on configuration - */ +/** Write Value into document as configured in sub-class. +* Do not take ownership of sout, but maintain a reference during function. +* \pre sout != NULL +* \return zero on success (For now, we always return zero, so check the +* stream instead.) \throw std::exception possibly, depending on configuration +*/ virtual int write(Value const& root, OStream* sout) = 0; /** \brief A simple abstract factory. @@ -73,49 +73,49 @@ String JSON_API writeString(StreamWriter::Factory const& factory, /** \brief Build a StreamWriter implementation. -Usage: -\code - using namespace Json; - Value value = ...; - StreamWriterBuilder builder; - builder["commentStyle"] = "None"; - builder["indentation"] = " "; // or whatever you like - std::unique_ptr writer( - builder.newStreamWriter()); - writer->write(value, &std::cout); - std::cout << std::endl; // add lf and flush -\endcode +* Usage: +* \code +* using namespace Json; +* Value value = ...; +* StreamWriterBuilder builder; +* builder["commentStyle"] = "None"; +* builder["indentation"] = " "; // or whatever you like +* std::unique_ptr writer( +* builder.newStreamWriter()); +* writer->write(value, &std::cout); +* std::cout << std::endl; // add lf and flush +* \endcode */ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { public: // Note: We use a Json::Value so that we can add data-members to this class // without a major version bump. /** Configuration of this builder. - Available settings (case-sensitive): - - "commentStyle": "None" or "All" - - "indentation": "". - - Setting this to an empty string also omits newline characters. - - "enableYAMLCompatibility": false or true - - slightly change the whitespace around colons - - "dropNullPlaceholders": false or true - - Drop the "null" string from the writer's output for nullValues. - Strictly speaking, this is not valid JSON. But when the output is being - fed to a browser's JavaScript, it makes for smaller output and the - browser can handle the output just fine. - - "useSpecialFloats": false or true - - If true, outputs non-finite floating point values in the following way: - NaN values as "NaN", positive infinity as "Infinity", and negative - infinity as "-Infinity". - - "precision": int - - Number of precision digits for formatting of real values. - - "precisionType": "significant"(default) or "decimal" - - Type of precision for formatting of real values. - - You can examine 'settings_` yourself - to see the defaults. You can also write and read them just like any - JSON Value. - \sa setDefaults() - */ + * Available settings (case-sensitive): + * - "commentStyle": "None" or "All" + * - "indentation": "". + * - Setting this to an empty string also omits newline characters. + * - "enableYAMLCompatibility": false or true + * - slightly change the whitespace around colons + * - "dropNullPlaceholders": false or true + * - Drop the "null" string from the writer's output for nullValues. + * Strictly speaking, this is not valid JSON. But when the output is being + * fed to a browser's JavaScript, it makes for smaller output and the + * browser can handle the output just fine. + * - "useSpecialFloats": false or true + * - If true, outputs non-finite floating point values in the following way: + * NaN values as "NaN", positive infinity as "Infinity", and negative + * infinity as "-Infinity". + * - "precision": int + * - Number of precision digits for formatting of real values. + * - "precisionType": "significant"(default) or "decimal" + * - Type of precision for formatting of real values. + + * You can examine 'settings_` yourself + * to see the defaults. You can also write and read them just like any + * JSON Value. + * \sa setDefaults() + */ Json::Value settings_; StreamWriterBuilder(); From c5cb313ca0652f5669624648d972d5fbaa96000c Mon Sep 17 00:00:00 2001 From: Frank Richter Date: Mon, 16 Sep 2019 19:41:50 +0200 Subject: [PATCH 201/410] Do not allow tokenError tokens after input if failIfExtra is set. (#1014) Currently when failIfExtra is set and strictRoot is not set, OurReader::parse() will accept trailing non-whitespace after the JSON value as long as the first token is not a valid JSON token. This commit changes this to disallow any non-whitespace after the JSON value. This commit also suppresses the "Extra non-whitespace after JSON value." error message if parsing was aborted after another error. --- src/lib_json/json_reader.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 8cc4f43c3..8dad1d147 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1051,12 +1051,9 @@ bool OurReader::parse(const char* beginDoc, nodes_.pop(); Token token; skipCommentTokens(token); - if (features_.failIfExtra_) { - if ((features_.strictRoot_ || token.type_ != tokenError) && - token.type_ != tokenEndOfStream) { - addError("Extra non-whitespace after JSON value.", token); - return false; - } + if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) { + addError("Extra non-whitespace after JSON value.", token); + return false; } if (collectComments_ && !commentsBefore_.empty()) root.setComment(commentsBefore_, commentAfter); From 2cb9a5803e5123efcc0a08f7c3f52dd521917a34 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Tue, 17 Sep 2019 02:25:22 +0800 Subject: [PATCH 202/410] reinforce readToken function and add simple tests (#1012) --- src/lib_json/json_reader.cpp | 8 ++++++++ src/test_lib_json/main.cpp | 11 +++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 8dad1d147..6a1c76578 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1227,6 +1227,14 @@ bool OurReader::readToken(Token& token) { ok = features_.allowSpecialFloats_ && match("nfinity", 7); } break; + case '+': + if (readNumber(true)) { + token.type_ = tokenNumber; + } else { + token.type_ = tokenPosInf; + ok = features_.allowSpecialFloats_ && match("nfinity", 7); + } + break; case 't': token.type_ = tokenTrue; ok = match("rue", 3); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index cc5ebf2a2..6d3a0224a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2451,17 +2451,19 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::String errs; Json::CharReader* reader(b.newCharReader()); { - char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity}"; + char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(3u, root.size()); + JSONTEST_ASSERT_EQUAL(4u, root.size()); double n = root["a"].asDouble(); JSONTEST_ASSERT(std::isnan(n)); JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), root.get("b", 0.0)); JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root.get("c", 0.0)); + JSONTEST_ASSERT_EQUAL(std::numeric_limits::infinity(), + root.get("d", 0.0)); } struct TestData { @@ -2485,7 +2487,8 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { {__LINE__, false, "{\"a\":.Infinity}"}, // {__LINE__, false, "{\"a\":_Infinity}"}, // {__LINE__, false, "{\"a\":_nfinity}"}, // - {__LINE__, true, "{\"a\":-Infinity}"} // + {__LINE__, true, "{\"a\":-Infinity}"}, // + {__LINE__, true, "{\"a\":+Infinity}"} // }; for (const auto& td : test_data) { bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), @@ -2499,7 +2502,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { } { - char const doc[] = "{\"posInf\": Infinity, \"NegInf\": -Infinity}"; + char const doc[] = "{\"posInf\": +Infinity, \"NegInf\": -Infinity}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); From 3013ed48b333c70d5960393412a3b2c541cc97ba Mon Sep 17 00:00:00 2001 From: m-gupta Date: Mon, 16 Sep 2019 12:24:13 -0700 Subject: [PATCH 203/410] jsoncpp: Define JSON_USE_INT64_DOUBLE_CONVERSION for clang as well. (#1002) The current check to define JSON_USE_INT64_DOUBLE_CONVERSION works for GCC but not clang. Clang does define __GNUC__ but with a value 4 which misses the check for >= 6. This avoids the -Wimplicit-int-float-conversion warning when jsoncpp is built with a recent version of clang. Signed-off-by: Manoj Gupta --- include/json/config.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/json/config.h b/include/json/config.h index 6426c3b29..0ff5968e7 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -104,7 +104,9 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_OP_EXPLICIT #endif -#if defined(__GNUC__) && (__GNUC__ >= 6) +#if defined(__clang__) +#define JSON_USE_INT64_DOUBLE_CONVERSION 1 +#elif defined(__GNUC__) && (__GNUC__ >= 6) #define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif From 18f790fbe7854c30415b08e88ce115fc10488059 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 16 Sep 2019 12:27:59 -0700 Subject: [PATCH 204/410] Issue 1021: Fix clang 10 compilation (#1023) This patch fixes an implicit long to double conversion, fixing compilation on the as-of-yet unreleased clang v10. --- src/lib_json/json_value.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 730794d3d..152f2abaf 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -94,8 +94,7 @@ template static inline bool InRange(double d, T min, U max) { // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn - // return d >= static_cast(min) && d <= static_cast(max); - return d >= min && d <= max; + return d >= static_cast(min) && d <= static_cast(max); } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) static inline double integerToDouble(Json::UInt64 value) { From 81ae1d55f78eec0c097029c782e26f5e79bc33a3 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 16 Sep 2019 12:37:14 -0700 Subject: [PATCH 205/410] Just run clang format (#1025) --- include/json/reader.h | 54 +++++++++++++++------------------- include/json/value.h | 10 +++---- include/json/writer.h | 46 ++++++++++++++--------------- src/lib_json/json_value.cpp | 1 - src/test_lib_json/jsontest.cpp | 4 +-- src/test_lib_json/main.cpp | 17 ++++++----- 6 files changed, 64 insertions(+), 68 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index b94b30724..8b388b0a8 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -36,7 +36,8 @@ namespace Json { * * \deprecated Use CharReader and CharReaderBuilder. */ -class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_API Reader { +class [[deprecated( + "deprecated Use CharReader and CharReaderBuilder.")]] JSON_API Reader { public: typedef char Char; typedef const Char* Location; @@ -74,8 +75,8 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ - bool - parse(const std::string& document, Value& root, bool collectComments = true); + bool parse(const std::string& document, Value& root, + bool collectComments = true); /** \brief Read a Value from a JSON * document. @@ -93,14 +94,12 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ - bool parse(const char* beginDoc, - const char* endDoc, - Value& root, + bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); /// \brief Parse from input stream. /// \see Json::operator>>(std::istream&, Json::Value&). - bool parse(IStream& is, Value& root, bool collectComments = true); + bool parse(IStream & is, Value & root, bool collectComments = true); /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -110,8 +109,8 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP * occurred during parsing. * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ - [[deprecated("Use getFormattedErrorMessages() instead.")]] - String getFormatedErrorMessages() const; + [[deprecated("Use getFormattedErrorMessages() instead.")]] String + getFormatedErrorMessages() const; /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -191,7 +190,7 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP typedef std::deque Errors; - bool readToken(Token& token); + bool readToken(Token & token); void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); @@ -200,35 +199,30 @@ class [[deprecated("deprecated Use CharReader and CharReaderBuilder.")]] JSON_AP bool readString(); void readNumber(); bool readValue(); - bool readObject(Token& token); - bool readArray(Token& token); - bool decodeNumber(Token& token); - bool decodeNumber(Token& token, Value& decoded); - bool decodeString(Token& token); - bool decodeString(Token& token, String& decoded); - bool decodeDouble(Token& token); - bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, + bool readObject(Token & token); + bool readArray(Token & token); + bool decodeNumber(Token & token); + bool decodeNumber(Token & token, Value & decoded); + bool decodeString(Token & token); + bool decodeString(Token & token, String & decoded); + bool decodeDouble(Token & token); + bool decodeDouble(Token & token, Value & decoded); + bool decodeUnicodeCodePoint(Token & token, Location & current, Location end, unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token & token, Location & current, + Location end, unsigned int& unicode); bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const String& message, - Token& token, + bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); Value& currentValue(); Char getNextChar(); - void - getLocationLineAndColumn(Location location, int& line, int& column) const; + void getLocationLineAndColumn(Location location, int& line, int& column) + const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); + void skipCommentTokens(Token & token); static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); diff --git a/include/json/value.h b/include/json/value.h index c9729241a..aa7bc5425 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -203,7 +203,8 @@ class JSON_API Value { static Value const& nullSingleton(); /// Minimum signed integer value that can be stored in a Json::Value. - static constexpr LargestInt minLargestInt = LargestInt(~(LargestUInt(-1) / 2)); + static constexpr LargestInt minLargestInt = + LargestInt(~(LargestUInt(-1) / 2)); /// Maximum signed integer value that can be stored in a Json::Value. static constexpr LargestInt maxLargestInt = LargestInt(LargestUInt(-1) / 2); /// Maximum unsigned integer value that can be stored in a Json::Value. @@ -566,8 +567,8 @@ class JSON_API Value { //# endif /// \deprecated Always pass len. - [[deprecated("Use setComment(String const&) instead.")]] - void setComment(const char* comment, CommentPlacement placement) { + [[deprecated("Use setComment(String const&) instead.")]] void + setComment(const char* comment, CommentPlacement placement) { setComment(String(comment, strlen(comment)), placement); } /// Comments must be //... or /* ... */ @@ -752,8 +753,7 @@ class JSON_API ValueIteratorBase { /// objectValue. /// \deprecated This cannot be used for UTF-8 strings, since there can be /// embedded nulls. - [[deprecated("Use `key = name();` instead.")]] - char const* memberName() const; + [[deprecated("Use `key = name();` instead.")]] char const* memberName() const; /// Return the member name of the referenced Value, or NULL if it is not an /// objectValue. /// \note Better version than memberName(). Allows embedded nulls. diff --git a/include/json/writer.h b/include/json/writer.h index 7eab29ef8..9799a3bb3 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -27,30 +27,30 @@ namespace Json { class Value; /** -* -* Usage: -* \code -* using namespace Json; -* void writeToStdout(StreamWriter::Factory const& factory, Value const& value) { -* std::unique_ptr const writer( -* factory.newStreamWriter()); -* writer->write(value, &std::cout); -* std::cout << std::endl; // add lf and flush -* } -* \endcode -*/ + * + * Usage: + * \code + * using namespace Json; + * void writeToStdout(StreamWriter::Factory const& factory, Value const& value) + * { std::unique_ptr const writer( factory.newStreamWriter()); + * writer->write(value, &std::cout); + * std::cout << std::endl; // add lf and flush + * } + * \endcode + */ class JSON_API StreamWriter { protected: OStream* sout_; // not owned; will not delete public: StreamWriter(); virtual ~StreamWriter(); -/** Write Value into document as configured in sub-class. -* Do not take ownership of sout, but maintain a reference during function. -* \pre sout != NULL -* \return zero on success (For now, we always return zero, so check the -* stream instead.) \throw std::exception possibly, depending on configuration -*/ + /** Write Value into document as configured in sub-class. + * Do not take ownership of sout, but maintain a reference during function. + * \pre sout != NULL + * \return zero on success (For now, we always return zero, so check the + * stream instead.) \throw std::exception possibly, depending on + * configuration + */ virtual int write(Value const& root, OStream* sout) = 0; /** \brief A simple abstract factory. @@ -225,8 +225,8 @@ class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API FastWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API - StyledWriter : public Writer { +class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API StyledWriter + : public Writer { public: StyledWriter(); ~StyledWriter() override = default; @@ -294,8 +294,8 @@ class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API - StyledStreamWriter { +class [[deprecated( + "Use StreamWriterBuilder instead")]] JSON_API StyledStreamWriter { public: /** * \param indentation Each level will be indented by this amount extra. @@ -310,7 +310,7 @@ class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API * \note There is no point in deriving from Writer, since write() should not * return a value. */ - void write(OStream& out, const Value& root); + void write(OStream & out, const Value& root); private: void writeValue(const Value& value); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 152f2abaf..4f71e77cc 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -88,7 +88,6 @@ Value const& Value::null = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton(); #endif - #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template static inline bool InRange(double d, T min, U max) { diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 4c59d07b5..c0b5296d9 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -378,8 +378,8 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) -// @todo investigate this handler (for buffer overflow) -// _set_security_error_handler + // @todo investigate this handler (for buffer overflow) + // _set_security_error_handler #if defined(_WIN32) // Prevents the system from popping a dialog for debugging if the diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 6d3a0224a..21adef32c 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1920,7 +1920,8 @@ JSONTEST_FIXTURE(StreamWriterTest, indentation) { JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); b.settings_["indentation"] = "\t"; - JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"hello\" : \"world\"\n}"); + JSONTEST_ASSERT(Json::writeString(b, root) == + "{\n\t\"hello\" : \"world\"\n}"); } JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { @@ -2198,9 +2199,10 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT_STRING_EQUAL("* Line 1, Column 1\n" - " A valid JSON document must be either an array or an object value.\n", - errs); + JSONTEST_ASSERT_STRING_EQUAL( + "* Line 1, Column 1\n" + " A valid JSON document must be either an array or an object value.\n", + errs); JSONTEST_ASSERT_EQUAL("property", root); delete reader; } @@ -2451,7 +2453,8 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { Json::String errs; Json::CharReader* reader(b.newCharReader()); { - char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; + char const doc[] = + "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -2487,7 +2490,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { {__LINE__, false, "{\"a\":.Infinity}"}, // {__LINE__, false, "{\"a\":_Infinity}"}, // {__LINE__, false, "{\"a\":_nfinity}"}, // - {__LINE__, true, "{\"a\":-Infinity}"}, // + {__LINE__, true, "{\"a\":-Infinity}"}, // {__LINE__, true, "{\"a\":+Infinity}"} // }; for (const auto& td : test_data) { @@ -2594,7 +2597,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( Json::Value::iterator it(v.begin()) // Compile, but throw. - ); + ); Json::Value value; From c97bd59ff293cf5a03d4cef0300957d21a1a8517 Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 18 Sep 2019 03:46:29 +0800 Subject: [PATCH 206/410] add a testcase in ValueTest:CopyObject (#1028) --- src/test_lib_json/main.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 21adef32c..b0106bd62 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1515,6 +1515,24 @@ JSONTEST_FIXTURE(ValueTest, CopyObject) { JSONTEST_ASSERT(copy1 == "string value"); copy2.copy(arrayVal); JSONTEST_ASSERT(copy2.size() == 5); + { + Json::Value srcObject, objectCopy, otherObject; + srcObject["key0"] = 10; + objectCopy.copy(srcObject); + JSONTEST_ASSERT(srcObject["key0"] == 10); + JSONTEST_ASSERT(objectCopy["key0"] == 10); + JSONTEST_ASSERT(srcObject.getMemberNames().size() == 1); + JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 1); + otherObject["key1"] = 15; + otherObject["key2"] = 16; + JSONTEST_ASSERT(otherObject.getMemberNames().size() == 2); + objectCopy.copy(otherObject); + JSONTEST_ASSERT(objectCopy["key1"] == 15); + JSONTEST_ASSERT(objectCopy["key2"] == 16); + JSONTEST_ASSERT(objectCopy.getMemberNames().size() == 2); + otherObject["key1"] = 20; + JSONTEST_ASSERT(objectCopy["key1"] == 15); + } } void ValueTest::checkIsLess(const Json::Value& x, const Json::Value& y) { From 21e3d2124353ae27fdafe80a7b3081b5dad49609 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 17 Sep 2019 12:46:55 -0700 Subject: [PATCH 207/410] pkgconfig: Fix for cross compilation (#1027) exec_ and prefix must be overridden in such a case. Makes the .pc file more consistent with other projects. --- pkg-config/jsoncpp.pc.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg-config/jsoncpp.pc.in b/pkg-config/jsoncpp.pc.in index dea51f512..d4fa9ef26 100644 --- a/pkg-config/jsoncpp.pc.in +++ b/pkg-config/jsoncpp.pc.in @@ -1,5 +1,7 @@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: jsoncpp Description: A C++ library for interacting with JSON From e9ccbe01453908cd1753dbe882ffe5349f82cd93 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Wed, 18 Sep 2019 04:30:00 +0800 Subject: [PATCH 208/410] Create an example directory and add some code examples. (#944) * update example directory * modify some compile error. * update with clang-format * update * update * add_definitions("../include/json") # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jul 10 21:26:16 2019 +0800 # # On branch code_example # Your branch is up-to-date with 'origin/code_example'. # # Changes to be committed: # modified: example/CMakeLists.txt # * change CMakeLists.txt * update streamWrite.cpp * update * Update readFromStream.cpp * fix typo --- CMakeLists.txt | 2 ++ example/CMakeLists.txt | 29 ++++++++++++++++++ example/README.md | 13 ++++++++ example/readFromStream/errorFormat.json | 3 ++ example/readFromStream/readFromStream.cpp | 30 ++++++++++++++++++ example/readFromStream/withComment.json | 6 ++++ example/readFromString/readFromString.cpp | 37 +++++++++++++++++++++++ example/streamWrite/streamWrite.cpp | 22 ++++++++++++++ example/stringWrite/stringWrite.cpp | 33 ++++++++++++++++++++ src/test_lib_json/jsontest.cpp | 4 +-- src/test_lib_json/main.cpp | 2 +- 11 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 example/CMakeLists.txt create mode 100644 example/README.md create mode 100644 example/readFromStream/errorFormat.json create mode 100644 example/readFromStream/readFromStream.cpp create mode 100644 example/readFromStream/withComment.json create mode 100644 example/readFromString/readFromString.cpp create mode 100644 example/streamWrite/streamWrite.cpp create mode 100644 example/stringWrite/stringWrite.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b4eb83039..9f2bab55f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,3 +187,5 @@ add_subdirectory( src ) #install the includes add_subdirectory( include ) +#install the example +add_subdirectory( example ) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt new file mode 100644 index 000000000..c8eba5335 --- /dev/null +++ b/example/CMakeLists.txt @@ -0,0 +1,29 @@ +#vim: et ts =4 sts = 4 sw = 4 tw = 0 +cmake_minimum_required(VERSION 3.1) + +set(EXAMPLES + readFromString + readFromStream + stringWrite + streamWrite + ) +add_definitions(-D_GLIBCXX_USE_CXX11_ABI) +set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") +else() + add_definitions( + -D_SCL_SECURE_NO_WARNINGS + -D_CRT_SECURE_NO_WARNINGS + -D_WIN32_WINNT=0x601 + -D_WINSOCK_DEPRECATED_NO_WARNINGS) +endif() + +foreach (example ${EXAMPLES}) + add_executable(${example} ${example}/${example}.cpp) + target_include_directories(${example} PUBLIC ${CMAKE_SOURCE_DIR}/include) + target_link_libraries(${example} jsoncpp_lib) +endforeach() + +add_custom_target(examples ALL DEPENDS ${EXAMPLES}) diff --git a/example/README.md b/example/README.md new file mode 100644 index 000000000..b1ae4c875 --- /dev/null +++ b/example/README.md @@ -0,0 +1,13 @@ +***NOTE*** + +If you get linker errors about undefined references to symbols that involve types in the `std::__cxx11` namespace or the tag +`[abi:cxx11]` then it probably indicates that you are trying to link together object files that were compiled with different +values for the _GLIBCXX_USE_CXX11_ABI marco. This commonly happens when linking to a third-party library that was compiled with +an older version of GCC. If the third-party library cannot be rebuilt with the new ABI, then you need to recompile your code with +the old ABI,just like: +**g++ stringWrite.cpp -ljsoncpp -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -o stringWrite** + +Not all of uses of the new ABI will cause changes in symbol names, for example a class with a `std::string` member variable will +have the same mangled name whether compiled with the older or new ABI. In order to detect such problems, the new types and functions +are annotated with the abi_tag attribute, allowing the compiler to warn about potential ABI incompatibilities in code using them. +Those warnings can be enabled with the `-Wabi-tag` option. diff --git a/example/readFromStream/errorFormat.json b/example/readFromStream/errorFormat.json new file mode 100644 index 000000000..2d13290b1 --- /dev/null +++ b/example/readFromStream/errorFormat.json @@ -0,0 +1,3 @@ +{ + 1: "value" +} \ No newline at end of file diff --git a/example/readFromStream/readFromStream.cpp b/example/readFromStream/readFromStream.cpp new file mode 100644 index 000000000..358d2cab0 --- /dev/null +++ b/example/readFromStream/readFromStream.cpp @@ -0,0 +1,30 @@ +#include "json/json.h" +#include +#include +/** \brief Parse from stream, collect comments and capture error info. + * Example Usage: + * $g++ readFromStream.cpp -ljsoncpp -std=c++11 -o readFromStream + * $./readFromStream + * // comment head + * { + * // comment before + * "key" : "value" + * } + * // comment after + * // comment tail + */ +int main(int argc, char* argv[]) { + Json::Value root; + std::ifstream ifs; + ifs.open(argv[1]); + + Json::CharReaderBuilder builder; + builder["collectComments"] = true; + JSONCPP_STRING errs; + if (!parseFromStream(builder, ifs, &root, &errs)) { + std::cout << errs << std::endl; + return EXIT_FAILURE; + } + std::cout << root << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/readFromStream/withComment.json b/example/readFromStream/withComment.json new file mode 100644 index 000000000..7a8c82822 --- /dev/null +++ b/example/readFromStream/withComment.json @@ -0,0 +1,6 @@ +// comment head +{ + // comment before + "key" : "value" + // comment after +}// comment tail diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp new file mode 100644 index 000000000..753f9c94b --- /dev/null +++ b/example/readFromString/readFromString.cpp @@ -0,0 +1,37 @@ +#include "json/json.h" +#include +/** + * \brief Parse a raw string into Value object using the CharReaderBuilder + * class, or the legacy Reader class. + * Example Usage: + * $g++ readFromString.cpp -ljsoncpp -std=c++11 -o readFromString + * $./readFromString + * colin + * 20 + */ +int main() { + const std::string rawJson = R"({"Age": 20, "Name": "colin"})"; + const int rawJsonLength = static_cast(rawJson.length()); + constexpr bool shouldUseOldWay = false; + JSONCPP_STRING err; + Json::Value root; + + if (shouldUseOldWay) { + Json::Reader reader; + reader.parse(rawJson, root); + } else { + Json::CharReaderBuilder builder; + const std::unique_ptr reader(builder.newCharReader()); + if (!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root, + &err)) { + std::cout << "error" << std::endl; + return EXIT_FAILURE; + } + } + const std::string name = root["Name"].asString(); + const int age = root["Age"].asInt(); + + std::cout << name << std::endl; + std::cout << age << std::endl; + return EXIT_SUCCESS; +} diff --git a/example/streamWrite/streamWrite.cpp b/example/streamWrite/streamWrite.cpp new file mode 100644 index 000000000..6f7f7972a --- /dev/null +++ b/example/streamWrite/streamWrite.cpp @@ -0,0 +1,22 @@ +#include "json/json.h" +#include +/** \brief Write the Value object to a stream. + * Example Usage: + * $g++ streamWrite.cpp -ljsoncpp -std=c++11 -o streamWrite + * $./streamWrite + * { + * "Age" : 20, + * "Name" : "robin" + * } + */ +int main() { + Json::Value root; + Json::StreamWriterBuilder builder; + const std::unique_ptr writer(builder.newStreamWriter()); + + root["Name"] = "robin"; + root["Age"] = 20; + writer->write(root, &std::cout); + + return EXIT_SUCCESS; +} diff --git a/example/stringWrite/stringWrite.cpp b/example/stringWrite/stringWrite.cpp new file mode 100644 index 000000000..d501ba948 --- /dev/null +++ b/example/stringWrite/stringWrite.cpp @@ -0,0 +1,33 @@ +#include "json/json.h" +#include +/** \brief Write a Value object to a string. + * Example Usage: + * $g++ stringWrite.cpp -ljsoncpp -std=c++11 -o stringWrite + * $./stringWrite + * { + * "action" : "run", + * "data" : + * { + * "number" : 1 + * } + * } + */ +int main() { + Json::Value root; + Json::Value data; + constexpr bool shouldUseOldWay = false; + root["action"] = "run"; + data["number"] = 1; + root["data"] = data; + + if (shouldUseOldWay) { + Json::FastWriter writer; + const std::string json_file = writer.write(root); + std::cout << json_file << std::endl; + } else { + Json::StreamWriterBuilder builder; + const std::string json_file = Json::writeString(builder, root); + std::cout << json_file << std::endl; + } + return EXIT_SUCCESS; +} diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index c0b5296d9..4c59d07b5 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -378,8 +378,8 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) - // @todo investigate this handler (for buffer overflow) - // _set_security_error_handler +// @todo investigate this handler (for buffer overflow) +// _set_security_error_handler #if defined(_WIN32) // Prevents the system from popping a dialog for debugging if the diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index b0106bd62..4897f8c8e 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2615,7 +2615,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( Json::Value::iterator it(v.begin()) // Compile, but throw. - ); + ); Json::Value value; From ae4dc9aa626e6ea90f876864c4a50cc13da78b3a Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Wed, 25 Sep 2019 14:03:30 -0700 Subject: [PATCH 209/410] clang-tidy fixes (#1033) * [clang-tidy] Replace C typedef with C++ using Found with modernize-use-using Added to .clang-tidy file. Signed-off-by: Rosen Penev * [clang-tidy] Remove redundant member init Found with readability-redundant-member-init Added to .clang-tidy * [clang-tidy] Replace C casts with C++ ones Found with google-readability-casting Signed-off-by: Rosen Penev * [clang-tidy] Use default member init Found with modernize-use-default-member-init Signed-off-by: Rosen Penev --- .clang-tidy | 11 +++++++++++ src/lib_json/json_reader.cpp | 21 ++++++++++----------- src/lib_json/json_value.cpp | 8 ++++---- src/lib_json/json_writer.cpp | 4 ++-- 4 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000..6b5e8018e --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,11 @@ +--- +Checks: 'google-readability-casting,modernize-use-default-member-init,modernize-use-using,readability-redundant-member-init' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none +CheckOptions: + - key: modernize-use-using.IgnoreMacros + value: '0' +... + diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 6a1c76578..d1ae192d9 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -51,7 +51,7 @@ static size_t const stackLimit_g = namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) -typedef std::unique_ptr CharReaderPtr; +using CharReaderPtr = std::unique_ptr; #else typedef std::auto_ptr CharReaderPtr; #endif @@ -86,11 +86,10 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // ////////////////////////////////////////////////////////////////// Reader::Reader() - : errors_(), document_(), commentsBefore_(), features_(Features::all()) {} + : features_(Features::all()) {} Reader::Reader(const Features& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(features), collectComments_() { + : features_(features) { } bool Reader::parse(const std::string& document, @@ -111,7 +110,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { // Since String is reference-counted, this at least does not // create an extra copy. String doc; - std::getline(is, doc, (char)EOF); + std::getline(is, doc, static_castEOF); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } @@ -895,8 +894,8 @@ OurFeatures OurFeatures::all() { return {}; } // for implementing JSON reading. class OurReader { public: - typedef char Char; - typedef const Char* Location; + using Char = char; + using Location = const Char *; struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; @@ -952,7 +951,7 @@ class OurReader { Location extra_; }; - typedef std::deque Errors; + using Errors = std::deque; bool readToken(Token& token); void skipSpaces(); @@ -997,7 +996,7 @@ class OurReader { static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); - typedef std::stack Nodes; + using Nodes = std::stack; Nodes nodes_; Errors errors_; String document_; @@ -1023,8 +1022,8 @@ bool OurReader::containsNewLine(OurReader::Location begin, } OurReader::OurReader(OurFeatures const& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(features), collectComments_() { + : begin_(), end_(), current_(), lastValueEnd_(), + lastValue_(), features_(features), collectComments_() { } bool OurReader::parse(const char* beginDoc, diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 4f71e77cc..cce2b2934 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1547,16 +1547,16 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() : key_() {} +PathArgument::PathArgument() {} PathArgument::PathArgument(ArrayIndex index) - : key_(), index_(index), kind_(kindIndex) {} + : index_(index), kind_(kindIndex) {} PathArgument::PathArgument(const char* key) - : key_(key), index_(), kind_(kindKey) {} + : key_(key), kind_(kindKey) {} PathArgument::PathArgument(const String& key) - : key_(key.c_str()), index_(), kind_(kindKey) {} + : key_(key.c_str()), kind_(kindKey) {} // class Path // ////////////////////////////////////////////////////////////////// diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 41dfd8cf6..4b91035c2 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -84,7 +84,7 @@ namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) -typedef std::unique_ptr StreamWriterPtr; +using StreamWriterPtr = std::unique_ptr; #else typedef std::auto_ptr StreamWriterPtr; #endif @@ -887,7 +887,7 @@ struct BuiltStyledStreamWriter : public StreamWriter { void writeCommentAfterValueOnSameLine(Value const& root); static bool hasCommentForValue(const Value& value); - typedef std::vector ChildValues; + using ChildValues = std::vector; ChildValues childValues_; String indentString_; From 00b979f086587046266f862f2a645cce02c485dc Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Wed, 25 Sep 2019 14:04:53 -0700 Subject: [PATCH 210/410] Issue #970: Rename features.h to json_features.h (#1024) This patch fixes a build issue on CMake, presumably due to the new glibc having a features.h include file. This patch renames our features.h file to avoid a name collision. --- amalgamate.py | 2 +- include/json/forwards.h | 2 +- include/json/json.h | 2 +- include/json/{features.h => json_features.h} | 0 include/json/reader.h | 2 +- meson.build | 2 +- src/lib_json/CMakeLists.txt | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename include/json/{features.h => json_features.h} (100%) diff --git a/amalgamate.py b/amalgamate.py index 7b41e2e5b..fedee1eae 100755 --- a/amalgamate.py +++ b/amalgamate.py @@ -75,7 +75,7 @@ def amalgamate_source(source_top_dir=None, header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) header.add_file(os.path.join(INCLUDE_PATH, "config.h")) header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) - header.add_file(os.path.join(INCLUDE_PATH, "features.h")) + header.add_file(os.path.join(INCLUDE_PATH, "json_features.h")) header.add_file(os.path.join(INCLUDE_PATH, "value.h")) header.add_file(os.path.join(INCLUDE_PATH, "reader.h")) header.add_file(os.path.join(INCLUDE_PATH, "writer.h")) diff --git a/include/json/forwards.h b/include/json/forwards.h index 958b5bcc8..b0d981be0 100644 --- a/include/json/forwards.h +++ b/include/json/forwards.h @@ -25,7 +25,7 @@ class Reader; class CharReader; class CharReaderBuilder; -// features.h +// json_features.h class Features; // value.h diff --git a/include/json/json.h b/include/json/json.h index 19f14c266..f1b679a59 100644 --- a/include/json/json.h +++ b/include/json/json.h @@ -7,7 +7,7 @@ #define JSON_JSON_H_INCLUDED #include "autolink.h" -#include "features.h" +#include "json_features.h" #include "reader.h" #include "value.h" #include "writer.h" diff --git a/include/json/features.h b/include/json/json_features.h similarity index 100% rename from include/json/features.h rename to include/json/json_features.h diff --git a/include/json/reader.h b/include/json/reader.h index 8b388b0a8..fb2365ab3 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -7,7 +7,7 @@ #define CPPTL_JSON_READER_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) -#include "features.h" +#include "json_features.h" #include "value.h" #endif // if !defined(JSON_IS_AMALGAMATION) #include diff --git a/meson.build b/meson.build index d1f49897a..65dcffa8c 100644 --- a/meson.build +++ b/meson.build @@ -23,7 +23,7 @@ jsoncpp_headers = [ 'include/json/assertions.h', 'include/json/autolink.h', 'include/json/config.h', - 'include/json/features.h', + 'include/json/json_features.h', 'include/json/forwards.h', 'include/json/json.h', 'include/json/reader.h', diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 0fa2f5953..a9bf786cd 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -42,7 +42,7 @@ set( JSONCPP_INCLUDE_DIR ../../include ) set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/config.h ${JSONCPP_INCLUDE_DIR}/json/forwards.h - ${JSONCPP_INCLUDE_DIR}/json/features.h + ${JSONCPP_INCLUDE_DIR}/json/json_features.h ${JSONCPP_INCLUDE_DIR}/json/value.h ${JSONCPP_INCLUDE_DIR}/json/reader.h ${JSONCPP_INCLUDE_DIR}/json/version.h From d4486107702876c12778fbc11f5c7d33b4bd6094 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Wed, 25 Sep 2019 14:05:45 -0700 Subject: [PATCH 211/410] Fixup Json::Value append methods, run clang format. (#1022) --- src/lib_json/json_value.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index cce2b2934..e2cb7a1bc 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1155,10 +1155,14 @@ Value const& Value::operator[](CppTL::ConstString const& key) const { } #endif -Value& Value::append(const Value& value) { return (*this)[size()] = value; } - +Value& Value::append(const Value& value) { return append(Value(value)); } Value& Value::append(Value&& value) { - return (*this)[size()] = std::move(value); + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, + "in Json::Value::append: requires arrayValue"); + if (type() == nullValue) { + *this = Value(arrayValue); + } + return this->value_.map_->emplace(size(), std::move(value)).first->second; } Value Value::get(char const* begin, From 00c2c9f6e4ba43bc9e17528ac4e33c794988effc Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 26 Sep 2019 05:07:08 +0800 Subject: [PATCH 212/410] Supplement the testcase for comparing the Array and Null (#1031) * supplement the testcase for comparing the Array and Null * update testcase --- src/test_lib_json/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 4897f8c8e..83fab4e8a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1391,6 +1391,8 @@ void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_FIXTURE(ValueTest, compareNull) { JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value(), Json::Value())); + JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value::nullSingleton(), Json::Value())); + JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value::nullSingleton(), Json::Value::nullSingleton())); } JSONTEST_FIXTURE(ValueTest, compareInt) { @@ -1445,10 +1447,13 @@ JSONTEST_FIXTURE(ValueTest, compareArray) { l2bArray.append(10); JSONTEST_ASSERT_PRED(checkIsLess(emptyArray, l1aArray)); JSONTEST_ASSERT_PRED(checkIsLess(emptyArray, l2aArray)); - JSONTEST_ASSERT_PRED(checkIsLess(l1aArray, l2aArray)); + JSONTEST_ASSERT_PRED(checkIsLess(l1aArray, l1bArray)); + JSONTEST_ASSERT_PRED(checkIsLess(l1bArray, l2aArray)); JSONTEST_ASSERT_PRED(checkIsLess(l2aArray, l2bArray)); JSONTEST_ASSERT_PRED(checkIsEqual(emptyArray, Json::Value(emptyArray))); JSONTEST_ASSERT_PRED(checkIsEqual(l1aArray, Json::Value(l1aArray))); + JSONTEST_ASSERT_PRED(checkIsEqual(l1bArray, Json::Value(l1bArray))); + JSONTEST_ASSERT_PRED(checkIsEqual(l2aArray, Json::Value(l2aArray))); JSONTEST_ASSERT_PRED(checkIsEqual(l2bArray, Json::Value(l2bArray))); } From 227c7cdfa55c977cdee02ddba09c80dff8130595 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 26 Sep 2019 05:07:34 +0800 Subject: [PATCH 213/410] Supplement the testcase for comparing object (#1032) * supplement the testcase for comparing object * update testcase * add a new test scenarios in compareObject --- src/test_lib_json/main.cpp | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 83fab4e8a..7b9abafc1 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1463,16 +1463,41 @@ JSONTEST_FIXTURE(ValueTest, compareObject) { Json::Value l1aObject; l1aObject["key1"] = 0; Json::Value l1bObject; - l1aObject["key1"] = 10; + l1bObject["key1"] = 10; Json::Value l2aObject; l2aObject["key1"] = 0; l2aObject["key2"] = 0; + Json::Value l2bObject; + l2bObject["key1"] = 10; + l2bObject["key2"] = 0; JSONTEST_ASSERT_PRED(checkIsLess(emptyObject, l1aObject)); - JSONTEST_ASSERT_PRED(checkIsLess(emptyObject, l2aObject)); - JSONTEST_ASSERT_PRED(checkIsLess(l1aObject, l2aObject)); + JSONTEST_ASSERT_PRED(checkIsLess(l1aObject, l1bObject)); + JSONTEST_ASSERT_PRED(checkIsLess(l1bObject, l2aObject)); + JSONTEST_ASSERT_PRED(checkIsLess(l2aObject, l2bObject)); JSONTEST_ASSERT_PRED(checkIsEqual(emptyObject, Json::Value(emptyObject))); JSONTEST_ASSERT_PRED(checkIsEqual(l1aObject, Json::Value(l1aObject))); + JSONTEST_ASSERT_PRED(checkIsEqual(l1bObject, Json::Value(l1bObject))); JSONTEST_ASSERT_PRED(checkIsEqual(l2aObject, Json::Value(l2aObject))); + JSONTEST_ASSERT_PRED(checkIsEqual(l2bObject, Json::Value(l2bObject))); + { + Json::Value aObject; + aObject["a"] = 10; + Json::Value bObject; + bObject["b"] = 0; + Json::Value cObject; + cObject["c"] = 20; + cObject["f"] = 15; + Json::Value dObject; + dObject["d"] = -2; + dObject["e"] = 10; + JSONTEST_ASSERT_PRED(checkIsLess(aObject, bObject)); + JSONTEST_ASSERT_PRED(checkIsLess(bObject, cObject)); + JSONTEST_ASSERT_PRED(checkIsLess(cObject, dObject)); + JSONTEST_ASSERT_PRED(checkIsEqual(aObject, Json::Value(aObject))); + JSONTEST_ASSERT_PRED(checkIsEqual(bObject, Json::Value(bObject))); + JSONTEST_ASSERT_PRED(checkIsEqual(cObject, Json::Value(cObject))); + JSONTEST_ASSERT_PRED(checkIsEqual(dObject, Json::Value(dObject))); + } } JSONTEST_FIXTURE(ValueTest, compareType) { From 7e97345e26ebbd9b72266378255130fb433bc2fa Mon Sep 17 00:00:00 2001 From: Griffin Downs <35574547+grdowns@users.noreply.github.com> Date: Tue, 1 Oct 2019 12:53:42 -0700 Subject: [PATCH 214/410] Add vcpkg installation instructions (#1037) --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 8c8587060..4f5eb30ef 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,17 @@ format to store user input files. ## Using JsonCpp in your project +### The vcpkg dependency manager +You can download and install JsonCpp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + vcpkg install jsoncpp + +The JsonCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + ### Amalgamated source https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated From 736409f1b5dadc392a7a301c9176d8ef0d2a1d76 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Wed, 2 Oct 2019 03:54:07 +0800 Subject: [PATCH 215/410] fix clang-format error for ci (#1036) * fix clang-format error for ci * update --- src/lib_json/json_reader.cpp | 18 +++++++----------- src/lib_json/json_value.cpp | 9 ++++----- src/test_lib_json/jsontest.cpp | 4 ++-- src/test_lib_json/main.cpp | 9 +++++---- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index d1ae192d9..5d6207c14 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -85,12 +85,9 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // Class Reader // ////////////////////////////////////////////////////////////////// -Reader::Reader() - : features_(Features::all()) {} +Reader::Reader() : features_(Features::all()) {} -Reader::Reader(const Features& features) - : features_(features) { -} +Reader::Reader(const Features& features) : features_(features) {} bool Reader::parse(const std::string& document, Value& root, @@ -110,7 +107,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { // Since String is reference-counted, this at least does not // create an extra copy. String doc; - std::getline(is, doc, static_castEOF); + std::getline(is, doc, static_cast EOF); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } @@ -895,7 +892,7 @@ OurFeatures OurFeatures::all() { return {}; } class OurReader { public: using Char = char; - using Location = const Char *; + using Location = const Char*; struct StructuredError { ptrdiff_t offset_start; ptrdiff_t offset_limit; @@ -996,7 +993,7 @@ class OurReader { static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); - using Nodes = std::stack; + using Nodes = std::stack; Nodes nodes_; Errors errors_; String document_; @@ -1022,9 +1019,8 @@ bool OurReader::containsNewLine(OurReader::Location begin, } OurReader::OurReader(OurFeatures const& features) - : begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), features_(features), collectComments_() { -} + : begin_(), end_(), current_(), lastValueEnd_(), lastValue_(), + features_(features), collectComments_() {} bool OurReader::parse(const char* beginDoc, const char* endDoc, diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index e2cb7a1bc..6ee999cc2 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1551,16 +1551,15 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() {} +PathArgument::PathArgument() {} PathArgument::PathArgument(ArrayIndex index) - : index_(index), kind_(kindIndex) {} + : index_(index), kind_(kindIndex) {} -PathArgument::PathArgument(const char* key) - : key_(key), kind_(kindKey) {} +PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {} PathArgument::PathArgument(const String& key) - : key_(key.c_str()), kind_(kindKey) {} + : key_(key.c_str()), kind_(kindKey) {} // class Path // ////////////////////////////////////////////////////////////////// diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 4c59d07b5..c0b5296d9 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -378,8 +378,8 @@ void Runner::preventDialogOnCrash() { _CrtSetReportHook(&msvcrtSilentReportHook); #endif // if defined(_MSC_VER) -// @todo investigate this handler (for buffer overflow) -// _set_security_error_handler + // @todo investigate this handler (for buffer overflow) + // _set_security_error_handler #if defined(_WIN32) // Prevents the system from popping a dialog for debugging if the diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 7b9abafc1..c15b03f5f 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1391,8 +1391,10 @@ void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_FIXTURE(ValueTest, compareNull) { JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value(), Json::Value())); - JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value::nullSingleton(), Json::Value())); - JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value::nullSingleton(), Json::Value::nullSingleton())); + JSONTEST_ASSERT_PRED( + checkIsEqual(Json::Value::nullSingleton(), Json::Value())); + JSONTEST_ASSERT_PRED( + checkIsEqual(Json::Value::nullSingleton(), Json::Value::nullSingleton())); } JSONTEST_FIXTURE(ValueTest, compareInt) { @@ -2644,8 +2646,7 @@ JSONTEST_FIXTURE(IteratorTest, indexes) { JSONTEST_FIXTURE(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( - Json::Value::iterator it(v.begin()) // Compile, but throw. - ); + Json::Value::iterator it(v.begin())); // Compile, but throw. Json::Value value; From c4bc6da87d9588032a3ce54abf59c7548af58f7f Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Thu, 10 Oct 2019 04:22:25 +0200 Subject: [PATCH 216/410] Fix dead link in CONTRIBUTING.md (#1044) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e14b2b31..08428b6f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ An example of a common Meson/Ninja environment is described next. Thanks to David Seifert (@SoapGentoo), we (the maintainers) now use [meson](http://mesonbuild.com/) and [ninja](https://ninja-build.org/) to build for debugging, as well as for continuous integration (see -[`./travis_scripts/meson_builder.sh`](./travis_scripts/meson_builder.sh) ). Other systems may work, but minor +[`./.travis_scripts/meson_builder.sh`](./.travis_scripts/meson_builder.sh) ). Other systems may work, but minor things like version strings might break. First, install both meson (which requires Python3) and ninja. From f34bf24bbd7bfdf67c1ada9b30728e7ced5afaec Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 11 Oct 2019 11:19:00 -0700 Subject: [PATCH 217/410] Issue #958: Travis CI should enforce clang-format standards (#1026) * Issue #958: Travis CI should enfore clang-format standards This patch adds clang format support to the travis bots. * Update path * Roll back to version 8 since 9 is in test * Cleanup clang * Revert "Delete JSONCPP_DEPRECATED, use [[deprecated]] instead. (#978)" (#1029) This reverts commit b27c83f691a03f521a1b3b99eefa2973f8e2bfcd. --- .clang-format | 49 +--- .travis.yml | 4 +- .travis_scripts/meson_builder.sh | 4 +- .travis_scripts/run-clang-format.py | 356 ++++++++++++++++++++++++++++ .travis_scripts/run-clang-format.sh | 4 + include/json/config.h | 45 ++-- include/json/reader.h | 53 ++--- include/json/value.h | 20 +- include/json/writer.h | 21 +- src/jsontestrunner/main.cpp | 7 +- src/lib_json/json_reader.cpp | 82 ++----- src/lib_json/json_value.cpp | 34 +-- src/lib_json/json_writer.cpp | 33 +-- src/test_lib_json/jsontest.cpp | 23 +- src/test_lib_json/jsontest.h | 25 +- 15 files changed, 511 insertions(+), 249 deletions(-) create mode 100755 .travis_scripts/run-clang-format.py create mode 100755 .travis_scripts/run-clang-format.sh diff --git a/.clang-format b/.clang-format index 2a372fc5b..2a8066958 100644 --- a/.clang-format +++ b/.clang-format @@ -1,47 +1,4 @@ ---- -# BasedOnStyle: LLVM -AccessModifierOffset: -2 -ConstructorInitializerIndentWidth: 4 -AlignEscapedNewlinesLeft: false -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakTemplateDeclarations: false -AlwaysBreakBeforeMultilineStrings: false -BreakBeforeBinaryOperators: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BinPackParameters: false -ColumnLimit: 80 -ConstructorInitializerAllOnOneLineOrOnePerLine: false -DerivePointerBinding: false -ExperimentalAutoDetectBinPacking: false -IndentCaseLabels: false -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCSpaceBeforeProtocolList: true -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 60 -PenaltyBreakString: 1000 -PenaltyBreakFirstLessLess: 120 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerBindsToType: true -SpacesBeforeTrailingComments: 1 -Cpp11BracedListStyle: true -Standard: Cpp11 -IndentWidth: 2 -TabWidth: 8 -UseTab: Never -BreakBeforeBraces: Attach -IndentFunctionDeclarationAfterType: false -SpacesInParentheses: false -SpacesInAngles: false -SpaceInEmptyParentheses: false -SpacesInCStyleCastParentheses: false -SpaceAfterControlStatementKeyword: true -SpaceBeforeAssignmentOperators: true -ContinuationIndentWidth: 4 -... +BasedOnStyle: LLVM +DerivePointerAlignment: false +PointerAlignment: Left diff --git a/.travis.yml b/.travis.yml index b649b4633..a63929e72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ sudo: false addons: homebrew: packages: + - clang-format - meson - ninja update: false # do not update homebrew by default @@ -17,6 +18,7 @@ addons: - ubuntu-toolchain-r-test - llvm-toolchain-xenial-8 packages: + - clang-format-8 - clang-8 - valgrind matrix: @@ -25,7 +27,7 @@ matrix: include: - name: Mac clang meson static release testing os: osx - osx_image: xcode10.2 + osx_image: xcode11 compiler: clang env: CXX="clang++" diff --git a/.travis_scripts/meson_builder.sh b/.travis_scripts/meson_builder.sh index dbf03cb2f..0820c890c 100755 --- a/.travis_scripts/meson_builder.sh +++ b/.travis_scripts/meson_builder.sh @@ -63,9 +63,11 @@ meson --version ninja --version _COMPILER_NAME=`basename ${CXX}` _BUILD_DIR_NAME="build-${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}" + +./.travis_scripts/run-clang-format.sh meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" ninja -v -j 2 -C "${_BUILD_DIR_NAME}" -#ninja -v -j 2 -C "${_BUILD_DIR_NAME}" test + cd "${_BUILD_DIR_NAME}" meson test --no-rebuild --print-errorlogs diff --git a/.travis_scripts/run-clang-format.py b/.travis_scripts/run-clang-format.py new file mode 100755 index 000000000..68179aafd --- /dev/null +++ b/.travis_scripts/run-clang-format.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python +"""A wrapper script around clang-format, suitable for linting multiple files +and to use for continuous integration. +This is an alternative API for the clang-format command line. +It runs over multiple files and directories in parallel. +A diff output is produced and a sensible exit code is returned. + +NOTE: pulled from https://github.com/Sarcasm/run-clang-format, which is +licensed under the MIT license. +""" + +from __future__ import print_function, unicode_literals + +import argparse +import codecs +import difflib +import fnmatch +import io +import multiprocessing +import os +import signal +import subprocess +import sys +import traceback + +from functools import partial + +try: + from subprocess import DEVNULL # py3k +except ImportError: + DEVNULL = open(os.devnull, "wb") + + +DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx' + + +class ExitStatus: + SUCCESS = 0 + DIFF = 1 + TROUBLE = 2 + + +def list_files(files, recursive=False, extensions=None, exclude=None): + if extensions is None: + extensions = [] + if exclude is None: + exclude = [] + + out = [] + for file in files: + if recursive and os.path.isdir(file): + for dirpath, dnames, fnames in os.walk(file): + fpaths = [os.path.join(dirpath, fname) for fname in fnames] + for pattern in exclude: + # os.walk() supports trimming down the dnames list + # by modifying it in-place, + # to avoid unnecessary directory listings. + dnames[:] = [ + x for x in dnames + if + not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) + ] + fpaths = [ + x for x in fpaths if not fnmatch.fnmatch(x, pattern) + ] + for f in fpaths: + ext = os.path.splitext(f)[1][1:] + if ext in extensions: + out.append(f) + else: + out.append(file) + return out + + +def make_diff(file, original, reformatted): + return list( + difflib.unified_diff( + original, + reformatted, + fromfile='{}\t(original)'.format(file), + tofile='{}\t(reformatted)'.format(file), + n=3)) + + +class DiffError(Exception): + def __init__(self, message, errs=None): + super(DiffError, self).__init__(message) + self.errs = errs or [] + + +class UnexpectedError(Exception): + def __init__(self, message, exc=None): + super(UnexpectedError, self).__init__(message) + self.formatted_traceback = traceback.format_exc() + self.exc = exc + + +def run_clang_format_diff_wrapper(args, file): + try: + ret = run_clang_format_diff(args, file) + return ret + except DiffError: + raise + except Exception as e: + raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__, + e), e) + + +def run_clang_format_diff(args, file): + try: + with io.open(file, 'r', encoding='utf-8') as f: + original = f.readlines() + except IOError as exc: + raise DiffError(str(exc)) + invocation = [args.clang_format_executable, file] + + # Use of utf-8 to decode the process output. + # + # Hopefully, this is the correct thing to do. + # + # It's done due to the following assumptions (which may be incorrect): + # - clang-format will returns the bytes read from the files as-is, + # without conversion, and it is already assumed that the files use utf-8. + # - if the diagnostics were internationalized, they would use utf-8: + # > Adding Translations to Clang + # > + # > Not possible yet! + # > Diagnostic strings should be written in UTF-8, + # > the client can translate to the relevant code page if needed. + # > Each translation completely replaces the format string + # > for the diagnostic. + # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation + # + # It's not pretty, due to Python 2 & 3 compatibility. + encoding_py3 = {} + if sys.version_info[0] >= 3: + encoding_py3['encoding'] = 'utf-8' + + try: + proc = subprocess.Popen( + invocation, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + **encoding_py3) + except OSError as exc: + raise DiffError( + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(invocation), exc + ) + ) + proc_stdout = proc.stdout + proc_stderr = proc.stderr + if sys.version_info[0] < 3: + # make the pipes compatible with Python 3, + # reading lines should output unicode + encoding = 'utf-8' + proc_stdout = codecs.getreader(encoding)(proc_stdout) + proc_stderr = codecs.getreader(encoding)(proc_stderr) + # hopefully the stderr pipe won't get full and block the process + outs = list(proc_stdout.readlines()) + errs = list(proc_stderr.readlines()) + proc.wait() + if proc.returncode: + raise DiffError( + "Command '{}' returned non-zero exit status {}".format( + subprocess.list2cmdline(invocation), proc.returncode + ), + errs, + ) + return make_diff(file, original, outs), errs + + +def bold_red(s): + return '\x1b[1m\x1b[31m' + s + '\x1b[0m' + + +def colorize(diff_lines): + def bold(s): + return '\x1b[1m' + s + '\x1b[0m' + + def cyan(s): + return '\x1b[36m' + s + '\x1b[0m' + + def green(s): + return '\x1b[32m' + s + '\x1b[0m' + + def red(s): + return '\x1b[31m' + s + '\x1b[0m' + + for line in diff_lines: + if line[:4] in ['--- ', '+++ ']: + yield bold(line) + elif line.startswith('@@ '): + yield cyan(line) + elif line.startswith('+'): + yield green(line) + elif line.startswith('-'): + yield red(line) + else: + yield line + + +def print_diff(diff_lines, use_color): + if use_color: + diff_lines = colorize(diff_lines) + if sys.version_info[0] < 3: + sys.stdout.writelines((l.encode('utf-8') for l in diff_lines)) + else: + sys.stdout.writelines(diff_lines) + + +def print_trouble(prog, message, use_colors): + error_text = 'error:' + if use_colors: + error_text = bold_red(error_text) + print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--clang-format-executable', + metavar='EXECUTABLE', + help='path to the clang-format executable', + default='clang-format') + parser.add_argument( + '--extensions', + help='comma separated list of file extensions (default: {})'.format( + DEFAULT_EXTENSIONS), + default=DEFAULT_EXTENSIONS) + parser.add_argument( + '-r', + '--recursive', + action='http://github.com/store_true', + help='run recursively over directories') + parser.add_argument('files', metavar='file', nargs='+') + parser.add_argument( + '-q', + '--quiet', + action='http://github.com/store_true') + parser.add_argument( + '-j', + metavar='N', + type=int, + default=0, + help='run N clang-format jobs in parallel' + ' (default number of cpus + 1)') + parser.add_argument( + '--color', + default='auto', + choices=['auto', 'always', 'never'], + help='show colored diff (default: auto)') + parser.add_argument( + '-e', + '--exclude', + metavar='PATTERN', + action='http://github.com/append', + default=[], + help='exclude paths matching the given glob-like pattern(s)' + ' from recursive search') + + args = parser.parse_args() + + # use default signal handling, like diff return SIGINT value on ^C + # https://bugs.python.org/issue14229#msg156446 + signal.signal(signal.SIGINT, signal.SIG_DFL) + try: + signal.SIGPIPE + except AttributeError: + # compatibility, SIGPIPE does not exist on Windows + pass + else: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + colored_stdout = False + colored_stderr = False + if args.color == 'always': + colored_stdout = True + colored_stderr = True + elif args.color == 'auto': + colored_stdout = sys.stdout.isatty() + colored_stderr = sys.stderr.isatty() + + version_invocation = [args.clang_format_executable, str("--version")] + try: + subprocess.check_call(version_invocation, stdout=DEVNULL) + except subprocess.CalledProcessError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + return ExitStatus.TROUBLE + except OSError as e: + print_trouble( + parser.prog, + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(version_invocation), e + ), + use_colors=colored_stderr, + ) + return ExitStatus.TROUBLE + + retcode = ExitStatus.SUCCESS + files = list_files( + args.files, + recursive=args.recursive, + exclude=args.exclude, + extensions=args.extensions.split(',')) + + if not files: + return + + njobs = args.j + if njobs == 0: + njobs = multiprocessing.cpu_count() + 1 + njobs = min(len(files), njobs) + + if njobs == 1: + # execute directly instead of in a pool, + # less overhead, simpler stacktraces + it = (run_clang_format_diff_wrapper(args, file) for file in files) + pool = None + else: + pool = multiprocessing.Pool(njobs) + it = pool.imap_unordered( + partial(run_clang_format_diff_wrapper, args), files) + while True: + try: + outs, errs = next(it) + except StopIteration: + break + except DiffError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + retcode = ExitStatus.TROUBLE + sys.stderr.writelines(e.errs) + except UnexpectedError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + sys.stderr.write(e.formatted_traceback) + retcode = ExitStatus.TROUBLE + # stop at the first unexpected error, + # something could be very wrong, + # don't process all files unnecessarily + if pool: + pool.terminate() + break + else: + sys.stderr.writelines(errs) + if outs == []: + continue + if not args.quiet: + print_diff(outs, use_color=colored_stdout) + if retcode == ExitStatus.SUCCESS: + retcode = ExitStatus.DIFF + return retcode + + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/.travis_scripts/run-clang-format.sh b/.travis_scripts/run-clang-format.sh new file mode 100755 index 000000000..91972840d --- /dev/null +++ b/.travis_scripts/run-clang-format.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +python $DIR/run-clang-format.py -r $DIR/../src/**/ $DIR/../include/**/ \ No newline at end of file diff --git a/include/json/config.h b/include/json/config.h index 0ff5968e7..cbb5950e2 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -74,8 +74,8 @@ #if defined(_MSC_VER) && _MSC_VER < 1900 // As recommended at // https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 -extern JSON_API int -msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); +extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, + const char* format, ...); #define jsoncpp_snprintf msvc_pre1900_c99_snprintf #else #define jsoncpp_snprintf std::snprintf @@ -104,9 +104,26 @@ msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...); #define JSONCPP_OP_EXPLICIT #endif -#if defined(__clang__) -#define JSON_USE_INT64_DOUBLE_CONVERSION 1 -#elif defined(__GNUC__) && (__GNUC__ >= 6) +#ifdef __clang__ +#if __has_extension(attribute_deprecated_with_message) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#endif +#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc) +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) +#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) +#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__)) +#endif // GNUC version +#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates + // MSVC) +#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif // __clang__ || __GNUC__ || _MSC_VER + +#if !defined(JSONCPP_DEPRECATED) +#define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6)) #define JSON_USE_INT64_DOUBLE_CONVERSION 1 #endif @@ -139,16 +156,16 @@ typedef UInt64 LargestUInt; #endif // if defined(JSON_NO_INT64) template -using Allocator = typename std::conditional, - std::allocator>::type; +using Allocator = + typename std::conditional, + std::allocator>::type; using String = std::basic_string, Allocator>; -using IStringStream = std::basic_istringstream; -using OStringStream = std::basic_ostringstream; +using IStringStream = + std::basic_istringstream; +using OStringStream = + std::basic_ostringstream; using IStream = std::istream; using OStream = std::ostream; } // namespace Json diff --git a/include/json/reader.h b/include/json/reader.h index fb2365ab3..359c1eb89 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -25,10 +25,6 @@ #pragma pack(push, 8) -#if defined(_MSC_VER) -#pragma warning(disable : 4996) -#endif - namespace Json { /** \brief Unserialize a JSON document into a @@ -36,8 +32,9 @@ namespace Json { * * \deprecated Use CharReader and CharReaderBuilder. */ -class [[deprecated( - "deprecated Use CharReader and CharReaderBuilder.")]] JSON_API Reader { + +class JSONCPP_DEPRECATED( + "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { public: typedef char Char; typedef const Char* Location; @@ -55,10 +52,12 @@ class [[deprecated( /** \brief Constructs a Reader allowing all features for parsing. */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. */ + JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON @@ -99,7 +98,7 @@ class [[deprecated( /// \brief Parse from input stream. /// \see Json::operator>>(std::istream&, Json::Value&). - bool parse(IStream & is, Value & root, bool collectComments = true); + bool parse(IStream& is, Value& root, bool collectComments = true); /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -109,8 +108,8 @@ class [[deprecated( * occurred during parsing. * \deprecated Use getFormattedErrorMessages() instead (typo fix). */ - [[deprecated("Use getFormattedErrorMessages() instead.")]] String - getFormatedErrorMessages() const; + JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.") + String getFormatedErrorMessages() const; /** \brief Returns a user friendly string that list errors in the parsed * document. @@ -190,7 +189,7 @@ class [[deprecated( typedef std::deque Errors; - bool readToken(Token & token); + bool readToken(Token& token); void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); @@ -199,17 +198,17 @@ class [[deprecated( bool readString(); void readNumber(); bool readValue(); - bool readObject(Token & token); - bool readArray(Token & token); - bool decodeNumber(Token & token); - bool decodeNumber(Token & token, Value & decoded); - bool decodeString(Token & token); - bool decodeString(Token & token, String & decoded); - bool decodeDouble(Token & token); - bool decodeDouble(Token & token, Value & decoded); - bool decodeUnicodeCodePoint(Token & token, Location & current, Location end, + bool readObject(Token& token); + bool readArray(Token& token); + bool decodeNumber(Token& token); + bool decodeNumber(Token& token, Value& decoded); + bool decodeString(Token& token); + bool decodeString(Token& token, String& decoded); + bool decodeDouble(Token& token); + bool decodeDouble(Token& token, Value& decoded); + bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token & token, Location & current, + bool decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& unicode); bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); @@ -218,11 +217,11 @@ class [[deprecated( void skipUntilSpace(); Value& currentValue(); Char getNextChar(); - void getLocationLineAndColumn(Location location, int& line, int& column) - const; + void getLocationLineAndColumn(Location location, int& line, + int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token & token); + void skipCommentTokens(Token& token); static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); @@ -262,9 +261,7 @@ class JSON_API CharReader { * \return \c true if the document was successfully parsed, \c false if an * error occurred. */ - virtual bool parse(char const* beginDoc, - char const* endDoc, - Value* root, + virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, String* errs) = 0; class JSON_API Factory { @@ -364,9 +361,7 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * Someday we might have a real StreamReader, but for now this * is convenient. */ -bool JSON_API parseFromStream(CharReader::Factory const&, - IStream&, - Value* root, +bool JSON_API parseFromStream(CharReader::Factory const&, IStream&, Value* root, String* errs); /** \brief Read from 'sin' into 'root'. diff --git a/include/json/value.h b/include/json/value.h index aa7bc5425..a0a5a1181 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -493,8 +493,8 @@ class JSON_API Value { /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \note key may contain embedded nulls. - Value - get(const char* begin, const char* end, const Value& defaultValue) const; + Value get(const char* begin, const char* end, + const Value& defaultValue) const; /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \param key may contain embedded nulls. @@ -567,8 +567,8 @@ class JSON_API Value { //# endif /// \deprecated Always pass len. - [[deprecated("Use setComment(String const&) instead.")]] void - setComment(const char* comment, CommentPlacement placement) { + JSONCPP_DEPRECATED("Use setComment(String const&) instead.") + void setComment(const char* comment, CommentPlacement placement) { setComment(String(comment, strlen(comment)), placement); } /// Comments must be //... or /* ... */ @@ -691,8 +691,7 @@ class JSON_API PathArgument { */ class JSON_API Path { public: - Path(const String& path, - const PathArgument& a1 = PathArgument(), + Path(const String& path, const PathArgument& a1 = PathArgument(), const PathArgument& a2 = PathArgument(), const PathArgument& a3 = PathArgument(), const PathArgument& a4 = PathArgument(), @@ -709,10 +708,8 @@ class JSON_API Path { typedef std::vector Args; void makePath(const String& path, const InArgs& in); - void addPathInArg(const String& path, - const InArgs& in, - InArgs::const_iterator& itInArg, - PathArgument::Kind kind); + void addPathInArg(const String& path, const InArgs& in, + InArgs::const_iterator& itInArg, PathArgument::Kind kind); static void invalidPath(const String& path, int location); Args args_; @@ -753,7 +750,8 @@ class JSON_API ValueIteratorBase { /// objectValue. /// \deprecated This cannot be used for UTF-8 strings, since there can be /// embedded nulls. - [[deprecated("Use `key = name();` instead.")]] char const* memberName() const; + JSONCPP_DEPRECATED("Use `key = name();` instead.") + char const* memberName() const; /// Return the member name of the referenced Value, or NULL if it is not an /// objectValue. /// \note Better version than memberName(). Allows embedded nulls. diff --git a/include/json/writer.h b/include/json/writer.h index 9799a3bb3..a72c06a40 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -145,7 +145,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { /** \brief Abstract class for writers. * \deprecated Use StreamWriter. (And really, this is an implementation detail.) */ -class [[deprecated("Use StreamWriter instead")]] JSON_API Writer { +class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { public: virtual ~Writer(); @@ -165,7 +165,7 @@ class [[deprecated("Use StreamWriter instead")]] JSON_API Writer { #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API FastWriter +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter : public Writer { public: FastWriter(); @@ -225,8 +225,8 @@ class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API FastWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API StyledWriter - : public Writer { +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledWriter : public Writer { public: StyledWriter(); ~StyledWriter() override = default; @@ -294,8 +294,8 @@ class [[deprecated("Use StreamWriterBuilder instead")]] JSON_API StyledWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class [[deprecated( - "Use StreamWriterBuilder instead")]] JSON_API StyledStreamWriter { +class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API + StyledStreamWriter { public: /** * \param indentation Each level will be indented by this amount extra. @@ -310,7 +310,7 @@ class [[deprecated( * \note There is no point in deriving from Writer, since write() should not * return a value. */ - void write(OStream & out, const Value& root); + void write(OStream& out, const Value& root); private: void writeValue(const Value& value); @@ -346,10 +346,9 @@ String JSON_API valueToString(UInt value); #endif // if defined(JSON_HAS_INT64) String JSON_API valueToString(LargestInt value); String JSON_API valueToString(LargestUInt value); -String JSON_API -valueToString(double value, - unsigned int precision = Value::defaultRealPrecision, - PrecisionType precisionType = PrecisionType::significantDigits); +String JSON_API valueToString( + double value, unsigned int precision = Value::defaultRealPrecision, + PrecisionType precisionType = PrecisionType::significantDigits); String JSON_API valueToString(bool value); String JSON_API valueToQuotedString(const char* value); diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index d2d41aa5f..cb9db66cd 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -68,8 +68,8 @@ static Json::String readInputTestFile(const char* path) { return text; } -static void -printValueTree(FILE* fout, Json::Value& value, const Json::String& path = ".") { +static void printValueTree(FILE* fout, Json::Value& value, + const Json::String& path = ".") { if (value.hasComment(Json::commentBefore)) { fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str()); } @@ -125,8 +125,7 @@ printValueTree(FILE* fout, Json::Value& value, const Json::String& path = ".") { static int parseAndSaveValueTree(const Json::String& input, const Json::String& actual, const Json::String& kind, - const Json::Features& features, - bool parseOnly, + const Json::Features& features, bool parseOnly, Json::Value* root) { Json::Reader reader(features); bool parsingSuccessful = diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 5d6207c14..ac673ffce 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -89,8 +89,7 @@ Reader::Reader() : features_(Features::all()) {} Reader::Reader(const Features& features) : features_(features) {} -bool Reader::parse(const std::string& document, - Value& root, +bool Reader::parse(const std::string& document, Value& root, bool collectComments) { document_.assign(document.begin(), document.end()); const char* begin = document_.c_str(); @@ -111,9 +110,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } -bool Reader::parse(const char* beginDoc, - const char* endDoc, - Value& root, +bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments) { if (!features_.allowComments_) { collectComments = false; @@ -373,8 +370,7 @@ String Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { return normalized; } -void Reader::addComment(Location begin, - Location end, +void Reader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); const String& normalized = normalizeEOL(begin, end); @@ -677,10 +673,8 @@ bool Reader::decodeString(Token& token, String& decoded) { return true; } -bool Reader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { +bool Reader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) { if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; @@ -704,8 +698,7 @@ bool Reader::decodeUnicodeCodePoint(Token& token, return true; } -bool Reader::decodeUnicodeEscapeSequence(Token& token, - Location& current, +bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& ret_unicode) { if (end - current < 4) @@ -753,8 +746,7 @@ bool Reader::recoverFromError(TokenType skipUntilToken) { return false; } -bool Reader::addErrorAndRecover(const String& message, - Token& token, +bool Reader::addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken) { addError(message, token); return recoverFromError(skipUntilToken); @@ -768,8 +760,7 @@ Reader::Char Reader::getNextChar() { return *current_++; } -void Reader::getLocationLineAndColumn(Location location, - int& line, +void Reader::getLocationLineAndColumn(Location location, int& line, int& column) const { Location current = begin_; Location lastLineStart = current; @@ -845,8 +836,7 @@ bool Reader::pushError(const Value& value, const String& message) { return true; } -bool Reader::pushError(const Value& value, - const String& message, +bool Reader::pushError(const Value& value, const String& message, const Value& extra) { ptrdiff_t const length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length || @@ -900,9 +890,7 @@ class OurReader { }; OurReader(OurFeatures const& features); - bool parse(const char* beginDoc, - const char* endDoc, - Value& root, + bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); String getFormattedErrorMessages() const; std::vector getStructuredErrors() const; @@ -968,24 +956,19 @@ class OurReader { bool decodeString(Token& token, String& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, + bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode); + bool decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, unsigned int& unicode); bool addError(const String& message, Token& token, Location extra = nullptr); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const String& message, - Token& token, + bool addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); Value& currentValue(); Char getNextChar(); - void - getLocationLineAndColumn(Location location, int& line, int& column) const; + void getLocationLineAndColumn(Location location, int& line, + int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); @@ -1022,9 +1005,7 @@ OurReader::OurReader(OurFeatures const& features) : begin_(), end_(), current_(), lastValueEnd_(), lastValue_(), features_(features), collectComments_() {} -bool OurReader::parse(const char* beginDoc, - const char* endDoc, - Value& root, +bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments) { if (!features_.allowComments_) { collectComments = false; @@ -1341,8 +1322,7 @@ String OurReader::normalizeEOL(OurReader::Location begin, return normalized; } -void OurReader::addComment(Location begin, - Location end, +void OurReader::addComment(Location begin, Location end, CommentPlacement placement) { assert(collectComments_); const String& normalized = normalizeEOL(begin, end); @@ -1700,10 +1680,8 @@ bool OurReader::decodeString(Token& token, String& decoded) { return true; } -bool OurReader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { +bool OurReader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) { if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; @@ -1727,8 +1705,7 @@ bool OurReader::decodeUnicodeCodePoint(Token& token, return true; } -bool OurReader::decodeUnicodeEscapeSequence(Token& token, - Location& current, +bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, unsigned int& ret_unicode) { if (end - current < 4) @@ -1776,8 +1753,7 @@ bool OurReader::recoverFromError(TokenType skipUntilToken) { return false; } -bool OurReader::addErrorAndRecover(const String& message, - Token& token, +bool OurReader::addErrorAndRecover(const String& message, Token& token, TokenType skipUntilToken) { addError(message, token); return recoverFromError(skipUntilToken); @@ -1791,8 +1767,7 @@ OurReader::Char OurReader::getNextChar() { return *current_++; } -void OurReader::getLocationLineAndColumn(Location location, - int& line, +void OurReader::getLocationLineAndColumn(Location location, int& line, int& column) const { Location current = begin_; Location lastLineStart = current; @@ -1863,8 +1838,7 @@ bool OurReader::pushError(const Value& value, const String& message) { return true; } -bool OurReader::pushError(const Value& value, - const String& message, +bool OurReader::pushError(const Value& value, const String& message, const Value& extra) { ptrdiff_t length = end_ - begin_; if (value.getOffsetStart() > length || value.getOffsetLimit() > length || @@ -1891,9 +1865,7 @@ class OurCharReader : public CharReader { public: OurCharReader(bool collectComments, OurFeatures const& features) : collectComments_(collectComments), reader_(features) {} - bool parse(char const* beginDoc, - char const* endDoc, - Value* root, + bool parse(char const* beginDoc, char const* endDoc, Value* root, String* errs) override { bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); if (errs) { @@ -1989,9 +1961,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { ////////////////////////////////// // global functions -bool parseFromStream(CharReader::Factory const& fact, - IStream& sin, - Value* root, +bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root, String* errs) { OStringStream ssin; ssin << sin.rdbuf(); diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 6ee999cc2..cf93ec7d5 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -22,10 +22,8 @@ // Provide implementation equivalent of std::snprintf for older _MSC compilers #if defined(_MSC_VER) && _MSC_VER < 1900 #include -static int msvc_pre1900_c99_vsnprintf(char* outBuf, - size_t size, - const char* format, - va_list ap) { +static int msvc_pre1900_c99_vsnprintf(char* outBuf, size_t size, + const char* format, va_list ap) { int count = -1; if (size != 0) count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); @@ -34,10 +32,8 @@ static int msvc_pre1900_c99_vsnprintf(char* outBuf, return count; } -int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, - size_t size, - const char* format, - ...) { +int JSON_API msvc_pre1900_c99_snprintf(char* outBuf, size_t size, + const char* format, ...) { va_list ap; va_start(ap, format); const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap); @@ -156,10 +152,8 @@ static inline char* duplicateAndPrefixStringValue(const char* value, 0; // to avoid buffer over-run accidents by users later return newString; } -inline static void decodePrefixedString(bool isPrefixed, - char const* prefixed, - unsigned* length, - char const** value) { +inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, + unsigned* length, char const** value) { if (!isPrefixed) { *length = static_cast(strlen(prefixed)); *value = prefixed; @@ -235,8 +229,7 @@ LogicError::LogicError(String const& msg) : Exception(msg) {} Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {} -Value::CZString::CZString(char const* str, - unsigned length, +Value::CZString::CZString(char const* str, unsigned length, DuplicationPolicy allocate) : cstr_(str) { // allocate != duplicate @@ -1165,8 +1158,7 @@ Value& Value::append(Value&& value) { return this->value_.map_->emplace(size(), std::move(value)).first->second; } -Value Value::get(char const* begin, - char const* end, +Value Value::get(char const* begin, char const* end, Value const& defaultValue) const { Value const* found = find(begin, end); return !found ? defaultValue : *found; @@ -1564,11 +1556,8 @@ PathArgument::PathArgument(const String& key) // class Path // ////////////////////////////////////////////////////////////////// -Path::Path(const String& path, - const PathArgument& a1, - const PathArgument& a2, - const PathArgument& a3, - const PathArgument& a4, +Path::Path(const String& path, const PathArgument& a1, const PathArgument& a2, + const PathArgument& a3, const PathArgument& a4, const PathArgument& a5) { InArgs in; in.reserve(5); @@ -1611,8 +1600,7 @@ void Path::makePath(const String& path, const InArgs& in) { } } -void Path::addPathInArg(const String& /*path*/, - const InArgs& in, +void Path::addPathInArg(const String& /*path*/, const InArgs& in, InArgs::const_iterator& itInArg, PathArgument::Kind kind) { if (itInArg == in.end()) { diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 4b91035c2..e16d84f5f 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -122,10 +122,8 @@ String valueToString(UInt value) { return valueToString(LargestUInt(value)); } #endif // # if defined(JSON_HAS_INT64) namespace { -String valueToString(double value, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType) { +String valueToString(double value, bool useSpecialFloats, + unsigned int precision, PrecisionType precisionType) { // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. @@ -168,8 +166,7 @@ String valueToString(double value, } } // namespace -String valueToString(double value, - unsigned int precision, +String valueToString(double value, unsigned int precision, PrecisionType precisionType) { return valueToString(value, false, precision, precisionType); } @@ -864,14 +861,10 @@ struct CommentStyle { }; struct BuiltStyledStreamWriter : public StreamWriter { - BuiltStyledStreamWriter(String indentation, - CommentStyle::Enum cs, - String colonSymbol, - String nullSymbol, - String endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType); + BuiltStyledStreamWriter(String indentation, CommentStyle::Enum cs, + String colonSymbol, String nullSymbol, + String endingLineFeedSymbol, bool useSpecialFloats, + unsigned int precision, PrecisionType precisionType); int write(Value const& root, OStream* sout) override; private: @@ -903,14 +896,10 @@ struct BuiltStyledStreamWriter : public StreamWriter { unsigned int precision_; PrecisionType precisionType_; }; -BuiltStyledStreamWriter::BuiltStyledStreamWriter(String indentation, - CommentStyle::Enum cs, - String colonSymbol, - String nullSymbol, - String endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision, - PrecisionType precisionType) +BuiltStyledStreamWriter::BuiltStyledStreamWriter( + String indentation, CommentStyle::Enum cs, String colonSymbol, + String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, + unsigned int precision, PrecisionType precisionType) : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index c0b5296d9..0cc500a88 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -82,8 +82,8 @@ TestResult::TestResult() { void TestResult::setTestName(const Json::String& name) { name_ = name; } -TestResult& -TestResult::addFailure(const char* file, unsigned int line, const char* expr) { +TestResult& TestResult::addFailure(const char* file, unsigned int line, + const char* expr) { /// Walks the PredicateContext stack adding them to failures_ if not already /// added. unsigned int nestingLevel = 0; @@ -107,10 +107,8 @@ TestResult::addFailure(const char* file, unsigned int line, const char* expr) { return *this; } -void TestResult::addFailureInfo(const char* file, - unsigned int line, - const char* expr, - unsigned int nestingLevel) { +void TestResult::addFailureInfo(const char* file, unsigned int line, + const char* expr, unsigned int nestingLevel) { Failure failure; failure.file_ = file; failure.line_ = line; @@ -342,8 +340,8 @@ int Runner::runCommandLine(int argc, const char* argv[]) const { #if defined(_MSC_VER) && defined(_DEBUG) // Hook MSVCRT assertions to prevent dialog from appearing -static int -msvcrtSilentReportHook(int reportType, char* message, int* /*returnValue*/) { +static int msvcrtSilentReportHook(int reportType, char* message, + int* /*returnValue*/) { // The default CRT handling of error and assertion is to display // an error dialog to the user. // Instead, when an error or an assertion occurs, we force the @@ -418,12 +416,9 @@ Json::String ToJsonString(std::string in) { } #endif -TestResult& checkStringEqual(TestResult& result, - const Json::String& expected, - const Json::String& actual, - const char* file, - unsigned int line, - const char* expr) { +TestResult& checkStringEqual(TestResult& result, const Json::String& expected, + const Json::String& actual, const char* file, + unsigned int line, const char* expr) { if (expected != actual) { result.addFailure(file, line, expr); result << "Expected: '" << expected << "'\n"; diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index e9c11a470..5d213dcb2 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -68,8 +68,8 @@ class TestResult { void setTestName(const Json::String& name); /// Adds an assertion failure. - TestResult& - addFailure(const char* file, unsigned int line, const char* expr = nullptr); + TestResult& addFailure(const char* file, unsigned int line, + const char* expr = nullptr); /// Removes the last PredicateContext added to the predicate stack /// chained list. @@ -98,9 +98,7 @@ class TestResult { private: TestResult& addToLastFailure(const Json::String& message); /// Adds a failure or a predicate context - void addFailureInfo(const char* file, - unsigned int line, - const char* expr, + void addFailureInfo(const char* file, unsigned int line, const char* expr, unsigned int nestingLevel); static Json::String indentText(const Json::String& text, const Json::String& indent); @@ -176,12 +174,8 @@ class Runner { }; template -TestResult& checkEqual(TestResult& result, - T expected, - U actual, - const char* file, - unsigned int line, - const char* expr) { +TestResult& checkEqual(TestResult& result, T expected, U actual, + const char* file, unsigned int line, const char* expr) { if (static_cast(expected) != actual) { result.addFailure(file, line, expr); result << "Expected: " << static_cast(expected) << "\n"; @@ -196,12 +190,9 @@ Json::String ToJsonString(Json::String in); Json::String ToJsonString(std::string in); #endif -TestResult& checkStringEqual(TestResult& result, - const Json::String& expected, - const Json::String& actual, - const char* file, - unsigned int line, - const char* expr); +TestResult& checkStringEqual(TestResult& result, const Json::String& expected, + const Json::String& actual, const char* file, + unsigned int line, const char* expr); } // namespace JsonTest From 2ee3b1dbb15944c12638a763b21707ff05abaf6b Mon Sep 17 00:00:00 2001 From: es1x <56224787+es1x@users.noreply.github.com> Date: Fri, 11 Oct 2019 21:33:36 +0300 Subject: [PATCH 218/410] Re-add JSONCPP_NORETURN (#1041) Fixes Visual Studio 2013 compatibility. --- include/json/value.h | 16 ++++++++++++++-- src/lib_json/json_value.cpp | 8 ++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index a0a5a1181..7efc7c5e0 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -9,6 +9,18 @@ #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" #endif // if !defined(JSON_IS_AMALGAMATION) + +// Conditional NORETURN attribute on the throw functions would: +// a) suppress false positives from static code analysis +// b) possibly improve optimization opportunities. +#if !defined(JSONCPP_NORETURN) +#if defined(_MSC_VER) && _MSC_VER == 1800 +#define JSONCPP_NORETURN __declspec(noreturn) +#else +#define JSONCPP_NORETURN [[noreturn]] +#endif +#endif + #include #include #include @@ -76,9 +88,9 @@ class JSON_API LogicError : public Exception { #endif /// used internally -[[noreturn]] void throwRuntimeError(String const& msg); +JSONCPP_NORETURN void throwRuntimeError(String const& msg); /// used internally -[[noreturn]] void throwLogicError(String const& msg); +JSONCPP_NORETURN void throwLogicError(String const& msg); /** \brief Type of the value held by a Value object. */ diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index cf93ec7d5..30d9ad8ab 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -207,13 +207,13 @@ Exception::~Exception() JSONCPP_NOEXCEPT {} char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} -[[noreturn]] void throwRuntimeError(String const& msg) { +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { throw RuntimeError(msg); } -[[noreturn]] void throwLogicError(String const& msg) { throw LogicError(msg); } +JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } #else // !JSON_USE_EXCEPTION -[[noreturn]] void throwRuntimeError(String const& msg) { abort(); } -[[noreturn]] void throwLogicError(String const& msg) { abort(); } +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { abort(); } +JSONCPP_NORETURN void throwLogicError(String const& msg) { abort(); } #endif // ////////////////////////////////////////////////////////////////// From ddc0748c4fcaf5f9f47398cd1d6fe1c618a6cfba Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Sat, 12 Oct 2019 05:39:09 +0800 Subject: [PATCH 219/410] add testcases for writerTest [improve coverage] (#1039) * add testcases for writerTest * update StyledWriterTest, StyledStreamWriterTest and StreamWriterTest * run clang-format * add FastWriter Test * Improve Coverage to 90+% --- src/test_lib_json/main.cpp | 461 ++++++++++++++++++++++++++++++++++++- 1 file changed, 454 insertions(+), 7 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c15b03f5f..7e772366f 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1903,9 +1903,9 @@ JSONTEST_FIXTURE(ValueTest, precision) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -struct WriterTest : JsonTest::TestCase {}; +struct FastWriterTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) { +JSONTEST_FIXTURE(FastWriterTest, dropNullPlaceholders) { Json::FastWriter writer; Json::Value nullValue; JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); @@ -1914,7 +1914,7 @@ JSONTEST_FIXTURE(WriterTest, dropNullPlaceholders) { JSONTEST_ASSERT(writer.write(nullValue) == "\n"); } -JSONTEST_FIXTURE(WriterTest, enableYAMLCompatibility) { +JSONTEST_FIXTURE(FastWriterTest, enableYAMLCompatibility) { Json::FastWriter writer; Json::Value root; root["hello"] = "world"; @@ -1925,7 +1925,7 @@ JSONTEST_FIXTURE(WriterTest, enableYAMLCompatibility) { JSONTEST_ASSERT(writer.write(root) == "{\"hello\": \"world\"}\n"); } -JSONTEST_FIXTURE(WriterTest, omitEndingLineFeed) { +JSONTEST_FIXTURE(FastWriterTest, omitEndingLineFeed) { Json::FastWriter writer; Json::Value nullValue; @@ -1935,8 +1935,438 @@ JSONTEST_FIXTURE(WriterTest, omitEndingLineFeed) { JSONTEST_ASSERT(writer.write(nullValue) == "null"); } +JSONTEST_FIXTURE(FastWriterTest, writeNumericValue) { + Json::FastWriter writer; + const Json::String expected("{" + "\"emptyValue\":null," + "\"false\":false," + "\"null\":\"null\"," + "\"number\":-6200000000000000.0," + "\"real\":1.256," + "\"uintValue\":17" + "}\n"); + Json::Value root; + root["emptyValue"] = Json::nullValue; + root["false"] = false; + root["null"] = "null"; + root["number"] = -6.2e+15; + root["real"] = 1.256; + root["uintValue"] = Json::Value(17U); + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(FastWriterTest, writeArrays) { + Json::FastWriter writer; + const Json::String expected("{" + "\"property1\":[\"value1\",\"value2\"]," + "\"property2\":[]" + "}\n"); + Json::Value root; + root["property1"][0] = "value1"; + root["property1"][1] = "value2"; + root["property2"] = Json::arrayValue; + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(FastWriterTest, writeNestedObjects) { + Json::FastWriter writer; + const Json::String expected("{" + "\"object1\":{" + "\"bool\":true," + "\"nested\":123" + "}," + "\"object2\":{}" + "}\n"); + Json::Value root, child; + child["nested"] = 123; + child["bool"] = true; + root["object1"] = child; + root["object2"] = Json::objectValue; + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +struct StyledWriterTest : JsonTest::TestCase {}; + +JSONTEST_FIXTURE(StyledWriterTest, writeNumericValue) { + Json::StyledWriter writer; + const Json::String expected("{\n" + " \"emptyValue\" : null,\n" + " \"false\" : false,\n" + " \"null\" : \"null\",\n" + " \"number\" : -6200000000000000.0,\n" + " \"real\" : 1.256,\n" + " \"uintValue\" : 17\n" + "}\n"); + Json::Value root; + root["emptyValue"] = Json::nullValue; + root["false"] = false; + root["null"] = "null"; + root["number"] = -6.2e+15; + root["real"] = 1.256; + root["uintValue"] = Json::Value(17U); + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledWriterTest, writeArrays) { + Json::StyledWriter writer; + const Json::String expected("{\n" + " \"property1\" : [ \"value1\", \"value2\" ],\n" + " \"property2\" : []\n" + "}\n"); + Json::Value root; + root["property1"][0] = "value1"; + root["property1"][1] = "value2"; + root["property2"] = Json::arrayValue; + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledWriterTest, writeNestedObjects) { + Json::StyledWriter writer; + const Json::String expected("{\n" + " \"object1\" : {\n" + " \"bool\" : true,\n" + " \"nested\" : 123\n" + " },\n" + " \"object2\" : {}\n" + "}\n"); + Json::Value root, child; + child["nested"] = 123; + child["bool"] = true; + root["object1"] = child; + root["object2"] = Json::objectValue; + + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledWriterTest, multiLineArray) { + Json::StyledWriter writer; + { + // Array member has more than 20 print effect rendering lines + const Json::String expected("[\n " + "0,\n 1,\n 2,\n " + "3,\n 4,\n 5,\n " + "6,\n 7,\n 8,\n " + "9,\n 10,\n 11,\n " + "12,\n 13,\n 14,\n " + "15,\n 16,\n 17,\n " + "18,\n 19,\n 20\n]\n"); + Json::Value root; + for (int i = 0; i < 21; i++) + root[i] = i; + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + // Array members do not exceed 21 print effects to render a single line + const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); + Json::Value root; + for (int i = 0; i < 10; i++) + root[i] = i; + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } +} + +JSONTEST_FIXTURE(StyledWriterTest, writeValueWithComment) { + Json::StyledWriter writer; + { + const Json::String expected("\n//commentBeforeValue\n\"hello\"\n"); + Json::Value root = "hello"; + root.setComment(Json::String("//commentBeforeValue"), + Json::commentBefore); + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + const Json::String expected("\"hello\" //commentAfterValueOnSameLine\n"); + Json::Value root = "hello"; + root.setComment(Json::String("//commentAfterValueOnSameLine"), + Json::commentAfterOnSameLine); + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + const Json::String expected("\"hello\"\n//commentAfter\n\n"); + Json::Value root = "hello"; + root.setComment(Json::String("//commentAfter"), + Json::commentAfter); + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } +} + +struct StyledStreamWriterTest : JsonTest::TestCase {}; + +JSONTEST_FIXTURE(StyledStreamWriterTest, writeNumericValue) { + Json::StyledStreamWriter writer; + const Json::String expected("{\n" + "\t\"emptyValue\" : null,\n" + "\t\"false\" : false,\n" + "\t\"null\" : \"null\",\n" + "\t\"number\" : -6200000000000000.0,\n" + "\t\"real\" : 1.256,\n" + "\t\"uintValue\" : 17\n" + "}\n"); + + Json::Value root; + root["emptyValue"] = Json::nullValue; + root["false"] = false; + root["null"] = "null"; + root["number"] = -6.2e+15; // big float number + root["real"] = 1.256; // float number + root["uintValue"] = Json::Value(17U); + + Json::OStringStream sout; + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledStreamWriterTest, writeArrays) { + Json::StyledStreamWriter writer; + const Json::String expected("{\n" + "\t\"property1\" : [ \"value1\", \"value2\" ],\n" + "\t\"property2\" : []\n" + "}\n"); + Json::Value root; + root["property1"][0] = "value1"; + root["property1"][1] = "value2"; + root["property2"] = Json::arrayValue; + + Json::OStringStream sout; + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledStreamWriterTest, writeNestedObjects) { + Json::StyledStreamWriter writer; + const Json::String expected("{\n" + "\t\"object1\" : \n" + "\t" + "{\n" + "\t\t\"bool\" : true,\n" + "\t\t\"nested\" : 123\n" + "\t},\n" + "\t\"object2\" : {}\n" + "}\n"); + Json::Value root, child; + child["nested"] = 123; + child["bool"] = true; + root["object1"] = child; + root["object2"] = Json::objectValue; + + Json::OStringStream sout; + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StyledStreamWriterTest, multiLineArray) { + Json::StyledStreamWriter writer; + { + // Array member has more than 20 print effect rendering lines + const Json::String expected( + "[" + "\n\t0," + "\n\t1," + "\n\t2," + "\n\t3," + "\n\t4," + "\n\t5," + "\n\t6," + "\n\t7," + "\n\t8," + "\n\t9," + "\n\t10," + "\n\t11," + "\n\t12," + "\n\t13," + "\n\t14," + "\n\t15," + "\n\t16," + "\n\t17," + "\n\t18," + "\n\t19," + "\n\t20\n]\n"); + Json::StyledStreamWriter writer; + Json::Value root; + for (int i = 0; i < 21; i++) + root[i] = i; + Json::OStringStream sout; + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + // Array members do not exceed 21 print effects to render a single line + const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); + Json::Value root; + for (int i = 0; i < 10; i++) + root[i] = i; + Json::OStringStream sout; + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } +} + +JSONTEST_FIXTURE(StyledStreamWriterTest, writeValueWithComment) { + Json::StyledStreamWriter writer("\t"); + { + const Json::String expected("//commentBeforeValue\n\"hello\"\n"); + Json::Value root = "hello"; + Json::OStringStream sout; + root.setComment(Json::String("//commentBeforeValue"), + Json::commentBefore); + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + const Json::String expected("\"hello\" //commentAfterValueOnSameLine\n"); + Json::Value root = "hello"; + Json::OStringStream sout; + root.setComment(Json::String("//commentAfterValueOnSameLine"), + Json::commentAfterOnSameLine); + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + const Json::String expected("\"hello\"\n//commentAfter\n"); + Json::Value root = "hello"; + Json::OStringStream sout; + root.setComment(Json::String("//commentAfter"), + Json::commentAfter); + writer.write(sout, root); + const Json::String result = sout.str(); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } +} + struct StreamWriterTest : JsonTest::TestCase {}; +JSONTEST_FIXTURE(StreamWriterTest, writeNumericValue) { + Json::StreamWriterBuilder writer; + const Json::String expected("{\n" + "\t\"emptyValue\" : null,\n" + "\t\"false\" : false,\n" + "\t\"null\" : \"null\",\n" + "\t\"number\" : -6200000000000000.0,\n" + "\t\"real\" : 1.256,\n" + "\t\"uintValue\" : 17\n" + "}"); + Json::Value root; + root["emptyValue"] = Json::nullValue; + root["false"] = false; + root["null"] = "null"; + root["number"] = -6.2e+15; + root["real"] = 1.256; + root["uintValue"] = Json::Value(17U); + + const Json::String result = Json::writeString(writer, root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StreamWriterTest, writeArrays) { + Json::StreamWriterBuilder writer; + const Json::String expected("{\n" + "\t\"property1\" : \n" + "\t[\n" + "\t\t\"value1\",\n" + "\t\t\"value2\"\n" + "\t],\n" + "\t\"property2\" : []\n" + "}"); + + Json::Value root; + root["property1"][0] = "value1"; + root["property1"][1] = "value2"; + root["property2"] = Json::arrayValue; + + const Json::String result = Json::writeString(writer, root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StreamWriterTest, writeNestedObjects) { + Json::StreamWriterBuilder writer; + const Json::String expected("{\n" + "\t\"object1\" : \n" + "\t{\n" + "\t\t\"bool\" : true,\n" + "\t\t\"nested\" : 123\n" + "\t},\n" + "\t\"object2\" : {}\n" + "}"); + + Json::Value root, child; + child["nested"] = 123; + child["bool"] = true; + root["object1"] = child; + root["object2"] = Json::objectValue; + + const Json::String result = Json::writeString(writer, root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + +JSONTEST_FIXTURE(StreamWriterTest, multiLineArray) { + Json::StreamWriterBuilder wb; + wb.settings_["commentStyle"] = "None"; + { + // When wb.settings_["commentStyle"] = "None", the effect of + // printing multiple lines will be displayed when there are + // more than 20 array members. + const Json::String expected( + "[\n\t0," + "\n\t1," + "\n\t2," + "\n\t3," + "\n\t4," + "\n\t5," + "\n\t6," + "\n\t7," + "\n\t8," + "\n\t9," + "\n\t10," + "\n\t11," + "\n\t12," + "\n\t13," + "\n\t14," + "\n\t15," + "\n\t16," + "\n\t17," + "\n\t18," + "\n\t19," + "\n\t20\n]"); + Json::Value root; + for (int i = 0; i < 21; i++) + root[i] = i; + const Json::String result = Json::writeString(wb, root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } + { + //Array members do not exceed 21 print effects to render a single line + const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]"); + Json::Value root; + for (int i = 0; i < 10; i++) + root[i] = i; + const Json::String result = Json::writeString(wb, root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + } +} + JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { Json::StreamWriterBuilder b; Json::Value nullValue; @@ -2724,9 +3154,26 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats); JSONTEST_REGISTER_FIXTURE(runner, ValueTest, precision); - JSONTEST_REGISTER_FIXTURE(runner, WriterTest, dropNullPlaceholders); - JSONTEST_REGISTER_FIXTURE(runner, WriterTest, enableYAMLCompatibility); - JSONTEST_REGISTER_FIXTURE(runner, WriterTest, omitEndingLineFeed); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, dropNullPlaceholders); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, enableYAMLCompatibility); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, omitEndingLineFeed); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeNumericValue); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeArrays); + JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeNestedObjects); + JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeNumericValue); + JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeArrays); + JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeNestedObjects); + JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, multiLineArray); + JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeValueWithComment); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeNumericValue); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeArrays); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeNestedObjects); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, multiLineArray); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeValueWithComment); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNumericValue); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeArrays); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNestedObjects); + JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, multiLineArray); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, enableYAMLCompatibility); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, indentation); From 2e33c218cbd53b8d016e9230c2f600411b6146b8 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 11 Oct 2019 15:08:42 -0700 Subject: [PATCH 220/410] Fix fuzzer off by one error (#1047) * Fix fuzzer off by one error Currently the fuzzer has an off by one error, as it passing a bad length to the CharReader::parse method, resulting in a heap buffer overflow. * Rebase master, rerun clang format --- example/readFromString/readFromString.cpp | 4 ++-- src/lib_json/json_value.cpp | 4 +++- src/test_lib_json/fuzz.cpp | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp index 753f9c94b..ce3223692 100644 --- a/example/readFromString/readFromString.cpp +++ b/example/readFromString/readFromString.cpp @@ -2,8 +2,8 @@ #include /** * \brief Parse a raw string into Value object using the CharReaderBuilder - * class, or the legacy Reader class. - * Example Usage: + * class, or the legacy Reader class. + * Example Usage: * $g++ readFromString.cpp -ljsoncpp -std=c++11 -o readFromString * $./readFromString * colin diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 30d9ad8ab..e13678359 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -210,7 +210,9 @@ LogicError::LogicError(String const& msg) : Exception(msg) {} JSONCPP_NORETURN void throwRuntimeError(String const& msg) { throw RuntimeError(msg); } -JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } +JSONCPP_NORETURN void throwLogicError(String const& msg) { + throw LogicError(msg); +} #else // !JSON_USE_EXCEPTION JSONCPP_NORETURN void throwRuntimeError(String const& msg) { abort(); } JSONCPP_NORETURN void throwLogicError(String const& msg) { abort(); } diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index f79f19ffe..d6e3815ad 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -25,6 +25,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint32_t hash_settings = *(const uint32_t*)data; data += sizeof(uint32_t); + size -= sizeof(uint32_t); builder.settings_["failIfExtra"] = hash_settings & (1 << 0); builder.settings_["allowComments_"] = hash_settings & (1 << 1); From 7329223f58a803cf6e1b57e82afabd1f2081573b Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Mon, 14 Oct 2019 09:42:47 +0800 Subject: [PATCH 221/410] fix clang-format (#1049) fix clang-format for #1039 --- src/test_lib_json/main.cpp | 134 ++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 70 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 7e772366f..1faf8ca06 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2054,16 +2054,16 @@ JSONTEST_FIXTURE(StyledWriterTest, multiLineArray) { { // Array member has more than 20 print effect rendering lines const Json::String expected("[\n " - "0,\n 1,\n 2,\n " - "3,\n 4,\n 5,\n " - "6,\n 7,\n 8,\n " - "9,\n 10,\n 11,\n " - "12,\n 13,\n 14,\n " - "15,\n 16,\n 17,\n " - "18,\n 19,\n 20\n]\n"); + "0,\n 1,\n 2,\n " + "3,\n 4,\n 5,\n " + "6,\n 7,\n 8,\n " + "9,\n 10,\n 11,\n " + "12,\n 13,\n 14,\n " + "15,\n 16,\n 17,\n " + "18,\n 19,\n 20\n]\n"); Json::Value root; for (int i = 0; i < 21; i++) - root[i] = i; + root[i] = i; const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } @@ -2072,7 +2072,7 @@ JSONTEST_FIXTURE(StyledWriterTest, multiLineArray) { const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); Json::Value root; for (int i = 0; i < 10; i++) - root[i] = i; + root[i] = i; const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } @@ -2083,8 +2083,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeValueWithComment) { { const Json::String expected("\n//commentBeforeValue\n\"hello\"\n"); Json::Value root = "hello"; - root.setComment(Json::String("//commentBeforeValue"), - Json::commentBefore); + root.setComment(Json::String("//commentBeforeValue"), Json::commentBefore); const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } @@ -2099,8 +2098,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeValueWithComment) { { const Json::String expected("\"hello\"\n//commentAfter\n\n"); Json::Value root = "hello"; - root.setComment(Json::String("//commentAfter"), - Json::commentAfter); + root.setComment(Json::String("//commentAfter"), Json::commentAfter); const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } @@ -2177,44 +2175,42 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, multiLineArray) { Json::StyledStreamWriter writer; { // Array member has more than 20 print effect rendering lines - const Json::String expected( - "[" - "\n\t0," - "\n\t1," - "\n\t2," - "\n\t3," - "\n\t4," - "\n\t5," - "\n\t6," - "\n\t7," - "\n\t8," - "\n\t9," - "\n\t10," - "\n\t11," - "\n\t12," - "\n\t13," - "\n\t14," - "\n\t15," - "\n\t16," - "\n\t17," - "\n\t18," - "\n\t19," - "\n\t20\n]\n"); + const Json::String expected("[\n\t0," + "\n\t1," + "\n\t2," + "\n\t3," + "\n\t4," + "\n\t5," + "\n\t6," + "\n\t7," + "\n\t8," + "\n\t9," + "\n\t10," + "\n\t11," + "\n\t12," + "\n\t13," + "\n\t14," + "\n\t15," + "\n\t16," + "\n\t17," + "\n\t18," + "\n\t19," + "\n\t20\n]\n"); Json::StyledStreamWriter writer; Json::Value root; for (int i = 0; i < 21; i++) - root[i] = i; + root[i] = i; Json::OStringStream sout; writer.write(sout, root); const Json::String result = sout.str(); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } - { + { // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); Json::Value root; for (int i = 0; i < 10; i++) - root[i] = i; + root[i] = i; Json::OStringStream sout; writer.write(sout, root); const Json::String result = sout.str(); @@ -2228,8 +2224,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeValueWithComment) { const Json::String expected("//commentBeforeValue\n\"hello\"\n"); Json::Value root = "hello"; Json::OStringStream sout; - root.setComment(Json::String("//commentBeforeValue"), - Json::commentBefore); + root.setComment(Json::String("//commentBeforeValue"), Json::commentBefore); writer.write(sout, root); const Json::String result = sout.str(); JSONTEST_ASSERT_STRING_EQUAL(expected, result); @@ -2248,8 +2243,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeValueWithComment) { const Json::String expected("\"hello\"\n//commentAfter\n"); Json::Value root = "hello"; Json::OStringStream sout; - root.setComment(Json::String("//commentAfter"), - Json::commentAfter); + root.setComment(Json::String("//commentAfter"), Json::commentAfter); writer.write(sout, root); const Json::String result = sout.str(); JSONTEST_ASSERT_STRING_EQUAL(expected, result); @@ -2326,42 +2320,41 @@ JSONTEST_FIXTURE(StreamWriterTest, multiLineArray) { wb.settings_["commentStyle"] = "None"; { // When wb.settings_["commentStyle"] = "None", the effect of - // printing multiple lines will be displayed when there are + // printing multiple lines will be displayed when there are // more than 20 array members. - const Json::String expected( - "[\n\t0," - "\n\t1," - "\n\t2," - "\n\t3," - "\n\t4," - "\n\t5," - "\n\t6," - "\n\t7," - "\n\t8," - "\n\t9," - "\n\t10," - "\n\t11," - "\n\t12," - "\n\t13," - "\n\t14," - "\n\t15," - "\n\t16," - "\n\t17," - "\n\t18," - "\n\t19," - "\n\t20\n]"); + const Json::String expected("[\n\t0," + "\n\t1," + "\n\t2," + "\n\t3," + "\n\t4," + "\n\t5," + "\n\t6," + "\n\t7," + "\n\t8," + "\n\t9," + "\n\t10," + "\n\t11," + "\n\t12," + "\n\t13," + "\n\t14," + "\n\t15," + "\n\t16," + "\n\t17," + "\n\t18," + "\n\t19," + "\n\t20\n]"); Json::Value root; for (int i = 0; i < 21; i++) - root[i] = i; + root[i] = i; const Json::String result = Json::writeString(wb, root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } { - //Array members do not exceed 21 print effects to render a single line + // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]"); Json::Value root; for (int i = 0; i < 10; i++) - root[i] = i; + root[i] = i; const Json::String result = Json::writeString(wb, root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } @@ -3169,7 +3162,8 @@ int main(int argc, const char* argv[]) { JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeArrays); JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeNestedObjects); JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, multiLineArray); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeValueWithComment); + JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, + writeValueWithComment); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNumericValue); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeArrays); JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNestedObjects); From bcad4e4de22830f550eae6ae8ae0820c979b100c Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 15 Oct 2019 00:27:23 -0700 Subject: [PATCH 222/410] clang-tidy cleanups 2 (#1048) * [clang-tidy] Add explicit to single argument constructor Found with hicpp-explicit-conversions Signed-off-by: Rosen Penev * [clang-tidy] Fix mismatching declaration Found with readability-inconsistent-declaration-parameter-name Signed-off-by: Rosen Penev * [clang-tidy] Replace {} with = default Found with modernize-use-equals-default Signed-off-by: Rosen Penev * [clang-tidy] Remove redundant .c_Str Found with readability-redundant-string-cstr Signed-off-by: Rosen Penev * [clang-tidy] Simplify boolean expressions Found with readability-simplify-boolean-expr Signed-off-by: Rosen Penev * [clang-tidy] Use std::move Found with modernize-pass-by-value Signed-off-by: Rosen Penev * [clang-tidy] Uppercase literal suffixes Found with hicpp-uppercase-literal-suffix Signed-off-by: Rosen Penev --- include/json/value.h | 4 ++-- src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_value.cpp | 26 +++++++++++--------------- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 7efc7c5e0..e3c3d2b7e 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -657,7 +657,7 @@ class JSON_API Value { Comments& operator=(Comments&& that); bool has(CommentPlacement slot) const; String get(CommentPlacement slot) const; - void set(CommentPlacement slot, String s); + void set(CommentPlacement slot, String comment); private: using Array = std::array; @@ -681,7 +681,7 @@ class JSON_API PathArgument { PathArgument(); PathArgument(ArrayIndex index); PathArgument(const char* key); - PathArgument(const String& key); + PathArgument(String key); private: enum Kind { kindNone = 0, kindIndex, kindKey }; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index ac673ffce..958a39869 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -889,7 +889,7 @@ class OurReader { String message; }; - OurReader(OurFeatures const& features); + explicit OurReader(OurFeatures const& features); bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); String getFormattedErrorMessages() const; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index e13678359..9518ab828 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -203,7 +203,7 @@ namespace Json { #if JSON_USE_EXCEPTION Exception::Exception(String msg) : msg_(std::move(msg)) {} -Exception::~Exception() JSONCPP_NOEXCEPT {} +Exception::~Exception() JSONCPP_NOEXCEPT = default; char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} @@ -263,7 +263,7 @@ Value::CZString::CZString(CZString&& other) Value::CZString::~CZString() { if (cstr_ && storage_.policy_ == duplicate) { releaseStringValue(const_cast(cstr_), - storage_.length_ + 1u); // +1 for null terminating + storage_.length_ + 1U); // +1 for null terminating // character for sake of // completeness but not actually // necessary @@ -494,7 +494,7 @@ int Value::compare(const Value& other) const { bool Value::operator<(const Value& other) const { int typeDelta = type() - other.type(); if (typeDelta) - return typeDelta < 0 ? true : false; + return typeDelta < 0; switch (type()) { case nullValue: return false; @@ -508,10 +508,7 @@ bool Value::operator<(const Value& other) const { return value_.bool_ < other.value_.bool_; case stringValue: { if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) { - if (other.value_.string_) - return true; - else - return false; + return other.value_.string_ != nullptr; } unsigned this_len; unsigned other_len; @@ -809,7 +806,7 @@ float Value::asFloat() const { case nullValue: return 0.0; case booleanValue: - return value_.bool_ ? 1.0f : 0.0f; + return value_.bool_ ? 1.0F : 0.0F; default: break; } @@ -823,9 +820,9 @@ bool Value::asBool() const { case nullValue: return false; case intValue: - return value_.int_ ? true : false; + return value_.int_ != 0; case uintValue: - return value_.uint_ ? true : false; + return value_.uint_ != 0; case realValue: { // According to JavaScript language zero or NaN is regarded as false const auto value_classification = std::fpclassify(value_.real_); @@ -841,7 +838,7 @@ bool Value::isConvertibleTo(ValueType other) const { switch (other) { case nullValue: return (isNumeric() && asDouble() == 0.0) || - (type() == booleanValue && value_.bool_ == false) || + (type() == booleanValue && !value_.bool_) || (type() == stringValue && asString().empty()) || (type() == arrayValue && value_.map_->empty()) || (type() == objectValue && value_.map_->empty()) || @@ -896,7 +893,7 @@ ArrayIndex Value::size() const { bool Value::empty() const { if (isNull() || isArray() || isObject()) - return size() == 0u; + return size() == 0U; else return false; } @@ -1545,15 +1542,14 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() {} +PathArgument::PathArgument() = default; PathArgument::PathArgument(ArrayIndex index) : index_(index), kind_(kindIndex) {} PathArgument::PathArgument(const char* key) : key_(key), kind_(kindKey) {} -PathArgument::PathArgument(const String& key) - : key_(key.c_str()), kind_(kindKey) {} +PathArgument::PathArgument(String key) : key_(std::move(key)), kind_(kindKey) {} // class Path // ////////////////////////////////////////////////////////////////// From c5f66ab816bcf28dc2d677a866d93a45f22e95fc Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Wed, 16 Oct 2019 06:48:50 +0800 Subject: [PATCH 223/410] Test Framework Modify : Remove JSONTEST_REGISTER_FIXTURE (#1050) * add JSONTEST_FIXTURE_V2 to automatically register * fix clang-format * revert singleton --- src/test_lib_json/jsontest.h | 22 +++ src/test_lib_json/main.cpp | 272 ++++++++++++----------------------- 2 files changed, 112 insertions(+), 182 deletions(-) diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 5d213dcb2..49d1dcd8c 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -264,4 +264,26 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, #define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \ (runner).add(JSONTEST_FIXTURE_FACTORY(FixtureType, name)) +/// \brief Begin a fixture test case. +#define JSONTEST_FIXTURE_V2(FixtureType, name, collections) \ + class Test##FixtureType##name : public FixtureType { \ + public: \ + static JsonTest::TestCase* factory() { \ + return new Test##FixtureType##name(); \ + } \ + static bool collect() { \ + (collections).push_back(JSONTEST_FIXTURE_FACTORY(FixtureType, name)); \ + return true; \ + } \ + \ + public: /* overridden from TestCase */ \ + const char* testName() const override { return #FixtureType "/" #name; } \ + void runTestCase() override; \ + }; \ + \ + static bool test##FixtureType##name##collect = \ + Test##FixtureType##name::collect(); \ + \ + void Test##FixtureType##name::runTestCase() + #endif // ifndef JSONTEST_H_INCLUDED diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 1faf8ca06..c79ad1ea4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -53,6 +53,11 @@ static inline double uint64ToDouble(Json::UInt64 value) { } #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) +// local_ is the collection for the testcases in this code file. +static std::deque local_; +#define JSONTEST_FIXTURE_LOCAL(FixtureType, name) \ + JSONTEST_FIXTURE_V2(FixtureType, name, local_) + struct ValueTest : JsonTest::TestCase { Json::Value null_; Json::Value emptyArray_; @@ -135,7 +140,7 @@ Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { return s; } -JSONTEST_FIXTURE(ValueTest, checkNormalizeFloatingPointStr) { +JSONTEST_FIXTURE_LOCAL(ValueTest, checkNormalizeFloatingPointStr) { JSONTEST_ASSERT_STRING_EQUAL("0.0", normalizeFloatingPointStr("0.0")); JSONTEST_ASSERT_STRING_EQUAL("0e0", normalizeFloatingPointStr("0e0")); JSONTEST_ASSERT_STRING_EQUAL("1234.0", normalizeFloatingPointStr("1234.0")); @@ -165,7 +170,7 @@ JSONTEST_FIXTURE(ValueTest, checkNormalizeFloatingPointStr) { normalizeFloatingPointStr("1234e-100")); } -JSONTEST_FIXTURE(ValueTest, memberCount) { +JSONTEST_FIXTURE_LOCAL(ValueTest, memberCount) { JSONTEST_ASSERT_PRED(checkMemberCount(emptyArray_, 0)); JSONTEST_ASSERT_PRED(checkMemberCount(emptyObject_, 0)); JSONTEST_ASSERT_PRED(checkMemberCount(array1_, 1)); @@ -183,7 +188,7 @@ JSONTEST_FIXTURE(ValueTest, memberCount) { JSONTEST_ASSERT_PRED(checkMemberCount(float_, 0)); } -JSONTEST_FIXTURE(ValueTest, objects) { +JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { // Types IsCheck checks; checks.isObject_ = true; @@ -264,7 +269,7 @@ JSONTEST_FIXTURE(ValueTest, objects) { JSONTEST_ASSERT_EQUAL(true, did); } -JSONTEST_FIXTURE(ValueTest, arrays) { +JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { const unsigned int index0 = 0; // Types @@ -309,7 +314,7 @@ JSONTEST_FIXTURE(ValueTest, arrays) { JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } -JSONTEST_FIXTURE(ValueTest, arrayIssue252) { +JSONTEST_FIXTURE_LOCAL(ValueTest, arrayIssue252) { int count = 5; Json::Value root; Json::Value item; @@ -322,7 +327,7 @@ JSONTEST_FIXTURE(ValueTest, arrayIssue252) { // JSONTEST_ASSERT_EQUAL(5, root["array"].size()); } -JSONTEST_FIXTURE(ValueTest, null) { +JSONTEST_FIXTURE_LOCAL(ValueTest, null) { JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type()); IsCheck checks; @@ -355,7 +360,7 @@ JSONTEST_FIXTURE(ValueTest, null) { JSONTEST_ASSERT_EQUAL(!object1_, false); } -JSONTEST_FIXTURE(ValueTest, strings) { +JSONTEST_FIXTURE_LOCAL(ValueTest, strings) { JSONTEST_ASSERT_EQUAL(Json::stringValue, string1_.type()); IsCheck checks; @@ -384,7 +389,7 @@ JSONTEST_FIXTURE(ValueTest, strings) { JSONTEST_ASSERT_STRING_EQUAL("a", string1_.asCString()); } -JSONTEST_FIXTURE(ValueTest, bools) { +JSONTEST_FIXTURE_LOCAL(ValueTest, bools) { JSONTEST_ASSERT_EQUAL(Json::booleanValue, false_.type()); IsCheck checks; @@ -426,7 +431,7 @@ JSONTEST_FIXTURE(ValueTest, bools) { JSONTEST_ASSERT_EQUAL(0.0, false_.asFloat()); } -JSONTEST_FIXTURE(ValueTest, integers) { +JSONTEST_FIXTURE_LOCAL(ValueTest, integers) { IsCheck checks; Json::Value val; @@ -1164,7 +1169,7 @@ JSONTEST_FIXTURE(ValueTest, integers) { #endif } -JSONTEST_FIXTURE(ValueTest, nonIntegers) { +JSONTEST_FIXTURE_LOCAL(ValueTest, nonIntegers) { IsCheck checks; Json::Value val; @@ -1389,7 +1394,7 @@ void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { #endif } -JSONTEST_FIXTURE(ValueTest, compareNull) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareNull) { JSONTEST_ASSERT_PRED(checkIsEqual(Json::Value(), Json::Value())); JSONTEST_ASSERT_PRED( checkIsEqual(Json::Value::nullSingleton(), Json::Value())); @@ -1397,27 +1402,27 @@ JSONTEST_FIXTURE(ValueTest, compareNull) { checkIsEqual(Json::Value::nullSingleton(), Json::Value::nullSingleton())); } -JSONTEST_FIXTURE(ValueTest, compareInt) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareInt) { JSONTEST_ASSERT_PRED(checkIsLess(0, 10)); JSONTEST_ASSERT_PRED(checkIsEqual(10, 10)); JSONTEST_ASSERT_PRED(checkIsEqual(-10, -10)); JSONTEST_ASSERT_PRED(checkIsLess(-10, 0)); } -JSONTEST_FIXTURE(ValueTest, compareUInt) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareUInt) { JSONTEST_ASSERT_PRED(checkIsLess(0u, 10u)); JSONTEST_ASSERT_PRED(checkIsLess(0u, Json::Value::maxUInt)); JSONTEST_ASSERT_PRED(checkIsEqual(10u, 10u)); } -JSONTEST_FIXTURE(ValueTest, compareDouble) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareDouble) { JSONTEST_ASSERT_PRED(checkIsLess(0.0, 10.0)); JSONTEST_ASSERT_PRED(checkIsEqual(10.0, 10.0)); JSONTEST_ASSERT_PRED(checkIsEqual(-10.0, -10.0)); JSONTEST_ASSERT_PRED(checkIsLess(-10.0, 0.0)); } -JSONTEST_FIXTURE(ValueTest, compareString) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareString) { JSONTEST_ASSERT_PRED(checkIsLess("", " ")); JSONTEST_ASSERT_PRED(checkIsLess("", "a")); JSONTEST_ASSERT_PRED(checkIsLess("abcd", "zyui")); @@ -1428,13 +1433,13 @@ JSONTEST_FIXTURE(ValueTest, compareString) { JSONTEST_ASSERT_PRED(checkIsEqual("ABCD", "ABCD")); } -JSONTEST_FIXTURE(ValueTest, compareBoolean) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareBoolean) { JSONTEST_ASSERT_PRED(checkIsLess(false, true)); JSONTEST_ASSERT_PRED(checkIsEqual(false, false)); JSONTEST_ASSERT_PRED(checkIsEqual(true, true)); } -JSONTEST_FIXTURE(ValueTest, compareArray) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareArray) { // array compare size then content Json::Value emptyArray(Json::arrayValue); Json::Value l1aArray; @@ -1459,7 +1464,7 @@ JSONTEST_FIXTURE(ValueTest, compareArray) { JSONTEST_ASSERT_PRED(checkIsEqual(l2bArray, Json::Value(l2bArray))); } -JSONTEST_FIXTURE(ValueTest, compareObject) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareObject) { // object compare size then content Json::Value emptyObject(Json::objectValue); Json::Value l1aObject; @@ -1502,7 +1507,7 @@ JSONTEST_FIXTURE(ValueTest, compareObject) { } } -JSONTEST_FIXTURE(ValueTest, compareType) { +JSONTEST_FIXTURE_LOCAL(ValueTest, compareType) { // object of different type are ordered according to their type JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(), Json::Value(1))); JSONTEST_ASSERT_PRED(checkIsLess(Json::Value(1), Json::Value(1u))); @@ -1515,7 +1520,7 @@ JSONTEST_FIXTURE(ValueTest, compareType) { Json::Value(Json::objectValue))); } -JSONTEST_FIXTURE(ValueTest, CopyObject) { +JSONTEST_FIXTURE_LOCAL(ValueTest, CopyObject) { Json::Value arrayVal; arrayVal.append("val1"); arrayVal.append("val2"); @@ -1597,7 +1602,7 @@ void ValueTest::checkIsEqual(const Json::Value& x, const Json::Value& y) { JSONTEST_ASSERT(y.compare(x) == 0); } -JSONTEST_FIXTURE(ValueTest, typeChecksThrowExceptions) { +JSONTEST_FIXTURE_LOCAL(ValueTest, typeChecksThrowExceptions) { #if JSON_USE_EXCEPTION Json::Value intVal(1); @@ -1663,7 +1668,7 @@ JSONTEST_FIXTURE(ValueTest, typeChecksThrowExceptions) { #endif } -JSONTEST_FIXTURE(ValueTest, offsetAccessors) { +JSONTEST_FIXTURE_LOCAL(ValueTest, offsetAccessors) { Json::Value x; JSONTEST_ASSERT(x.getOffsetStart() == 0); JSONTEST_ASSERT(x.getOffsetLimit() == 0); @@ -1682,7 +1687,7 @@ JSONTEST_FIXTURE(ValueTest, offsetAccessors) { JSONTEST_ASSERT(y.getOffsetLimit() == 0); } -JSONTEST_FIXTURE(ValueTest, StaticString) { +JSONTEST_FIXTURE_LOCAL(ValueTest, StaticString) { char mutant[] = "hello"; Json::StaticString ss(mutant); Json::String regular(mutant); @@ -1705,7 +1710,7 @@ JSONTEST_FIXTURE(ValueTest, StaticString) { } } -JSONTEST_FIXTURE(ValueTest, WideString) { +JSONTEST_FIXTURE_LOCAL(ValueTest, WideString) { // https://github.com/open-source-parsers/jsoncpp/issues/756 const std::string uni = u8"式,进"; // "\u5f0f\uff0c\u8fdb" std::string styled; @@ -1727,7 +1732,7 @@ JSONTEST_FIXTURE(ValueTest, WideString) { JSONTEST_ASSERT_STRING_EQUAL(root["abc"].asString(), uni); } -JSONTEST_FIXTURE(ValueTest, CommentBefore) { +JSONTEST_FIXTURE_LOCAL(ValueTest, CommentBefore) { Json::Value val; // fill val val.setComment(Json::String("// this comment should appear before"), Json::commentBefore); @@ -1771,7 +1776,7 @@ JSONTEST_FIXTURE(ValueTest, CommentBefore) { } } -JSONTEST_FIXTURE(ValueTest, zeroes) { +JSONTEST_FIXTURE_LOCAL(ValueTest, zeroes) { char const cstr[] = "h\0i"; Json::String binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); @@ -1797,7 +1802,7 @@ JSONTEST_FIXTURE(ValueTest, zeroes) { } } -JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { +JSONTEST_FIXTURE_LOCAL(ValueTest, zeroesInKeys) { char const cstr[] = "h\0i"; Json::String binary(cstr, sizeof(cstr)); // include trailing 0 JSONTEST_ASSERT_EQUAL(4U, binary.length()); @@ -1825,7 +1830,7 @@ JSONTEST_FIXTURE(ValueTest, zeroesInKeys) { } } -JSONTEST_FIXTURE(ValueTest, specialFloats) { +JSONTEST_FIXTURE_LOCAL(ValueTest, specialFloats) { Json::StreamWriterBuilder b; b.settings_["useSpecialFloats"] = true; @@ -1845,7 +1850,7 @@ JSONTEST_FIXTURE(ValueTest, specialFloats) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(ValueTest, precision) { +JSONTEST_FIXTURE_LOCAL(ValueTest, precision) { Json::StreamWriterBuilder b; b.settings_["precision"] = 5; @@ -1905,7 +1910,7 @@ JSONTEST_FIXTURE(ValueTest, precision) { struct FastWriterTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(FastWriterTest, dropNullPlaceholders) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, dropNullPlaceholders) { Json::FastWriter writer; Json::Value nullValue; JSONTEST_ASSERT(writer.write(nullValue) == "null\n"); @@ -1914,7 +1919,7 @@ JSONTEST_FIXTURE(FastWriterTest, dropNullPlaceholders) { JSONTEST_ASSERT(writer.write(nullValue) == "\n"); } -JSONTEST_FIXTURE(FastWriterTest, enableYAMLCompatibility) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, enableYAMLCompatibility) { Json::FastWriter writer; Json::Value root; root["hello"] = "world"; @@ -1925,7 +1930,7 @@ JSONTEST_FIXTURE(FastWriterTest, enableYAMLCompatibility) { JSONTEST_ASSERT(writer.write(root) == "{\"hello\": \"world\"}\n"); } -JSONTEST_FIXTURE(FastWriterTest, omitEndingLineFeed) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, omitEndingLineFeed) { Json::FastWriter writer; Json::Value nullValue; @@ -1935,7 +1940,7 @@ JSONTEST_FIXTURE(FastWriterTest, omitEndingLineFeed) { JSONTEST_ASSERT(writer.write(nullValue) == "null"); } -JSONTEST_FIXTURE(FastWriterTest, writeNumericValue) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeNumericValue) { Json::FastWriter writer; const Json::String expected("{" "\"emptyValue\":null," @@ -1957,7 +1962,7 @@ JSONTEST_FIXTURE(FastWriterTest, writeNumericValue) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(FastWriterTest, writeArrays) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeArrays) { Json::FastWriter writer; const Json::String expected("{" "\"property1\":[\"value1\",\"value2\"]," @@ -1972,7 +1977,7 @@ JSONTEST_FIXTURE(FastWriterTest, writeArrays) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(FastWriterTest, writeNestedObjects) { +JSONTEST_FIXTURE_LOCAL(FastWriterTest, writeNestedObjects) { Json::FastWriter writer; const Json::String expected("{" "\"object1\":{" @@ -1993,7 +1998,7 @@ JSONTEST_FIXTURE(FastWriterTest, writeNestedObjects) { struct StyledWriterTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(StyledWriterTest, writeNumericValue) { +JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeNumericValue) { Json::StyledWriter writer; const Json::String expected("{\n" " \"emptyValue\" : null,\n" @@ -2015,7 +2020,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeNumericValue) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledWriterTest, writeArrays) { +JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeArrays) { Json::StyledWriter writer; const Json::String expected("{\n" " \"property1\" : [ \"value1\", \"value2\" ],\n" @@ -2030,7 +2035,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeArrays) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledWriterTest, writeNestedObjects) { +JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeNestedObjects) { Json::StyledWriter writer; const Json::String expected("{\n" " \"object1\" : {\n" @@ -2049,7 +2054,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeNestedObjects) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledWriterTest, multiLineArray) { +JSONTEST_FIXTURE_LOCAL(StyledWriterTest, multiLineArray) { Json::StyledWriter writer; { // Array member has more than 20 print effect rendering lines @@ -2078,7 +2083,7 @@ JSONTEST_FIXTURE(StyledWriterTest, multiLineArray) { } } -JSONTEST_FIXTURE(StyledWriterTest, writeValueWithComment) { +JSONTEST_FIXTURE_LOCAL(StyledWriterTest, writeValueWithComment) { Json::StyledWriter writer; { const Json::String expected("\n//commentBeforeValue\n\"hello\"\n"); @@ -2106,7 +2111,7 @@ JSONTEST_FIXTURE(StyledWriterTest, writeValueWithComment) { struct StyledStreamWriterTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(StyledStreamWriterTest, writeNumericValue) { +JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeNumericValue) { Json::StyledStreamWriter writer; const Json::String expected("{\n" "\t\"emptyValue\" : null,\n" @@ -2131,7 +2136,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeNumericValue) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledStreamWriterTest, writeArrays) { +JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeArrays) { Json::StyledStreamWriter writer; const Json::String expected("{\n" "\t\"property1\" : [ \"value1\", \"value2\" ],\n" @@ -2148,7 +2153,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeArrays) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledStreamWriterTest, writeNestedObjects) { +JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeNestedObjects) { Json::StyledStreamWriter writer; const Json::String expected("{\n" "\t\"object1\" : \n" @@ -2171,7 +2176,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeNestedObjects) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StyledStreamWriterTest, multiLineArray) { +JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { Json::StyledStreamWriter writer; { // Array member has more than 20 print effect rendering lines @@ -2218,7 +2223,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, multiLineArray) { } } -JSONTEST_FIXTURE(StyledStreamWriterTest, writeValueWithComment) { +JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeValueWithComment) { Json::StyledStreamWriter writer("\t"); { const Json::String expected("//commentBeforeValue\n\"hello\"\n"); @@ -2252,7 +2257,7 @@ JSONTEST_FIXTURE(StyledStreamWriterTest, writeValueWithComment) { struct StreamWriterTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(StreamWriterTest, writeNumericValue) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNumericValue) { Json::StreamWriterBuilder writer; const Json::String expected("{\n" "\t\"emptyValue\" : null,\n" @@ -2274,7 +2279,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeNumericValue) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StreamWriterTest, writeArrays) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeArrays) { Json::StreamWriterBuilder writer; const Json::String expected("{\n" "\t\"property1\" : \n" @@ -2294,7 +2299,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeArrays) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StreamWriterTest, writeNestedObjects) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeNestedObjects) { Json::StreamWriterBuilder writer; const Json::String expected("{\n" "\t\"object1\" : \n" @@ -2315,7 +2320,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeNestedObjects) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } -JSONTEST_FIXTURE(StreamWriterTest, multiLineArray) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, multiLineArray) { Json::StreamWriterBuilder wb; wb.settings_["commentStyle"] = "None"; { @@ -2360,7 +2365,7 @@ JSONTEST_FIXTURE(StreamWriterTest, multiLineArray) { } } -JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, dropNullPlaceholders) { Json::StreamWriterBuilder b; Json::Value nullValue; b.settings_["dropNullPlaceholders"] = false; @@ -2369,7 +2374,7 @@ JSONTEST_FIXTURE(StreamWriterTest, dropNullPlaceholders) { JSONTEST_ASSERT(Json::writeString(b, nullValue).empty()); } -JSONTEST_FIXTURE(StreamWriterTest, enableYAMLCompatibility) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, enableYAMLCompatibility) { Json::StreamWriterBuilder b; Json::Value root; root["hello"] = "world"; @@ -2384,7 +2389,7 @@ JSONTEST_FIXTURE(StreamWriterTest, enableYAMLCompatibility) { JSONTEST_ASSERT(Json::writeString(b, root) == "{\"hello\":\"world\"}"); } -JSONTEST_FIXTURE(StreamWriterTest, indentation) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, indentation) { Json::StreamWriterBuilder b; Json::Value root; root["hello"] = "world"; @@ -2397,7 +2402,7 @@ JSONTEST_FIXTURE(StreamWriterTest, indentation) { "{\n\t\"hello\" : \"world\"\n}"); } -JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeZeroes) { Json::String binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); Json::String expected("\"hi\\u0000\""); // unicoded zero @@ -2421,7 +2426,7 @@ JSONTEST_FIXTURE(StreamWriterTest, writeZeroes) { struct ReaderTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) { +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"property\" : \"value\" }", root); @@ -2430,7 +2435,7 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrors) { JSONTEST_ASSERT(reader.getStructuredErrors().empty()); } -JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) { +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"property\" : [\"value\", \"value2\"], \"obj\" : " @@ -2460,7 +2465,7 @@ JSONTEST_FIXTURE(ReaderTest, parseWithNoErrorsTestingOffsets) { JSONTEST_ASSERT(root.getOffsetLimit() == 110); } -JSONTEST_FIXTURE(ReaderTest, parseWithOneError) { +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"property\" :: \"value\" }", root); @@ -2477,7 +2482,7 @@ JSONTEST_FIXTURE(ReaderTest, parseWithOneError) { "Syntax error: value, object or array expected."); } -JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) { +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"pr佐藤erty\" :: \"value\" }", root); @@ -2494,7 +2499,7 @@ JSONTEST_FIXTURE(ReaderTest, parseChineseWithOneError) { "Syntax error: value, object or array expected."); } -JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) { +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"property\" : \"v\\alue\" }", root); @@ -2512,7 +2517,7 @@ JSONTEST_FIXTURE(ReaderTest, parseWithDetailError) { struct CharReaderTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); Json::String errs; @@ -2524,7 +2529,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrors) { delete reader; } -JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); Json::String errs; @@ -2538,7 +2543,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithNoErrorsTestingOffsets) { delete reader; } -JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); Json::String errs; @@ -2552,7 +2557,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithOneError) { delete reader; } -JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); Json::String errs; @@ -2566,7 +2571,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseChineseWithOneError) { delete reader; } -JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { Json::CharReaderBuilder b; Json::CharReader* reader(b.newCharReader()); Json::String errs; @@ -2580,7 +2585,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithDetailError) { delete reader; } -JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = "{ \"property\" : \"value\" }"; @@ -2606,7 +2611,7 @@ JSONTEST_FIXTURE(CharReaderTest, parseWithStackLimit) { struct CharReaderStrictModeTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { +JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = @@ -2626,7 +2631,7 @@ JSONTEST_FIXTURE(CharReaderStrictModeTest, dupKeys) { } struct CharReaderFailIfExtraTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { // This is interpreted as a string value followed by a colon. Json::CharReaderBuilder b; Json::Value root; @@ -2680,7 +2685,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue164) { delete reader; } } -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { // This is interpreted as an int value followed by a colon. Json::CharReaderBuilder b; Json::Value root; @@ -2696,7 +2701,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, issue107) { JSONTEST_ASSERT_EQUAL(1, root.asInt()); delete reader; } -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { Json::CharReaderBuilder b; Json::Value root; { @@ -2711,7 +2716,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterObject) { delete reader; } } -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n"; @@ -2724,7 +2729,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterArray) { JSONTEST_ASSERT_EQUAL("value", root[1u]); delete reader; } -JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterBool) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = " true /*trailing\ncomment*/"; @@ -2739,7 +2744,7 @@ JSONTEST_FIXTURE(CharReaderFailIfExtraTest, commentAfterBool) { } struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { +JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { Json::CharReaderBuilder b; b.settings_["allowDroppedNullPlaceholders"] = true; Json::Value root; @@ -2861,7 +2866,7 @@ JSONTEST_FIXTURE(CharReaderAllowDropNullTest, issue178) { struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { +JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; @@ -2890,7 +2895,7 @@ JSONTEST_FIXTURE(CharReaderAllowSingleQuotesTest, issue182) { struct CharReaderAllowZeroesTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { +JSONTEST_FIXTURE_LOCAL(CharReaderAllowZeroesTest, issue176) { Json::CharReaderBuilder b; b.settings_["allowSingleQuotes"] = true; Json::Value root; @@ -2919,7 +2924,7 @@ JSONTEST_FIXTURE(CharReaderAllowZeroesTest, issue176) { struct CharReaderAllowSpecialFloatsTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { +JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { Json::CharReaderBuilder b; b.settings_["allowSpecialFloats"] = true; Json::Value root; @@ -2993,7 +2998,7 @@ JSONTEST_FIXTURE(CharReaderAllowSpecialFloatsTest, issue209) { struct BuilderTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(BuilderTest, settings) { +JSONTEST_FIXTURE_LOCAL(BuilderTest, settings) { { Json::Value errs; Json::CharReaderBuilder rb; @@ -3016,7 +3021,7 @@ JSONTEST_FIXTURE(BuilderTest, settings) { struct IteratorTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(IteratorTest, distance) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { Json::Value json; json["k1"] = "a"; json["k2"] = "b"; @@ -3030,7 +3035,7 @@ JSONTEST_FIXTURE(IteratorTest, distance) { JSONTEST_ASSERT_STRING_EQUAL("b", str); } -JSONTEST_FIXTURE(IteratorTest, names) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, names) { Json::Value json; json["k1"] = "a"; json["k2"] = "b"; @@ -3048,7 +3053,7 @@ JSONTEST_FIXTURE(IteratorTest, names) { JSONTEST_ASSERT(it == json.end()); } -JSONTEST_FIXTURE(IteratorTest, indexes) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, indexes) { Json::Value json; json[0] = "a"; json[1] = "b"; @@ -3066,7 +3071,7 @@ JSONTEST_FIXTURE(IteratorTest, indexes) { JSONTEST_ASSERT(it == json.end()); } -JSONTEST_FIXTURE(IteratorTest, const) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, const) { Json::Value const v; JSONTEST_ASSERT_THROWS( Json::Value::iterator it(v.begin())); // Compile, but throw. @@ -3092,7 +3097,7 @@ JSONTEST_FIXTURE(IteratorTest, const) { struct RValueTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE(RValueTest, moveConstruction) { +JSONTEST_FIXTURE_LOCAL(RValueTest, moveConstruction) { Json::Value json; json["key"] = "value"; Json::Value moved = std::move(json); @@ -3106,7 +3111,7 @@ struct FuzzTest : JsonTest::TestCase {}; // Build and run the fuzz test without any fuzzer, so that it's guaranteed not // go out of date, even if it's never run as an actual fuzz test. -JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { +JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) { const std::string example = "{}"; JSONTEST_ASSERT_EQUAL( 0, @@ -3116,107 +3121,10 @@ JSONTEST_FIXTURE(FuzzTest, fuzzDoesntCrash) { int main(int argc, const char* argv[]) { JsonTest::Runner runner; - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, checkNormalizeFloatingPointStr); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, memberCount); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, objects); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrays); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, arrayIssue252); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, null); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, strings); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, bools); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, integers); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nonIntegers); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareNull); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareInt); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareUInt); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareDouble); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareString); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareBoolean); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareArray); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareObject); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, compareType); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CopyObject); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, offsetAccessors); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, typeChecksThrowExceptions); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, StaticString); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, WideString); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, CommentBefore); - // JSONTEST_REGISTER_FIXTURE(runner, ValueTest, nulls); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroes); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, zeroesInKeys); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, specialFloats); - JSONTEST_REGISTER_FIXTURE(runner, ValueTest, precision); - - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, dropNullPlaceholders); - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, enableYAMLCompatibility); - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, omitEndingLineFeed); - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeNumericValue); - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeArrays); - JSONTEST_REGISTER_FIXTURE(runner, FastWriterTest, writeNestedObjects); - JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeNumericValue); - JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeArrays); - JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeNestedObjects); - JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, multiLineArray); - JSONTEST_REGISTER_FIXTURE(runner, StyledWriterTest, writeValueWithComment); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeNumericValue); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeArrays); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, writeNestedObjects); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, multiLineArray); - JSONTEST_REGISTER_FIXTURE(runner, StyledStreamWriterTest, - writeValueWithComment); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNumericValue); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeArrays); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeNestedObjects); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, multiLineArray); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, dropNullPlaceholders); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, enableYAMLCompatibility); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, indentation); - JSONTEST_REGISTER_FIXTURE(runner, StreamWriterTest, writeZeroes); - - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, - parseWithNoErrorsTestingOffsets); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseChineseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, ReaderTest, parseWithDetailError); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithNoErrors); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, - parseWithNoErrorsTestingOffsets); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseChineseWithOneError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithDetailError); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderTest, parseWithStackLimit); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderStrictModeTest, dupKeys); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue164); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, issue107); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, - commentAfterObject); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, - commentAfterArray); - JSONTEST_REGISTER_FIXTURE(runner, CharReaderFailIfExtraTest, - commentAfterBool); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowDropNullTest, issue178); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowSingleQuotesTest, issue182); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowZeroesTest, issue176); - - JSONTEST_REGISTER_FIXTURE(runner, CharReaderAllowSpecialFloatsTest, issue209); - - JSONTEST_REGISTER_FIXTURE(runner, BuilderTest, settings); - - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, distance); - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, names); - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, indexes); - JSONTEST_REGISTER_FIXTURE(runner, IteratorTest, const); - - JSONTEST_REGISTER_FIXTURE(runner, RValueTest, moveConstruction); - - JSONTEST_REGISTER_FIXTURE(runner, FuzzTest, fuzzDoesntCrash); + + for (auto it = local_.begin(); it != local_.end(); it++) { + runner.add(*it); + } return runner.runCommandLine(argc, argv); } From bdacfd7bc0fd890d2712a7773f3c32f26f3f2cd7 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Wed, 16 Oct 2019 14:33:53 +0800 Subject: [PATCH 224/410] add a new method to insert a new value in an array at specific index. (#949) * add a new method to insert a new value in an array at specific index. * update: index > length, return false; * fix clang-format --- include/json/value.h | 2 ++ src/lib_json/json_value.cpp | 16 +++++++++++ src/test_lib_json/main.cpp | 57 +++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index e3c3d2b7e..5c10163e4 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -464,6 +464,8 @@ class JSON_API Value { /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); Value& append(Value&& value); + /// \brief Insert value in array at specific index + bool insert(ArrayIndex index, Value newValue); /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 9518ab828..00d28f774 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1148,6 +1148,7 @@ Value const& Value::operator[](CppTL::ConstString const& key) const { #endif Value& Value::append(const Value& value) { return append(Value(value)); } + Value& Value::append(Value&& value) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, "in Json::Value::append: requires arrayValue"); @@ -1157,6 +1158,21 @@ Value& Value::append(Value&& value) { return this->value_.map_->emplace(size(), std::move(value)).first->second; } +bool Value::insert(ArrayIndex index, Value newValue) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, + "in Json::Value::insert: requires arrayValue"); + ArrayIndex length = size(); + if (index > length) { + return false; + } else { + for (ArrayIndex i = length; i > index; i--) { + (*this)[i] = std::move((*this)[i - 1]); + } + (*this)[index] = std::move(newValue); + return true; + } +} + Value Value::get(char const* begin, char const* end, Value const& defaultValue) const { Value const* found = find(begin, end); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c79ad1ea4..f32a11fbf 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -327,6 +327,63 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayIssue252) { // JSONTEST_ASSERT_EQUAL(5, root["array"].size()); } +JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { + Json::Value array; + const Json::Value str0("index2"); + const Json::Value str1("index3"); + array.append("index0"); // append rvalue + array.append("index1"); + array.append(str0); // append lvalue + + std::vector vec; // storage value address for checking + for (int i = 0; i < 3; i++) { + vec.push_back(&array[i]); + } + JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]); // check append + JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]); + + // insert lvalue at the head + JSONTEST_ASSERT(array.insert(0, str1)); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); + JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); + JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[2]); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[3]); + // checking address + for (int i = 0; i < 3; i++) { + JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); + } + vec.push_back(&array[3]); + // insert rvalue at middle + JSONTEST_ASSERT(array.insert(2, "index4")); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); + JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); + JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); + JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); + // checking address + for (int i = 0; i < 4; i++) { + JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); + } + vec.push_back(&array[4]); + // insert rvalue at the tail + Json::Value index5("index5"); + JSONTEST_ASSERT(array.insert(5, std::move(index5))); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); + JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); + JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); + JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); + JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[5]); + // checking address + for (int i = 0; i < 5; i++) { + JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); + } + vec.push_back(&array[5]); + // beyond max array size, it should not be allowed to insert into its tail + JSONTEST_ASSERT(!array.insert(10, "index10")); +} + JSONTEST_FIXTURE_LOCAL(ValueTest, null) { JSONTEST_ASSERT_EQUAL(Json::nullValue, null_.type()); From aebc7faa4fa69fa16ffe9082d03a3527120d5fa3 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Wed, 16 Oct 2019 09:38:05 -0500 Subject: [PATCH 225/410] BUG: New CMake features used that break backward compatibility We desire for jsoncpp to compile and be readily available with older versions of cmake. The use of newer cmake commands requires conditional statements so that older strategies can be used with older versions of cmake. Resolves: #1018 --- CMakeLists.txt | 52 +++++++++++++++++++++++++++---- src/jsontestrunner/CMakeLists.txt | 4 +++ src/lib_json/CMakeLists.txt | 13 ++++++-- src/test_lib_json/CMakeLists.txt | 4 +++ 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f2bab55f..8a7d3ef4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,11 +104,23 @@ macro(UseCompilationWarningAsError) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # warnings when compiled in release configuration. - add_compile_options($<$:/WX>) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options($<$:/WX>) + else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - add_compile_options(-Werror) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Werror) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + endif() if(JSONCPP_WITH_STRICT_ISO) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_options(-pedantic-errors) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") + endif() endif() endif() endmacro() @@ -119,29 +131,57 @@ include_directories( ${jsoncpp_SOURCE_DIR}/include ) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. - add_compile_options($<$:/W4>) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options($<$:/W4>) + else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") + endif() endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC - add_compile_options(-Wall -Wconversion -Wshadow -Wextra) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Wall -Wconversion -Wshadow -Wextra) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") + endif() # not yet ready for -Wsign-conversion if(JSONCPP_WITH_STRICT_ISO) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_options(-pedantic) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + endif() endif() if(JSONCPP_WITH_WARNING_AS_ERROR) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_options(-Werror=conversion) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") + endif() endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler - add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") + endif() if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_options(-pedantic) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + endif() endif() endif() diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 023a44e64..39c6f4871 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -5,7 +5,11 @@ add_executable(jsontestrunner_exe ) if(BUILD_SHARED_LIBS) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_definitions( JSON_DLL ) + else() + add_definitions( -DJSON_DLL ) + endif() endif() target_link_libraries(jsontestrunner_exe jsoncpp_lib) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index a9bf786cd..b56788e27 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -34,7 +34,11 @@ endif() if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) message(WARNING "Locale functionality is not supported") - add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT) + else() + add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) + endif() endif() set( JSONCPP_INCLUDE_DIR ../../include ) @@ -66,8 +70,13 @@ else(JSONCPP_WITH_CMAKE_PACKAGE) set(INSTALL_EXPORT) endif() + if(BUILD_SHARED_LIBS) - add_compile_definitions( JSON_DLL_BUILD ) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_definitions( JSON_DLL_BUILD ) + else() + add_definitions( -DJSON_DLL_BUILD ) + endif() endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index abb181361..6e301ec69 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -10,7 +10,11 @@ add_executable( jsoncpp_test if(BUILD_SHARED_LIBS) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) add_compile_definitions( JSON_DLL ) + else() + add_definitions( -DJSON_DLL ) + endif() endif() target_link_libraries(jsoncpp_test jsoncpp_lib) From a07b37e4ecbf74a382702575f501a53180d78192 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 17 Oct 2019 10:43:25 -0700 Subject: [PATCH 226/410] Improve performance for comment parsing (#1052) * Improve performance for comment parsing * Fix weird main.cpp issue * Readd newline * remove carriage return feed char * Remove unnecessary checks --- src/lib_json/json_reader.cpp | 67 +++++++++++++++++++++++------------- src/test_lib_json/fuzz.cpp | 6 +++- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 958a39869..4d4f89b6e 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -12,6 +12,7 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include #include +#include #include #include #include @@ -942,7 +943,7 @@ class OurReader { void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); - bool readCStyleComment(); + bool readCStyleComment(bool* containsNewLineResult); bool readCppStyleComment(); bool readString(); bool readStringSingleQuote(); @@ -977,18 +978,20 @@ class OurReader { static bool containsNewLine(Location begin, Location end); using Nodes = std::stack; - Nodes nodes_; - Errors errors_; - String document_; - Location begin_; - Location end_; - Location current_; - Location lastValueEnd_; - Value* lastValue_; - String commentsBefore_; + + Nodes nodes_{}; + Errors errors_{}; + String document_{}; + Location begin_ = nullptr; + Location end_ = nullptr; + Location current_ = nullptr; + Location lastValueEnd_ = nullptr; + Value* lastValue_ = nullptr; + bool lastValueHasAComment_ = false; + String commentsBefore_{}; OurFeatures const features_; - bool collectComments_; + bool collectComments_ = false; }; // OurReader // complete copy of Read impl, for OurReader @@ -1001,9 +1004,7 @@ bool OurReader::containsNewLine(OurReader::Location begin, return false; } -OurReader::OurReader(OurFeatures const& features) - : begin_(), end_(), current_(), lastValueEnd_(), lastValue_(), - features_(features), collectComments_() {} +OurReader::OurReader(OurFeatures const& features) : features_(features) {} bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments) { @@ -1134,6 +1135,7 @@ bool OurReader::readValue() { if (collectComments_) { lastValueEnd_ = current_; + lastValueHasAComment_ = false; lastValue_ = ¤tValue(); } @@ -1280,21 +1282,32 @@ bool OurReader::match(const Char* pattern, int patternLength) { } bool OurReader::readComment() { - Location commentBegin = current_ - 1; - Char c = getNextChar(); + const Location commentBegin = current_ - 1; + const Char c = getNextChar(); bool successful = false; - if (c == '*') - successful = readCStyleComment(); - else if (c == '/') + bool cStyleWithEmbeddedNewline = false; + + const bool isCStyleComment = (c == '*'); + const bool isCppStyleComment = (c == '/'); + if (isCStyleComment) { + successful = readCStyleComment(&cStyleWithEmbeddedNewline); + } else if (isCppStyleComment) { successful = readCppStyleComment(); + } + if (!successful) return false; if (collectComments_) { CommentPlacement placement = commentBefore; - if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, current_)) - placement = commentAfterOnSameLine; + + if (!lastValueHasAComment_) { + if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { + if (isCppStyleComment || !cStyleWithEmbeddedNewline) { + placement = commentAfterOnSameLine; + lastValueHasAComment_ = true; + } + } } addComment(commentBegin, current_, placement); @@ -1334,12 +1347,18 @@ void OurReader::addComment(Location begin, Location end, } } -bool OurReader::readCStyleComment() { +bool OurReader::readCStyleComment(bool* containsNewLineResult) { + *containsNewLineResult = false; + while ((current_ + 1) < end_) { Char c = getNextChar(); - if (c == '*' && *current_ == '/') + if (c == '*' && *current_ == '/') { break; + } else if (c == '\n') { + *containsNewLineResult = true; + } } + return getNextChar() == '/'; } diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index d6e3815ad..b31c597c8 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -23,7 +23,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } - uint32_t hash_settings = *(const uint32_t*)data; + const uint32_t hash_settings = static_cast(data[0]) | + (static_cast(data[1]) << 8) | + (static_cast(data[2]) << 16) | + (static_cast(data[3]) << 24); data += sizeof(uint32_t); size -= sizeof(uint32_t); @@ -36,6 +39,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { builder.settings_["failIfExtra_"] = hash_settings & (1 << 6); builder.settings_["rejectDupKeys_"] = hash_settings & (1 << 7); builder.settings_["allowSpecialFloats_"] = hash_settings & (1 << 8); + builder.settings_["collectComments"] = hash_settings & (1 << 9); std::unique_ptr reader(builder.newCharReader()); From f59ac2a1d78decc596beee983915a975e35cfb28 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Fri, 18 Oct 2019 01:46:41 +0800 Subject: [PATCH 227/410] add coveralls to test coverage (#1060) --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index a63929e72..0554dc93b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,10 @@ matrix: BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp + before_install: + - pip install --user cpp-coveralls script: ./.travis_scripts/cmake_builder.sh + after_success: + - coveralls --include src/lib_json --include include notifications: email: false From a955529e474e819319023a9d456a1c9bdc745f31 Mon Sep 17 00:00:00 2001 From: nicolaswilson <56082512+nicolaswilson@users.noreply.github.com> Date: Thu, 17 Oct 2019 18:47:51 +0100 Subject: [PATCH 228/410] Added emitUTF8 setting. (#1045) * Added emitUTF8 setting to emit UTF8 format JSON. * Added a test for emitUTF8, with it in default, on and off states. * Review comments addressed. * Merged master into my branch & resolved conflicts. * Fix clang-format errors. * Fix clang-format errors. * Fixed clang-format errors. * Fixed clang-format errors. --- src/lib_json/json_writer.cpp | 75 ++++++++++++++++++++++-------------- src/test_lib_json/main.cpp | 29 ++++++++++++++ 2 files changed, 75 insertions(+), 29 deletions(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index e16d84f5f..519ce23ad 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -264,7 +264,8 @@ static String toHex16Bit(unsigned int x) { return result; } -static String valueToQuotedStringN(const char* value, unsigned length) { +static String valueToQuotedStringN(const char* value, unsigned length, + bool emitUTF8 = false) { if (value == nullptr) return ""; @@ -310,21 +311,31 @@ static String valueToQuotedStringN(const char* value, unsigned length) { // Should add a flag to allow this compatibility mode and prevent this // sequence from occurring. default: { - unsigned int cp = utf8ToCodepoint(c, end); - // don't escape non-control characters - // (short escape sequence are applied above) - if (cp < 0x80 && cp >= 0x20) - result += static_cast(cp); - else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane - result += "\\u"; - result += toHex16Bit(cp); - } else { // codepoint is not in Basic Multilingual Plane - // convert to surrogate pair first - cp -= 0x10000; - result += "\\u"; - result += toHex16Bit((cp >> 10) + 0xD800); - result += "\\u"; - result += toHex16Bit((cp & 0x3FF) + 0xDC00); + if (emitUTF8) { + result += *c; + } else { + unsigned int codepoint = utf8ToCodepoint(c, end); + const unsigned int FIRST_NON_CONTROL_CODEPOINT = 0x20; + const unsigned int LAST_NON_CONTROL_CODEPOINT = 0x7F; + const unsigned int FIRST_SURROGATE_PAIR_CODEPOINT = 0x10000; + // don't escape non-control characters + // (short escape sequence are applied above) + if (FIRST_NON_CONTROL_CODEPOINT <= codepoint && + codepoint <= LAST_NON_CONTROL_CODEPOINT) { + result += static_cast(codepoint); + } else if (codepoint < + FIRST_SURROGATE_PAIR_CODEPOINT) { // codepoint is in Basic + // Multilingual Plane + result += "\\u"; + result += toHex16Bit(codepoint); + } else { // codepoint is not in Basic Multilingual Plane + // convert to surrogate pair first + codepoint -= FIRST_SURROGATE_PAIR_CODEPOINT; + result += "\\u"; + result += toHex16Bit((codepoint >> 10) + 0xD800); + result += "\\u"; + result += toHex16Bit((codepoint & 0x3FF) + 0xDC00); + } } } break; } @@ -864,7 +875,8 @@ struct BuiltStyledStreamWriter : public StreamWriter { BuiltStyledStreamWriter(String indentation, CommentStyle::Enum cs, String colonSymbol, String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, - unsigned int precision, PrecisionType precisionType); + bool emitUTF8, unsigned int precision, + PrecisionType precisionType); int write(Value const& root, OStream* sout) override; private: @@ -893,19 +905,20 @@ struct BuiltStyledStreamWriter : public StreamWriter { bool addChildValues_ : 1; bool indented_ : 1; bool useSpecialFloats_ : 1; + bool emitUTF8_ : 1; unsigned int precision_; PrecisionType precisionType_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( String indentation, CommentStyle::Enum cs, String colonSymbol, String nullSymbol, String endingLineFeedSymbol, bool useSpecialFloats, - unsigned int precision, PrecisionType precisionType) + bool emitUTF8, unsigned int precision, PrecisionType precisionType) : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs), colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)), endingLineFeedSymbol_(std::move(endingLineFeedSymbol)), addChildValues_(false), indented_(false), - useSpecialFloats_(useSpecialFloats), precision_(precision), - precisionType_(precisionType) {} + useSpecialFloats_(useSpecialFloats), emitUTF8_(emitUTF8), + precision_(precision), precisionType_(precisionType) {} int BuiltStyledStreamWriter::write(Value const& root, OStream* sout) { sout_ = sout; addChildValues_ = false; @@ -942,7 +955,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast(end - str))); + pushValue(valueToQuotedStringN(str, static_cast(end - str), + emitUTF8_)); else pushValue(""); break; @@ -966,7 +980,7 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { Value const& childValue = value[name]; writeCommentBeforeValue(childValue); writeWithIndent(valueToQuotedStringN( - name.data(), static_cast(name.length()))); + name.data(), static_cast(name.length()), emitUTF8_)); *sout_ << colonSymbol_; writeValue(childValue); if (++it == members.end()) { @@ -1142,12 +1156,13 @@ StreamWriter::Factory::~Factory() = default; StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); } StreamWriterBuilder::~StreamWriterBuilder() = default; StreamWriter* StreamWriterBuilder::newStreamWriter() const { - String indentation = settings_["indentation"].asString(); - String cs_str = settings_["commentStyle"].asString(); - String pt_str = settings_["precisionType"].asString(); - bool eyc = settings_["enableYAMLCompatibility"].asBool(); - bool dnp = settings_["dropNullPlaceholders"].asBool(); - bool usf = settings_["useSpecialFloats"].asBool(); + const String indentation = settings_["indentation"].asString(); + const String cs_str = settings_["commentStyle"].asString(); + const String pt_str = settings_["precisionType"].asString(); + const bool eyc = settings_["enableYAMLCompatibility"].asBool(); + const bool dnp = settings_["dropNullPlaceholders"].asBool(); + const bool usf = settings_["useSpecialFloats"].asBool(); + const bool emitUTF8 = settings_["emitUTF8"].asBool(); unsigned int pre = settings_["precision"].asUInt(); CommentStyle::Enum cs = CommentStyle::All; if (cs_str == "All") { @@ -1179,7 +1194,7 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { pre = 17; String endingLineFeedSymbol; return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, - endingLineFeedSymbol, usf, pre, + endingLineFeedSymbol, usf, emitUTF8, pre, precisionType); } static void getValidWriterKeys(std::set* valid_keys) { @@ -1189,6 +1204,7 @@ static void getValidWriterKeys(std::set* valid_keys) { valid_keys->insert("enableYAMLCompatibility"); valid_keys->insert("dropNullPlaceholders"); valid_keys->insert("useSpecialFloats"); + valid_keys->insert("emitUTF8"); valid_keys->insert("precision"); valid_keys->insert("precisionType"); } @@ -1220,6 +1236,7 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) { (*settings)["enableYAMLCompatibility"] = false; (*settings)["dropNullPlaceholders"] = false; (*settings)["useSpecialFloats"] = false; + (*settings)["emitUTF8"] = false; (*settings)["precision"] = 17; (*settings)["precisionType"] = "significant"; //! [StreamWriterBuilderDefaults] diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index f32a11fbf..326519fe8 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2481,6 +2481,35 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeZeroes) { } } +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) { + // Create a Json value containing UTF-8 string with some chars that need + // escape (tab,newline). + Json::Value root; + root["test"] = "\t\n\xF0\x91\xA2\xA1\x3D\xC4\xB3\xF0\x9B\x84\x9B\xEF\xBD\xA7"; + + Json::StreamWriterBuilder b; + + // Default settings - should be unicode escaped. + JSONTEST_ASSERT(Json::writeString(b, root) == + "{\n\t\"test\" : " + "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); + + b.settings_["emitUTF8"] = true; + + // Should not be unicode escaped. + JSONTEST_ASSERT( + Json::writeString(b, root) == + "{\n\t\"test\" : " + "\"\\t\\n\xF0\x91\xA2\xA1=\xC4\xB3\xF0\x9B\x84\x9B\xEF\xBD\xA7\"\n}"); + + b.settings_["emitUTF8"] = false; + + // Should be unicode escaped. + JSONTEST_ASSERT(Json::writeString(b, root) == + "{\n\t\"test\" : " + "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); +} + struct ReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { From b082693b9ebbb6e0402c7c95f4d8b9cd262595c8 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 17 Oct 2019 12:52:13 -0500 Subject: [PATCH 229/410] COMP: Improve const correctness for ValueIterators (#1056) The protected deref method had inconsistent interface of being a const function that returned a non-const reference. Resolves #914. --- include/json/value.h | 19 +++++++++++++++---- src/lib_json/json_valueiterator.inl | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 5c10163e4..d0af7116b 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -772,7 +772,14 @@ class JSON_API ValueIteratorBase { char const* memberName(char const** end) const; protected: - Value& deref() const; + /*! Internal utility functions to assist with implementing + * other iterator functions. The const and non-const versions + * of the "deref" protected methods expose the protected + * current_ member variable in a way that can often be + * optimized away by the compiler. + */ + const Value& deref() const; + Value& deref(); void increment(); @@ -895,9 +902,13 @@ class JSON_API ValueIterator : public ValueIteratorBase { return *this; } - reference operator*() const { return deref(); } - - pointer operator->() const { return &deref(); } + /*! The return value of non-const iterators can be + * changed, so the these functions are not const + * because the returned references/pointers can be used + * to change state of the base class. + */ + reference operator*() { return deref(); } + pointer operator->() { return &deref(); } }; inline void swap(Value& a, Value& b) { a.swap(b); } diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 4a3d210de..9bd9315e0 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -21,7 +21,8 @@ ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator& current) : current_(current), isNull_(false) {} -Value& ValueIteratorBase::deref() const { return current_->second; } +Value& ValueIteratorBase::deref() { return current_->second; } +const Value& ValueIteratorBase::deref() const { return current_->second; } void ValueIteratorBase::increment() { ++current_; } From 41ffff01d39085222280791a23451d3e852b06c2 Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Fri, 18 Oct 2019 20:06:56 +0200 Subject: [PATCH 230/410] Fix link to Amalgamated wiki article (#1064) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4f5eb30ef..8445aa583 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ You can download and install JsonCpp using the [vcpkg](https://github.com/Micros The JsonCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. ### Amalgamated source -https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated +https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated-(Possibly-outdated) ### The Meson Build System If you are using the [Meson Build System](http://mesonbuild.com), then you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/jsoncpp), or simply use `meson wrap install jsoncpp`. From 54bd178bd8e1f4e4145bbd7b70e5c7e27d240fb9 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Thu, 24 Oct 2019 06:30:34 +0800 Subject: [PATCH 231/410] update testcases to improve coverage (#1061) --- src/test_lib_json/main.cpp | 141 +++++++++++++++++++++++++++++++++---- 1 file changed, 129 insertions(+), 12 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 326519fe8..950e92e0b 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2521,12 +2521,35 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { JSONTEST_ASSERT(reader.getStructuredErrors().empty()); } +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseComment) { + Json::Reader reader; + Json::Value root; + bool ok = reader.parse("{ /*commentBeforeValue*/" + " \"property\" : \"value\" }" + "//commentAfterValue\n", + root); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); + JSONTEST_ASSERT(reader.getStructuredErrors().empty()); +} + +JSONTEST_FIXTURE_LOCAL(ReaderTest, streamParseWithNoErrors) { + Json::Reader reader; + std::string styled = "{ \"property\" : \"value\" }"; + std::istringstream iss(styled); + Json::Value root; + bool ok = reader.parse(iss, root); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); + JSONTEST_ASSERT(reader.getStructuredErrors().empty()); +} + JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { Json::Reader reader; Json::Value root; bool ok = reader.parse("{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " - "null, \"false\" : false }", + "{ \"nested\" : -6.2e+15, \"bool\" : true}, \"null\" :" + " null, \"false\" : false }", root); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); @@ -2538,17 +2561,17 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25); JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33); JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44); - JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 76); + JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 81); JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57); - JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 60); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 71); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 75); - JSONTEST_ASSERT(root["null"].getOffsetStart() == 87); - JSONTEST_ASSERT(root["null"].getOffsetLimit() == 91); - JSONTEST_ASSERT(root["false"].getOffsetStart() == 103); - JSONTEST_ASSERT(root["false"].getOffsetLimit() == 108); + JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 65); + JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 76); + JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 80); + JSONTEST_ASSERT(root["null"].getOffsetStart() == 92); + JSONTEST_ASSERT(root["null"].getOffsetLimit() == 96); + JSONTEST_ASSERT(root["false"].getOffsetStart() == 108); + JSONTEST_ASSERT(root["false"].getOffsetLimit() == 113); JSONTEST_ASSERT(root.getOffsetStart() == 0); - JSONTEST_ASSERT(root.getOffsetLimit() == 110); + JSONTEST_ASSERT(root.getOffsetLimit() == 115); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { @@ -2568,6 +2591,26 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { "Syntax error: value, object or array expected."); } +JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) { + Json::Features feature; + Json::Reader reader(feature.strictMode()); + Json::Value root; + bool ok = reader.parse("123", root); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages() == + "* Line 1, Column 1\n" + " A valid JSON document must be either an array or" + " an object value.\n"); + std::vector errors = + reader.getStructuredErrors(); + JSONTEST_ASSERT(errors.size() == 1); + JSONTEST_ASSERT(errors.at(0).offset_start == 0); + JSONTEST_ASSERT(errors.at(0).offset_limit == 3); + JSONTEST_ASSERT(errors.at(0).message == + "A valid JSON document must be either an array or" + " an object value."); +} + JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { Json::Reader reader; Json::Value root; @@ -2621,7 +2664,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : 123, \"bool\" : true}, \"null\" : " + "{ \"nested\" : -6.2e+15, \"bool\" : true}, \"null\" : " "null, \"false\" : false }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); @@ -2695,6 +2738,14 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { } } +JSONTEST_FIXTURE_LOCAL(CharReaderTest, testOperator) { + const std::string styled = "{ \"property\" : \"value\" }"; + std::istringstream iss(styled); + Json::Value root; + iss >> root; + JSONTEST_ASSERT_EQUAL("value", root["property"]); +} + struct CharReaderStrictModeTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { @@ -2950,6 +3001,25 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { delete reader; } +struct CharReaderAllowNumericKeysTest : JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { + Json::CharReaderBuilder b; + b.settings_["allowNumericKeys"] = true; + Json::Value root; + Json::String errs; + Json::CharReader* reader(b.newCharReader()); + char const doc[] = "{15:true,-16:true,12.01:true}"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT_STRING_EQUAL("", errs); + JSONTEST_ASSERT_EQUAL(3u, root.size()); + JSONTEST_ASSERT_EQUAL(true, root.get("15", false)); + JSONTEST_ASSERT_EQUAL(true, root.get("-16", false)); + JSONTEST_ASSERT_EQUAL(true, root.get("12.01", false)); + delete reader; +} + struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { @@ -3082,6 +3152,53 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { delete reader; } +struct EscapeSequenceTest : JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, readerParseEscapeSequence) { + Json::Reader reader; + Json::Value root; + bool ok = reader.parse("[\"\\\"\",\"\\/\",\"\\\\\",\"\\b\"," + "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," + "\"\\u0278\",\"\\ud852\\udf62\"]\n", + root); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); + JSONTEST_ASSERT(reader.getStructuredErrors().empty()); +} + +JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, charReaderParseEscapeSequence) { + Json::CharReaderBuilder b; + Json::CharReader* reader(b.newCharReader()); + Json::Value root; + Json::String errs; + char const doc[] = "[\"\\\"\",\"\\/\",\"\\\\\",\"\\b\"," + "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," + "\"\\u0278\",\"\\ud852\\udf62\"]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + delete reader; +} + +JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, writeEscapeSequence) { + Json::FastWriter writer; + const Json::String expected("[\"\\\"\",\"\\\\\",\"\\b\"," + "\"\\f\",\"\\n\",\"\\r\",\"\\t\"," + "\"\\u0278\",\"\\ud852\\udf62\"]\n"); + Json::Value root; + root[0] = "\""; + root[1] = "\\"; + root[2] = "\b"; + root[3] = "\f"; + root[4] = "\n"; + root[5] = "\r"; + root[6] = "\t"; + root[7] = "ɸ"; + root[8] = "𤭢"; + const Json::String result = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); +} + struct BuilderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(BuilderTest, settings) { From 6c9408d12848773d74fb2c5879dab04851ddd901 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Thu, 24 Oct 2019 06:31:25 +0800 Subject: [PATCH 232/410] remove pushError in CharReader (#1055) --- src/lib_json/json_reader.cpp | 39 ------------------------------------ src/test_lib_json/main.cpp | 29 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 4d4f89b6e..38aab7838 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -895,9 +895,6 @@ class OurReader { bool collectComments = true); String getFormattedErrorMessages() const; std::vector getStructuredErrors() const; - bool pushError(const Value& value, const String& message); - bool pushError(const Value& value, const String& message, const Value& extra); - bool good() const; private: OurReader(OurReader const&); // no impl @@ -1841,42 +1838,6 @@ std::vector OurReader::getStructuredErrors() const { return allErrors; } -bool OurReader::pushError(const Value& value, const String& message) { - ptrdiff_t length = end_ - begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = nullptr; - errors_.push_back(info); - return true; -} - -bool OurReader::pushError(const Value& value, const String& message, - const Value& extra) { - ptrdiff_t length = end_ - begin_; - if (value.getOffsetStart() > length || value.getOffsetLimit() > length || - extra.getOffsetLimit() > length) - return false; - Token token; - token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); - ErrorInfo info; - info.token_ = token; - info.message_ = message; - info.extra_ = begin_ + extra.getOffsetStart(); - errors_.push_back(info); - return true; -} - -bool OurReader::good() const { return errors_.empty(); } - class OurCharReader : public CharReader { bool const collectComments_; OurReader reader_; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 950e92e0b..1d636d8a0 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2644,6 +2644,35 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string"); } +JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { + Json::Reader reader; + Json::Value root; + { + bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root); + JSONTEST_ASSERT(ok); + if (!root["AUTHOR"].isString()) { + ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string"); + } + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages() == + "* Line 1, Column 14\n" + " AUTHOR must be a string\n"); + } + { + bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root); + JSONTEST_ASSERT(ok); + if (!root["AUTHOR"].isString()) { + ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string", + root["AUTHOR"]); + } + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(reader.getFormattedErrorMessages() == + "* Line 1, Column 14\n" + " AUTHOR must be a string\n" + "See Line 1, Column 14 for detail.\n"); + } +} + struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { From c634b98e7da401fcf5f3f5a7fdca7037cfe1a21d Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Fri, 25 Oct 2019 17:12:11 +0800 Subject: [PATCH 233/410] modify README.md: add some badges (#1070) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8445aa583..d7b210681 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # JsonCpp [![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](https://bintray.com/theirix/conan-repo/jsoncpp%3Atheirix) +[![badge](https://img.shields.io/badge/license-MIT-blue)](https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE) +[![badge](https://img.shields.io/badge/document-doxygen-brightgreen)](http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html) + [JSON][json-org] is a lightweight data-interchange format. It can represent numbers, strings, ordered sequences of values, and collections of name/value @@ -49,7 +52,7 @@ https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated-(Possibly-outdat If you are using the [Meson Build System](http://mesonbuild.com), then you can get a wrap file by downloading it from [Meson WrapDB](https://wrapdb.mesonbuild.com/jsoncpp), or simply use `meson wrap install jsoncpp`. ### Other ways -If you have trouble, see the Wiki, or post a question as an Issue. +If you have trouble, see the [Wiki](https://github.com/open-source-parsers/jsoncpp/wiki), or post a question as an Issue. ## License From 2703c306a3168e15613d94e57fb8832138d9155d Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Sat, 26 Oct 2019 17:03:05 +0800 Subject: [PATCH 234/410] add coverage badge in readme (#1072) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7b210681..005710940 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](https://bintray.com/theirix/conan-repo/jsoncpp%3Atheirix) [![badge](https://img.shields.io/badge/license-MIT-blue)](https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE) [![badge](https://img.shields.io/badge/document-doxygen-brightgreen)](http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html) +[![Coverage Status](https://coveralls.io/repos/github/open-source-parsers/jsoncpp/badge.svg)](https://coveralls.io/github/open-source-parsers/jsoncpp) [JSON][json-org] is a lightweight data-interchange format. It can represent From fb9aaf8112dc4aadcc3e4fc6579bc6b86e78b4ea Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Mon, 4 Nov 2019 00:27:02 -0800 Subject: [PATCH 235/410] Update meson/python ``` DEPRECATION: Project targetting '>= 0.41.1' but tried to use feature deprecated since '0.48.0': python3 module Build targets in project: 3 WARNING: Deprecated features used: * 0.48.0: {'python3 module'} ``` --- meson.build | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 65dcffa8c..b2560af29 100644 --- a/meson.build +++ b/meson.build @@ -71,7 +71,8 @@ jsoncpp_dep = declare_dependency( ) # tests -python = import('python3').find_python() +#python = import('python3').find_python() +python = find_program('python3', 'python') jsoncpp_test = executable( 'jsoncpp_test', From ec9302c4ed12e469401bcb54c90575b1bc9d8bb6 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Mon, 4 Nov 2019 01:13:59 -0800 Subject: [PATCH 236/410] Avoid deprecated Meson feature * https://mesonbuild.com/Python-3-module.html > This module is deprecated and replaced by the python module. --- .travis_scripts/meson_builder.sh | 2 +- meson.build | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis_scripts/meson_builder.sh b/.travis_scripts/meson_builder.sh index 0820c890c..1fdd8f65d 100755 --- a/.travis_scripts/meson_builder.sh +++ b/.travis_scripts/meson_builder.sh @@ -65,7 +65,7 @@ _COMPILER_NAME=`basename ${CXX}` _BUILD_DIR_NAME="build-${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}" ./.travis_scripts/run-clang-format.sh -meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" +meson --fatal-meson-warnings --werror --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" ninja -v -j 2 -C "${_BUILD_DIR_NAME}" cd "${_BUILD_DIR_NAME}" diff --git a/meson.build b/meson.build index b2560af29..aa50d8fbc 100644 --- a/meson.build +++ b/meson.build @@ -71,8 +71,7 @@ jsoncpp_dep = declare_dependency( ) # tests -#python = import('python3').find_python() -python = find_program('python3', 'python') +python = import('python').find_installation() jsoncpp_test = executable( 'jsoncpp_test', From 638ad269e75f28f9830f7bfc01278aeaf5b00135 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sun, 3 Nov 2019 15:27:39 -0500 Subject: [PATCH 237/410] Explicitly specify hexfloat in TestResult operator<< (#1078) --- src/test_lib_json/jsontest.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 49d1dcd8c..e076f7c2b 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -83,9 +84,7 @@ class TestResult { // Generic operator that will work with anything ostream can deal with. template TestResult& operator<<(const T& value) { Json::OStringStream oss; - oss.precision(16); - oss.setf(std::ios_base::floatfield); - oss << value; + oss << std::setprecision(16) << std::hexfloat << value; return addToLastFailure(oss.str()); } From 2eb20a938c454411c1d416caeeb2a6511daab5cb Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Mon, 4 Nov 2019 01:20:17 -0800 Subject: [PATCH 238/410] Remove deprecated makerelease.py re: #1081 --- makerelease.py | 390 ------------------------------------------------- 1 file changed, 390 deletions(-) delete mode 100644 makerelease.py diff --git a/makerelease.py b/makerelease.py deleted file mode 100644 index bc716cbab..000000000 --- a/makerelease.py +++ /dev/null @@ -1,390 +0,0 @@ -# Copyright 2010 Baptiste Lepilleur and The JsonCpp Authors -# Distributed under MIT license, or public domain if desired and -# recognized in your jurisdiction. -# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -"""Tag the sandbox for release, make source and doc tarballs. - -Requires Python 2.6 - -Example of invocation (use to test the script): -python makerelease.py --platform=msvc6,msvc71,msvc80,msvc90,mingw -ublep 0.6.0 0.7.0-dev - -When testing this script: -python makerelease.py --force --retag --platform=msvc6,msvc71,msvc80,mingw -ublep test-0.6.0 test-0.6.1-dev - -Example of invocation when doing a release: -python makerelease.py 0.5.0 0.6.0-dev - -Note: This was for Subversion. Now that we are in GitHub, we do not -need to build versioned tarballs anymore, so makerelease.py is defunct. -""" - -from __future__ import print_function -import os.path -import subprocess -import sys -import doxybuild -import subprocess -import xml.etree.ElementTree as ElementTree -import shutil -import urllib2 -import tempfile -import os -import time -from devtools import antglob, fixeol, tarball -import amalgamate - -SVN_ROOT = 'https://jsoncpp.svn.sourceforge.net/svnroot/jsoncpp/' -SVN_TAG_ROOT = SVN_ROOT + 'tags/jsoncpp' -SCONS_LOCAL_URL = 'http://sourceforge.net/projects/scons/files/scons-local/1.2.0/scons-local-1.2.0.tar.gz/download' -SOURCEFORGE_PROJECT = 'jsoncpp' - -def set_version(version): - with open('version','wb') as f: - f.write(version.strip()) - -def rmdir_if_exist(dir_path): - if os.path.isdir(dir_path): - shutil.rmtree(dir_path) - -class SVNError(Exception): - pass - -def svn_command(command, *args): - cmd = ['svn', '--non-interactive', command] + list(args) - print('Running:', ' '.join(cmd)) - process = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - stdout = process.communicate()[0] - if process.returncode: - error = SVNError('SVN command failed:\n' + stdout) - error.returncode = process.returncode - raise error - return stdout - -def check_no_pending_commit(): - """Checks that there is no pending commit in the sandbox.""" - stdout = svn_command('status', '--xml') - etree = ElementTree.fromstring(stdout) - msg = [] - for entry in etree.getiterator('entry'): - path = entry.get('path') - status = entry.find('wc-status').get('item') - if status != 'unversioned' and path != 'version': - msg.append('File "%s" has pending change (status="%s")' % (path, status)) - if msg: - msg.insert(0, 'Pending change to commit found in sandbox. Commit them first!') - return '\n'.join(msg) - -def svn_join_url(http://github.com/base_url,%20suffix): - if not base_url.endswith('/'): - base_url += '/' - if suffix.startswith('/'): - suffix = suffix[1:] - return base_url + suffix - -def svn_check_if_tag_exist(tag_url): - """Checks if a tag exist. - Returns: True if the tag exist, False otherwise. - """ - try: - list_stdout = svn_command('list', tag_url) - except SVNError as e: - if e.returncode != 1 or not str(e).find('tag_url'): - raise e - # otherwise ignore error, meaning tag does not exist - return False - return True - -def svn_commit(message): - """Commit the sandbox, providing the specified comment. - """ - svn_command('ci', '-m', message) - -def svn_tag_sandbox(tag_url, message): - """Makes a tag based on the sandbox revisions. - """ - svn_command('copy', '-m', message, '.', tag_url) - -def svn_remove_tag(tag_url, message): - """Removes an existing tag. - """ - svn_command('delete', '-m', message, tag_url) - -def svn_export(tag_url, export_dir): - """Exports the tag_url revision to export_dir. - Target directory, including its parent is created if it does not exist. - If the directory export_dir exist, it is deleted before export proceed. - """ - rmdir_if_exist(export_dir) - svn_command('export', tag_url, export_dir) - -def fix_sources_eol(dist_dir): - """Set file EOL for tarball distribution. - """ - print('Preparing exported source file EOL for distribution...') - prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist' - win_sources = antglob.glob(dist_dir, - includes = '**/*.sln **/*.vcproj', - prune_dirs = prune_dirs) - unix_sources = antglob.glob(dist_dir, - includes = '''**/*.h **/*.cpp **/*.inl **/*.txt **/*.dox **/*.py **/*.html **/*.in - sconscript *.json *.expected AUTHORS LICENSE''', - excludes = antglob.default_excludes + 'scons.py sconsign.py scons-*', - prune_dirs = prune_dirs) - for path in win_sources: - fixeol.fix_source_eol(path, is_dry_run = False, verbose = True, eol = '\r\n') - for path in unix_sources: - fixeol.fix_source_eol(path, is_dry_run = False, verbose = True, eol = '\n') - -def download(url, target_path): - """Download file represented by url to target_path. - """ - f = urllib2.urlopen(url) - try: - data = f.read() - finally: - f.close() - fout = open(target_path, 'wb') - try: - fout.write(data) - finally: - fout.close() - -def check_compile(distcheck_top_dir, platform): - cmd = [sys.executable, 'scons.py', 'platform=%s' % platform, 'check'] - print('Running:', ' '.join(cmd)) - log_path = os.path.join(distcheck_top_dir, 'build-%s.log' % platform) - flog = open(log_path, 'wb') - try: - process = subprocess.Popen(cmd, - stdout=flog, - stderr=subprocess.STDOUT, - cwd=distcheck_top_dir) - stdout = process.communicate()[0] - status = (process.returncode == 0) - finally: - flog.close() - return (status, log_path) - -def write_tempfile(content, **kwargs): - fd, path = tempfile.mkstemp(**kwargs) - f = os.fdopen(fd, 'wt') - try: - f.write(content) - finally: - f.close() - return path - -class SFTPError(Exception): - pass - -def run_sftp_batch(userhost, sftp, batch, retry=0): - path = write_tempfile(batch, suffix='.sftp', text=True) - # psftp -agent -C blep,jsoncpp@web.sourceforge.net -batch -b batch.sftp -bc - cmd = [sftp, '-agent', '-C', '-batch', '-b', path, '-bc', userhost] - error = None - for retry_index in range(0, max(1,retry)): - heading = retry_index == 0 and 'Running:' or 'Retrying:' - print(heading, ' '.join(cmd)) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout = process.communicate()[0] - if process.returncode != 0: - error = SFTPError('SFTP batch failed:\n' + stdout) - else: - break - if error: - raise error - return stdout - -def sourceforge_web_synchro(sourceforge_project, doc_dir, - user=None, sftp='sftp'): - """Notes: does not synchronize sub-directory of doc-dir. - """ - userhost = '%s,%s@web.sourceforge.net' % (user, sourceforge_project) - stdout = run_sftp_batch(userhost, sftp, """ -cd htdocs -dir -exit -""") - existing_paths = set() - collect = 0 - for line in stdout.split('\n'): - line = line.strip() - if not collect and line.endswith('> dir'): - collect = True - elif collect and line.endswith('> exit'): - break - elif collect == 1: - collect = 2 - elif collect == 2: - path = line.strip().split()[-1:] - if path and path[0] not in ('.', '..'): - existing_paths.add(path[0]) - upload_paths = set([os.path.basename(p) for p in antglob.glob(doc_dir)]) - paths_to_remove = existing_paths - upload_paths - if paths_to_remove: - print('Removing the following file from web:') - print('\n'.join(paths_to_remove)) - stdout = run_sftp_batch(userhost, sftp, """cd htdocs -rm %s -exit""" % ' '.join(paths_to_remove)) - print('Uploading %d files:' % len(upload_paths)) - batch_size = 10 - upload_paths = list(upload_paths) - start_time = time.time() - for index in range(0,len(upload_paths),batch_size): - paths = upload_paths[index:index+batch_size] - file_per_sec = (time.time() - start_time) / (index+1) - remaining_files = len(upload_paths) - index - remaining_sec = file_per_sec * remaining_files - print('%d/%d, ETA=%.1fs' % (index+1, len(upload_paths), remaining_sec)) - run_sftp_batch(userhost, sftp, """cd htdocs -lcd %s -mput %s -exit""" % (doc_dir, ' '.join(paths)), retry=3) - -def sourceforge_release_tarball(sourceforge_project, paths, user=None, sftp='sftp'): - userhost = '%s,%s@frs.sourceforge.net' % (user, sourceforge_project) - run_sftp_batch(userhost, sftp, """ -mput %s -exit -""" % (' '.join(paths),)) - - -def main(): - usage = """%prog release_version next_dev_version -Update 'version' file to release_version and commit. -Generates the document tarball. -Tags the sandbox revision with release_version. -Update 'version' file to next_dev_version and commit. - -Performs an svn export of tag release version, and build a source tarball. - -Must be started in the project top directory. - -Warning: --force should only be used when developing/testing the release script. -""" - from optparse import OptionParser - parser = OptionParser(usage=usage) - parser.allow_interspersed_args = False - parser.add_option('--dot', dest="dot_path", action='http://github.com/store', default=doxybuild.find_program('dot'), - help="""Path to GraphViz dot tool. Must be full qualified path. [Default: %default]""") - parser.add_option('--doxygen', dest="doxygen_path", action='http://github.com/store', default=doxybuild.find_program('doxygen'), - help="""Path to Doxygen tool. [Default: %default]""") - parser.add_option('--force', dest="ignore_pending_commit", action='http://github.com/store_true', default=False, - help="""Ignore pending commit. [Default: %default]""") - parser.add_option('--retag', dest="retag_release", action='http://github.com/store_true', default=False, - help="""Overwrite release existing tag if it exist. [Default: %default]""") - parser.add_option('-p', '--platforms', dest="platforms", action='http://github.com/store', default='', - help="""Comma separated list of platform passed to scons for build check.""") - parser.add_option('--no-test', dest="no_test", action='http://github.com/store_true', default=False, - help="""Skips build check.""") - parser.add_option('--no-web', dest="no_web", action='http://github.com/store_true', default=False, - help="""Do not update web site.""") - parser.add_option('-u', '--upload-user', dest="user", action='http://github.com/store', - help="""Sourceforge user for SFTP documentation upload.""") - parser.add_option('--sftp', dest='sftp', action='http://github.com/store', default=doxybuild.find_program('psftp', 'sftp'), - help="""Path of the SFTP compatible binary used to upload the documentation.""") - parser.enable_interspersed_args() - options, args = parser.parse_args() - - if len(args) != 2: - parser.error('release_version missing on command-line.') - release_version = args[0] - next_version = args[1] - - if not options.platforms and not options.no_test: - parser.error('You must specify either --platform or --no-test option.') - - if options.ignore_pending_commit: - msg = '' - else: - msg = check_no_pending_commit() - if not msg: - print('Setting version to', release_version) - set_version(release_version) - svn_commit('Release ' + release_version) - tag_url = svn_join_url(http://github.com/SVN_TAG_ROOT,%20release_version) - if svn_check_if_tag_exist(tag_url): - if options.retag_release: - svn_remove_tag(tag_url, 'Overwriting previous tag') - else: - print('Aborting, tag %s already exist. Use --retag to overwrite it!' % tag_url) - sys.exit(1) - svn_tag_sandbox(tag_url, 'Release ' + release_version) - - print('Generated doxygen document...') -## doc_dirname = r'jsoncpp-api-html-0.5.0' -## doc_tarball_path = r'e:\prg\vc\Lib\jsoncpp-trunk\dist\jsoncpp-api-html-0.5.0.tar.gz' - doc_tarball_path, doc_dirname = doxybuild.build_doc(options, make_release=True) - doc_distcheck_dir = 'dist/doccheck' - tarball.decompress(doc_tarball_path, doc_distcheck_dir) - doc_distcheck_top_dir = os.path.join(doc_distcheck_dir, doc_dirname) - - export_dir = 'dist/export' - svn_export(tag_url, export_dir) - fix_sources_eol(export_dir) - - source_dir = 'jsoncpp-src-' + release_version - source_tarball_path = 'dist/%s.tar.gz' % source_dir - print('Generating source tarball to', source_tarball_path) - tarball.make_tarball(source_tarball_path, [export_dir], export_dir, prefix_dir=source_dir) - - amalgamation_tarball_path = 'dist/%s-amalgamation.tar.gz' % source_dir - print('Generating amalgamation source tarball to', amalgamation_tarball_path) - amalgamation_dir = 'dist/amalgamation' - amalgamate.amalgamate_source(export_dir, '%s/jsoncpp.cpp' % amalgamation_dir, 'json/json.h') - amalgamation_source_dir = 'jsoncpp-src-amalgamation' + release_version - tarball.make_tarball(amalgamation_tarball_path, [amalgamation_dir], - amalgamation_dir, prefix_dir=amalgamation_source_dir) - - # Decompress source tarball, download and install scons-local - distcheck_dir = 'dist/distcheck' - distcheck_top_dir = distcheck_dir + '/' + source_dir - print('Decompressing source tarball to', distcheck_dir) - rmdir_if_exist(distcheck_dir) - tarball.decompress(source_tarball_path, distcheck_dir) - scons_local_path = 'dist/scons-local.tar.gz' - print('Downloading scons-local to', scons_local_path) - download(SCONS_LOCAL_URL, scons_local_path) - print('Decompressing scons-local to', distcheck_top_dir) - tarball.decompress(scons_local_path, distcheck_top_dir) - - # Run compilation - print('Compiling decompressed tarball') - all_build_status = True - for platform in options.platforms.split(','): - print('Testing platform:', platform) - build_status, log_path = check_compile(distcheck_top_dir, platform) - print('see build log:', log_path) - print(build_status and '=> ok' or '=> FAILED') - all_build_status = all_build_status and build_status - if not build_status: - print('Testing failed on at least one platform, aborting...') - svn_remove_tag(tag_url, 'Removing tag due to failed testing') - sys.exit(1) - if options.user: - if not options.no_web: - print('Uploading documentation using user', options.user) - sourceforge_web_synchro(SOURCEFORGE_PROJECT, doc_distcheck_top_dir, user=options.user, sftp=options.sftp) - print('Completed documentation upload') - print('Uploading source and documentation tarballs for release using user', options.user) - sourceforge_release_tarball(SOURCEFORGE_PROJECT, - [source_tarball_path, doc_tarball_path], - user=options.user, sftp=options.sftp) - print('Source and doc release tarballs uploaded') - else: - print('No upload user specified. Web site and download tarball were not uploaded.') - print('Tarball can be found at:', doc_tarball_path) - - # Set next version number and commit - set_version(next_version) - svn_commit('Released ' + release_version) - else: - sys.stderr.write(msg + '\n') - -if __name__ == '__main__': - main() From 7429bb2bfa5f7c90c7b63c6103d75033fe244dd9 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 4 Nov 2019 07:35:52 -0600 Subject: [PATCH 239/410] COMP: Fix type mismatch ambiguity jsoncpp/src/test_lib_json/main.cpp:354:31: error: implicit conversion changes signedness: 'int' to 'std::__1::vector >::size_type' aka 'unsigned long') [-Werror,-Wsign-conversion] JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); ~~~ ^ --- src/test_lib_json/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 1d636d8a0..8afed1dde 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -350,7 +350,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[2]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[3]); // checking address - for (int i = 0; i < 3; i++) { + for (Json::ArrayIndex i = 0; i < 3; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); } vec.push_back(&array[3]); @@ -362,7 +362,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); // checking address - for (int i = 0; i < 4; i++) { + for (Json::ArrayIndex i = 0; i < 4; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); } vec.push_back(&array[4]); @@ -376,7 +376,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[5]); // checking address - for (int i = 0; i < 5; i++) { + for (Json::ArrayIndex i = 0; i < 5; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); } vec.push_back(&array[5]); From 5fb17a66b85f7dde6dbaa378c280e96b63d70366 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 4 Nov 2019 07:37:19 -0600 Subject: [PATCH 240/410] COMP: Remove shadow variable warning jsoncpp/src/test_lib_json/main.cpp:2261:30: warning: declaration shadows a local variable [-Wshadow] Json::StyledStreamWriter writer; ^ jsoncpp/src/test_lib_json/main.cpp:2237:28: note: previous declaration is here Json::StyledStreamWriter writer; ^ --- src/test_lib_json/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 8afed1dde..ad34c8ae9 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2234,7 +2234,6 @@ JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, writeNestedObjects) { } JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { - Json::StyledStreamWriter writer; { // Array member has more than 20 print effect rendering lines const Json::String expected("[\n\t0," @@ -2268,6 +2267,7 @@ JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { JSONTEST_ASSERT_STRING_EQUAL(expected, result); } { + Json::StyledStreamWriter writer; // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); Json::Value root; From a86e129983d30fba3c9b1de77036b19cf6c6a7a8 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Mon, 4 Nov 2019 07:46:51 -0600 Subject: [PATCH 241/410] ENH: Move to requiring python 3 Resolves #1081 See for more details: https://devguide.python.org/devcycle/#end-of-life-branches https://pythonclock.org/ --- src/jsontestrunner/CMakeLists.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 39c6f4871..210e0900b 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -1,4 +1,13 @@ -find_package(PythonInterp 2.6) +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + # The new Python3 module is much more robust than the previous PythonInterp + find_package (Python3 COMPONENTS Interpreter) + # Set variables for backwards compatibility with cmake < 3.12.0 + set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND}) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) +else() + set(Python_ADDITIONAL_VERSIONS 3.8) + find_package(PythonInterp 3) +endif() add_executable(jsontestrunner_exe main.cpp From 82b736734d9f38a3c2c5b1118b30a7ab217cb4ed Mon Sep 17 00:00:00 2001 From: chenguoping Date: Sat, 26 Oct 2019 15:57:35 +0800 Subject: [PATCH 242/410] add testcase for json_value.cpp to improve coverage [90+%] --- src/test_lib_json/main.cpp | 141 +++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index ad34c8ae9..5fd1b4524 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -267,6 +267,21 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { did = object1_.removeMember("some other id", gotPtr); JSONTEST_ASSERT_EQUAL(nullptr, gotPtr); JSONTEST_ASSERT_EQUAL(true, did); + + // Using other removeMember interfaces, the test idea is the same as above. + object1_["some other id"] = "foo"; + const Json::String key("some other id"); + did = object1_.removeMember(key, &got); + JSONTEST_ASSERT_EQUAL(Json::Value("foo"), got); + JSONTEST_ASSERT_EQUAL(true, did); + got = Json::Value("bar"); + did = object1_.removeMember(key, &got); + JSONTEST_ASSERT_EQUAL(Json::Value("bar"), got); + JSONTEST_ASSERT_EQUAL(false, did); + + object1_["some other id"] = "foo"; + object1_.removeMember(key); + JSONTEST_ASSERT_EQUAL(Json::nullValue, object1_[key]); } JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { @@ -314,6 +329,50 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { JSONTEST_ASSERT_EQUAL(Json::Value(17), got); JSONTEST_ASSERT_EQUAL(false, array1_.removeIndex(2, &got)); // gone now } +JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { + Json::Value array; + { + for (int i = 0; i < 10; i++) + array[i] = i; + JSONTEST_ASSERT_EQUAL(array.size(), 10); + // The length set is greater than the length of the array. + array.resize(15); + JSONTEST_ASSERT_EQUAL(array.size(), 15); + + // The length set is less than the length of the array. + array.resize(5); + JSONTEST_ASSERT_EQUAL(array.size(), 5); + + // The length of the array is set to 0. + array.resize(0); + JSONTEST_ASSERT_EQUAL(array.size(), 0); + } + { + for (int i = 0; i < 10; i++) + array[i] = i; + JSONTEST_ASSERT_EQUAL(array.size(), 10); + array.clear(); + JSONTEST_ASSERT_EQUAL(array.size(), 0); + } +} +JSONTEST_FIXTURE_LOCAL(ValueTest, getArrayValue) { + Json::Value array; + for (int i = 0; i < 5; i++) + array[i] = i; + + JSONTEST_ASSERT_EQUAL(array.size(), 5); + const Json::Value defaultValue(10); + Json::ArrayIndex index = 0; + for (; index <= 4; index++) + JSONTEST_ASSERT_EQUAL(index, array.get(index, defaultValue).asInt()); + + index = 4; + JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), true); + index = 5; + JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), false); + JSONTEST_ASSERT_EQUAL(defaultValue, array.get(index, defaultValue)); + JSONTEST_ASSERT_EQUAL(array.isValidIndex(index), false); +} JSONTEST_FIXTURE_LOCAL(ValueTest, arrayIssue252) { int count = 5; Json::Value root; @@ -1964,7 +2023,89 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, precision) { result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); } +JSONTEST_FIXTURE_LOCAL(ValueTest, searchValueByPath) { + Json::Value root, subroot; + root["property1"][0] = 0; + root["property1"][1] = 1; + subroot["object"] = "object"; + root["property2"] = subroot; + + const Json::Value defaultValue("error"); + Json::FastWriter writer; + { + const Json::String expected("{" + "\"property1\":[0,1]," + "\"property2\":{\"object\":\"object\"}" + "}\n"); + Json::String outcome = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); + + // Array member exists. + const Json::Path path1(".property1.[%]", 1); + Json::Value result = path1.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::Value(1), result); + result = path1.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(Json::Value(1), result); + + // Array member does not exist. + const Json::Path path2(".property1.[2]"); + result = path2.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, result); + result = path2.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(defaultValue, result); + + // Access array path form error + const Json::Path path3(".property1.0"); + result = path3.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, result); + result = path3.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(defaultValue, result); + + // Object member exists. + const Json::Path path4(".property2.%", "object"); + result = path4.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::Value("object"), result); + result = path4.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(Json::Value("object"), result); + + // Object member does not exist. + const Json::Path path5(".property2.hello"); + result = path5.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, result); + result = path5.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(defaultValue, result); + + // Access object path form error + const Json::Path path6(".property2.[0]"); + result = path5.resolve(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, result); + result = path6.resolve(root, defaultValue); + JSONTEST_ASSERT_EQUAL(defaultValue, result); + + // resolve will not change the value + outcome = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); + } + { + const Json::String expected("{" + "\"property1\":[0,1,null]," + "\"property2\":{" + "\"hello\":null," + "\"object\":\"object\"}}\n"); + Json::Path path1(".property1.[%]", 2); + Json::Value& value1 = path1.make(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, value1); + + Json::Path path2(".property2.%", "hello"); + Json::Value& value2 = path2.make(root); + JSONTEST_ASSERT_EQUAL(Json::nullValue, value2); + + // make will change the value + const Json::String outcome = writer.write(root); + JSONTEST_ASSERT_STRING_EQUAL(expected, outcome); + } +} struct FastWriterTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(FastWriterTest, dropNullPlaceholders) { From ff58fdcc756b2fbf312b3e4b69fc48d29167f509 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Thu, 7 Nov 2019 15:25:06 +0800 Subject: [PATCH 243/410] Update coverage badge (#1088) update coverage badge change int to Json::ArrayIndex in for-loop --- README.md | 2 +- src/test_lib_json/main.cpp | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 005710940..b6fc76913 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![badge](https://img.shields.io/badge/conan.io-jsoncpp%2F1.8.0-green.svg?logo=data:image/png;base64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAA1VBMVEUAAABhlctjlstkl8tlmMtlmMxlmcxmmcxnmsxpnMxpnM1qnc1sn85voM91oM11oc1xotB2oc56pNF6pNJ2ptJ8ptJ8ptN9ptN8p9N5qNJ9p9N9p9R8qtOBqdSAqtOAqtR%2BrNSCrNJ/rdWDrNWCsNWCsNaJs9eLs9iRvNuVvdyVv9yXwd2Zwt6axN6dxt%2Bfx%2BChyeGiyuGjyuCjyuGly%2BGlzOKmzOGozuKoz%2BKqz%2BOq0OOv1OWw1OWw1eWx1eWy1uay1%2Baz1%2Baz1%2Bez2Oe02Oe12ee22ujUGwH3AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfgBQkREyOxFIh/AAAAiklEQVQI12NgAAMbOwY4sLZ2NtQ1coVKWNvoc/Eq8XDr2wB5Ig62ekza9vaOqpK2TpoMzOxaFtwqZua2Bm4makIM7OzMAjoaCqYuxooSUqJALjs7o4yVpbowvzSUy87KqSwmxQfnsrPISyFzWeWAXCkpMaBVIC4bmCsOdgiUKwh3JojLgAQ4ZCE0AMm2D29tZwe6AAAAAElFTkSuQmCC)](https://bintray.com/theirix/conan-repo/jsoncpp%3Atheirix) [![badge](https://img.shields.io/badge/license-MIT-blue)](https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE) [![badge](https://img.shields.io/badge/document-doxygen-brightgreen)](http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html) -[![Coverage Status](https://coveralls.io/repos/github/open-source-parsers/jsoncpp/badge.svg)](https://coveralls.io/github/open-source-parsers/jsoncpp) +[![Coverage Status](https://coveralls.io/repos/github/open-source-parsers/jsoncpp/badge.svg?branch=master)](https://coveralls.io/github/open-source-parsers/jsoncpp?branch=master) [JSON][json-org] is a lightweight data-interchange format. It can represent diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 5fd1b4524..fff5b2ce1 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -332,7 +332,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { Json::Value array; { - for (int i = 0; i < 10; i++) + for (Json::ArrayIndex i = 0; i < 10; i++) array[i] = i; JSONTEST_ASSERT_EQUAL(array.size(), 10); // The length set is greater than the length of the array. @@ -348,7 +348,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { JSONTEST_ASSERT_EQUAL(array.size(), 0); } { - for (int i = 0; i < 10; i++) + for (Json::ArrayIndex i = 0; i < 10; i++) array[i] = i; JSONTEST_ASSERT_EQUAL(array.size(), 10); array.clear(); @@ -357,7 +357,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { } JSONTEST_FIXTURE_LOCAL(ValueTest, getArrayValue) { Json::Value array; - for (int i = 0; i < 5; i++) + for (Json::ArrayIndex i = 0; i < 5; i++) array[i] = i; JSONTEST_ASSERT_EQUAL(array.size(), 5); @@ -395,7 +395,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { array.append(str0); // append lvalue std::vector vec; // storage value address for checking - for (int i = 0; i < 3; i++) { + for (Json::ArrayIndex i = 0; i < 3; i++) { vec.push_back(&array[i]); } JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]); // check append @@ -2265,7 +2265,7 @@ JSONTEST_FIXTURE_LOCAL(StyledWriterTest, multiLineArray) { "15,\n 16,\n 17,\n " "18,\n 19,\n 20\n]\n"); Json::Value root; - for (int i = 0; i < 21; i++) + for (Json::ArrayIndex i = 0; i < 21; i++) root[i] = i; const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); @@ -2274,7 +2274,7 @@ JSONTEST_FIXTURE_LOCAL(StyledWriterTest, multiLineArray) { // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); Json::Value root; - for (int i = 0; i < 10; i++) + for (Json::ArrayIndex i = 0; i < 10; i++) root[i] = i; const Json::String result = writer.write(root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); @@ -2400,7 +2400,7 @@ JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { "\n\t20\n]\n"); Json::StyledStreamWriter writer; Json::Value root; - for (int i = 0; i < 21; i++) + for (Json::ArrayIndex i = 0; i < 21; i++) root[i] = i; Json::OStringStream sout; writer.write(sout, root); @@ -2412,7 +2412,7 @@ JSONTEST_FIXTURE_LOCAL(StyledStreamWriterTest, multiLineArray) { // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n"); Json::Value root; - for (int i = 0; i < 10; i++) + for (Json::ArrayIndex i = 0; i < 10; i++) root[i] = i; Json::OStringStream sout; writer.write(sout, root); @@ -2547,7 +2547,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, multiLineArray) { "\n\t19," "\n\t20\n]"); Json::Value root; - for (int i = 0; i < 21; i++) + for (Json::ArrayIndex i = 0; i < 21; i++) root[i] = i; const Json::String result = Json::writeString(wb, root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); @@ -2556,7 +2556,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, multiLineArray) { // Array members do not exceed 21 print effects to render a single line const Json::String expected("[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]"); Json::Value root; - for (int i = 0; i < 10; i++) + for (Json::ArrayIndex i = 0; i < 10; i++) root[i] = i; const Json::String result = Json::writeString(wb, root); JSONTEST_ASSERT_STRING_EQUAL(expected, result); From 645cd0412c100d633a882da30d6245a30a8a4c82 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 8 Nov 2019 19:49:16 -0800 Subject: [PATCH 244/410] Number fixes (#1053) * cleaning up the logic for parsing numbers * Add Testcases for new Reader in jsontestrunner --- meson.build | 2 +- src/jsontestrunner/main.cpp | 97 ++++++++++++----- src/lib_json/json_reader.cpp | 101 +++++++++--------- ...expected => legacy_test_array_01.expected} | 0 ...rray_01.json => legacy_test_array_01.json} | 0 ...expected => legacy_test_array_02.expected} | 0 ...rray_02.json => legacy_test_array_02.json} | 0 ...expected => legacy_test_array_03.expected} | 0 ...rray_03.json => legacy_test_array_03.json} | 0 ...expected => legacy_test_array_04.expected} | 0 ...rray_04.json => legacy_test_array_04.json} | 0 ...expected => legacy_test_array_05.expected} | 0 ...rray_05.json => legacy_test_array_05.json} | 0 ...expected => legacy_test_array_06.expected} | 0 ...rray_06.json => legacy_test_array_06.json} | 0 ...expected => legacy_test_array_07.expected} | 0 ...rray_07.json => legacy_test_array_07.json} | 0 ...expected => legacy_test_basic_01.expected} | 0 ...asic_01.json => legacy_test_basic_01.json} | 0 ...expected => legacy_test_basic_02.expected} | 0 ...asic_02.json => legacy_test_basic_02.json} | 0 ...expected => legacy_test_basic_03.expected} | 0 ...asic_03.json => legacy_test_basic_03.json} | 0 ...expected => legacy_test_basic_04.expected} | 0 ...asic_04.json => legacy_test_basic_04.json} | 0 ...expected => legacy_test_basic_05.expected} | 0 ...asic_05.json => legacy_test_basic_05.json} | 0 ...expected => legacy_test_basic_06.expected} | 0 ...asic_06.json => legacy_test_basic_06.json} | 0 ...expected => legacy_test_basic_07.expected} | 0 ...asic_07.json => legacy_test_basic_07.json} | 0 ...expected => legacy_test_basic_08.expected} | 0 ...asic_08.json => legacy_test_basic_08.json} | 0 ...expected => legacy_test_basic_09.expected} | 0 ...asic_09.json => legacy_test_basic_09.json} | 0 ...pected => legacy_test_comment_00.expected} | 0 ...nt_00.json => legacy_test_comment_00.json} | 0 ...pected => legacy_test_comment_01.expected} | 0 ...nt_01.json => legacy_test_comment_01.json} | 0 ...pected => legacy_test_comment_02.expected} | 0 ...nt_02.json => legacy_test_comment_02.json} | 0 ...pected => legacy_test_complex_01.expected} | 0 ...ex_01.json => legacy_test_complex_01.json} | 0 ...pected => legacy_test_integer_01.expected} | 0 ...er_01.json => legacy_test_integer_01.json} | 0 ...pected => legacy_test_integer_02.expected} | 0 ...er_02.json => legacy_test_integer_02.json} | 0 ...pected => legacy_test_integer_03.expected} | 0 ...er_03.json => legacy_test_integer_03.json} | 0 ...pected => legacy_test_integer_04.expected} | 0 ...er_04.json => legacy_test_integer_04.json} | 0 ...pected => legacy_test_integer_05.expected} | 0 ...er_05.json => legacy_test_integer_05.json} | 0 ...=> legacy_test_integer_06_64bits.expected} | 0 ...son => legacy_test_integer_06_64bits.json} | 0 ...=> legacy_test_integer_07_64bits.expected} | 0 ...son => legacy_test_integer_07_64bits.json} | 0 ...=> legacy_test_integer_08_64bits.expected} | 0 ...son => legacy_test_integer_08_64bits.json} | 0 ...expected => legacy_test_large_01.expected} | 0 ...arge_01.json => legacy_test_large_01.json} | 0 ...xpected => legacy_test_object_01.expected} | 0 ...ect_01.json => legacy_test_object_01.json} | 0 ...xpected => legacy_test_object_02.expected} | 0 ...ect_02.json => legacy_test_object_02.json} | 0 ...xpected => legacy_test_object_03.expected} | 0 ...ect_03.json => legacy_test_object_03.json} | 0 ...xpected => legacy_test_object_04.expected} | 0 ...ect_04.json => legacy_test_object_04.json} | 0 ... legacy_test_preserve_comment_01.expected} | 0 ...n => legacy_test_preserve_comment_01.json} | 0 ....expected => legacy_test_real_01.expected} | 0 ..._real_01.json => legacy_test_real_01.json} | 0 ....expected => legacy_test_real_02.expected} | 0 ..._real_02.json => legacy_test_real_02.json} | 0 ....expected => legacy_test_real_03.expected} | 0 ..._real_03.json => legacy_test_real_03.json} | 0 ....expected => legacy_test_real_04.expected} | 0 ..._real_04.json => legacy_test_real_04.json} | 0 ....expected => legacy_test_real_05.expected} | 0 ..._real_05.json => legacy_test_real_05.json} | 0 ....expected => legacy_test_real_06.expected} | 0 ..._real_06.json => legacy_test_real_06.json} | 0 ....expected => legacy_test_real_07.expected} | 0 ..._real_07.json => legacy_test_real_07.json} | 0 ....expected => legacy_test_real_08.expected} | 0 ..._real_08.json => legacy_test_real_08.json} | 0 ....expected => legacy_test_real_09.expected} | 0 ..._real_09.json => legacy_test_real_09.json} | 0 ....expected => legacy_test_real_10.expected} | 0 ..._real_10.json => legacy_test_real_10.json} | 0 ....expected => legacy_test_real_11.expected} | 0 ..._real_11.json => legacy_test_real_11.json} | 0 ....expected => legacy_test_real_12.expected} | 0 ..._real_12.json => legacy_test_real_12.json} | 0 ...xpected => legacy_test_string_01.expected} | 0 ...ing_01.json => legacy_test_string_01.json} | 0 ...xpected => legacy_test_string_02.expected} | 0 ...ing_02.json => legacy_test_string_02.json} | 0 ...xpected => legacy_test_string_03.expected} | 0 ...ing_03.json => legacy_test_string_03.json} | 0 ...xpected => legacy_test_string_04.expected} | 0 ...ing_04.json => legacy_test_string_04.json} | 0 ...xpected => legacy_test_string_05.expected} | 0 ...ing_05.json => legacy_test_string_05.json} | 0 ...=> legacy_test_string_unicode_01.expected} | 0 ...son => legacy_test_string_unicode_01.json} | 0 ...=> legacy_test_string_unicode_02.expected} | 0 ...son => legacy_test_string_unicode_02.json} | 0 ...=> legacy_test_string_unicode_03.expected} | 0 ...son => legacy_test_string_unicode_03.json} | 0 ...=> legacy_test_string_unicode_04.expected} | 0 ...son => legacy_test_string_unicode_04.json} | 0 ...=> legacy_test_string_unicode_05.expected} | 0 ...son => legacy_test_string_unicode_05.json} | 0 115 files changed, 124 insertions(+), 76 deletions(-) rename test/data/{test_array_01.expected => legacy_test_array_01.expected} (100%) rename test/data/{test_array_01.json => legacy_test_array_01.json} (100%) rename test/data/{test_array_02.expected => legacy_test_array_02.expected} (100%) rename test/data/{test_array_02.json => legacy_test_array_02.json} (100%) rename test/data/{test_array_03.expected => legacy_test_array_03.expected} (100%) rename test/data/{test_array_03.json => legacy_test_array_03.json} (100%) rename test/data/{test_array_04.expected => legacy_test_array_04.expected} (100%) rename test/data/{test_array_04.json => legacy_test_array_04.json} (100%) rename test/data/{test_array_05.expected => legacy_test_array_05.expected} (100%) rename test/data/{test_array_05.json => legacy_test_array_05.json} (100%) rename test/data/{test_array_06.expected => legacy_test_array_06.expected} (100%) rename test/data/{test_array_06.json => legacy_test_array_06.json} (100%) rename test/data/{test_array_07.expected => legacy_test_array_07.expected} (100%) rename test/data/{test_array_07.json => legacy_test_array_07.json} (100%) rename test/data/{test_basic_01.expected => legacy_test_basic_01.expected} (100%) rename test/data/{test_basic_01.json => legacy_test_basic_01.json} (100%) rename test/data/{test_basic_02.expected => legacy_test_basic_02.expected} (100%) rename test/data/{test_basic_02.json => legacy_test_basic_02.json} (100%) rename test/data/{test_basic_03.expected => legacy_test_basic_03.expected} (100%) rename test/data/{test_basic_03.json => legacy_test_basic_03.json} (100%) rename test/data/{test_basic_04.expected => legacy_test_basic_04.expected} (100%) rename test/data/{test_basic_04.json => legacy_test_basic_04.json} (100%) rename test/data/{test_basic_05.expected => legacy_test_basic_05.expected} (100%) rename test/data/{test_basic_05.json => legacy_test_basic_05.json} (100%) rename test/data/{test_basic_06.expected => legacy_test_basic_06.expected} (100%) rename test/data/{test_basic_06.json => legacy_test_basic_06.json} (100%) rename test/data/{test_basic_07.expected => legacy_test_basic_07.expected} (100%) rename test/data/{test_basic_07.json => legacy_test_basic_07.json} (100%) rename test/data/{test_basic_08.expected => legacy_test_basic_08.expected} (100%) rename test/data/{test_basic_08.json => legacy_test_basic_08.json} (100%) rename test/data/{test_basic_09.expected => legacy_test_basic_09.expected} (100%) rename test/data/{test_basic_09.json => legacy_test_basic_09.json} (100%) rename test/data/{test_comment_00.expected => legacy_test_comment_00.expected} (100%) rename test/data/{test_comment_00.json => legacy_test_comment_00.json} (100%) rename test/data/{test_comment_01.expected => legacy_test_comment_01.expected} (100%) rename test/data/{test_comment_01.json => legacy_test_comment_01.json} (100%) rename test/data/{test_comment_02.expected => legacy_test_comment_02.expected} (100%) rename test/data/{test_comment_02.json => legacy_test_comment_02.json} (100%) rename test/data/{test_complex_01.expected => legacy_test_complex_01.expected} (100%) rename test/data/{test_complex_01.json => legacy_test_complex_01.json} (100%) rename test/data/{test_integer_01.expected => legacy_test_integer_01.expected} (100%) rename test/data/{test_integer_01.json => legacy_test_integer_01.json} (100%) rename test/data/{test_integer_02.expected => legacy_test_integer_02.expected} (100%) rename test/data/{test_integer_02.json => legacy_test_integer_02.json} (100%) rename test/data/{test_integer_03.expected => legacy_test_integer_03.expected} (100%) rename test/data/{test_integer_03.json => legacy_test_integer_03.json} (100%) rename test/data/{test_integer_04.expected => legacy_test_integer_04.expected} (100%) rename test/data/{test_integer_04.json => legacy_test_integer_04.json} (100%) rename test/data/{test_integer_05.expected => legacy_test_integer_05.expected} (100%) rename test/data/{test_integer_05.json => legacy_test_integer_05.json} (100%) rename test/data/{test_integer_06_64bits.expected => legacy_test_integer_06_64bits.expected} (100%) rename test/data/{test_integer_06_64bits.json => legacy_test_integer_06_64bits.json} (100%) rename test/data/{test_integer_07_64bits.expected => legacy_test_integer_07_64bits.expected} (100%) rename test/data/{test_integer_07_64bits.json => legacy_test_integer_07_64bits.json} (100%) rename test/data/{test_integer_08_64bits.expected => legacy_test_integer_08_64bits.expected} (100%) rename test/data/{test_integer_08_64bits.json => legacy_test_integer_08_64bits.json} (100%) rename test/data/{test_large_01.expected => legacy_test_large_01.expected} (100%) rename test/data/{test_large_01.json => legacy_test_large_01.json} (100%) rename test/data/{test_object_01.expected => legacy_test_object_01.expected} (100%) rename test/data/{test_object_01.json => legacy_test_object_01.json} (100%) rename test/data/{test_object_02.expected => legacy_test_object_02.expected} (100%) rename test/data/{test_object_02.json => legacy_test_object_02.json} (100%) rename test/data/{test_object_03.expected => legacy_test_object_03.expected} (100%) rename test/data/{test_object_03.json => legacy_test_object_03.json} (100%) rename test/data/{test_object_04.expected => legacy_test_object_04.expected} (100%) rename test/data/{test_object_04.json => legacy_test_object_04.json} (100%) rename test/data/{test_preserve_comment_01.expected => legacy_test_preserve_comment_01.expected} (100%) rename test/data/{test_preserve_comment_01.json => legacy_test_preserve_comment_01.json} (100%) rename test/data/{test_real_01.expected => legacy_test_real_01.expected} (100%) rename test/data/{test_real_01.json => legacy_test_real_01.json} (100%) rename test/data/{test_real_02.expected => legacy_test_real_02.expected} (100%) rename test/data/{test_real_02.json => legacy_test_real_02.json} (100%) rename test/data/{test_real_03.expected => legacy_test_real_03.expected} (100%) rename test/data/{test_real_03.json => legacy_test_real_03.json} (100%) rename test/data/{test_real_04.expected => legacy_test_real_04.expected} (100%) rename test/data/{test_real_04.json => legacy_test_real_04.json} (100%) rename test/data/{test_real_05.expected => legacy_test_real_05.expected} (100%) rename test/data/{test_real_05.json => legacy_test_real_05.json} (100%) rename test/data/{test_real_06.expected => legacy_test_real_06.expected} (100%) rename test/data/{test_real_06.json => legacy_test_real_06.json} (100%) rename test/data/{test_real_07.expected => legacy_test_real_07.expected} (100%) rename test/data/{test_real_07.json => legacy_test_real_07.json} (100%) rename test/data/{test_real_08.expected => legacy_test_real_08.expected} (100%) rename test/data/{test_real_08.json => legacy_test_real_08.json} (100%) rename test/data/{test_real_09.expected => legacy_test_real_09.expected} (100%) rename test/data/{test_real_09.json => legacy_test_real_09.json} (100%) rename test/data/{test_real_10.expected => legacy_test_real_10.expected} (100%) rename test/data/{test_real_10.json => legacy_test_real_10.json} (100%) rename test/data/{test_real_11.expected => legacy_test_real_11.expected} (100%) rename test/data/{test_real_11.json => legacy_test_real_11.json} (100%) rename test/data/{test_real_12.expected => legacy_test_real_12.expected} (100%) rename test/data/{test_real_12.json => legacy_test_real_12.json} (100%) rename test/data/{test_string_01.expected => legacy_test_string_01.expected} (100%) rename test/data/{test_string_01.json => legacy_test_string_01.json} (100%) rename test/data/{test_string_02.expected => legacy_test_string_02.expected} (100%) rename test/data/{test_string_02.json => legacy_test_string_02.json} (100%) rename test/data/{test_string_03.expected => legacy_test_string_03.expected} (100%) rename test/data/{test_string_03.json => legacy_test_string_03.json} (100%) rename test/data/{test_string_04.expected => legacy_test_string_04.expected} (100%) rename test/data/{test_string_04.json => legacy_test_string_04.json} (100%) rename test/data/{test_string_05.expected => legacy_test_string_05.expected} (100%) rename test/data/{test_string_05.json => legacy_test_string_05.json} (100%) rename test/data/{test_string_unicode_01.expected => legacy_test_string_unicode_01.expected} (100%) rename test/data/{test_string_unicode_01.json => legacy_test_string_unicode_01.json} (100%) rename test/data/{test_string_unicode_02.expected => legacy_test_string_unicode_02.expected} (100%) rename test/data/{test_string_unicode_02.json => legacy_test_string_unicode_02.json} (100%) rename test/data/{test_string_unicode_03.expected => legacy_test_string_unicode_03.expected} (100%) rename test/data/{test_string_unicode_03.json => legacy_test_string_unicode_03.json} (100%) rename test/data/{test_string_unicode_04.expected => legacy_test_string_unicode_04.expected} (100%) rename test/data/{test_string_unicode_04.json => legacy_test_string_unicode_04.json} (100%) rename test/data/{test_string_unicode_05.expected => legacy_test_string_unicode_05.expected} (100%) rename test/data/{test_string_unicode_05.json => legacy_test_string_unicode_05.json} (100%) diff --git a/meson.build b/meson.build index aa50d8fbc..8531dcec4 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ project( 'cpp_std=c++11', 'warning_level=1'], license : 'Public Domain', - meson_version : '>= 0.50.0') + meson_version : '>= 0.49.0') jsoncpp_headers = [ diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index cb9db66cd..dbfbe98c1 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -15,7 +15,9 @@ #include // sort #include +#include #include +#include #include struct Options { @@ -126,19 +128,45 @@ static int parseAndSaveValueTree(const Json::String& input, const Json::String& actual, const Json::String& kind, const Json::Features& features, bool parseOnly, - Json::Value* root) { - Json::Reader reader(features); - bool parsingSuccessful = - reader.parse(input.data(), input.data() + input.size(), *root); - if (!parsingSuccessful) { - printf("Failed to parse %s file: \n%s\n", kind.c_str(), - reader.getFormattedErrorMessages().c_str()); - return 1; + Json::Value* root, bool use_legacy) { + if (!use_legacy) { + Json::CharReaderBuilder builder; + + builder.settings_["allowComments"] = features.allowComments_; + builder.settings_["strictRoot"] = features.strictRoot_; + builder.settings_["allowDroppedNullPlaceholders"] = + features.allowDroppedNullPlaceholders_; + builder.settings_["allowNumericKeys"] = features.allowNumericKeys_; + + std::unique_ptr reader(builder.newCharReader()); + Json::String errors; + const bool parsingSuccessful = + reader->parse(input.data(), input.data() + input.size(), root, &errors); + + if (!parsingSuccessful) { + std::cerr << "Failed to parse " << kind << " file: " << std::endl + << errors << std::endl; + return 1; + } + + // We may instead check the legacy implementation (to ensure it doesn't + // randomly get broken). + } else { + Json::Reader reader(features); + const bool parsingSuccessful = + reader.parse(input.data(), input.data() + input.size(), *root); + if (!parsingSuccessful) { + std::cerr << "Failed to parse " << kind << " file: " << std::endl + << reader.getFormatedErrorMessages() << std::endl; + return 1; + } } + if (!parseOnly) { FILE* factual = fopen(actual.c_str(), "wt"); if (!factual) { - printf("Failed to create %s actual file.\n", kind.c_str()); + std::cerr << "Failed to create '" << kind << "' actual file." + << std::endl; return 2; } printValueTree(factual, *root); @@ -172,7 +200,7 @@ static int rewriteValueTree(const Json::String& rewritePath, *rewrite = write(root); FILE* fout = fopen(rewritePath.c_str(), "wt"); if (!fout) { - printf("Failed to create rewrite file: %s\n", rewritePath.c_str()); + std::cerr << "Failed to create rewrite file: " << rewritePath << std::endl; return 2; } fprintf(fout, "%s\n", rewrite->c_str()); @@ -193,14 +221,15 @@ static Json::String removeSuffix(const Json::String& path, static void printConfig() { // Print the configuration used to compile JsonCpp #if defined(JSON_NO_INT64) - printf("JSON_NO_INT64=1\n"); + std::cout << "JSON_NO_INT64=1" << std::endl; #else - printf("JSON_NO_INT64=0\n"); + std::cout << "JSON_NO_INT64=0" << std::endl; #endif } static int printUsage(const char* argv[]) { - printf("Usage: %s [--strict] input-json-file", argv[0]); + std::cout << "Usage: " << argv[0] << " [--strict] input-json-file" + << std::endl; return 3; } @@ -230,7 +259,7 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) { } else if (writerName == "BuiltStyledStreamWriter") { opts->write = &useBuiltStyledStreamWriter; } else { - printf("Unknown '--json-writer %s'\n", writerName.c_str()); + std::cerr << "Unknown '--json-writer' " << writerName << std::endl; return 4; } } @@ -240,19 +269,20 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) { opts->path = argv[index]; return 0; } -static int runTest(Options const& opts) { + +static int runTest(Options const& opts, bool use_legacy) { int exitCode = 0; Json::String input = readInputTestFile(opts.path.c_str()); if (input.empty()) { - printf("Failed to read input or empty input: %s\n", opts.path.c_str()); + std::cerr << "Invalid input file: " << opts.path << std::endl; return 3; } Json::String basePath = removeSuffix(opts.path, ".json"); if (!opts.parseOnly && basePath.empty()) { - printf("Bad input path. Path does not end with '.expected':\n%s\n", - opts.path.c_str()); + std::cerr << "Bad input path '" << opts.path + << "'. Must end with '.expected'" << std::endl; return 3; } @@ -262,34 +292,47 @@ static int runTest(Options const& opts) { Json::Value root; exitCode = parseAndSaveValueTree(input, actualPath, "input", opts.features, - opts.parseOnly, &root); + opts.parseOnly, &root, use_legacy); if (exitCode || opts.parseOnly) { return exitCode; } + Json::String rewrite; exitCode = rewriteValueTree(rewritePath, root, opts.write, &rewrite); if (exitCode) { return exitCode; } + Json::Value rewriteRoot; exitCode = parseAndSaveValueTree(rewrite, rewriteActualPath, "rewrite", - opts.features, opts.parseOnly, &rewriteRoot); - if (exitCode) { - return exitCode; - } - return 0; + opts.features, opts.parseOnly, &rewriteRoot, + use_legacy); + + return exitCode; } + int main(int argc, const char* argv[]) { Options opts; try { int exitCode = parseCommandLine(argc, argv, &opts); if (exitCode != 0) { - printf("Failed to parse command-line."); + std::cerr << "Failed to parse command-line." << std::endl; return exitCode; } - return runTest(opts); + + const int modern_return_code = runTest(opts, false); + if (modern_return_code) { + return modern_return_code; + } + + const std::string filename = + opts.path.substr(opts.path.find_last_of("\\/") + 1); + const bool should_run_legacy = (filename.rfind("legacy_", 0) == 0); + if (should_run_legacy) { + return runTest(opts, true); + } } catch (const std::exception& e) { - printf("Unhandled exception:\n%s\n", e.what()); + std::cerr << "Unhandled exception:" << std::endl << e.what() << std::endl; return 1; } } diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 38aab7838..0c1e88d21 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1540,19 +1540,45 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { // larger than the maximum supported value of an integer then // we decode the number as a double. Location current = token.start_; - bool isNegative = *current == '-'; - if (isNegative) + const bool isNegative = *current == '-'; + if (isNegative) { ++current; + } - static constexpr auto positive_threshold = Value::maxLargestUInt / 10; - static constexpr auto positive_last_digit = Value::maxLargestUInt % 10; - static constexpr auto negative_threshold = - Value::LargestUInt(Value::minLargestInt) / 10; - static constexpr auto negative_last_digit = - Value::LargestUInt(Value::minLargestInt) % 10; - - const auto threshold = isNegative ? negative_threshold : positive_threshold; - const auto last_digit = + // We assume we can represent the largest and smallest integer types as + // unsigned integers with separate sign. This is only true if they can fit + // into an unsigned integer. + static_assert(Value::maxLargestInt <= Value::maxLargestUInt, + "Int must be smaller than UInt"); + + // We need to convert minLargestInt into a positive number. The easiest way + // to do this conversion is to assume our "threshold" value of minLargestInt + // divided by 10 can fit in maxLargestInt when absolute valued. This should + // be a safe assumption. + static_assert(Value::minLargestInt <= -Value::maxLargestInt, + "The absolute value of minLargestInt must be greater than or " + "equal to maxLargestInt"); + static_assert(Value::minLargestInt / 10 >= -Value::maxLargestInt, + "The absolute value of minLargestInt must be only 1 magnitude " + "larger than maxLargest Int"); + + static constexpr Value::LargestUInt positive_threshold = + Value::maxLargestUInt / 10; + static constexpr Value::UInt positive_last_digit = Value::maxLargestUInt % 10; + + // For the negative values, we have to be more careful. Since typically + // -Value::minLargestInt will cause an overflow, we first divide by 10 and + // then take the inverse. This assumes that minLargestInt is only a single + // power of 10 different in magnitude, which we check above. For the last + // digit, we take the modulus before negating for the same reason. + static constexpr Value::LargestUInt negative_threshold = + Value::LargestUInt(-(Value::minLargestInt / 10)); + static constexpr Value::UInt negative_last_digit = + Value::UInt(-(Value::minLargestInt % 10)); + + const Value::LargestUInt threshold = + isNegative ? negative_threshold : positive_threshold; + const Value::UInt max_last_digit = isNegative ? negative_last_digit : positive_last_digit; Value::LargestUInt value = 0; @@ -1561,26 +1587,30 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (c < '0' || c > '9') return decodeDouble(token, decoded); - const auto digit(static_cast(c - '0')); + const Value::UInt digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, meaing value == threshold, // b) this is the last digit, or // c) it's small enough to fit in that rounding delta, we're okay. // Otherwise treat this number as a double to avoid overflow. - if (value > threshold || current != token.end_ || digit > last_digit) { + if (value > threshold || current != token.end_ || + digit > max_last_digit) { return decodeDouble(token, decoded); } } value = value * 10 + digit; } - if (isNegative) - decoded = -Value::LargestInt(value); - else if (value <= Value::LargestUInt(Value::maxLargestInt)) + if (isNegative) { + // We use the same magnitude assumption here, just in case. + const Value::UInt last_digit = static_cast(value % 10); + decoded = -Value::LargestInt(value / 10) * 10 - last_digit; + } else if (value <= Value::LargestUInt(Value::maxLargestInt)) { decoded = Value::LargestInt(value); - else + } else { decoded = value; + } return true; } @@ -1597,37 +1627,12 @@ bool OurReader::decodeDouble(Token& token) { bool OurReader::decodeDouble(Token& token, Value& decoded) { double value = 0; - const int bufferSize = 32; - int count; - ptrdiff_t const length = token.end_ - token.start_; - - // Sanity check to avoid buffer overflow exploits. - if (length < 0) { - return addError("Unable to parse token length", token); - } - auto const ulength = static_cast(length); - - // Avoid using a string constant for the format control string given to - // sscanf, as this can cause hard to debug crashes on OS X. See here for more - // info: - // - // http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html - char format[] = "%lf"; - - if (length <= bufferSize) { - Char buffer[bufferSize + 1]; - memcpy(buffer, token.start_, ulength); - buffer[length] = 0; - fixNumericLocaleInput(buffer, buffer + length); - count = sscanf(buffer, format, &value); - } else { - String buffer(token.start_, token.end_); - count = sscanf(buffer.c_str(), format, &value); - } - - if (count != 1) + const String buffer(token.start_, token.end_); + IStringStream is(buffer); + if (!(is >> value)) { return addError( "'" + String(token.start_, token.end_) + "' is not a number.", token); + } decoded = value; return true; } @@ -1649,9 +1654,9 @@ bool OurReader::decodeString(Token& token, String& decoded) { Location end = token.end_ - 1; // do not include '"' while (current != end) { Char c = *current++; - if (c == '"') + if (c == '"') { break; - else if (c == '\\') { + } else if (c == '\\') { if (current == end) return addError("Empty escape sequence in string", token, current); Char escape = *current++; diff --git a/test/data/test_array_01.expected b/test/data/legacy_test_array_01.expected similarity index 100% rename from test/data/test_array_01.expected rename to test/data/legacy_test_array_01.expected diff --git a/test/data/test_array_01.json b/test/data/legacy_test_array_01.json similarity index 100% rename from test/data/test_array_01.json rename to test/data/legacy_test_array_01.json diff --git a/test/data/test_array_02.expected b/test/data/legacy_test_array_02.expected similarity index 100% rename from test/data/test_array_02.expected rename to test/data/legacy_test_array_02.expected diff --git a/test/data/test_array_02.json b/test/data/legacy_test_array_02.json similarity index 100% rename from test/data/test_array_02.json rename to test/data/legacy_test_array_02.json diff --git a/test/data/test_array_03.expected b/test/data/legacy_test_array_03.expected similarity index 100% rename from test/data/test_array_03.expected rename to test/data/legacy_test_array_03.expected diff --git a/test/data/test_array_03.json b/test/data/legacy_test_array_03.json similarity index 100% rename from test/data/test_array_03.json rename to test/data/legacy_test_array_03.json diff --git a/test/data/test_array_04.expected b/test/data/legacy_test_array_04.expected similarity index 100% rename from test/data/test_array_04.expected rename to test/data/legacy_test_array_04.expected diff --git a/test/data/test_array_04.json b/test/data/legacy_test_array_04.json similarity index 100% rename from test/data/test_array_04.json rename to test/data/legacy_test_array_04.json diff --git a/test/data/test_array_05.expected b/test/data/legacy_test_array_05.expected similarity index 100% rename from test/data/test_array_05.expected rename to test/data/legacy_test_array_05.expected diff --git a/test/data/test_array_05.json b/test/data/legacy_test_array_05.json similarity index 100% rename from test/data/test_array_05.json rename to test/data/legacy_test_array_05.json diff --git a/test/data/test_array_06.expected b/test/data/legacy_test_array_06.expected similarity index 100% rename from test/data/test_array_06.expected rename to test/data/legacy_test_array_06.expected diff --git a/test/data/test_array_06.json b/test/data/legacy_test_array_06.json similarity index 100% rename from test/data/test_array_06.json rename to test/data/legacy_test_array_06.json diff --git a/test/data/test_array_07.expected b/test/data/legacy_test_array_07.expected similarity index 100% rename from test/data/test_array_07.expected rename to test/data/legacy_test_array_07.expected diff --git a/test/data/test_array_07.json b/test/data/legacy_test_array_07.json similarity index 100% rename from test/data/test_array_07.json rename to test/data/legacy_test_array_07.json diff --git a/test/data/test_basic_01.expected b/test/data/legacy_test_basic_01.expected similarity index 100% rename from test/data/test_basic_01.expected rename to test/data/legacy_test_basic_01.expected diff --git a/test/data/test_basic_01.json b/test/data/legacy_test_basic_01.json similarity index 100% rename from test/data/test_basic_01.json rename to test/data/legacy_test_basic_01.json diff --git a/test/data/test_basic_02.expected b/test/data/legacy_test_basic_02.expected similarity index 100% rename from test/data/test_basic_02.expected rename to test/data/legacy_test_basic_02.expected diff --git a/test/data/test_basic_02.json b/test/data/legacy_test_basic_02.json similarity index 100% rename from test/data/test_basic_02.json rename to test/data/legacy_test_basic_02.json diff --git a/test/data/test_basic_03.expected b/test/data/legacy_test_basic_03.expected similarity index 100% rename from test/data/test_basic_03.expected rename to test/data/legacy_test_basic_03.expected diff --git a/test/data/test_basic_03.json b/test/data/legacy_test_basic_03.json similarity index 100% rename from test/data/test_basic_03.json rename to test/data/legacy_test_basic_03.json diff --git a/test/data/test_basic_04.expected b/test/data/legacy_test_basic_04.expected similarity index 100% rename from test/data/test_basic_04.expected rename to test/data/legacy_test_basic_04.expected diff --git a/test/data/test_basic_04.json b/test/data/legacy_test_basic_04.json similarity index 100% rename from test/data/test_basic_04.json rename to test/data/legacy_test_basic_04.json diff --git a/test/data/test_basic_05.expected b/test/data/legacy_test_basic_05.expected similarity index 100% rename from test/data/test_basic_05.expected rename to test/data/legacy_test_basic_05.expected diff --git a/test/data/test_basic_05.json b/test/data/legacy_test_basic_05.json similarity index 100% rename from test/data/test_basic_05.json rename to test/data/legacy_test_basic_05.json diff --git a/test/data/test_basic_06.expected b/test/data/legacy_test_basic_06.expected similarity index 100% rename from test/data/test_basic_06.expected rename to test/data/legacy_test_basic_06.expected diff --git a/test/data/test_basic_06.json b/test/data/legacy_test_basic_06.json similarity index 100% rename from test/data/test_basic_06.json rename to test/data/legacy_test_basic_06.json diff --git a/test/data/test_basic_07.expected b/test/data/legacy_test_basic_07.expected similarity index 100% rename from test/data/test_basic_07.expected rename to test/data/legacy_test_basic_07.expected diff --git a/test/data/test_basic_07.json b/test/data/legacy_test_basic_07.json similarity index 100% rename from test/data/test_basic_07.json rename to test/data/legacy_test_basic_07.json diff --git a/test/data/test_basic_08.expected b/test/data/legacy_test_basic_08.expected similarity index 100% rename from test/data/test_basic_08.expected rename to test/data/legacy_test_basic_08.expected diff --git a/test/data/test_basic_08.json b/test/data/legacy_test_basic_08.json similarity index 100% rename from test/data/test_basic_08.json rename to test/data/legacy_test_basic_08.json diff --git a/test/data/test_basic_09.expected b/test/data/legacy_test_basic_09.expected similarity index 100% rename from test/data/test_basic_09.expected rename to test/data/legacy_test_basic_09.expected diff --git a/test/data/test_basic_09.json b/test/data/legacy_test_basic_09.json similarity index 100% rename from test/data/test_basic_09.json rename to test/data/legacy_test_basic_09.json diff --git a/test/data/test_comment_00.expected b/test/data/legacy_test_comment_00.expected similarity index 100% rename from test/data/test_comment_00.expected rename to test/data/legacy_test_comment_00.expected diff --git a/test/data/test_comment_00.json b/test/data/legacy_test_comment_00.json similarity index 100% rename from test/data/test_comment_00.json rename to test/data/legacy_test_comment_00.json diff --git a/test/data/test_comment_01.expected b/test/data/legacy_test_comment_01.expected similarity index 100% rename from test/data/test_comment_01.expected rename to test/data/legacy_test_comment_01.expected diff --git a/test/data/test_comment_01.json b/test/data/legacy_test_comment_01.json similarity index 100% rename from test/data/test_comment_01.json rename to test/data/legacy_test_comment_01.json diff --git a/test/data/test_comment_02.expected b/test/data/legacy_test_comment_02.expected similarity index 100% rename from test/data/test_comment_02.expected rename to test/data/legacy_test_comment_02.expected diff --git a/test/data/test_comment_02.json b/test/data/legacy_test_comment_02.json similarity index 100% rename from test/data/test_comment_02.json rename to test/data/legacy_test_comment_02.json diff --git a/test/data/test_complex_01.expected b/test/data/legacy_test_complex_01.expected similarity index 100% rename from test/data/test_complex_01.expected rename to test/data/legacy_test_complex_01.expected diff --git a/test/data/test_complex_01.json b/test/data/legacy_test_complex_01.json similarity index 100% rename from test/data/test_complex_01.json rename to test/data/legacy_test_complex_01.json diff --git a/test/data/test_integer_01.expected b/test/data/legacy_test_integer_01.expected similarity index 100% rename from test/data/test_integer_01.expected rename to test/data/legacy_test_integer_01.expected diff --git a/test/data/test_integer_01.json b/test/data/legacy_test_integer_01.json similarity index 100% rename from test/data/test_integer_01.json rename to test/data/legacy_test_integer_01.json diff --git a/test/data/test_integer_02.expected b/test/data/legacy_test_integer_02.expected similarity index 100% rename from test/data/test_integer_02.expected rename to test/data/legacy_test_integer_02.expected diff --git a/test/data/test_integer_02.json b/test/data/legacy_test_integer_02.json similarity index 100% rename from test/data/test_integer_02.json rename to test/data/legacy_test_integer_02.json diff --git a/test/data/test_integer_03.expected b/test/data/legacy_test_integer_03.expected similarity index 100% rename from test/data/test_integer_03.expected rename to test/data/legacy_test_integer_03.expected diff --git a/test/data/test_integer_03.json b/test/data/legacy_test_integer_03.json similarity index 100% rename from test/data/test_integer_03.json rename to test/data/legacy_test_integer_03.json diff --git a/test/data/test_integer_04.expected b/test/data/legacy_test_integer_04.expected similarity index 100% rename from test/data/test_integer_04.expected rename to test/data/legacy_test_integer_04.expected diff --git a/test/data/test_integer_04.json b/test/data/legacy_test_integer_04.json similarity index 100% rename from test/data/test_integer_04.json rename to test/data/legacy_test_integer_04.json diff --git a/test/data/test_integer_05.expected b/test/data/legacy_test_integer_05.expected similarity index 100% rename from test/data/test_integer_05.expected rename to test/data/legacy_test_integer_05.expected diff --git a/test/data/test_integer_05.json b/test/data/legacy_test_integer_05.json similarity index 100% rename from test/data/test_integer_05.json rename to test/data/legacy_test_integer_05.json diff --git a/test/data/test_integer_06_64bits.expected b/test/data/legacy_test_integer_06_64bits.expected similarity index 100% rename from test/data/test_integer_06_64bits.expected rename to test/data/legacy_test_integer_06_64bits.expected diff --git a/test/data/test_integer_06_64bits.json b/test/data/legacy_test_integer_06_64bits.json similarity index 100% rename from test/data/test_integer_06_64bits.json rename to test/data/legacy_test_integer_06_64bits.json diff --git a/test/data/test_integer_07_64bits.expected b/test/data/legacy_test_integer_07_64bits.expected similarity index 100% rename from test/data/test_integer_07_64bits.expected rename to test/data/legacy_test_integer_07_64bits.expected diff --git a/test/data/test_integer_07_64bits.json b/test/data/legacy_test_integer_07_64bits.json similarity index 100% rename from test/data/test_integer_07_64bits.json rename to test/data/legacy_test_integer_07_64bits.json diff --git a/test/data/test_integer_08_64bits.expected b/test/data/legacy_test_integer_08_64bits.expected similarity index 100% rename from test/data/test_integer_08_64bits.expected rename to test/data/legacy_test_integer_08_64bits.expected diff --git a/test/data/test_integer_08_64bits.json b/test/data/legacy_test_integer_08_64bits.json similarity index 100% rename from test/data/test_integer_08_64bits.json rename to test/data/legacy_test_integer_08_64bits.json diff --git a/test/data/test_large_01.expected b/test/data/legacy_test_large_01.expected similarity index 100% rename from test/data/test_large_01.expected rename to test/data/legacy_test_large_01.expected diff --git a/test/data/test_large_01.json b/test/data/legacy_test_large_01.json similarity index 100% rename from test/data/test_large_01.json rename to test/data/legacy_test_large_01.json diff --git a/test/data/test_object_01.expected b/test/data/legacy_test_object_01.expected similarity index 100% rename from test/data/test_object_01.expected rename to test/data/legacy_test_object_01.expected diff --git a/test/data/test_object_01.json b/test/data/legacy_test_object_01.json similarity index 100% rename from test/data/test_object_01.json rename to test/data/legacy_test_object_01.json diff --git a/test/data/test_object_02.expected b/test/data/legacy_test_object_02.expected similarity index 100% rename from test/data/test_object_02.expected rename to test/data/legacy_test_object_02.expected diff --git a/test/data/test_object_02.json b/test/data/legacy_test_object_02.json similarity index 100% rename from test/data/test_object_02.json rename to test/data/legacy_test_object_02.json diff --git a/test/data/test_object_03.expected b/test/data/legacy_test_object_03.expected similarity index 100% rename from test/data/test_object_03.expected rename to test/data/legacy_test_object_03.expected diff --git a/test/data/test_object_03.json b/test/data/legacy_test_object_03.json similarity index 100% rename from test/data/test_object_03.json rename to test/data/legacy_test_object_03.json diff --git a/test/data/test_object_04.expected b/test/data/legacy_test_object_04.expected similarity index 100% rename from test/data/test_object_04.expected rename to test/data/legacy_test_object_04.expected diff --git a/test/data/test_object_04.json b/test/data/legacy_test_object_04.json similarity index 100% rename from test/data/test_object_04.json rename to test/data/legacy_test_object_04.json diff --git a/test/data/test_preserve_comment_01.expected b/test/data/legacy_test_preserve_comment_01.expected similarity index 100% rename from test/data/test_preserve_comment_01.expected rename to test/data/legacy_test_preserve_comment_01.expected diff --git a/test/data/test_preserve_comment_01.json b/test/data/legacy_test_preserve_comment_01.json similarity index 100% rename from test/data/test_preserve_comment_01.json rename to test/data/legacy_test_preserve_comment_01.json diff --git a/test/data/test_real_01.expected b/test/data/legacy_test_real_01.expected similarity index 100% rename from test/data/test_real_01.expected rename to test/data/legacy_test_real_01.expected diff --git a/test/data/test_real_01.json b/test/data/legacy_test_real_01.json similarity index 100% rename from test/data/test_real_01.json rename to test/data/legacy_test_real_01.json diff --git a/test/data/test_real_02.expected b/test/data/legacy_test_real_02.expected similarity index 100% rename from test/data/test_real_02.expected rename to test/data/legacy_test_real_02.expected diff --git a/test/data/test_real_02.json b/test/data/legacy_test_real_02.json similarity index 100% rename from test/data/test_real_02.json rename to test/data/legacy_test_real_02.json diff --git a/test/data/test_real_03.expected b/test/data/legacy_test_real_03.expected similarity index 100% rename from test/data/test_real_03.expected rename to test/data/legacy_test_real_03.expected diff --git a/test/data/test_real_03.json b/test/data/legacy_test_real_03.json similarity index 100% rename from test/data/test_real_03.json rename to test/data/legacy_test_real_03.json diff --git a/test/data/test_real_04.expected b/test/data/legacy_test_real_04.expected similarity index 100% rename from test/data/test_real_04.expected rename to test/data/legacy_test_real_04.expected diff --git a/test/data/test_real_04.json b/test/data/legacy_test_real_04.json similarity index 100% rename from test/data/test_real_04.json rename to test/data/legacy_test_real_04.json diff --git a/test/data/test_real_05.expected b/test/data/legacy_test_real_05.expected similarity index 100% rename from test/data/test_real_05.expected rename to test/data/legacy_test_real_05.expected diff --git a/test/data/test_real_05.json b/test/data/legacy_test_real_05.json similarity index 100% rename from test/data/test_real_05.json rename to test/data/legacy_test_real_05.json diff --git a/test/data/test_real_06.expected b/test/data/legacy_test_real_06.expected similarity index 100% rename from test/data/test_real_06.expected rename to test/data/legacy_test_real_06.expected diff --git a/test/data/test_real_06.json b/test/data/legacy_test_real_06.json similarity index 100% rename from test/data/test_real_06.json rename to test/data/legacy_test_real_06.json diff --git a/test/data/test_real_07.expected b/test/data/legacy_test_real_07.expected similarity index 100% rename from test/data/test_real_07.expected rename to test/data/legacy_test_real_07.expected diff --git a/test/data/test_real_07.json b/test/data/legacy_test_real_07.json similarity index 100% rename from test/data/test_real_07.json rename to test/data/legacy_test_real_07.json diff --git a/test/data/test_real_08.expected b/test/data/legacy_test_real_08.expected similarity index 100% rename from test/data/test_real_08.expected rename to test/data/legacy_test_real_08.expected diff --git a/test/data/test_real_08.json b/test/data/legacy_test_real_08.json similarity index 100% rename from test/data/test_real_08.json rename to test/data/legacy_test_real_08.json diff --git a/test/data/test_real_09.expected b/test/data/legacy_test_real_09.expected similarity index 100% rename from test/data/test_real_09.expected rename to test/data/legacy_test_real_09.expected diff --git a/test/data/test_real_09.json b/test/data/legacy_test_real_09.json similarity index 100% rename from test/data/test_real_09.json rename to test/data/legacy_test_real_09.json diff --git a/test/data/test_real_10.expected b/test/data/legacy_test_real_10.expected similarity index 100% rename from test/data/test_real_10.expected rename to test/data/legacy_test_real_10.expected diff --git a/test/data/test_real_10.json b/test/data/legacy_test_real_10.json similarity index 100% rename from test/data/test_real_10.json rename to test/data/legacy_test_real_10.json diff --git a/test/data/test_real_11.expected b/test/data/legacy_test_real_11.expected similarity index 100% rename from test/data/test_real_11.expected rename to test/data/legacy_test_real_11.expected diff --git a/test/data/test_real_11.json b/test/data/legacy_test_real_11.json similarity index 100% rename from test/data/test_real_11.json rename to test/data/legacy_test_real_11.json diff --git a/test/data/test_real_12.expected b/test/data/legacy_test_real_12.expected similarity index 100% rename from test/data/test_real_12.expected rename to test/data/legacy_test_real_12.expected diff --git a/test/data/test_real_12.json b/test/data/legacy_test_real_12.json similarity index 100% rename from test/data/test_real_12.json rename to test/data/legacy_test_real_12.json diff --git a/test/data/test_string_01.expected b/test/data/legacy_test_string_01.expected similarity index 100% rename from test/data/test_string_01.expected rename to test/data/legacy_test_string_01.expected diff --git a/test/data/test_string_01.json b/test/data/legacy_test_string_01.json similarity index 100% rename from test/data/test_string_01.json rename to test/data/legacy_test_string_01.json diff --git a/test/data/test_string_02.expected b/test/data/legacy_test_string_02.expected similarity index 100% rename from test/data/test_string_02.expected rename to test/data/legacy_test_string_02.expected diff --git a/test/data/test_string_02.json b/test/data/legacy_test_string_02.json similarity index 100% rename from test/data/test_string_02.json rename to test/data/legacy_test_string_02.json diff --git a/test/data/test_string_03.expected b/test/data/legacy_test_string_03.expected similarity index 100% rename from test/data/test_string_03.expected rename to test/data/legacy_test_string_03.expected diff --git a/test/data/test_string_03.json b/test/data/legacy_test_string_03.json similarity index 100% rename from test/data/test_string_03.json rename to test/data/legacy_test_string_03.json diff --git a/test/data/test_string_04.expected b/test/data/legacy_test_string_04.expected similarity index 100% rename from test/data/test_string_04.expected rename to test/data/legacy_test_string_04.expected diff --git a/test/data/test_string_04.json b/test/data/legacy_test_string_04.json similarity index 100% rename from test/data/test_string_04.json rename to test/data/legacy_test_string_04.json diff --git a/test/data/test_string_05.expected b/test/data/legacy_test_string_05.expected similarity index 100% rename from test/data/test_string_05.expected rename to test/data/legacy_test_string_05.expected diff --git a/test/data/test_string_05.json b/test/data/legacy_test_string_05.json similarity index 100% rename from test/data/test_string_05.json rename to test/data/legacy_test_string_05.json diff --git a/test/data/test_string_unicode_01.expected b/test/data/legacy_test_string_unicode_01.expected similarity index 100% rename from test/data/test_string_unicode_01.expected rename to test/data/legacy_test_string_unicode_01.expected diff --git a/test/data/test_string_unicode_01.json b/test/data/legacy_test_string_unicode_01.json similarity index 100% rename from test/data/test_string_unicode_01.json rename to test/data/legacy_test_string_unicode_01.json diff --git a/test/data/test_string_unicode_02.expected b/test/data/legacy_test_string_unicode_02.expected similarity index 100% rename from test/data/test_string_unicode_02.expected rename to test/data/legacy_test_string_unicode_02.expected diff --git a/test/data/test_string_unicode_02.json b/test/data/legacy_test_string_unicode_02.json similarity index 100% rename from test/data/test_string_unicode_02.json rename to test/data/legacy_test_string_unicode_02.json diff --git a/test/data/test_string_unicode_03.expected b/test/data/legacy_test_string_unicode_03.expected similarity index 100% rename from test/data/test_string_unicode_03.expected rename to test/data/legacy_test_string_unicode_03.expected diff --git a/test/data/test_string_unicode_03.json b/test/data/legacy_test_string_unicode_03.json similarity index 100% rename from test/data/test_string_unicode_03.json rename to test/data/legacy_test_string_unicode_03.json diff --git a/test/data/test_string_unicode_04.expected b/test/data/legacy_test_string_unicode_04.expected similarity index 100% rename from test/data/test_string_unicode_04.expected rename to test/data/legacy_test_string_unicode_04.expected diff --git a/test/data/test_string_unicode_04.json b/test/data/legacy_test_string_unicode_04.json similarity index 100% rename from test/data/test_string_unicode_04.json rename to test/data/legacy_test_string_unicode_04.json diff --git a/test/data/test_string_unicode_05.expected b/test/data/legacy_test_string_unicode_05.expected similarity index 100% rename from test/data/test_string_unicode_05.expected rename to test/data/legacy_test_string_unicode_05.expected diff --git a/test/data/test_string_unicode_05.json b/test/data/legacy_test_string_unicode_05.json similarity index 100% rename from test/data/test_string_unicode_05.json rename to test/data/legacy_test_string_unicode_05.json From 53c8e2cb3b0f366dfdf7a8a93ad94f9d2a8139c5 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 11 Nov 2019 22:43:52 -0500 Subject: [PATCH 245/410] Issue 1066 (#1080) Implemented `as()` and `is()` with accompanying tests --- include/json/value.h | 39 +++++++++++++++++++++++++++++++ src/test_lib_json/main.cpp | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index d0af7116b..bf4f9c443 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -412,6 +412,10 @@ class JSON_API Value { bool isArray() const; bool isObject() const; + /// The `as` and `is` member function templates and specializations. + template T as() const = delete; + template bool is() const = delete; + bool isConvertibleTo(ValueType other) const; /// Number of values in array or object @@ -673,6 +677,41 @@ class JSON_API Value { ptrdiff_t limit_; }; +template <> inline bool Value::as() const { return asBool(); } +template <> inline bool Value::is() const { return isBool(); } + +template <> inline Int Value::as() const { return asInt(); } +template <> inline bool Value::is() const { return isInt(); } + +template <> inline UInt Value::as() const { return asUInt(); } +template <> inline bool Value::is() const { return isUInt(); } + +#if defined(JSON_HAS_INT64) +template <> inline Int64 Value::as() const { return asInt64(); } +template <> inline bool Value::is() const { return isInt64(); } + +template <> inline UInt64 Value::as() const { return asUInt64(); } +template <> inline bool Value::is() const { return isUInt64(); } +#endif + +template <> inline double Value::as() const { return asDouble(); } +template <> inline bool Value::is() const { return isDouble(); } + +template <> inline String Value::as() const { return asString(); } +template <> inline bool Value::is() const { return isString(); } + +/// These `as` specializations are type conversions, and do not have a +/// corresponding `is`. +template <> inline float Value::as() const { return asFloat(); } +template <> inline const char* Value::as() const { + return asCString(); +} +#ifdef JSON_USE_CPPTL +template <> inline CppTL::ConstString Value::as() const { + return asConstString(); +} +#endif + /** \brief Experimental and untested: represents an element of the "path" to * access a node. */ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index fff5b2ce1..c0cc00e5a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3502,6 +3502,53 @@ int main(int argc, const char* argv[]) { return runner.runCommandLine(argc, argv); } +struct MemberTemplateAs : JsonTest::TestCase { + template + JsonTest::TestResult& EqEval(T v, F f) const { + const Json::Value j = v; + return JSONTEST_ASSERT_EQUAL(j.as(), f(j)); + } +}; + +JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) { + const Json::Value jstr = "hello world"; + JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asCString()); + JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asString()); +#ifdef JSON_USE_CPPTL + JSONTEST_ASSERT_STRING_EQUAL(js.as(), js.asConstString()); +#endif + EqEval(Json::Int(64), [](const Json::Value& j) { return j.asInt(); }); + EqEval(Json::UInt(64), [](const Json::Value& j) { return j.asUInt(); }); +#if defined(JSON_HAS_INT64) + EqEval(Json::Int64(64), [](const Json::Value& j) { return j.asInt64(); }); + EqEval(Json::UInt64(64), [](const Json::Value& j) { return j.asUInt64(); }); +#endif // if defined(JSON_HAS_INT64) + EqEval(Json::LargestInt(64), + [](const Json::Value& j) { return j.asLargestInt(); }); + EqEval(Json::LargestUInt(64), + [](const Json::Value& j) { return j.asLargestUInt(); }); + + EqEval(69.69f, [](const Json::Value& j) { return j.asFloat(); }); + EqEval(69.69, [](const Json::Value& j) { return j.asDouble(); }); + EqEval(false, [](const Json::Value& j) { return j.asBool(); }); + EqEval(true, [](const Json::Value& j) { return j.asBool(); }); +} + +class MemberTemplateIs : public JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(MemberTemplateIs, BehavesSameAsNamedIs) { + const Json::Value values[] = {true, 142, 40.63, "hello world"}; + for (const Json::Value& j : values) { + JSONTEST_ASSERT_EQUAL(j.is(), j.isBool()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isInt()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isInt64()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isUInt()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isUInt64()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isDouble()); + JSONTEST_ASSERT_EQUAL(j.is(), j.isString()); + } +} + #if defined(__GNUC__) #pragma GCC diagnostic pop #endif From d2e6a971f4544c55b8e3b25cf96db266971b778f Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Tue, 12 Nov 2019 02:16:54 -0500 Subject: [PATCH 246/410] some test coverage for Value::iterator (#1093) --- src/test_lib_json/main.cpp | 88 ++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 9 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c0cc00e5a..f2e4d4cd2 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -3394,18 +3395,85 @@ JSONTEST_FIXTURE_LOCAL(BuilderTest, settings) { struct IteratorTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, convert) { + Json::Value j; + const Json::Value& cj = j; + auto it = j.begin(); + Json::Value::const_iterator cit; + cit = it; + JSONTEST_ASSERT(cit == cj.begin()); +} + +JSONTEST_FIXTURE_LOCAL(IteratorTest, decrement) { Json::Value json; json["k1"] = "a"; json["k2"] = "b"; - int dist = 0; - Json::String str; - for (Json::ValueIterator it = json.begin(); it != json.end(); ++it) { - dist = it - json.begin(); - str = it->asString().c_str(); + std::vector values; + for (auto it = json.end(); it != json.begin();) { + --it; + values.push_back(it->asString()); + } + JSONTEST_ASSERT((values == std::vector{"b", "a"})); +} + +JSONTEST_FIXTURE_LOCAL(IteratorTest, reverseIterator) { + Json::Value json; + json["k1"] = "a"; + json["k2"] = "b"; + std::vector values; + using Iter = decltype(json.begin()); + auto re = std::reverse_iterator(json.begin()); + for (auto it = std::reverse_iterator(json.end()); it != re; ++it) { + values.push_back(it->asString()); + } + JSONTEST_ASSERT((values == std::vector{"b", "a"})); +} + +JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { + { + Json::Value json; + json["k1"] = "a"; + json["k2"] = "b"; + int i = 0; + auto it = json.begin(); + for (;; ++it, ++i) { + auto dist = it - json.begin(); + JSONTEST_ASSERT_EQUAL(i, dist); + if (it == json.end()) + break; + } + } + { + Json::Value empty; + JSONTEST_ASSERT_EQUAL(empty.end() - empty.end(), 0); + JSONTEST_ASSERT_EQUAL(empty.end() - empty.begin(), 0); } - JSONTEST_ASSERT_EQUAL(1, dist); - JSONTEST_ASSERT_STRING_EQUAL("b", str); +} + +JSONTEST_FIXTURE_LOCAL(IteratorTest, nullValues) { + { + Json::Value json; + auto end = json.end(); + auto endCopy = end; + JSONTEST_ASSERT(endCopy == end); + endCopy = end; + JSONTEST_ASSERT(endCopy == end); + } + { + // Same test, now with const Value. + const Json::Value json; + auto end = json.end(); + auto endCopy = end; + JSONTEST_ASSERT(endCopy == end); + endCopy = end; + JSONTEST_ASSERT(endCopy == end); + } +} + +JSONTEST_FIXTURE_LOCAL(IteratorTest, staticStringKey) { + Json::Value json; + json[Json::StaticString("k1")] = "a"; + JSONTEST_ASSERT_EQUAL(Json::Value("k1"), json.begin().key()); } JSONTEST_FIXTURE_LOCAL(IteratorTest, names) { @@ -3416,11 +3484,13 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, names) { JSONTEST_ASSERT(it != json.end()); JSONTEST_ASSERT_EQUAL(Json::Value("k1"), it.key()); JSONTEST_ASSERT_STRING_EQUAL("k1", it.name()); + JSONTEST_ASSERT_STRING_EQUAL("k1", it.memberName()); JSONTEST_ASSERT_EQUAL(-1, it.index()); ++it; JSONTEST_ASSERT(it != json.end()); JSONTEST_ASSERT_EQUAL(Json::Value("k2"), it.key()); JSONTEST_ASSERT_STRING_EQUAL("k2", it.name()); + JSONTEST_ASSERT_STRING_EQUAL("k2", it.memberName()); JSONTEST_ASSERT_EQUAL(-1, it.index()); ++it; JSONTEST_ASSERT(it == json.end()); @@ -3444,7 +3514,7 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, indexes) { JSONTEST_ASSERT(it == json.end()); } -JSONTEST_FIXTURE_LOCAL(IteratorTest, const) { +JSONTEST_FIXTURE_LOCAL(IteratorTest, constness) { Json::Value const v; JSONTEST_ASSERT_THROWS( Json::Value::iterator it(v.begin())); // Compile, but throw. From 01db7b7430e6e448cecbd541ab105a9d2f0a982c Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Wed, 16 Oct 2019 17:07:41 +0200 Subject: [PATCH 247/410] Allow trailing comma in objects --- include/json/json_features.h | 5 +++++ include/json/reader.h | 2 ++ src/lib_json/json_reader.cpp | 10 ++++++++-- src/test_lib_json/fuzz.cpp | 1 + test/data/fail_test_object_01.json | 1 + test/data/test_object_05.expected | 2 ++ test/data/test_object_05.json | 1 + 7 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/data/fail_test_object_01.json create mode 100644 test/data/test_object_05.expected create mode 100644 test/data/test_object_05.json diff --git a/include/json/json_features.h b/include/json/json_features.h index ba25e8da6..8ba1e8fd3 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -23,6 +23,7 @@ class JSON_API Features { /** \brief A configuration that allows all features and assumes all strings * are UTF-8. * - C & C++ comments are allowed + * - Trailing commas in objects and arrays are allowed. * - Root object can be any JSON value * - Assumes Value strings are encoded in UTF-8 */ @@ -31,6 +32,7 @@ class JSON_API Features { /** \brief A configuration that is strictly compatible with the JSON * specification. * - Comments are forbidden. + * - Trailing commas in objects and arrays are forbidden. * - Root object must be either an array or an object value. * - Assumes Value strings are encoded in UTF-8 */ @@ -43,6 +45,9 @@ class JSON_API Features { /// \c true if comments are allowed. Default: \c true. bool allowComments_{true}; + /// \c true if trailing commas in objects and arrays are allowed. Default \c true. + bool allowTrailingCommas_{true}; + /// \c true if root must be either an array or an object value. Default: \c /// false. bool strictRoot_{false}; diff --git a/include/json/reader.h b/include/json/reader.h index 359c1eb89..0b3817649 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -299,6 +299,8 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * if allowComments is false. * - `"allowComments": false or true` * - true if comments are allowed. + * - `"allowTrailingCommas": false or true` + * - true if trailing commas in objects and arrays are allowed. * - `"strictRoot": false or true` * - true if root must be either an array or an object value * - `"allowDroppedNullPlaceholders": false or true` diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 0c1e88d21..e53979303 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -67,6 +67,7 @@ Features Features::all() { return {}; } Features Features::strictMode() { Features features; features.allowComments_ = false; + features.allowTrailingCommas_ = false; features.strictRoot_ = true; features.allowDroppedNullPlaceholders_ = false; features.allowNumericKeys_ = false; @@ -454,7 +455,7 @@ bool Reader::readObject(Token& token) { initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; - if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma return true; name.clear(); if (tokenName.type_ == tokenString) { @@ -863,6 +864,7 @@ class OurFeatures { public: static OurFeatures all(); bool allowComments_; + bool allowTrailingCommas_; bool strictRoot_; bool allowDroppedNullPlaceholders_; bool allowNumericKeys_; @@ -1437,7 +1439,7 @@ bool OurReader::readObject(Token& token) { initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; - if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object + if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma return true; name.clear(); if (tokenName.type_ == tokenString) { @@ -1866,6 +1868,7 @@ CharReader* CharReaderBuilder::newCharReader() const { bool collectComments = settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); features.allowComments_ = settings_["allowComments"].asBool(); + features.allowTrailingCommas_ = settings_["allowTrailingCommas"].asBool(); features.strictRoot_ = settings_["strictRoot"].asBool(); features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); @@ -1884,6 +1887,7 @@ static void getValidReaderKeys(std::set* valid_keys) { valid_keys->clear(); valid_keys->insert("collectComments"); valid_keys->insert("allowComments"); + valid_keys->insert("allowTrailingCommas"); valid_keys->insert("strictRoot"); valid_keys->insert("allowDroppedNullPlaceholders"); valid_keys->insert("allowNumericKeys"); @@ -1917,6 +1921,7 @@ Value& CharReaderBuilder::operator[](const String& key) { void CharReaderBuilder::strictMode(Json::Value* settings) { //! [CharReaderBuilderStrictMode] (*settings)["allowComments"] = false; + (*settings)["allowTrailingCommas"] = false; (*settings)["strictRoot"] = true; (*settings)["allowDroppedNullPlaceholders"] = false; (*settings)["allowNumericKeys"] = false; @@ -1932,6 +1937,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { //! [CharReaderBuilderDefaults] (*settings)["collectComments"] = true; (*settings)["allowComments"] = true; + (*settings)["allowTrailingCommas"] = true; (*settings)["strictRoot"] = false; (*settings)["allowDroppedNullPlaceholders"] = false; (*settings)["allowNumericKeys"] = false; diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index b31c597c8..fe515b16f 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -40,6 +40,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { builder.settings_["rejectDupKeys_"] = hash_settings & (1 << 7); builder.settings_["allowSpecialFloats_"] = hash_settings & (1 << 8); builder.settings_["collectComments"] = hash_settings & (1 << 9); + builder.settings_["allowTrailingCommas_"] = hash_settings & (1 << 10); std::unique_ptr reader(builder.newCharReader()); diff --git a/test/data/fail_test_object_01.json b/test/data/fail_test_object_01.json new file mode 100644 index 000000000..46fd39ab3 --- /dev/null +++ b/test/data/fail_test_object_01.json @@ -0,0 +1 @@ +{ "count" : 1234,, } diff --git a/test/data/test_object_05.expected b/test/data/test_object_05.expected new file mode 100644 index 000000000..79391c2a6 --- /dev/null +++ b/test/data/test_object_05.expected @@ -0,0 +1,2 @@ +.={} +.count=1234 diff --git a/test/data/test_object_05.json b/test/data/test_object_05.json new file mode 100644 index 000000000..c4344b17f --- /dev/null +++ b/test/data/test_object_05.json @@ -0,0 +1 @@ +{ "count" : 1234, } From 554d961625e6857a55d99d29d7136e39b6f5302a Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Thu, 17 Oct 2019 16:03:31 +0200 Subject: [PATCH 248/410] Allow trailing comma in arrays if dropped null placeholders are not allowed --- src/lib_json/json_reader.cpp | 29 +++++++++++++++-------------- test/data/fail_test_array_02.json | 1 + test/data/test_array_08.expected | 2 ++ test/data/test_array_08.json | 1 + 4 files changed, 19 insertions(+), 14 deletions(-) create mode 100644 test/data/fail_test_array_02.json create mode 100644 test/data/test_array_08.expected create mode 100644 test/data/test_array_08.json diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index e53979303..aa788cd69 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -503,15 +503,16 @@ bool Reader::readArray(Token& token) { Value init(arrayValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - skipSpaces(); - if (current_ != end_ && *current_ == ']') // empty array - { - Token endArray; - readToken(endArray); - return true; - } int index = 0; for (;;) { + skipSpaces(); + if (current_ != end_ && *current_ == ']' && (index == 0 || (features_.allowTrailingCommas_ && !features_.allowDroppedNullPlaceholders_))) // empty array or trailing comma + { + Token endArray; + readToken(endArray); + return true; + } + Value& value = currentValue()[index++]; nodes_.push(&value); bool ok = readValue(); @@ -1493,15 +1494,15 @@ bool OurReader::readArray(Token& token) { Value init(arrayValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - skipSpaces(); - if (current_ != end_ && *current_ == ']') // empty array - { - Token endArray; - readToken(endArray); - return true; - } int index = 0; for (;;) { + skipSpaces(); + if (current_ != end_ && *current_ == ']' && (index == 0 || (features_.allowTrailingCommas_ && !features_.allowDroppedNullPlaceholders_))) // empty array or trailing comma + { + Token endArray; + readToken(endArray); + return true; + } Value& value = currentValue()[index++]; nodes_.push(&value); bool ok = readValue(); diff --git a/test/data/fail_test_array_02.json b/test/data/fail_test_array_02.json new file mode 100644 index 000000000..222a1b47c --- /dev/null +++ b/test/data/fail_test_array_02.json @@ -0,0 +1 @@ +[1,,] diff --git a/test/data/test_array_08.expected b/test/data/test_array_08.expected new file mode 100644 index 000000000..ef1f2623d --- /dev/null +++ b/test/data/test_array_08.expected @@ -0,0 +1,2 @@ +.=[] +.[0]=1 diff --git a/test/data/test_array_08.json b/test/data/test_array_08.json new file mode 100644 index 000000000..e8b1a170f --- /dev/null +++ b/test/data/test_array_08.json @@ -0,0 +1 @@ +[1,] From 1c8f7d8ae5f4ed19215f6572f94c527369182fcb Mon Sep 17 00:00:00 2001 From: Jacob Bundgaard Date: Mon, 4 Nov 2019 13:29:17 +0100 Subject: [PATCH 249/410] Run clang-format --- include/json/json_features.h | 3 ++- src/lib_json/json_reader.cpp | 20 ++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/json/json_features.h b/include/json/json_features.h index 8ba1e8fd3..c12d64727 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -45,7 +45,8 @@ class JSON_API Features { /// \c true if comments are allowed. Default: \c true. bool allowComments_{true}; - /// \c true if trailing commas in objects and arrays are allowed. Default \c true. + /// \c true if trailing commas in objects and arrays are allowed. Default \c + /// true. bool allowTrailingCommas_{true}; /// \c true if root must be either an array or an object value. Default: \c diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index aa788cd69..63b693795 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -455,7 +455,9 @@ bool Reader::readObject(Token& token) { initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; - if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma + if (tokenName.type_ == tokenObjectEnd && + (name.empty() || + features_.allowTrailingCommas_)) // empty object or trailing comma return true; name.clear(); if (tokenName.type_ == tokenString) { @@ -506,7 +508,11 @@ bool Reader::readArray(Token& token) { int index = 0; for (;;) { skipSpaces(); - if (current_ != end_ && *current_ == ']' && (index == 0 || (features_.allowTrailingCommas_ && !features_.allowDroppedNullPlaceholders_))) // empty array or trailing comma + if (current_ != end_ && *current_ == ']' && + (index == 0 || + (features_.allowTrailingCommas_ && + !features_.allowDroppedNullPlaceholders_))) // empty array or trailing + // comma { Token endArray; readToken(endArray); @@ -1440,7 +1446,9 @@ bool OurReader::readObject(Token& token) { initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; - if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma + if (tokenName.type_ == tokenObjectEnd && + (name.empty() || + features_.allowTrailingCommas_)) // empty object or trailing comma return true; name.clear(); if (tokenName.type_ == tokenString) { @@ -1497,7 +1505,11 @@ bool OurReader::readArray(Token& token) { int index = 0; for (;;) { skipSpaces(); - if (current_ != end_ && *current_ == ']' && (index == 0 || (features_.allowTrailingCommas_ && !features_.allowDroppedNullPlaceholders_))) // empty array or trailing comma + if (current_ != end_ && *current_ == ']' && + (index == 0 || + (features_.allowTrailingCommas_ && + !features_.allowDroppedNullPlaceholders_))) // empty array or trailing + // comma { Token endArray; readToken(endArray); From 9704cedb20dd8b2c28974cb1eb14ef1740d58c38 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 14 Nov 2019 09:38:11 -0800 Subject: [PATCH 250/410] Issue 1100: Drop CPPTL support CPPTL support is no longer relevant to JsonCpp, and can be removed from the library. This patch removes all mentions of CPPTL, by removing all definitions and code sections conditionally compiled only when JsonCpp is used with CPPTL. Include guards are also renamed to not refer to CPPTL where appropriate. --- include/json/allocator.h | 6 +-- include/json/assertions.h | 6 +-- include/json/autolink.h | 12 ++--- include/json/config.h | 32 ------------- include/json/json_features.h | 6 +-- include/json/reader.h | 6 +-- include/json/value.h | 57 ++-------------------- src/lib_json/json_value.cpp | 74 +---------------------------- src/lib_json/json_valueiterator.inl | 4 -- src/test_lib_json/main.cpp | 3 -- 10 files changed, 21 insertions(+), 185 deletions(-) diff --git a/include/json/allocator.h b/include/json/allocator.h index d5f987e97..0f5c224b9 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED -#define CPPTL_JSON_ALLOCATOR_H_INCLUDED +#ifndef JSON_ALLOCATOR_H_INCLUDED +#define JSON_ALLOCATOR_H_INCLUDED #include #include @@ -86,4 +86,4 @@ bool operator!=(const SecureAllocator&, const SecureAllocator&) { #pragma pack(pop) -#endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED +#endif // JSON_ALLOCATOR_H_INCLUDED diff --git a/include/json/assertions.h b/include/json/assertions.h index 20716b067..9d93238dc 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED -#define CPPTL_JSON_ASSERTIONS_H_INCLUDED +#ifndef JSON_ASSERTIONS_H_INCLUDED +#define JSON_ASSERTIONS_H_INCLUDED #include #include @@ -56,4 +56,4 @@ JSON_FAIL_MESSAGE(message); \ } -#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED +#endif // JSON_ASSERTIONS_H_INCLUDED diff --git a/include/json/autolink.h b/include/json/autolink.h index b2c0f0024..5f04a55bf 100644 --- a/include/json/autolink.h +++ b/include/json/autolink.h @@ -8,16 +8,10 @@ #include "config.h" -#ifdef JSON_IN_CPPTL -#include -#endif - -#if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) && \ - !defined(JSON_IN_CPPTL) -#define CPPTL_AUTOLINK_NAME "json" -#undef CPPTL_AUTOLINK_DLL +#if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) +#define AUTOLINK_NAME "json" #ifdef JSON_DLL -#define CPPTL_AUTOLINK_DLL +#define AUTOLINK_DLL #endif #include "autolink.h" #endif diff --git a/include/json/config.h b/include/json/config.h index cbb5950e2..2b4392c2b 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -14,16 +14,6 @@ #include #include -/// If defined, indicates that json library is embedded in CppTL library. -//# define JSON_IN_CPPTL 1 - -/// If defined, indicates that json may leverage CppTL library -//# define JSON_USE_CPPTL 1 -/// If defined, indicates that cpptl vector based map should be used instead of -/// std::map -/// as Value container. -//# define JSON_USE_CPPTL_SMALLMAP 1 - // If non-zero, the library uses exceptions to report bad input instead of C // assertion macros. The default is to use exceptions. #ifndef JSON_USE_EXCEPTION @@ -40,28 +30,6 @@ /// Remarks: it is automatically defined in the generated amalgamated header. // #define JSON_IS_AMALGAMATION -#ifdef JSON_IN_CPPTL -#include -#ifndef JSON_USE_CPPTL -#define JSON_USE_CPPTL 1 -#endif -#endif - -#ifdef JSON_IN_CPPTL -#define JSON_API CPPTL_API -#elif defined(JSON_DLL_BUILD) -#if defined(_MSC_VER) || defined(__MINGW32__) -#define JSON_API __declspec(dllexport) -#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING -#elif defined(__GNUC__) || defined(__clang__) -#define JSON_API __attribute__((visibility("default"))) -#endif // if defined(_MSC_VER) -#elif defined(JSON_DLL) -#if defined(_MSC_VER) || defined(__MINGW32__) -#define JSON_API __declspec(dllimport) -#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING -#endif // if defined(_MSC_VER) -#endif // ifdef JSON_IN_CPPTL #if !defined(JSON_API) #define JSON_API #endif diff --git a/include/json/json_features.h b/include/json/json_features.h index c12d64727..a5b73052a 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef CPPTL_JSON_FEATURES_H_INCLUDED -#define CPPTL_JSON_FEATURES_H_INCLUDED +#ifndef JSON_FEATURES_H_INCLUDED +#define JSON_FEATURES_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" @@ -64,4 +64,4 @@ class JSON_API Features { #pragma pack(pop) -#endif // CPPTL_JSON_FEATURES_H_INCLUDED +#endif // JSON_FEATURES_H_INCLUDED diff --git a/include/json/reader.h b/include/json/reader.h index 0b3817649..1540ac3db 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef CPPTL_JSON_READER_H_INCLUDED -#define CPPTL_JSON_READER_H_INCLUDED +#ifndef JSON_READER_H_INCLUDED +#define JSON_READER_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "json_features.h" @@ -400,4 +400,4 @@ JSON_API IStream& operator>>(IStream&, Value&); #pragma warning(pop) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#endif // CPPTL_JSON_READER_H_INCLUDED +#endif // JSON_READER_H_INCLUDED diff --git a/include/json/value.h b/include/json/value.h index bf4f9c443..0c9844124 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef CPPTL_JSON_H_INCLUDED -#define CPPTL_JSON_H_INCLUDED +#ifndef JSON_H_INCLUDED +#define JSON_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" @@ -23,19 +23,11 @@ #include #include +#include #include #include #include -#ifndef JSON_USE_CPPTL_SMALLMAP -#include -#else -#include -#endif -#ifdef JSON_USE_CPPTL -#include -#endif - // Disable warning C4251: : needs to have dll-interface to // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) @@ -120,11 +112,6 @@ enum PrecisionType { decimalPlaces ///< we set max number of digits after "." in string }; -//# ifdef JSON_USE_CPPTL -// typedef CppTL::AnyEnumerator EnumMemberNames; -// typedef CppTL::AnyEnumerator EnumValues; -//# endif - /** \brief Lightweight wrapper to tag static string. * * Value constructor and objectValue member assignment takes advantage of the @@ -287,11 +274,7 @@ class JSON_API Value { }; public: -#ifndef JSON_USE_CPPTL_SMALLMAP typedef std::map ObjectValues; -#else - typedef CppTL::SmallMap ObjectValues; -#endif // ifndef JSON_USE_CPPTL_SMALLMAP #endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION public: @@ -340,9 +323,6 @@ class JSON_API Value { */ Value(const StaticString& value); Value(const String& value); -#ifdef JSON_USE_CPPTL - Value(const CppTL::ConstString& value); -#endif Value(bool value); Value(const Value& other); Value(Value&& other); @@ -384,9 +364,6 @@ class JSON_API Value { * \return false if !string. (Seg-fault if str or end are NULL.) */ bool getString(char const** begin, char const** end) const; -#ifdef JSON_USE_CPPTL - CppTL::ConstString asConstString() const; -#endif Int asInt() const; UInt asUInt() const; #if defined(JSON_HAS_INT64) @@ -498,13 +475,6 @@ class JSON_API Value { * \endcode */ Value& operator[](const StaticString& key); -#ifdef JSON_USE_CPPTL - /// Access an object value by name, create a null member if it does not exist. - Value& operator[](const CppTL::ConstString& key); - /// Access an object value by name, returns null if there is no member with - /// that name. - const Value& operator[](const CppTL::ConstString& key) const; -#endif /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy Value get(const char* key, const Value& defaultValue) const; @@ -517,11 +487,6 @@ class JSON_API Value { /// \note deep copy /// \param key may contain embedded nulls. Value get(const String& key, const Value& defaultValue) const; -#ifdef JSON_USE_CPPTL - /// Return the member named key if it exist, defaultValue otherwise. - /// \note deep copy - Value get(const CppTL::ConstString& key, const Value& defaultValue) const; -#endif /// Most general and efficient version of isMember()const, get()const, /// and operator[]const /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 @@ -567,10 +532,6 @@ class JSON_API Value { bool isMember(const String& key) const; /// Same as isMember(String const& key)const bool isMember(const char* begin, const char* end) const; -#ifdef JSON_USE_CPPTL - /// Return true if the object has a member named key. - bool isMember(const CppTL::ConstString& key) const; -#endif /// \brief Return a list of the member names. /// @@ -579,11 +540,6 @@ class JSON_API Value { /// \post if type() was nullValue, it remains nullValue Members getMemberNames() const; - //# ifdef JSON_USE_CPPTL - // EnumMemberNames enumMemberNames() const; - // EnumValues enumValues() const; - //# endif - /// \deprecated Always pass len. JSONCPP_DEPRECATED("Use setComment(String const&) instead.") void setComment(const char* comment, CommentPlacement placement) { @@ -706,11 +662,6 @@ template <> inline float Value::as() const { return asFloat(); } template <> inline const char* Value::as() const { return asCString(); } -#ifdef JSON_USE_CPPTL -template <> inline CppTL::ConstString Value::as() const { - return asConstString(); -} -#endif /** \brief Experimental and untested: represents an element of the "path" to * access a node. @@ -960,4 +911,4 @@ inline void swap(Value& a, Value& b) { a.swap(b); } #pragma warning(pop) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#endif // CPPTL_JSON_H_INCLUDED +#endif // JSON_H_INCLUDED diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 00d28f774..9c48ab110 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -8,16 +8,13 @@ #include #include #endif // if !defined(JSON_IS_AMALGAMATION) +#include #include #include +#include #include #include #include -#ifdef JSON_USE_CPPTL -#include -#endif -#include // min() -#include // size_t // Provide implementation equivalent of std::snprintf for older _MSC compilers #if defined(_MSC_VER) && _MSC_VER < 1900 @@ -419,14 +416,6 @@ Value::Value(const StaticString& value) { value_.string_ = const_cast(value.c_str()); } -#ifdef JSON_USE_CPPTL -Value::Value(const CppTL::ConstString& value) { - initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue( - value, static_cast(value.length())); -} -#endif - Value::Value(bool value) { initBasic(booleanValue); value_.bool_ = value; @@ -654,15 +643,6 @@ String Value::asString() const { } } -#ifdef JSON_USE_CPPTL -CppTL::ConstString Value::asConstString() const { - unsigned len; - char const* str; - decodePrefixedString(isAllocated(), value_.string_, &len, &str); - return CppTL::ConstString(str, len); -} -#endif - Value::Int Value::asInt() const { switch (type()) { case intValue: @@ -1135,18 +1115,6 @@ Value& Value::operator[](const StaticString& key) { return resolveReference(key.c_str()); } -#ifdef JSON_USE_CPPTL -Value& Value::operator[](const CppTL::ConstString& key) { - return resolveReference(key.c_str(), key.end_c_str()); -} -Value const& Value::operator[](CppTL::ConstString const& key) const { - Value const* found = find(key.c_str(), key.end_c_str()); - if (!found) - return nullSingleton(); - return *found; -} -#endif - Value& Value::append(const Value& value) { return append(Value(value)); } Value& Value::append(Value&& value) { @@ -1240,13 +1208,6 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { return true; } -#ifdef JSON_USE_CPPTL -Value Value::get(const CppTL::ConstString& key, - const Value& defaultValue) const { - return get(key.c_str(), key.end_c_str(), defaultValue); -} -#endif - bool Value::isMember(char const* begin, char const* end) const { Value const* value = find(begin, end); return nullptr != value; @@ -1258,12 +1219,6 @@ bool Value::isMember(String const& key) const { return isMember(key.data(), key.data() + key.length()); } -#ifdef JSON_USE_CPPTL -bool Value::isMember(const CppTL::ConstString& key) const { - return isMember(key.c_str(), key.end_c_str()); -} -#endif - Value::Members Value::getMemberNames() const { JSON_ASSERT_MESSAGE( type() == nullValue || type() == objectValue, @@ -1279,31 +1234,6 @@ Value::Members Value::getMemberNames() const { } return members; } -// -//# ifdef JSON_USE_CPPTL -// EnumMemberNames -// Value::enumMemberNames() const -//{ -// if ( type() == objectValue ) -// { -// return CppTL::Enum::any( CppTL::Enum::transform( -// CppTL::Enum::keys( *(value_.map_), CppTL::Type() ), -// MemberNamesTransform() ) ); -// } -// return EnumMemberNames(); -//} -// -// -// EnumValues -// Value::enumValues() const -//{ -// if ( type() == objectValue || type() == arrayValue ) -// return CppTL::Enum::anyValues( *(value_.map_), -// CppTL::Type() ); -// return EnumValues(); -//} -// -//# endif static bool IsIntegral(double d) { double integral_part; diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 9bd9315e0..d6128b8ed 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -30,9 +30,6 @@ void ValueIteratorBase::decrement() { --current_; } ValueIteratorBase::difference_type ValueIteratorBase::computeDistance(const SelfType& other) const { -#ifdef JSON_USE_CPPTL_SMALLMAP - return other.current_ - current_; -#else // Iterator for null value are initialized using the default // constructor, which initialize current_ to the default // std::map::iterator. As begin() and end() are two instance @@ -53,7 +50,6 @@ ValueIteratorBase::computeDistance(const SelfType& other) const { ++myDistance; } return myDistance; -#endif } bool ValueIteratorBase::isEqual(const SelfType& other) const { diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index f2e4d4cd2..d85a98bdb 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3584,9 +3584,6 @@ JSONTEST_FIXTURE_LOCAL(MemberTemplateAs, BehavesSameAsNamedAs) { const Json::Value jstr = "hello world"; JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asCString()); JSONTEST_ASSERT_STRING_EQUAL(jstr.as(), jstr.asString()); -#ifdef JSON_USE_CPPTL - JSONTEST_ASSERT_STRING_EQUAL(js.as(), js.asConstString()); -#endif EqEval(Json::Int(64), [](const Json::Value& j) { return j.asInt(); }); EqEval(Json::UInt(64), [](const Json::Value& j) { return j.asUInt(); }); #if defined(JSON_HAS_INT64) From a481201af1d4e4b2910b4407aef31d76723e7825 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 14 Nov 2019 10:15:49 -0800 Subject: [PATCH 251/410] Readd some overzealously removed code --- include/json/autolink.h | 19 ------------------- include/json/config.h | 16 ++++++++++++++++ include/json/json.h | 2 +- meson.build | 1 - 4 files changed, 17 insertions(+), 21 deletions(-) delete mode 100644 include/json/autolink.h diff --git a/include/json/autolink.h b/include/json/autolink.h deleted file mode 100644 index 5f04a55bf..000000000 --- a/include/json/autolink.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors -// Distributed under MIT license, or public domain if desired and -// recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE - -#ifndef JSON_AUTOLINK_H_INCLUDED -#define JSON_AUTOLINK_H_INCLUDED - -#include "config.h" - -#if !defined(JSON_NO_AUTOLINK) && !defined(JSON_DLL_BUILD) -#define AUTOLINK_NAME "json" -#ifdef JSON_DLL -#define AUTOLINK_DLL -#endif -#include "autolink.h" -#endif - -#endif // JSON_AUTOLINK_H_INCLUDED diff --git a/include/json/config.h b/include/json/config.h index 2b4392c2b..0a3bc92e7 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -30,6 +30,22 @@ /// Remarks: it is automatically defined in the generated amalgamated header. // #define JSON_IS_AMALGAMATION +// Export macros for DLL visibility +#if defined(JSON_DLL_BUILD) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllexport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#elif defined(__GNUC__) || defined(__clang__) +#define JSON_API __attribute__((visibility("default"))) +#endif // if defined(_MSC_VER) + +#elif defined(JSON_DLL) +#if defined(_MSC_VER) || defined(__MINGW32__) +#define JSON_API __declspec(dllimport) +#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +#endif // if defined(_MSC_VER) +#endif // ifdef JSON_DLL_BUILD + #if !defined(JSON_API) #define JSON_API #endif diff --git a/include/json/json.h b/include/json/json.h index f1b679a59..5c776a160 100644 --- a/include/json/json.h +++ b/include/json/json.h @@ -6,7 +6,7 @@ #ifndef JSON_JSON_H_INCLUDED #define JSON_JSON_H_INCLUDED -#include "autolink.h" +#include "config.h" #include "json_features.h" #include "reader.h" #include "value.h" diff --git a/meson.build b/meson.build index 8531dcec4..1bc94a8af 100644 --- a/meson.build +++ b/meson.build @@ -21,7 +21,6 @@ project( jsoncpp_headers = [ 'include/json/allocator.h', 'include/json/assertions.h', - 'include/json/autolink.h', 'include/json/config.h', 'include/json/json_features.h', 'include/json/forwards.h', From f200239d5b0207c15a670f09761866ebd5517fb3 Mon Sep 17 00:00:00 2001 From: dota17 <50514813+dota17@users.noreply.github.com> Date: Fri, 15 Nov 2019 14:51:43 +0800 Subject: [PATCH 252/410] Add some testcases for charReader (#1095) * update charReader test case * remove C ++ compiler version switch for smart pointer * remove comma test due to PR #1098 --- src/test_lib_json/main.cpp | 292 +++++++++++++++++++++++++++++++------ 1 file changed, 246 insertions(+), 46 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index d85a98bdb..cc59120b6 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -23,6 +23,8 @@ #include #include +using CharReaderPtr = std::unique_ptr; + // Make numeric limits more convenient to talk about. // Assumes int type in 32 bits. #define kint32max Json::Value::maxInt @@ -2819,33 +2821,193 @@ struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : \"value\" }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrorsTestingOffsets) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : -6.2e+15, \"bool\" : true}, \"null\" : " - "null, \"false\" : false }"; + "{ \"nested\" : -6.2e+15, \"num\" : +123, \"bool\" : " + "true}, \"null\" : null, \"false\" : false }"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); - delete reader; +} + +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseNumber) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::String errs; + Json::Value root; + { + // if intvalue > threshold, treat the number as a double. + // 21 digits + char const doc[] = "[111111111111111111111]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_EQUAL(1.1111111111111111e+020, root[0]); + } +} + +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = "[\"\"]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_EQUAL("", root[0]); + } + { + char const doc[] = "[\"\\u8A2a\"]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_EQUAL("訪", root[0].asString()); // "\u8A2a" + } + { + char const doc[] = "[ \"\\uD801\" ]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" + " additional six characters expected to " + "parse unicode surrogate pair.\n" + "See Line 1, Column 10 for detail.\n"); + } + { + char const doc[] = "[ \"\\uD801\\d1234\" ]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" + " expecting another \\u token to begin the " + "second half of a unicode surrogate pair\n" + "See Line 1, Column 12 for detail.\n"); + } + { + char const doc[] = "[ \"\\ua3t@\" ]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" + " Bad unicode escape sequence in string: " + "hexadecimal digit expected.\n" + "See Line 1, Column 9 for detail.\n"); + } + { + char const doc[] = "[ \"\\ua3t\" ]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT( + errs == + "* Line 1, Column 3\n" + " Bad unicode escape sequence in string: four digits expected.\n" + "See Line 1, Column 6 for detail.\n"); + } + { + b.settings_["allowSingleQuotes"] = true; + CharReaderPtr charreader(b.newCharReader()); + char const doc[] = "{'a': 'x\\ty', \"b\":'x\\\\y'}"; + bool ok = charreader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT_STRING_EQUAL("", errs); + JSONTEST_ASSERT_EQUAL(2u, root.size()); + JSONTEST_ASSERT_STRING_EQUAL("x\ty", root["a"].asString()); + JSONTEST_ASSERT_STRING_EQUAL("x\\y", root["b"].asString()); + } +} + +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseComment) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = "//comment1\n { //comment2\n \"property\" :" + " \"value\" //comment3\n } //comment4\n"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_EQUAL("value", root["property"]); + } + { + char const doc[] = "{ \"property\" //comment\n : \"value\" }"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 14\n" + " Missing ':' after object member name\n"); + } + { + char const doc[] = "//comment1\n [ //comment2\n \"value\" //comment3\n," + " //comment4\n true //comment5\n ] //comment6\n"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_EQUAL("value", root[0]); + JSONTEST_ASSERT_EQUAL(true, root[1]); + } +} + +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = "{ \"property\" : \"value\" "; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 24\n" + " Missing ',' or '}' in object declaration\n"); + JSONTEST_ASSERT_EQUAL("value", root["property"]); + } + { + char const doc[] = "{ \"property\" : \"value\" ,"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 25\n" + " Missing '}' or object member name\n"); + JSONTEST_ASSERT_EQUAL("value", root["property"]); + } +} + +JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseArrayWithErrors) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = "[ \"value\" "; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 11\n" + " Missing ',' or ']' in array declaration\n"); + JSONTEST_ASSERT_EQUAL("value", root[0]); + } + { + char const doc[] = "[ \"value1\" \"value2\" ]"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(errs == "* Line 1, Column 12\n" + " Missing ',' or ']' in array declaration\n"); + JSONTEST_ASSERT_EQUAL("value1", root[0]); + } } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; char const doc[] = "{ \"property\" :: \"value\" }"; @@ -2854,12 +3016,11 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { JSONTEST_ASSERT(errs == "* Line 1, Column 15\n Syntax error: value, object or array " "expected.\n"); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; char const doc[] = "{ \"pr佐藤erty\" :: \"value\" }"; @@ -2868,12 +3029,11 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseChineseWithOneError) { JSONTEST_ASSERT(errs == "* Line 1, Column 19\n Syntax error: value, object or array " "expected.\n"); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; char const doc[] = "{ \"property\" : \"v\\alue\" }"; @@ -2882,7 +3042,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { JSONTEST_ASSERT(errs == "* Line 1, Column 16\n Bad escape sequence in string\nSee " "Line 1, Column 20 for detail.\n"); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { @@ -2891,21 +3050,19 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { char const doc[] = "{ \"property\" : \"value\" }"; { b.settings_["stackLimit"] = 2; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("value", root["property"]); - delete reader; } { b.settings_["stackLimit"] = 1; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; JSONTEST_ASSERT_THROWS( reader->parse(doc, doc + std::strlen(doc), &root, &errs)); - delete reader; } } @@ -2926,7 +3083,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { "{ \"property\" : \"value\", \"key\" : \"val1\", \"key\" : \"val2\" }"; { b.strictMode(&b.settings_); - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); @@ -2934,7 +3091,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { " Duplicate key: 'key'\n", errs); JSONTEST_ASSERT_EQUAL("val1", root["key"]); // so far - delete reader; } } struct CharReaderFailIfExtraTest : JsonTest::TestCase {}; @@ -2946,17 +3102,16 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { char const doc[] = " \"property\" : \"value\" }"; { b.settings_["failIfExtra"] = false; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL("property", root); - delete reader; } { b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); @@ -2964,11 +3119,10 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); - delete reader; } { b.strictMode(&b.settings_); - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); @@ -2976,12 +3130,11 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); - delete reader; } { b.strictMode(&b.settings_); b.settings_["failIfExtra"] = false; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); @@ -2990,7 +3143,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { " A valid JSON document must be either an array or an object value.\n", errs); JSONTEST_ASSERT_EQUAL("property", root); - delete reader; } } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { @@ -2999,7 +3151,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { Json::Value root; char const doc[] = "1:2:3"; b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); @@ -3007,7 +3159,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { " Extra non-whitespace after JSON value.\n", errs); JSONTEST_ASSERT_EQUAL(1, root.asInt()); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { Json::CharReaderBuilder b; @@ -3015,13 +3166,12 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterObject) { { char const doc[] = "{ \"property\" : \"value\" } //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL("value", root["property"]); - delete reader; } } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { @@ -3029,26 +3179,57 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterArray) { Json::Value root; char const doc[] = "[ \"property\" , \"value\" ] //trailing\n//comment\n"; b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL("value", root[1u]); - delete reader; } JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, commentAfterBool) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = " true /*trailing\ncomment*/"; b.settings_["failIfExtra"] = true; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::String errs; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); JSONTEST_ASSERT_EQUAL(true, root.asBool()); - delete reader; +} + +JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) { + Json::CharReaderBuilder b; + b.settings_["failIfExtra"] = true; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = " true //comment1\n//comment2\r//comment3\r\n"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT_STRING_EQUAL("", errs); + JSONTEST_ASSERT_EQUAL(true, root.asBool()); + } + { + char const doc[] = " true //com\rment"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL("* Line 2, Column 1\n" + " Extra non-whitespace after JSON value.\n", + errs); + JSONTEST_ASSERT_EQUAL(true, root.asBool()); + } + { + char const doc[] = " true //com\nment"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL("* Line 2, Column 1\n" + " Extra non-whitespace after JSON value.\n", + errs); + JSONTEST_ASSERT_EQUAL(true, root.asBool()); + } } struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; @@ -3057,7 +3238,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { b.settings_["allowDroppedNullPlaceholders"] = true; Json::Value root; Json::String errs; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); { char const doc[] = "{\"a\":,\"b\":true}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -3169,7 +3350,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { JSONTEST_ASSERT_EQUAL(4u, root.size()); JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[3u]); } - delete reader; } struct CharReaderAllowNumericKeysTest : JsonTest::TestCase {}; @@ -3179,7 +3359,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { b.settings_["allowNumericKeys"] = true; Json::Value root; Json::String errs; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); char const doc[] = "{15:true,-16:true,12.01:true}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); @@ -3188,7 +3368,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowNumericKeysTest, allowNumericKeys) { JSONTEST_ASSERT_EQUAL(true, root.get("15", false)); JSONTEST_ASSERT_EQUAL(true, root.get("-16", false)); JSONTEST_ASSERT_EQUAL(true, root.get("12.01", false)); - delete reader; } struct CharReaderAllowSingleQuotesTest : JsonTest::TestCase {}; @@ -3198,7 +3377,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { b.settings_["allowSingleQuotes"] = true; Json::Value root; Json::String errs; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -3217,7 +3396,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSingleQuotesTest, issue182) { JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); } - delete reader; } struct CharReaderAllowZeroesTest : JsonTest::TestCase {}; @@ -3227,7 +3405,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowZeroesTest, issue176) { b.settings_["allowSingleQuotes"] = true; Json::Value root; Json::String errs; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); { char const doc[] = "{'a':true,\"b\":true}"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); @@ -3246,17 +3424,41 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowZeroesTest, issue176) { JSONTEST_ASSERT_STRING_EQUAL("x", root["a"].asString()); JSONTEST_ASSERT_STRING_EQUAL("y", root["b"].asString()); } - delete reader; } struct CharReaderAllowSpecialFloatsTest : JsonTest::TestCase {}; +JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, specialFloat) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + Json::String errs; + { + char const doc[] = "{\"a\": NaN}"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL( + "* Line 1, Column 7\n" + " Syntax error: value, object or array expected.\n", + errs); + } + { + char const doc[] = "{\"a\": Infinity}"; + bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT_STRING_EQUAL( + "* Line 1, Column 7\n" + " Syntax error: value, object or array expected.\n", + errs); + } +} + JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { Json::CharReaderBuilder b; b.settings_["allowSpecialFloats"] = true; Json::Value root; Json::String errs; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); { char const doc[] = "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; @@ -3320,7 +3522,6 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { JSONTEST_ASSERT_EQUAL(-std::numeric_limits::infinity(), root["NegInf"].asDouble()); } - delete reader; } struct EscapeSequenceTest : JsonTest::TestCase {}; @@ -3339,7 +3540,7 @@ JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, readerParseEscapeSequence) { JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, charReaderParseEscapeSequence) { Json::CharReaderBuilder b; - Json::CharReader* reader(b.newCharReader()); + CharReaderPtr reader(b.newCharReader()); Json::Value root; Json::String errs; char const doc[] = "[\"\\\"\",\"\\/\",\"\\\\\",\"\\b\"," @@ -3348,7 +3549,6 @@ JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, charReaderParseEscapeSequence) { bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); - delete reader; } JSONTEST_FIXTURE_LOCAL(EscapeSequenceTest, writeEscapeSequence) { From 9e0d70aa66e6ba993dd05723ca64c26ab00f3572 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 15 Nov 2019 09:18:32 -0500 Subject: [PATCH 253/410] eliminate some redundancy in test_lib_json/main.cpp (#1104) refactor test 'CharReaderAllowDropNullTest/issue178' --- src/test_lib_json/main.cpp | 281 ++++++++++++++----------------------- 1 file changed, 106 insertions(+), 175 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index cc59120b6..87be51591 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -14,6 +14,7 @@ #include "jsontest.h" #include #include +#include #include #include #include @@ -63,27 +64,22 @@ static std::deque local_; struct ValueTest : JsonTest::TestCase { Json::Value null_; - Json::Value emptyArray_; - Json::Value emptyObject_; - Json::Value integer_; - Json::Value unsignedInteger_; - Json::Value smallUnsignedInteger_; - Json::Value real_; - Json::Value float_; + Json::Value emptyArray_{Json::arrayValue}; + Json::Value emptyObject_{Json::objectValue}; + Json::Value integer_{123456789}; + Json::Value unsignedInteger_{34567890}; + Json::Value smallUnsignedInteger_{Json::Value::UInt(Json::Value::maxInt)}; + Json::Value real_{1234.56789}; + Json::Value float_{0.00390625f}; Json::Value array1_; Json::Value object1_; - Json::Value emptyString_; - Json::Value string1_; - Json::Value string_; - Json::Value true_; - Json::Value false_; - - ValueTest() - : emptyArray_(Json::arrayValue), emptyObject_(Json::objectValue), - integer_(123456789), unsignedInteger_(34567890u), - smallUnsignedInteger_(Json::Value::UInt(Json::Value::maxInt)), - real_(1234.56789), float_(0.00390625f), emptyString_(""), string1_("a"), - string_("sometext with space"), true_(true), false_(false) { + Json::Value emptyString_{""}; + Json::Value string1_{"a"}; + Json::Value string_{"sometext with space"}; + Json::Value true_{true}; + Json::Value false_{false}; + + ValueTest() { array1_.append(1234); object1_["id"] = 1234; } @@ -124,53 +120,45 @@ struct ValueTest : JsonTest::TestCase { }; Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { - Json::String::size_type index = s.find_last_of("eE"); - if (index != Json::String::npos) { - Json::String::size_type hasSign = - (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - Json::String::size_type exponentStartIndex = index + 1 + hasSign; - Json::String normalized = s.substr(0, exponentStartIndex); - Json::String::size_type indexDigit = - s.find_first_not_of('0', exponentStartIndex); - Json::String exponent = "0"; - if (indexDigit != Json::String::npos) // There is an exponent different - // from 0 - { - exponent = s.substr(indexDigit); - } - return normalized + exponent; + auto index = s.find_last_of("eE"); + if (index == s.npos) + return s; + int hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; + auto exponentStartIndex = index + 1 + hasSign; + Json::String normalized = s.substr(0, exponentStartIndex); + auto indexDigit = s.find_first_not_of('0', exponentStartIndex); + Json::String exponent = "0"; + if (indexDigit != s.npos) { // nonzero exponent + exponent = s.substr(indexDigit); } - return s; + return normalized + exponent; } JSONTEST_FIXTURE_LOCAL(ValueTest, checkNormalizeFloatingPointStr) { - JSONTEST_ASSERT_STRING_EQUAL("0.0", normalizeFloatingPointStr("0.0")); - JSONTEST_ASSERT_STRING_EQUAL("0e0", normalizeFloatingPointStr("0e0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0", normalizeFloatingPointStr("1234.0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e0", - normalizeFloatingPointStr("1234.0e0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e-1", - normalizeFloatingPointStr("1234.0e-1")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e+0", - normalizeFloatingPointStr("1234.0e+0")); - JSONTEST_ASSERT_STRING_EQUAL("1234.0e+1", - normalizeFloatingPointStr("1234.0e+001")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-1", normalizeFloatingPointStr("1234e-1")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+0", - normalizeFloatingPointStr("1234e+000")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+1", - normalizeFloatingPointStr("1234e+001")); - JSONTEST_ASSERT_STRING_EQUAL("1234e10", normalizeFloatingPointStr("1234e10")); - JSONTEST_ASSERT_STRING_EQUAL("1234e10", - normalizeFloatingPointStr("1234e010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+10", - normalizeFloatingPointStr("1234e+010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-10", - normalizeFloatingPointStr("1234e-010")); - JSONTEST_ASSERT_STRING_EQUAL("1234e+100", - normalizeFloatingPointStr("1234e+100")); - JSONTEST_ASSERT_STRING_EQUAL("1234e-100", - normalizeFloatingPointStr("1234e-100")); + struct TestData { + std::string in; + std::string out; + } const testData[] = { + {"0.0", "0.0"}, + {"0e0", "0e0"}, + {"1234.0", "1234.0"}, + {"1234.0e0", "1234.0e0"}, + {"1234.0e-1", "1234.0e-1"}, + {"1234.0e+0", "1234.0e+0"}, + {"1234.0e+001", "1234.0e+1"}, + {"1234e-1", "1234e-1"}, + {"1234e+000", "1234e+0"}, + {"1234e+001", "1234e+1"}, + {"1234e10", "1234e10"}, + {"1234e010", "1234e10"}, + {"1234e+010", "1234e+10"}, + {"1234e-010", "1234e-10"}, + {"1234e+100", "1234e+100"}, + {"1234e-100", "1234e-100"}, + }; + for (const auto& td : testData) { + JSONTEST_ASSERT_STRING_EQUAL(normalizeFloatingPointStr(td.in), td.out); + } } JSONTEST_FIXTURE_LOCAL(ValueTest, memberCount) { @@ -3145,6 +3133,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { JSONTEST_ASSERT_EQUAL("property", root); } } + JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue107) { // This is interpreted as an int value followed by a colon. Json::CharReaderBuilder b; @@ -3231,124 +3220,66 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, parseComment) { JSONTEST_ASSERT_EQUAL(true, root.asBool()); } } -struct CharReaderAllowDropNullTest : JsonTest::TestCase {}; -JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { - Json::CharReaderBuilder b; - b.settings_["allowDroppedNullPlaceholders"] = true; - Json::Value root; - Json::String errs; - CharReaderPtr reader(b.newCharReader()); - { - char const doc[] = "{\"a\":,\"b\":true}"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(2u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::nullValue, root.get("a", true)); - } - { - char const doc[] = "{\"a\":}"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(1u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::nullValue, root.get("a", true)); - } - { - char const doc[] = "[]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL(0u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root); - } - { - char const doc[] = "[null]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL(1u, root.size()); - } - { - char const doc[] = "[,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(2u, root.size()); - } - { - char const doc[] = "[,,,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(4u, root.size()); - } - { - char const doc[] = "[null,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(2u, root.size()); - } - { - char const doc[] = "[,null]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL(2u, root.size()); - } - { - char const doc[] = "[,,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(3u, root.size()); - } - { - char const doc[] = "[null,,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(3u, root.size()); - } - { - char const doc[] = "[,null,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(3u, root.size()); - } - { - char const doc[] = "[,,null]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL(3u, root.size()); +struct CharReaderAllowDropNullTest : JsonTest::TestCase { + using Value = Json::Value; + using ValueCheck = std::function; + + Value nullValue = Value{Json::nullValue}; + Value emptyArray = Value{Json::arrayValue}; + + ValueCheck checkEq(const Value& v) { + return [=](const Value& root) { JSONTEST_ASSERT_EQUAL(root, v); }; } - { - char const doc[] = "[[],,,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(4u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[0u]); + + ValueCheck objGetAnd(std::string idx, ValueCheck f) { + return [=](const Value& root) { f(root.get(idx, true)); }; } - { - char const doc[] = "[,[],,]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT_STRING_EQUAL("", errs); - JSONTEST_ASSERT_EQUAL(4u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[1u]); + + ValueCheck arrGetAnd(int idx, ValueCheck f) { + return [=](const Value& root) { f(root[idx]); }; } - { - char const doc[] = "[,,,[]]"; - bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); +}; + +JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { + struct TestSpec { + int line; + std::string doc; + size_t rootSize; + ValueCheck onRoot; + }; + const TestSpec specs[] = { + {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, R"({"a":})", 1, objGetAnd("a", checkEq(nullValue))}, + {__LINE__, "[]", 0, checkEq(emptyArray)}, + {__LINE__, "[null]", 1}, + {__LINE__, "[,]", 2}, + {__LINE__, "[,,,]", 4}, + {__LINE__, "[null,]", 2}, + {__LINE__, "[,null]", 2}, + {__LINE__, "[,,]", 3}, + {__LINE__, "[null,,]", 3}, + {__LINE__, "[,null,]", 3}, + {__LINE__, "[,,null]", 3}, + {__LINE__, "[[],,,]", 4, arrGetAnd(0, checkEq(emptyArray))}, + {__LINE__, "[,[],,]", 4, arrGetAnd(1, checkEq(emptyArray))}, + {__LINE__, "[,,,[]]", 4, arrGetAnd(3, checkEq(emptyArray))}, + }; + for (const auto& spec : specs) { + Json::CharReaderBuilder b; + b.settings_["allowDroppedNullPlaceholders"] = true; + std::unique_ptr reader(b.newCharReader()); + + Json::Value root; + Json::String errs; + bool ok = reader->parse(spec.doc.data(), spec.doc.data() + spec.doc.size(), + &root, &errs); JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL(4u, root.size()); - JSONTEST_ASSERT_EQUAL(Json::arrayValue, root[3u]); + JSONTEST_ASSERT_STRING_EQUAL(errs, ""); + if (spec.onRoot) { + spec.onRoot(root); + } } } From a0bd9adfefbafd3c125981b15f5bbf413bf5dd30 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Tue, 3 Dec 2019 09:13:42 +0800 Subject: [PATCH 254/410] Add an insert overload function (#1110) --- include/json/value.h | 4 +++- src/lib_json/json_value.cpp | 6 +++++- src/test_lib_json/main.cpp | 3 +-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 0c9844124..c4b29b97d 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -445,8 +445,10 @@ class JSON_API Value { /// Equivalent to jsonvalue[jsonvalue.size()] = value; Value& append(const Value& value); Value& append(Value&& value); + /// \brief Insert value in array at specific index - bool insert(ArrayIndex index, Value newValue); + bool insert(ArrayIndex index, const Value& newValue); + bool insert(ArrayIndex index, Value&& newValue); /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 9c48ab110..235380745 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1126,7 +1126,11 @@ Value& Value::append(Value&& value) { return this->value_.map_->emplace(size(), std::move(value)).first->second; } -bool Value::insert(ArrayIndex index, Value newValue) { +bool Value::insert(ArrayIndex index, const Value& newValue) { + return insert(index, Value(newValue)); +} + +bool Value::insert(ArrayIndex index, Value&& newValue) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue, "in Json::Value::insert: requires arrayValue"); ArrayIndex length = size(); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 87be51591..2b552446a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -417,8 +417,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { } vec.push_back(&array[4]); // insert rvalue at the tail - Json::Value index5("index5"); - JSONTEST_ASSERT(array.insert(5, std::move(index5))); + JSONTEST_ASSERT(array.insert(5, "index5")); JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array[0]); JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); From 2983f5a89a9fd8399402af10b27ff214509431d3 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Wed, 4 Dec 2019 09:08:45 +0800 Subject: [PATCH 255/410] Run Clang-tidy with modernize-use-auto (#1077) * Run clang-tidy modify with modernize-use-auto * Use using instead of typedef --- .clang-tidy | 2 +- example/readFromString/readFromString.cpp | 2 +- include/json/config.h | 20 ++++----- include/json/forwards.h | 2 +- include/json/reader.h | 8 ++-- include/json/value.h | 54 +++++++++++------------ include/json/writer.h | 4 +- src/jsontestrunner/main.cpp | 2 +- src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_tool.h | 2 +- src/lib_json/json_value.cpp | 13 +++--- src/lib_json/json_writer.cpp | 2 +- src/test_lib_json/fuzz.cpp | 2 +- src/test_lib_json/jsontest.h | 8 ++-- 14 files changed, 62 insertions(+), 61 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 6b5e8018e..b78b3247e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: 'google-readability-casting,modernize-use-default-member-init,modernize-use-using,readability-redundant-member-init' +Checks: 'google-readability-casting,modernize-use-default-member-init,modernize-use-using,modernize-use-auto,readability-redundant-member-init' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp index ce3223692..c27bbd5ae 100644 --- a/example/readFromString/readFromString.cpp +++ b/example/readFromString/readFromString.cpp @@ -11,7 +11,7 @@ */ int main() { const std::string rawJson = R"({"Age": 20, "Name": "colin"})"; - const int rawJsonLength = static_cast(rawJson.length()); + const auto rawJsonLength = static_cast(rawJson.length()); constexpr bool shouldUseOldWay = false; JSONCPP_STRING err; Json::Value root; diff --git a/include/json/config.h b/include/json/config.h index 0a3bc92e7..3d148a69b 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -119,23 +119,23 @@ extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, #endif // if !defined(JSON_IS_AMALGAMATION) namespace Json { -typedef int Int; -typedef unsigned int UInt; +using Int = int; +using UInt = unsigned int; #if defined(JSON_NO_INT64) -typedef int LargestInt; -typedef unsigned int LargestUInt; +using LargestInt = int; +using LargestUInt = unsigned int; #undef JSON_HAS_INT64 #else // if defined(JSON_NO_INT64) // For Microsoft Visual use specific types as long long is not supported #if defined(_MSC_VER) // Microsoft Visual Studio -typedef __int64 Int64; -typedef unsigned __int64 UInt64; +using Int64 = __int64; +using UInt64 = unsigned __int64; #else // if defined(_MSC_VER) // Other platforms, use long long -typedef int64_t Int64; -typedef uint64_t UInt64; +using Int64 = int64_t; +using UInt64 = uint64_t; #endif // if defined(_MSC_VER) -typedef Int64 LargestInt; -typedef UInt64 LargestUInt; +using LargestInt = Int64; +using LargestUInt = UInt64; #define JSON_HAS_INT64 #endif // if defined(JSON_NO_INT64) diff --git a/include/json/forwards.h b/include/json/forwards.h index b0d981be0..affe33a7f 100644 --- a/include/json/forwards.h +++ b/include/json/forwards.h @@ -29,7 +29,7 @@ class CharReaderBuilder; class Features; // value.h -typedef unsigned int ArrayIndex; +using ArrayIndex = unsigned int; class StaticString; class Path; class PathArgument; diff --git a/include/json/reader.h b/include/json/reader.h index 1540ac3db..917546608 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -36,8 +36,8 @@ namespace Json { class JSONCPP_DEPRECATED( "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { public: - typedef char Char; - typedef const Char* Location; + using Char = char; + using Location = const Char*; /** \brief An error tagged with where in the JSON text it was encountered. * @@ -187,7 +187,7 @@ class JSONCPP_DEPRECATED( Location extra_; }; - typedef std::deque Errors; + using Errors = std::deque; bool readToken(Token& token); void skipSpaces(); @@ -226,7 +226,7 @@ class JSONCPP_DEPRECATED( static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); - typedef std::stack Nodes; + using Nodes = std::stack; Nodes nodes_; Errors errors_; String document_; diff --git a/include/json/value.h b/include/json/value.h index c4b29b97d..e169c3c69 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -176,21 +176,21 @@ class JSON_API Value { friend class ValueIteratorBase; public: - typedef std::vector Members; - typedef ValueIterator iterator; - typedef ValueConstIterator const_iterator; - typedef Json::UInt UInt; - typedef Json::Int Int; + using Members = std::vector; + using iterator = ValueIterator; + using const_iterator = ValueConstIterator; + using UInt = Json::UInt; + using Int = Json::Int; #if defined(JSON_HAS_INT64) - typedef Json::UInt64 UInt64; - typedef Json::Int64 Int64; + using UInt64 = Json::UInt64; + using Int64 = Json::Int64; #endif // defined(JSON_HAS_INT64) - typedef Json::LargestInt LargestInt; - typedef Json::LargestUInt LargestUInt; - typedef Json::ArrayIndex ArrayIndex; + using LargestInt = Json::LargestInt; + using LargestUInt = Json::LargestUInt; + using ArrayIndex = Json::ArrayIndex; // Required for boost integration, e. g. BOOST_TEST - typedef std::string value_type; + using value_type = std::string; #if JSON_USE_NULLREF // Binary compatibility kludges, do not use. @@ -710,8 +710,8 @@ class JSON_API Path { Value& make(Value& root) const; private: - typedef std::vector InArgs; - typedef std::vector Args; + using InArgs = std::vector; + using Args = std::vector; void makePath(const String& path, const InArgs& in); void addPathInArg(const String& path, const InArgs& in, @@ -726,10 +726,10 @@ class JSON_API Path { */ class JSON_API ValueIteratorBase { public: - typedef std::bidirectional_iterator_tag iterator_category; - typedef unsigned int size_t; - typedef int difference_type; - typedef ValueIteratorBase SelfType; + using iterator_category = std::bidirectional_iterator_tag; + using size_t = unsigned int; + using difference_type = int; + using SelfType = ValueIteratorBase; bool operator==(const SelfType& other) const { return isEqual(other); } @@ -802,12 +802,12 @@ class JSON_API ValueConstIterator : public ValueIteratorBase { friend class Value; public: - typedef const Value value_type; + using value_type = const Value; // typedef unsigned int size_t; // typedef int difference_type; - typedef const Value& reference; - typedef const Value* pointer; - typedef ValueConstIterator SelfType; + using reference = const Value&; + using pointer = const Value*; + using SelfType = ValueConstIterator; ValueConstIterator(); ValueConstIterator(ValueIterator const& other); @@ -853,12 +853,12 @@ class JSON_API ValueIterator : public ValueIteratorBase { friend class Value; public: - typedef Value value_type; - typedef unsigned int size_t; - typedef int difference_type; - typedef Value& reference; - typedef Value* pointer; - typedef ValueIterator SelfType; + using value_type = Value; + using size_t = unsigned int; + using difference_type = int; + using reference = Value&; + using pointer = Value*; + using SelfType = ValueIterator; ValueIterator(); explicit ValueIterator(const ValueConstIterator& other); diff --git a/include/json/writer.h b/include/json/writer.h index a72c06a40..fb0852a0c 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -252,7 +252,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); - typedef std::vector ChildValues; + using ChildValues = std::vector; ChildValues childValues_; String document_; @@ -326,7 +326,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API static bool hasCommentForValue(const Value& value); static String normalizeEOL(const String& text); - typedef std::vector ChildValues; + using ChildValues = std::vector; ChildValues childValues_; OStream* document_; diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index dbfbe98c1..f6b1a4dc3 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -58,7 +58,7 @@ static Json::String readInputTestFile(const char* path) { return ""; fseek(file, 0, SEEK_END); long const size = ftell(file); - size_t const usize = static_cast(size); + const auto usize = static_cast(size); fseek(file, 0, SEEK_SET); char* buffer = new char[size + 1]; buffer[size] = 0; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 63b693795..87483da60 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -54,7 +54,7 @@ namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) using CharReaderPtr = std::unique_ptr; #else -typedef std::auto_ptr CharReaderPtr; +using CharReaderPtr = std::auto_ptr; #endif // Implementation of class Features diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 5c13f1fed..2d7b7d9a0 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -71,7 +71,7 @@ enum { }; // Defines a char buffer for use with uintToString(). -typedef char UIntToStringBuffer[uintToStringBufferSize]; +using UIntToStringBuffer = char[uintToStringBufferSize]; /** Converts an unsigned integer to string. * @param value Unsigned integer to convert to string diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 235380745..1e3bbdebd 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -117,7 +117,7 @@ static inline char* duplicateStringValue(const char* value, size_t length) { if (length >= static_cast(Value::maxInt)) length = Value::maxInt - 1; - char* newString = static_cast(malloc(length + 1)); + auto newString = static_cast(malloc(length + 1)); if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateStringValue(): " "Failed to allocate string value buffer"); @@ -137,8 +137,8 @@ static inline char* duplicateAndPrefixStringValue(const char* value, sizeof(unsigned) - 1U, "in Json::Value::duplicateAndPrefixStringValue(): " "length too big for prefixing"); - unsigned actualLength = length + static_cast(sizeof(unsigned)) + 1U; - char* newString = static_cast(malloc(actualLength)); + size_t actualLength = sizeof(length) + length + 1; + auto newString = static_cast(malloc(actualLength)); if (newString == nullptr) { throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " "Failed to allocate string value buffer"); @@ -518,9 +518,10 @@ bool Value::operator<(const Value& other) const { } case arrayValue: case objectValue: { - int delta = int(value_.map_->size() - other.value_.map_->size()); - if (delta) - return delta < 0; + auto thisSize = value_.map_->size(); + auto otherSize = other.value_.map_->size(); + if (thisSize != otherSize) + return thisSize < otherSize; return (*value_.map_) < (*other.value_.map_); } default: diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 519ce23ad..8e06cca24 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -86,7 +86,7 @@ namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) using StreamWriterPtr = std::unique_ptr; #else -typedef std::auto_ptr StreamWriterPtr; +using StreamWriterPtr = std::auto_ptr; #endif String valueToString(LargestInt value) { diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index fe515b16f..68f839d53 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -45,7 +45,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::unique_ptr reader(builder.newCharReader()); Json::Value root; - const char* data_str = reinterpret_cast(data); + const auto data_str = reinterpret_cast(data); try { reader->parse(data_str, data_str + size, &root, nullptr); } catch (Json::Exception const&) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index e076f7c2b..8c3aa5e32 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -42,7 +42,7 @@ class Failure { /// Must be a POD to allow inline initialisation without stepping /// into the debugger. struct PredicateContext { - typedef unsigned int Id; + using Id = unsigned int; Id id_; const char* file_; unsigned int line_; @@ -102,7 +102,7 @@ class TestResult { static Json::String indentText(const Json::String& text, const Json::String& indent); - typedef std::deque Failures; + using Failures = std::deque; Failures failures_; Json::String name_; PredicateContext rootPredicateNode_; @@ -129,7 +129,7 @@ class TestCase { }; /// Function pointer type for TestCase factory -typedef TestCase* (*TestCaseFactory)(); +using TestCaseFactory = TestCase* (*)(); class Runner { public: @@ -168,7 +168,7 @@ class Runner { static void preventDialogOnCrash(); private: - typedef std::deque Factories; + using Factories = std::deque; Factories tests_; }; From a3c8642886b348d4f8fcb5384266c3a94ffe66b3 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Wed, 4 Dec 2019 10:24:52 +0800 Subject: [PATCH 256/410] Add test cases for Reader (#1108) * update testcase for reader * add a helper function * refactor structured error testing --- src/test_lib_json/main.cpp | 311 +++++++++++++++++++++---------------- 1 file changed, 179 insertions(+), 132 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 2b552446a..a20ef3ead 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2641,167 +2642,213 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) { "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); } -struct ReaderTest : JsonTest::TestCase {}; +struct ReaderTest : JsonTest::TestCase { + void setStrictMode() { + reader = std::unique_ptr( + new Json::Reader(Json::Features{}.strictMode())); + } -JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { - Json::Reader reader; + void checkStructuredErrors( + const std::vector& actual, + const std::vector& expected) { + JSONTEST_ASSERT_EQUAL(actual.size(), expected.size()); + for (size_t i = 0; i < actual.size(); ++i) { + const auto& a = actual[i]; + const auto& e = expected[i]; + JSONTEST_ASSERT_EQUAL(a.offset_start, e.offset_start) << i; + JSONTEST_ASSERT_EQUAL(a.offset_limit, e.offset_limit) << i; + JSONTEST_ASSERT_EQUAL(a.message, e.message) << i; + } + } + + template void checkParse(Input&& input) { + JSONTEST_ASSERT(reader->parse(input, root)); + } + + template + void + checkParse(Input&& input, + const std::vector& structured) { + JSONTEST_ASSERT(!reader->parse(input, root)); + checkStructuredErrors(reader->getStructuredErrors(), structured); + } + + template + void checkParse(Input&& input, + const std::vector& structured, + const std::string& formatted) { + checkParse(input, structured); + JSONTEST_ASSERT_EQUAL(reader->getFormattedErrorMessages(), formatted); + } + + std::unique_ptr reader{new Json::Reader()}; Json::Value root; - bool ok = reader.parse("{ \"property\" : \"value\" }", root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); - JSONTEST_ASSERT(reader.getStructuredErrors().empty()); +}; + +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) { + checkParse(R"({ "property" : "value" })"); +} + +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseObject) { + checkParse(R"({"property"})", + {{11, 12, "Missing ':' after object member name"}}, + "* Line 1, Column 12\n Missing ':' after object member name\n"); + checkParse( + R"({"property" : "value" )", + {{22, 22, "Missing ',' or '}' in object declaration"}}, + "* Line 1, Column 23\n Missing ',' or '}' in object declaration\n"); + checkParse(R"({"property" : "value", )", + {{23, 23, "Missing '}' or object member name"}}, + "* Line 1, Column 24\n Missing '}' or object member name\n"); +} + +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseArray) { + checkParse( + R"([ "value" )", {{10, 10, "Missing ',' or ']' in array declaration"}}, + "* Line 1, Column 11\n Missing ',' or ']' in array declaration\n"); + checkParse( + R"([ "value1" "value2" ] )", + {{11, 19, "Missing ',' or ']' in array declaration"}}, + "* Line 1, Column 12\n Missing ',' or ']' in array declaration\n"); +} + +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) { + checkParse(R"([ "\u8a2a" ])"); + checkParse( + R"([ "\ud801" ])", + {{2, 10, + "additional six characters expected to parse unicode surrogate " + "pair."}}, + "* Line 1, Column 3\n" + " additional six characters expected to parse unicode surrogate pair.\n" + "See Line 1, Column 10 for detail.\n"); + checkParse(R"([ "\ud801\d1234" ])", + {{2, 16, + "expecting another \\u token to begin the " + "second half of a unicode surrogate pair"}}, + "* Line 1, Column 3\n" + " expecting another \\u token to begin the " + "second half of a unicode surrogate pair\n" + "See Line 1, Column 12 for detail.\n"); + checkParse(R"([ "\ua3t@" ])", + {{2, 10, + "Bad unicode escape sequence in string: " + "hexadecimal digit expected."}}, + "* Line 1, Column 3\n" + " Bad unicode escape sequence in string: " + "hexadecimal digit expected.\n" + "See Line 1, Column 9 for detail.\n"); + checkParse( + R"([ "\ua3t" ])", + {{2, 9, "Bad unicode escape sequence in string: four digits expected."}}, + "* Line 1, Column 3\n" + " Bad unicode escape sequence in string: four digits expected.\n" + "See Line 1, Column 6 for detail.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseComment) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ /*commentBeforeValue*/" - " \"property\" : \"value\" }" - "//commentAfterValue\n", - root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); - JSONTEST_ASSERT(reader.getStructuredErrors().empty()); + checkParse( + R"({ /*commentBeforeValue*/ "property" : "value" }//commentAfterValue)" + "\n"); + checkParse(" true //comment1\n//comment2\r//comment3\r\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, streamParseWithNoErrors) { - Json::Reader reader; - std::string styled = "{ \"property\" : \"value\" }"; + std::string styled = R"({ "property" : "value" })"; std::istringstream iss(styled); - Json::Value root; - bool ok = reader.parse(iss, root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); - JSONTEST_ASSERT(reader.getStructuredErrors().empty()); + checkParse(iss); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" : [\"value\", \"value2\"], \"obj\" : " - "{ \"nested\" : -6.2e+15, \"bool\" : true}, \"null\" :" - " null, \"false\" : false }", - root); - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty()); - JSONTEST_ASSERT(reader.getStructuredErrors().empty()); - JSONTEST_ASSERT(root["property"].getOffsetStart() == 15); - JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34); - JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16); - JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23); - JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25); - JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33); - JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44); - JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 81); - JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57); - JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 65); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 76); - JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 80); - JSONTEST_ASSERT(root["null"].getOffsetStart() == 92); - JSONTEST_ASSERT(root["null"].getOffsetLimit() == 96); - JSONTEST_ASSERT(root["false"].getOffsetStart() == 108); - JSONTEST_ASSERT(root["false"].getOffsetLimit() == 113); - JSONTEST_ASSERT(root.getOffsetStart() == 0); - JSONTEST_ASSERT(root.getOffsetLimit() == 115); + checkParse(R"({)" + R"( "property" : ["value", "value2"],)" + R"( "obj" : { "nested" : -6.2e+15, "bool" : true},)" + R"( "null" : null,)" + R"( "false" : false)" + R"( })"); + auto checkOffsets = [&](const Json::Value& v, int start, int limit) { + JSONTEST_ASSERT_EQUAL(v.getOffsetStart(), start); + JSONTEST_ASSERT_EQUAL(v.getOffsetLimit(), limit); + }; + checkOffsets(root, 0, 115); + checkOffsets(root["property"], 15, 34); + checkOffsets(root["property"][0], 16, 23); + checkOffsets(root["property"][1], 25, 33); + checkOffsets(root["obj"], 44, 81); + checkOffsets(root["obj"]["nested"], 57, 65); + checkOffsets(root["obj"]["bool"], 76, 80); + checkOffsets(root["null"], 92, 96); + checkOffsets(root["false"], 108, 113); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" :: \"value\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 15\n Syntax error: value, object or array " - "expected.\n"); - std::vector errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 14); - JSONTEST_ASSERT(errors.at(0).offset_limit == 15); - JSONTEST_ASSERT(errors.at(0).message == - "Syntax error: value, object or array expected."); + checkParse(R"({ "property" :: "value" })", + {{14, 15, "Syntax error: value, object or array expected."}}, + "* Line 1, Column 15\n Syntax error: value, object or array " + "expected.\n"); + checkParse("s", {{0, 1, "Syntax error: value, object or array expected."}}, + "* Line 1, Column 1\n Syntax error: value, object or array " + "expected.\n"); +} + +JSONTEST_FIXTURE_LOCAL(ReaderTest, parseSpecialFloat) { + checkParse(R"({ "a" : Infi })", + {{8, 9, "Syntax error: value, object or array expected."}}, + "* Line 1, Column 9\n Syntax error: value, object or array " + "expected.\n"); + checkParse(R"({ "a" : Infiniaa })", + {{8, 9, "Syntax error: value, object or array expected."}}, + "* Line 1, Column 9\n Syntax error: value, object or array " + "expected.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) { - Json::Features feature; - Json::Reader reader(feature.strictMode()); - Json::Value root; - bool ok = reader.parse("123", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 1\n" - " A valid JSON document must be either an array or" - " an object value.\n"); - std::vector errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 0); - JSONTEST_ASSERT(errors.at(0).offset_limit == 3); - JSONTEST_ASSERT(errors.at(0).message == - "A valid JSON document must be either an array or" - " an object value."); + setStrictMode(); + checkParse( + "123", + {{0, 3, + "A valid JSON document must be either an array or an object value."}}, + "* Line 1, Column 1\n" + " A valid JSON document must be either an array or an object value.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"pr佐藤erty\" :: \"value\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 19\n Syntax error: value, object or array " - "expected.\n"); - std::vector errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 18); - JSONTEST_ASSERT(errors.at(0).offset_limit == 19); - JSONTEST_ASSERT(errors.at(0).message == - "Syntax error: value, object or array expected."); + // \u4f50\u85e4 佐藤 + checkParse(R"({ "pr)" + "佐藤" + R"(erty" :: "value" })", + {{18, 19, "Syntax error: value, object or array expected."}}, + "* Line 1, Column 19\n Syntax error: value, object or array " + "expected.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) { - Json::Reader reader; - Json::Value root; - bool ok = reader.parse("{ \"property\" : \"v\\alue\" }", root); - JSONTEST_ASSERT(!ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 16\n Bad escape sequence in string\nSee " - "Line 1, Column 20 for detail.\n"); - std::vector errors = - reader.getStructuredErrors(); - JSONTEST_ASSERT(errors.size() == 1); - JSONTEST_ASSERT(errors.at(0).offset_start == 15); - JSONTEST_ASSERT(errors.at(0).offset_limit == 23); - JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string"); + checkParse(R"({ "property" : "v\alue" })", + {{15, 23, "Bad escape sequence in string"}}, + "* Line 1, Column 16\n" + " Bad escape sequence in string\n" + "See Line 1, Column 20 for detail.\n"); } JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { - Json::Reader reader; - Json::Value root; - { - bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root); - JSONTEST_ASSERT(ok); - if (!root["AUTHOR"].isString()) { - ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string"); - } - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 14\n" - " AUTHOR must be a string\n"); + checkParse(R"({ "AUTHOR" : 123 })"); + if (!root["AUTHOR"].isString()) { + JSONTEST_ASSERT( + reader->pushError(root["AUTHOR"], "AUTHOR must be a string")); } - { - bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root); - JSONTEST_ASSERT(ok); - if (!root["AUTHOR"].isString()) { - ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string", - root["AUTHOR"]); - } - JSONTEST_ASSERT(ok); - JSONTEST_ASSERT(reader.getFormattedErrorMessages() == - "* Line 1, Column 14\n" - " AUTHOR must be a string\n" - "See Line 1, Column 14 for detail.\n"); + JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(), + "* Line 1, Column 14\n" + " AUTHOR must be a string\n"); + + checkParse(R"({ "AUTHOR" : 123 })"); + if (!root["AUTHOR"].isString()) { + JSONTEST_ASSERT(reader->pushError(root["AUTHOR"], "AUTHOR must be a string", + root["AUTHOR"])); } + JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(), + "* Line 1, Column 14\n" + " AUTHOR must be a string\n" + "See Line 1, Column 14 for detail.\n"); } struct CharReaderTest : JsonTest::TestCase {}; From d6c4a8fb2defc505d401d39097c00fdd8be9ae33 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Wed, 11 Dec 2019 15:12:37 -0500 Subject: [PATCH 257/410] tweak to avoid implicit narrowing warning. (#1114) * tweak to avoid implicit narrowing warning. change an int to size_t #1113 * Update main.cpp --- src/test_lib_json/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index a20ef3ead..6f4bbde04 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -124,8 +124,8 @@ Json::String ValueTest::normalizeFloatingPointStr(const Json::String& s) { auto index = s.find_last_of("eE"); if (index == s.npos) return s; - int hasSign = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; - auto exponentStartIndex = index + 1 + hasSign; + std::size_t signWidth = (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0; + auto exponentStartIndex = index + 1 + signWidth; Json::String normalized = s.substr(0, exponentStartIndex); auto indexDigit = s.find_first_not_of('0', exponentStartIndex); Json::String exponent = "0"; From 92d90250f2b3c34b355b32c5d7846870df4c21d3 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Mon, 23 Dec 2019 10:56:54 +0800 Subject: [PATCH 258/410] fix Reader bug and add testcase (#1122) --- src/lib_json/json_reader.cpp | 2 +- src/test_lib_json/main.cpp | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 87483da60..9818b5bf2 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -467,7 +467,7 @@ bool Reader::readObject(Token& token) { Value numberName; if (!decodeNumber(tokenName, numberName)) return recoverFromError(tokenObjectEnd); - name = String(numberName.asCString()); + name = numberName.asString(); } else { break; } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 6f4bbde04..6f5230450 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2648,6 +2648,10 @@ struct ReaderTest : JsonTest::TestCase { new Json::Reader(Json::Features{}.strictMode())); } + void setFeatures(Json::Features& features) { + reader = std::unique_ptr(new Json::Reader(features)); + } + void checkStructuredErrors( const std::vector& actual, const std::vector& expected) { @@ -2851,6 +2855,13 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) { "See Line 1, Column 14 for detail.\n"); } +JSONTEST_FIXTURE_LOCAL(ReaderTest, allowNumericKeysTest) { + Json::Features features; + features.allowNumericKeys_ = true; + setFeatures(features); + checkParse(R"({ 123 : "abc" })"); +} + struct CharReaderTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { From 7e5485ab5baea2faa578149a8b4cfd1fadb281c3 Mon Sep 17 00:00:00 2001 From: theirix Date: Mon, 23 Dec 2019 06:04:44 +0300 Subject: [PATCH 259/410] Add option JSONCPP_WITH_EXAMPLE (#1099) * Add option JSONCPP_WITH_EXAMPLE Allows to conditionally build examples as it has been done for tests. Useful for packaging. * Do not build example by default --- CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a7d3ef4a..4e0633173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,6 +82,7 @@ option(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occ option(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C and ISO C++" ON) option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) +option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF) option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) # Enable runtime search path support for dynamic libraries on OSX @@ -228,4 +229,6 @@ add_subdirectory( src ) add_subdirectory( include ) #install the example -add_subdirectory( example ) +if(JSONCPP_WITH_EXAMPLE) + add_subdirectory( example ) +endif() From 8f7f35c5cd281d03ba3b4fbe65efbbab8f7c6d18 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Thu, 26 Dec 2019 16:08:17 +0800 Subject: [PATCH 260/410] Replace Raw Unicode in Testcase (#1127) * use unicode code point * change values' order, because JSONTEST_ASSERT_EQUAL(expected, actual) --- src/test_lib_json/main.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 6f5230450..40d8ff273 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1819,7 +1819,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, StaticString) { JSONTEST_FIXTURE_LOCAL(ValueTest, WideString) { // https://github.com/open-source-parsers/jsoncpp/issues/756 - const std::string uni = u8"式,进"; // "\u5f0f\uff0c\u8fdb" + const std::string uni = u8"\u5f0f\uff0c\u8fdb"; // "式,进" std::string styled; { Json::Value v; @@ -2655,13 +2655,13 @@ struct ReaderTest : JsonTest::TestCase { void checkStructuredErrors( const std::vector& actual, const std::vector& expected) { - JSONTEST_ASSERT_EQUAL(actual.size(), expected.size()); + JSONTEST_ASSERT_EQUAL(expected.size(), actual.size()); for (size_t i = 0; i < actual.size(); ++i) { const auto& a = actual[i]; const auto& e = expected[i]; - JSONTEST_ASSERT_EQUAL(a.offset_start, e.offset_start) << i; - JSONTEST_ASSERT_EQUAL(a.offset_limit, e.offset_limit) << i; - JSONTEST_ASSERT_EQUAL(a.message, e.message) << i; + JSONTEST_ASSERT_EQUAL(e.offset_start, a.offset_start) << i; + JSONTEST_ASSERT_EQUAL(e.offset_limit, a.offset_limit) << i; + JSONTEST_ASSERT_EQUAL(e.message, a.message) << i; } } @@ -2682,7 +2682,7 @@ struct ReaderTest : JsonTest::TestCase { const std::vector& structured, const std::string& formatted) { checkParse(input, structured); - JSONTEST_ASSERT_EQUAL(reader->getFormattedErrorMessages(), formatted); + JSONTEST_ASSERT_EQUAL(formatted, reader->getFormattedErrorMessages()); } std::unique_ptr reader{new Json::Reader()}; @@ -2771,8 +2771,8 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) { R"( "false" : false)" R"( })"); auto checkOffsets = [&](const Json::Value& v, int start, int limit) { - JSONTEST_ASSERT_EQUAL(v.getOffsetStart(), start); - JSONTEST_ASSERT_EQUAL(v.getOffsetLimit(), limit); + JSONTEST_ASSERT_EQUAL(start, v.getOffsetStart()); + JSONTEST_ASSERT_EQUAL(limit, v.getOffsetLimit()); }; checkOffsets(root, 0, 115); checkOffsets(root["property"], 15, 34); @@ -2817,9 +2817,8 @@ JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) { } JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) { - // \u4f50\u85e4 佐藤 checkParse(R"({ "pr)" - "佐藤" + u8"\u4f50\u85e4" // 佐藤 R"(erty" :: "value" })", {{18, 19, "Syntax error: value, object or array expected."}}, "* Line 1, Column 19\n Syntax error: value, object or array " @@ -2921,7 +2920,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); - JSONTEST_ASSERT_EQUAL("訪", root[0].asString()); // "\u8A2a" + JSONTEST_ASSERT_EQUAL(u8"\u8A2a", root[0].asString()); // "訪" } { char const doc[] = "[ \"\\uD801\" ]"; @@ -3633,8 +3632,8 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, distance) { } { Json::Value empty; - JSONTEST_ASSERT_EQUAL(empty.end() - empty.end(), 0); - JSONTEST_ASSERT_EQUAL(empty.end() - empty.begin(), 0); + JSONTEST_ASSERT_EQUAL(0, empty.end() - empty.end()); + JSONTEST_ASSERT_EQUAL(0, empty.end() - empty.begin()); } } From f11611c8785082ead760494cba06196f14a06dcb Mon Sep 17 00:00:00 2001 From: Andrew Childs Date: Sat, 28 Dec 2019 16:04:24 +0900 Subject: [PATCH 261/410] json_writer: fix inverted sense in isAnyCharRequiredQuoting (#1120) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This bug is only affects platforms where `char` is unsigned. When char is a signed type, values >= 0x80 are also considered < 0, and hence require escaping due to the < ' ' condition. When char is an unsigned type, values >= 0x80 match none of the conditions and are considered safe to emit without escaping. This shows up as a test failure: * Detail of EscapeSequenceTest/writeEscapeSequence test failure: /build/source/src/test_lib_json/main.cpp(3370): expected == result Expected: '["\"","\\","\b","\f","\n","\r","\t","\u0278","\ud852\udf62"] ' Actual : '["\"","\\","\b","\f","\n","\r","\t","ɸ","𤭢"] ' --- src/lib_json/json_writer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 8e06cca24..56195dc15 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -178,8 +178,9 @@ static bool isAnyCharRequiredQuoting(char const* s, size_t n) { char const* const end = s + n; for (char const* cur = s; cur < end; ++cur) { - if (*cur == '\\' || *cur == '\"' || *cur < ' ' || - static_cast(*cur) < 0x80) + if (*cur == '\\' || *cur == '\"' || + static_cast(*cur) < ' ' || + static_cast(*cur) >= 0x80) return true; } return false; From 6bc55ec35d02931960ec1f5768fc9c56ab62ef66 Mon Sep 17 00:00:00 2001 From: David Seifert <16636962+SoapGentoo@users.noreply.github.com> Date: Tue, 7 Jan 2020 02:23:50 +0100 Subject: [PATCH 262/410] Meson updates (#1124) * Modernize meson.build * Make tests optional * Use `files()` for quick sanity checks * Bump version to 1.9.3 * Bump SOVERSION, as some functions were removed and structs were changed, as determined by libabigail. --- CMakeLists.txt | 2 +- include/json/version.h | 4 ++-- meson.build | 33 ++++++++++++++++++--------------- meson_options.txt | 5 +++++ 4 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 meson_options.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e0633173..c05ddccbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,7 +70,7 @@ project(JSONCPP # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - VERSION 1.9.2 # [.[.[.]]] + VERSION 1.9.3 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") diff --git a/include/json/version.h b/include/json/version.h index ff94372b0..0f2983411 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.2" +#define JSONCPP_VERSION_STRING "1.9.3" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 2 +#define JSONCPP_VERSION_PATCH 3 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/meson.build b/meson.build index 1bc94a8af..c29320307 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ project( # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - version : '1.9.2', + version : '1.9.3', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -18,7 +18,7 @@ project( meson_version : '>= 0.49.0') -jsoncpp_headers = [ +jsoncpp_headers = files([ 'include/json/allocator.h', 'include/json/assertions.h', 'include/json/config.h', @@ -28,7 +28,8 @@ jsoncpp_headers = [ 'include/json/reader.h', 'include/json/value.h', 'include/json/version.h', - 'include/json/writer.h'] + 'include/json/writer.h', +]) jsoncpp_include_directories = include_directories('include') install_headers( @@ -44,13 +45,12 @@ else endif jsoncpp_lib = library( - 'jsoncpp', - [ jsoncpp_headers, - 'src/lib_json/json_tool.h', + 'jsoncpp', files([ 'src/lib_json/json_reader.cpp', 'src/lib_json/json_value.cpp', - 'src/lib_json/json_writer.cpp'], - soversion : 22, + 'src/lib_json/json_writer.cpp', + ]), + soversion : 23, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) @@ -66,18 +66,21 @@ import('pkgconfig').generate( jsoncpp_dep = declare_dependency( include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, - version : meson.project_version(), - ) + version : meson.project_version()) # tests -python = import('python').find_installation() +if meson.is_subproject() or not get_option('tests') + subdir_done() +endif + +python = import('python').find_installation('python3') jsoncpp_test = executable( - 'jsoncpp_test', - [ 'src/test_lib_json/jsontest.cpp', - 'src/test_lib_json/jsontest.h', + 'jsoncpp_test', files([ + 'src/test_lib_json/jsontest.cpp', 'src/test_lib_json/main.cpp', - 'src/test_lib_json/fuzz.cpp'], + 'src/test_lib_json/fuzz.cpp', + ]), include_directories : jsoncpp_include_directories, link_with : jsoncpp_lib, install : false, diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 000000000..9c215ae6f --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,5 @@ +option( + 'tests', + type : 'boolean', + value : true, + description : 'Enable building tests') From 6317f9a406c43e264e0ae0164fa701362ef04c9a Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Mon, 20 Jan 2020 17:12:35 +0800 Subject: [PATCH 263/410] fix compile warnning using cmake (#1132) --- src/test_lib_json/main.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 40d8ff273..c2df69db0 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3309,15 +3309,15 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowDropNullTest, issue178) { {__LINE__, R"({"a":,"b":true})", 2, objGetAnd("a", checkEq(nullValue))}, {__LINE__, R"({"a":})", 1, objGetAnd("a", checkEq(nullValue))}, {__LINE__, "[]", 0, checkEq(emptyArray)}, - {__LINE__, "[null]", 1}, - {__LINE__, "[,]", 2}, - {__LINE__, "[,,,]", 4}, - {__LINE__, "[null,]", 2}, - {__LINE__, "[,null]", 2}, - {__LINE__, "[,,]", 3}, - {__LINE__, "[null,,]", 3}, - {__LINE__, "[,null,]", 3}, - {__LINE__, "[,,null]", 3}, + {__LINE__, "[null]", 1, nullptr}, + {__LINE__, "[,]", 2, nullptr}, + {__LINE__, "[,,,]", 4, nullptr}, + {__LINE__, "[null,]", 2, nullptr}, + {__LINE__, "[,null]", 2, nullptr}, + {__LINE__, "[,,]", 3, nullptr}, + {__LINE__, "[null,,]", 3, nullptr}, + {__LINE__, "[,null,]", 3, nullptr}, + {__LINE__, "[,,null]", 3, nullptr}, {__LINE__, "[[],,,]", 4, arrGetAnd(0, checkEq(emptyArray))}, {__LINE__, "[,[],,]", 4, arrGetAnd(1, checkEq(emptyArray))}, {__LINE__, "[,,,[]]", 4, arrGetAnd(3, checkEq(emptyArray))}, From edf528edfa66fd02f54f81ae341592f50e61c39f Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 2 Feb 2020 20:03:45 -0800 Subject: [PATCH 264/410] clang-tidy fixes again (#1087) * [clang-tidy] Do not use else after return Found with readability-else-after-return Signed-off-by: Rosen Penev * [clang-tidy] Convert several loops to be range based Found with modernize-loop-convert Signed-off-by: Rosen Penev * [clang-tidy] Replace deprecated C headers Found with modernize-deprecated-headers Signed-off-by: Rosen Penev * [clang-tidy] Use auto where applicable Found with modernize-use-auto Signed-off-by: Rosen Penev * .clang-tidy: Add these checks --- .clang-tidy | 2 +- src/jsontestrunner/main.cpp | 6 +++--- src/lib_json/json_reader.cpp | 19 +++++++++---------- src/lib_json/json_value.cpp | 14 ++++++-------- src/test_lib_json/fuzz.cpp | 1 - src/test_lib_json/jsontest.cpp | 24 ++++++++++++------------ src/test_lib_json/main.cpp | 8 +++----- 7 files changed, 34 insertions(+), 40 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index b78b3247e..be3d06a52 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: 'google-readability-casting,modernize-use-default-member-init,modernize-use-using,modernize-use-auto,readability-redundant-member-init' +Checks: 'google-readability-casting,modernize-deprecated-headers,modernize-loop-convert,modernize-use-auto,modernize-use-default-member-init,modernize-use-using,readability-else-after-return,readability-redundant-member-init,readability-redundant-string-cstr' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index f6b1a4dc3..cdf6bffb0 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -57,10 +57,10 @@ static Json::String readInputTestFile(const char* path) { if (!file) return ""; fseek(file, 0, SEEK_END); - long const size = ftell(file); - const auto usize = static_cast(size); + auto const size = ftell(file); + auto const usize = static_cast(size); fseek(file, 0, SEEK_SET); - char* buffer = new char[size + 1]; + auto buffer = new char[size + 1]; buffer[size] = 0; Json::String text; if (fread(buffer, 1, usize, file) == usize) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 9818b5bf2..2c6fead19 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -637,7 +637,7 @@ bool Reader::decodeString(Token& token, String& decoded) { Char c = *current++; if (c == '"') break; - else if (c == '\\') { + if (c == '\\') { if (current == end) return addError("Empty escape sequence in string", token, current); Char escape = *current++; @@ -1358,11 +1358,10 @@ bool OurReader::readCStyleComment(bool* containsNewLineResult) { while ((current_ + 1) < end_) { Char c = getNextChar(); - if (c == '*' && *current_ == '/') { + if (c == '*' && *current_ == '/') break; - } else if (c == '\n') { + if (c == '\n') *containsNewLineResult = true; - } } return getNextChar() == '/'; @@ -1586,9 +1585,9 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { // then take the inverse. This assumes that minLargestInt is only a single // power of 10 different in magnitude, which we check above. For the last // digit, we take the modulus before negating for the same reason. - static constexpr Value::LargestUInt negative_threshold = + static constexpr auto negative_threshold = Value::LargestUInt(-(Value::minLargestInt / 10)); - static constexpr Value::UInt negative_last_digit = + static constexpr auto negative_last_digit = Value::UInt(-(Value::minLargestInt % 10)); const Value::LargestUInt threshold = @@ -1602,7 +1601,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (c < '0' || c > '9') return decodeDouble(token, decoded); - const Value::UInt digit(static_cast(c - '0')); + const auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If // a) we've only just touched the limit, meaing value == threshold, @@ -1619,7 +1618,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { if (isNegative) { // We use the same magnitude assumption here, just in case. - const Value::UInt last_digit = static_cast(value % 10); + const auto last_digit = static_cast(value % 10); decoded = -Value::LargestInt(value / 10) * 10 - last_digit; } else if (value <= Value::LargestUInt(Value::maxLargestInt)) { decoded = Value::LargestInt(value); @@ -1669,9 +1668,9 @@ bool OurReader::decodeString(Token& token, String& decoded) { Location end = token.end_ - 1; // do not include '"' while (current != end) { Char c = *current++; - if (c == '"') { + if (c == '"') break; - } else if (c == '\\') { + if (c == '\\') { if (current == end) return addError("Empty escape sequence in string", token, current); Char escape = *current++; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 1e3bbdebd..74535fbd9 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -875,8 +875,7 @@ ArrayIndex Value::size() const { bool Value::empty() const { if (isNull() || isArray() || isObject()) return size() == 0U; - else - return false; + return false; } Value::operator bool() const { return !isNull(); } @@ -1137,13 +1136,12 @@ bool Value::insert(ArrayIndex index, Value&& newValue) { ArrayIndex length = size(); if (index > length) { return false; - } else { - for (ArrayIndex i = length; i > index; i--) { - (*this)[i] = std::move((*this)[i - 1]); - } - (*this)[index] = std::move(newValue); - return true; } + for (ArrayIndex i = length; i > index; i--) { + (*this)[i] = std::move((*this)[i - 1]); + } + (*this)[index] = std::move(newValue); + return true; } Value Value::get(char const* begin, char const* end, diff --git a/src/test_lib_json/fuzz.cpp b/src/test_lib_json/fuzz.cpp index 68f839d53..5b75c22e6 100644 --- a/src/test_lib_json/fuzz.cpp +++ b/src/test_lib_json/fuzz.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include namespace Json { diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 0cc500a88..0b7d12b97 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -267,19 +267,18 @@ bool Runner::runAllTest(bool printSummary) const { printf("All %zu tests passed\n", count); } return true; - } else { - for (auto& result : failures) { - result.printFailure(count > 1); - } + } + for (auto& result : failures) { + result.printFailure(count > 1); + } - if (printSummary) { - size_t const failedCount = failures.size(); - size_t const passedCount = count - failedCount; - printf("%zu/%zu tests passed (%zu failure(s))\n", passedCount, count, - failedCount); - } - return false; + if (printSummary) { + size_t const failedCount = failures.size(); + size_t const passedCount = count - failedCount; + printf("%zu/%zu tests passed (%zu failure(s))\n", passedCount, count, + failedCount); } + return false; } bool Runner::testIndex(const Json::String& testName, size_t& indexOut) const { @@ -308,7 +307,8 @@ int Runner::runCommandLine(int argc, const char* argv[]) const { if (opt == "--list-tests") { listTests(); return 0; - } else if (opt == "--test-auto") { + } + if (opt == "--test-auto") { preventDialogOnCrash(); } else if (opt == "--test") { ++index; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index c2df69db0..7b20e41ec 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1476,9 +1476,7 @@ void ValueTest::checkMemberCount(Json::Value& value, JSONTEST_ASSERT_PRED(checkConstMemberCount(value, expectedCount)); } -ValueTest::IsCheck::IsCheck() - - = default; +ValueTest::IsCheck::IsCheck() = default; void ValueTest::checkIs(const Json::Value& value, const IsCheck& check) { JSONTEST_ASSERT_EQUAL(check.isObject_, value.isObject()); @@ -3752,8 +3750,8 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) { int main(int argc, const char* argv[]) { JsonTest::Runner runner; - for (auto it = local_.begin(); it != local_.end(); it++) { - runner.add(*it); + for (auto& local : local_) { + runner.add(local); } return runner.runCommandLine(argc, argv); From a6fe8e27d84b927d820a89a0f134a934e09a63ed Mon Sep 17 00:00:00 2001 From: Claus Klein Date: Thu, 13 Feb 2020 22:20:46 +0100 Subject: [PATCH 265/410] Use ccache right (#1139) * Prevent cmakelint warnings Use 4 spaces for indent, no tabs * Use ccache right fix indents too at CMakeLists.txt --- CMakeLists.txt | 134 +++++++++++++++--------------- example/CMakeLists.txt | 33 ++++---- src/jsontestrunner/CMakeLists.txt | 42 +++++----- src/lib_json/CMakeLists.txt | 68 ++++++++------- src/test_lib_json/CMakeLists.txt | 44 +++++----- 5 files changed, 166 insertions(+), 155 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c05ddccbb..b7e2e09ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,7 @@ foreach(pold "") # Currently Empty endforeach() # ==== Define language standard configurations requiring at least c++11 standard -if(CMAKE_CXX_STANDARD EQUAL "98" ) +if(CMAKE_CXX_STANDARD EQUAL "98") message(FATAL_ERROR "CMAKE_CXX_STANDARD:STRING=98 is not supported.") endif() @@ -62,19 +62,29 @@ if(NOT DEFINED CMAKE_BUILD_TYPE) "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") endif() +# --------------------------------------------------------------------------- +# use ccache if found, has to be done before project() +# --------------------------------------------------------------------------- +find_program(CCACHE_EXECUTABLE "ccache" HINTS /usr/local/bin /opt/local/bin) +if(CCACHE_EXECUTABLE) + message(STATUS "use ccache") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE) +endif() + project(JSONCPP # Note: version must be updated in three places when doing a release. This # annoying process ensures that amalgamate, CMake, and meson all report the # correct version. - # 1. /meson.build - # 2. /include/json/version.h - # 3. /CMakeLists.txt - # IMPORTANT: also update the SOVERSION!! + # 1. ./meson.build + # 2. ./include/json/version.h + # 3. ./CMakeLists.txt + # IMPORTANT: also update the JSONCPP_SOVERSION!! VERSION 1.9.3 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set( JSONCPP_SOVERSION 22 ) +set(JSONCPP_SOVERSION 23) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) @@ -95,105 +105,99 @@ include(GNUInstallDirs) set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build") -set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL" ) +set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL") -configure_file( "${PROJECT_SOURCE_DIR}/version.in" - "${PROJECT_BINARY_DIR}/version" - NEWLINE_STYLE UNIX ) +configure_file("${PROJECT_SOURCE_DIR}/version.in" + "${PROJECT_BINARY_DIR}/version" + NEWLINE_STYLE UNIX) -macro(UseCompilationWarningAsError) +macro(use_compilation_warning_as_error) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # warnings when compiled in release configuration. if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options($<$:/WX>) + add_compile_options($<$:/WX>) else() - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Werror) + add_compile_options(-Werror) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") endif() if(JSONCPP_WITH_STRICT_ISO) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-pedantic-errors) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-pedantic-errors) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") + endif() endif() endif() endmacro() # Include our configuration header -include_directories( ${jsoncpp_SOURCE_DIR}/include ) +include_directories(${jsoncpp_SOURCE_DIR}/include) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options($<$:/W4>) + add_compile_options($<$:/W4>) else() - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") endif() endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) + add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Wextra) + add_compile_options(-Wall -Wconversion -Wshadow -Wextra) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") endif() # not yet ready for -Wsign-conversion if(JSONCPP_WITH_STRICT_ISO) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-pedantic) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Wpedantic) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") + endif() endif() if(JSONCPP_WITH_WARNING_AS_ERROR) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Werror=conversion) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Werror=conversion) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") + endif() endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) + add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") endif() if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-pedantic) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_options(-Wpedantic) + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") + endif() endif() endif() -find_program(CCACHE_FOUND ccache) -if(CCACHE_FOUND) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) -endif(CCACHE_FOUND) - if(JSONCPP_WITH_WARNING_AS_ERROR) - UseCompilationWarningAsError() + use_compilation_warning_as_error() endif() if(JSONCPP_WITH_PKGCONFIG_SUPPORT) @@ -206,29 +210,29 @@ if(JSONCPP_WITH_PKGCONFIG_SUPPORT) endif() if(JSONCPP_WITH_CMAKE_PACKAGE) - include (CMakePackageConfigHelpers) - install(EXPORT jsoncpp - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp - FILE jsoncppConfig.cmake) - write_basic_package_version_file ("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) + include(CMakePackageConfigHelpers) + install(EXPORT jsoncpp + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp + FILE jsoncppConfig.cmake) + write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) endif() if(JSONCPP_WITH_TESTS) - enable_testing() - include(CTest) + enable_testing() + include(CTest) endif() # Build the different applications -add_subdirectory( src ) +add_subdirectory(src) #install the includes -add_subdirectory( include ) +add_subdirectory(include) #install the example if(JSONCPP_WITH_EXAMPLE) - add_subdirectory( example ) + add_subdirectory(example) endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index c8eba5335..51c32182d 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,28 +2,29 @@ cmake_minimum_required(VERSION 3.1) set(EXAMPLES - readFromString - readFromStream - stringWrite - streamWrite - ) + readFromString + readFromStream + stringWrite + streamWrite +) add_definitions(-D_GLIBCXX_USE_CXX11_ABI) set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") -else() - add_definitions( - -D_SCL_SECURE_NO_WARNINGS - -D_CRT_SECURE_NO_WARNINGS - -D_WIN32_WINNT=0x601 - -D_WINSOCK_DEPRECATED_NO_WARNINGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") +else() + add_definitions( + -D_SCL_SECURE_NO_WARNINGS + -D_CRT_SECURE_NO_WARNINGS + -D_WIN32_WINNT=0x601 + -D_WINSOCK_DEPRECATED_NO_WARNINGS + ) endif() -foreach (example ${EXAMPLES}) - add_executable(${example} ${example}/${example}.cpp) - target_include_directories(${example} PUBLIC ${CMAKE_SOURCE_DIR}/include) - target_link_libraries(${example} jsoncpp_lib) +foreach(example ${EXAMPLES}) + add_executable(${example} ${example}/${example}.cpp) + target_include_directories(${example} PUBLIC ${CMAKE_SOURCE_DIR}/include) + target_link_libraries(${example} jsoncpp_lib) endforeach() add_custom_target(examples ALL DEPENDS ${EXAMPLES}) diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index 210e0900b..d24aa6f46 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -1,24 +1,24 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - # The new Python3 module is much more robust than the previous PythonInterp - find_package (Python3 COMPONENTS Interpreter) - # Set variables for backwards compatibility with cmake < 3.12.0 - set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND}) - set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) + # The new Python3 module is much more robust than the previous PythonInterp + find_package(Python3 COMPONENTS Interpreter) + # Set variables for backwards compatibility with cmake < 3.12.0 + set(PYTHONINTERP_FOUND ${Python3_Interpreter_FOUND}) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) else() - set(Python_ADDITIONAL_VERSIONS 3.8) - find_package(PythonInterp 3) + set(Python_ADDITIONAL_VERSIONS 3.8) + find_package(PythonInterp 3) endif() add_executable(jsontestrunner_exe - main.cpp - ) + main.cpp +) if(BUILD_SHARED_LIBS) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_definitions( JSON_DLL ) - else() - add_definitions( -DJSON_DLL ) - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_definitions( JSON_DLL ) + else() + add_definitions(-DJSON_DLL) + endif() endif() target_link_libraries(jsontestrunner_exe jsoncpp_lib) @@ -32,18 +32,18 @@ if(PYTHONINTERP_FOUND) # Run unit tests in post-build # (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) add_custom_target(jsoncpp_readerwriter_tests - "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" - DEPENDS jsontestrunner_exe jsoncpp_test - ) + "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" + DEPENDS jsontestrunner_exe jsoncpp_test + ) add_custom_target(jsoncpp_check DEPENDS jsoncpp_readerwriter_tests) ## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp add_test(NAME jsoncpp_readerwriter - COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" - WORKING_DIRECTORY "${TEST_DIR}/data" + COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" $ "${TEST_DIR}/data" + WORKING_DIRECTORY "${TEST_DIR}/data" ) add_test(NAME jsoncpp_readerwriter_json_checker - COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $ "${TEST_DIR}/data" - WORKING_DIRECTORY "${TEST_DIR}/data" + COMMAND "${PYTHON_EXECUTABLE}" -B "${RUNJSONTESTS_PATH}" --with-json-checker $ "${TEST_DIR}/data" + WORKING_DIRECTORY "${TEST_DIR}/data" ) endif() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index b56788e27..401e1f7e8 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -1,13 +1,14 @@ -if( CMAKE_COMPILER_IS_GNUCXX ) +if(CMAKE_COMPILER_IS_GNUCXX) #Get compiler version. - execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion - OUTPUT_VARIABLE GNUCXX_VERSION ) + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion + OUTPUT_VARIABLE GNUCXX_VERSION + ) #-Werror=* was introduced -after- GCC 4.1.2 - if( GNUCXX_VERSION VERSION_GREATER 4.1.2 ) + if(GNUCXX_VERSION VERSION_GREATER 4.1.2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing") endif() -endif( CMAKE_COMPILER_IS_GNUCXX ) +endif() include(CheckIncludeFileCXX) include(CheckTypeSize) @@ -35,15 +36,15 @@ endif() if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) message(WARNING "Locale functionality is not supported") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT) + add_compile_definitions(JSONCPP_NO_LOCALE_SUPPORT) else() - add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) + add_definitions(-DJSONCPP_NO_LOCALE_SUPPORT) endif() endif() -set( JSONCPP_INCLUDE_DIR ../../include ) +set(JSONCPP_INCLUDE_DIR ../../include) -set( PUBLIC_HEADERS +set(PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/config.h ${JSONCPP_INCLUDE_DIR}/json/forwards.h ${JSONCPP_INCLUDE_DIR}/json/json_features.h @@ -52,43 +53,44 @@ set( PUBLIC_HEADERS ${JSONCPP_INCLUDE_DIR}/json/version.h ${JSONCPP_INCLUDE_DIR}/json/writer.h ${JSONCPP_INCLUDE_DIR}/json/assertions.h - ) +) -source_group( "Public API" FILES ${PUBLIC_HEADERS} ) +source_group("Public API" FILES ${PUBLIC_HEADERS}) set(jsoncpp_sources - json_tool.h - json_reader.cpp - json_valueiterator.inl - json_value.cpp - json_writer.cpp) + json_tool.h + json_reader.cpp + json_valueiterator.inl + json_value.cpp + json_writer.cpp +) # Install instructions for this target if(JSONCPP_WITH_CMAKE_PACKAGE) set(INSTALL_EXPORT EXPORT jsoncpp) -else(JSONCPP_WITH_CMAKE_PACKAGE) +else() set(INSTALL_EXPORT) endif() if(BUILD_SHARED_LIBS) if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_definitions( JSON_DLL_BUILD ) + add_compile_definitions(JSON_DLL_BUILD) else() - add_definitions( -DJSON_DLL_BUILD ) + add_definitions(-DJSON_DLL_BUILD) endif() endif() add_library(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) -set_target_properties( jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) -set_target_properties( jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp - DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX} ) -set_target_properties( jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties(jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) +set_target_properties(jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp + DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX}) +set_target_properties(jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) # Set library's runtime search path on OSX if(APPLE) - set_target_properties( jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/." ) + set_target_properties(jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/.") endif() # Specify compiler features required when compiling a given target. @@ -141,14 +143,16 @@ target_compile_features(jsoncpp_lib PUBLIC cxx_variadic_templates # Variadic templates, as defined in N2242. ) -install( TARGETS jsoncpp_lib ${INSTALL_EXPORT} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS jsoncpp_lib ${INSTALL_EXPORT} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories( jsoncpp_lib PUBLIC - $ - $ - $) + target_include_directories(jsoncpp_lib PUBLIC + $ + $ + $ + ) endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index 6e301ec69..c9730d0d2 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -1,20 +1,20 @@ # vim: et ts=4 sts=4 sw=4 tw=0 -add_executable( jsoncpp_test - jsontest.cpp - jsontest.h - fuzz.cpp - fuzz.h - main.cpp - ) +add_executable(jsoncpp_test + jsontest.cpp + jsontest.h + fuzz.cpp + fuzz.h + main.cpp +) if(BUILD_SHARED_LIBS) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_definitions( JSON_DLL ) - else() - add_definitions( -DJSON_DLL ) - endif() + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_definitions( JSON_DLL ) + else() + add_definitions( -DJSON_DLL ) + endif() endif() target_link_libraries(jsoncpp_test jsoncpp_lib) @@ -27,19 +27,21 @@ if(JSONCPP_WITH_POST_BUILD_UNITTEST) if(BUILD_SHARED_LIBS) # First, copy the shared lib, for Microsoft. # Then, run the test executable. - add_custom_command( TARGET jsoncpp_test - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) - else(BUILD_SHARED_LIBS) + add_custom_command(TARGET jsoncpp_test + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + ) + else() # Just run the test executable. - add_custom_command( TARGET jsoncpp_test - POST_BUILD - COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + add_custom_command(TARGET jsoncpp_test + POST_BUILD + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + ) endif() ## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp add_test(NAME jsoncpp_test - COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ) endif() From dc180eb25eca8d7ce16f062641e005e464ea398f Mon Sep 17 00:00:00 2001 From: David Gobbi Date: Thu, 13 Feb 2020 14:22:49 -0700 Subject: [PATCH 266/410] Remove '=delete' from template methods for Xcode 8 (#1133) For Apple clang-800.0.42.1, which was released with Xcode 8 in September 2016, the '=delete' on the 'is' and 'as' methods causes the following errors for value.h: inline declaration of 'as' follows non-inline definition inline declaration of 'is' follows non-inline definition etcetera for the other specializations of 'is' and 'as'. The same problem also occurs for clang-3.8 but not clang-3.9 or later. --- include/json/value.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index e169c3c69..bea2a568e 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -21,6 +21,24 @@ #endif #endif +// Support for '= delete' with template declarations was a late addition +// to the c++11 standard and is rejected by clang 3.8 and Apple clang 8.2 +// even though these declare themselves to be c++11 compilers. +#if !defined(JSONCPP_TEMPLATE_DELETE) +#if defined(__clang__) && defined(__apple_build_version__) +#if __apple_build_version__ <= 8000042 +#define JSONCPP_TEMPLATE_DELETE +#endif +#elif defined(__clang__) +#if __clang_major__ == 3 && __clang_minor__ <= 8 +#define JSONCPP_TEMPLATE_DELETE +#endif +#endif +#if !defined(JSONCPP_TEMPLATE_DELETE) +#define JSONCPP_TEMPLATE_DELETE = delete +#endif +#endif + #include #include #include @@ -390,8 +408,8 @@ class JSON_API Value { bool isObject() const; /// The `as` and `is` member function templates and specializations. - template T as() const = delete; - template bool is() const = delete; + template T as() const JSONCPP_TEMPLATE_DELETE; + template bool is() const JSONCPP_TEMPLATE_DELETE; bool isConvertibleTo(ValueType other) const; From 3beb37ea14aec1bdce1a6d542dc464d00f4a6cec Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Fri, 14 Feb 2020 05:25:08 +0800 Subject: [PATCH 267/410] revert trailing comma in old Reader (#1126) --- include/json/json_features.h | 6 ------ src/lib_json/json_reader.cpp | 24 ++++++++---------------- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/include/json/json_features.h b/include/json/json_features.h index a5b73052a..7c7e9f5de 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -23,7 +23,6 @@ class JSON_API Features { /** \brief A configuration that allows all features and assumes all strings * are UTF-8. * - C & C++ comments are allowed - * - Trailing commas in objects and arrays are allowed. * - Root object can be any JSON value * - Assumes Value strings are encoded in UTF-8 */ @@ -32,7 +31,6 @@ class JSON_API Features { /** \brief A configuration that is strictly compatible with the JSON * specification. * - Comments are forbidden. - * - Trailing commas in objects and arrays are forbidden. * - Root object must be either an array or an object value. * - Assumes Value strings are encoded in UTF-8 */ @@ -45,10 +43,6 @@ class JSON_API Features { /// \c true if comments are allowed. Default: \c true. bool allowComments_{true}; - /// \c true if trailing commas in objects and arrays are allowed. Default \c - /// true. - bool allowTrailingCommas_{true}; - /// \c true if root must be either an array or an object value. Default: \c /// false. bool strictRoot_{false}; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 2c6fead19..10be6d2cf 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -67,7 +67,6 @@ Features Features::all() { return {}; } Features Features::strictMode() { Features features; features.allowComments_ = false; - features.allowTrailingCommas_ = false; features.strictRoot_ = true; features.allowDroppedNullPlaceholders_ = false; features.allowNumericKeys_ = false; @@ -455,9 +454,7 @@ bool Reader::readObject(Token& token) { initialTokenOk = readToken(tokenName); if (!initialTokenOk) break; - if (tokenName.type_ == tokenObjectEnd && - (name.empty() || - features_.allowTrailingCommas_)) // empty object or trailing comma + if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); if (tokenName.type_ == tokenString) { @@ -505,20 +502,15 @@ bool Reader::readArray(Token& token) { Value init(arrayValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); + skipSpaces(); + if (current_ != end_ && *current_ == ']') // empty array + { + Token endArray; + readToken(endArray); + return true; + } int index = 0; for (;;) { - skipSpaces(); - if (current_ != end_ && *current_ == ']' && - (index == 0 || - (features_.allowTrailingCommas_ && - !features_.allowDroppedNullPlaceholders_))) // empty array or trailing - // comma - { - Token endArray; - readToken(endArray); - return true; - } - Value& value = currentValue()[index++]; nodes_.push(&value); bool ok = readValue(); From 90ca694e4697497a8c2bc8c60a9c9f89e7290a10 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sat, 11 Apr 2020 22:26:04 -0700 Subject: [PATCH 268/410] clang-tidy fixes again (#1155) * [clang-tidy] remove redundant string initialization Found with readability-redundant-string-init Signed-off-by: Rosen Penev * [clang-tidy] switch to raw strings Easier to read. Found with modernize-raw-string-literal Signed-off-by: Rosen Penev * [clang-tidy] fix performance issues Found with performance* Signed-off-by: Rosen Penev * fix extra comma warnings Found with clang's -Wextra-semi-stmt Signed-off-by: Rosen Penev * remove JSONCPP_OP_EXPLICIT This codebase in C++11. No need for compatibility with C++98. Signed-off-by: Rosen Penev * remove JSONCPP_NOEXCEPT This codebase is C++11 now. No need for this macro. Signed-off-by: Rosen Penev --- include/json/assertions.h | 16 ++++++++------ include/json/config.h | 14 ------------ include/json/value.h | 6 ++--- src/jsontestrunner/main.cpp | 2 +- src/lib_json/json_value.cpp | 4 ++-- src/test_lib_json/jsontest.h | 8 +++---- src/test_lib_json/main.cpp | 43 ++++++++++++++++++------------------ 7 files changed, 40 insertions(+), 53 deletions(-) diff --git a/include/json/assertions.h b/include/json/assertions.h index 9d93238dc..666fa7f54 100644 --- a/include/json/assertions.h +++ b/include/json/assertions.h @@ -21,19 +21,19 @@ // @todo <= add detail about condition in exception #define JSON_ASSERT(condition) \ - { \ + do { \ if (!(condition)) { \ Json::throwLogicError("assert json failed"); \ } \ - } + } while (0) #define JSON_FAIL_MESSAGE(message) \ - { \ + do { \ OStringStream oss; \ oss << message; \ Json::throwLogicError(oss.str()); \ abort(); \ - } + } while (0) #else // JSON_USE_EXCEPTION @@ -52,8 +52,10 @@ #endif #define JSON_ASSERT_MESSAGE(condition, message) \ - if (!(condition)) { \ - JSON_FAIL_MESSAGE(message); \ - } + do { \ + if (!(condition)) { \ + JSON_FAIL_MESSAGE(message); \ + } \ + } while (0) #endif // JSON_ASSERTIONS_H_INCLUDED diff --git a/include/json/config.h b/include/json/config.h index 3d148a69b..6359273a2 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -74,20 +74,6 @@ extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size, // C++11 should be used directly in JSONCPP. #define JSONCPP_OVERRIDE override -#if __cplusplus >= 201103L -#define JSONCPP_NOEXCEPT noexcept -#define JSONCPP_OP_EXPLICIT explicit -#elif defined(_MSC_VER) && _MSC_VER < 1900 -#define JSONCPP_NOEXCEPT throw() -#define JSONCPP_OP_EXPLICIT explicit -#elif defined(_MSC_VER) && _MSC_VER >= 1900 -#define JSONCPP_NOEXCEPT noexcept -#define JSONCPP_OP_EXPLICIT explicit -#else -#define JSONCPP_NOEXCEPT throw() -#define JSONCPP_OP_EXPLICIT -#endif - #ifdef __clang__ #if __has_extension(attribute_deprecated_with_message) #define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message))) diff --git a/include/json/value.h b/include/json/value.h index bea2a568e..dffc51a85 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -67,8 +67,8 @@ namespace Json { class JSON_API Exception : public std::exception { public: Exception(String msg); - ~Exception() JSONCPP_NOEXCEPT override; - char const* what() const JSONCPP_NOEXCEPT override; + ~Exception() noexcept override; + char const* what() const noexcept override; protected: String msg_; @@ -421,7 +421,7 @@ class JSON_API Value { bool empty() const; /// Return !isNull() - JSONCPP_OP_EXPLICIT operator bool() const; + explicit operator bool() const; /// Remove all object members and array elements. /// \pre type() is arrayValue, objectValue, or nullValue diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index cdf6bffb0..3452c5986 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -111,7 +111,7 @@ static void printValueTree(FILE* fout, Json::Value& value, Json::Value::Members members(value.getMemberNames()); std::sort(members.begin(), members.end()); Json::String suffix = *(path.end() - 1) == '.' ? "" : "."; - for (auto name : members) { + for (const auto& name : members) { printValueTree(fout, value[name], path + suffix + name); } } break; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 74535fbd9..71dba6e8c 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -200,8 +200,8 @@ namespace Json { #if JSON_USE_EXCEPTION Exception::Exception(String msg) : msg_(std::move(msg)) {} -Exception::~Exception() JSONCPP_NOEXCEPT = default; -char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } +Exception::~Exception() noexcept = default; +char const* Exception::what() const noexcept { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} JSONCPP_NORETURN void throwRuntimeError(String const& msg) { diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 8c3aa5e32..4e8af0f25 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -207,7 +207,7 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, /// The predicate may do other assertions and be a member function of the /// fixture. #define JSONTEST_ASSERT_PRED(expr) \ - { \ + do { \ JsonTest::PredicateContext _minitest_Context = { \ result_->predicateId_, __FILE__, __LINE__, #expr, NULL, NULL}; \ result_->predicateStackTail_->next_ = &_minitest_Context; \ @@ -215,7 +215,7 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, result_->predicateStackTail_ = &_minitest_Context; \ (expr); \ result_->popPredicateContext(); \ - } + } while (0) /// \brief Asserts that two values are equals. #define JSONTEST_ASSERT_EQUAL(expected, actual) \ @@ -230,7 +230,7 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, /// \brief Asserts that a given expression throws an exception #define JSONTEST_ASSERT_THROWS(expr) \ - { \ + do { \ bool _threw = false; \ try { \ expr; \ @@ -240,7 +240,7 @@ TestResult& checkStringEqual(TestResult& result, const Json::String& expected, if (!_threw) \ result_->addFailure(__FILE__, __LINE__, \ "expected exception thrown: " #expr); \ - } + } while (0) /// \brief Begin a fixture test case. #define JSONTEST_FIXTURE(FixtureType, name) \ diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 7b20e41ec..f0b84fcc7 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1874,7 +1874,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, CommentBefore) { Json::String result = Json::writeString(wbuilder, val); JSONTEST_ASSERT_STRING_EQUAL(expected, result); Json::String res2 = val.toStyledString(); - Json::String exp2 = ""; + Json::String exp2; exp2 += expected; exp2 += "\n"; JSONTEST_ASSERT_STRING_EQUAL(exp2, res2); @@ -2592,7 +2592,7 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, indentation) { JSONTEST_FIXTURE_LOCAL(StreamWriterTest, writeZeroes) { Json::String binary("hi", 3); // include trailing 0 JSONTEST_ASSERT_EQUAL(3, binary.length()); - Json::String expected("\"hi\\u0000\""); // unicoded zero + Json::String expected(R"("hi\u0000")"); // unicoded zero Json::StreamWriterBuilder b; { Json::Value root; @@ -2866,7 +2866,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithNoErrors) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = "{ \"property\" : \"value\" }"; + char const doc[] = R"({ "property" : "value" })"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); @@ -2914,14 +2914,14 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { JSONTEST_ASSERT_EQUAL("", root[0]); } { - char const doc[] = "[\"\\u8A2a\"]"; + char const doc[] = R"(["\u8A2a"])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_EQUAL(u8"\u8A2a", root[0].asString()); // "訪" } { - char const doc[] = "[ \"\\uD801\" ]"; + char const doc[] = R"([ "\uD801" ])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2930,7 +2930,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 10 for detail.\n"); } { - char const doc[] = "[ \"\\uD801\\d1234\" ]"; + char const doc[] = R"([ "\uD801\d1234" ])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2939,7 +2939,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 12 for detail.\n"); } { - char const doc[] = "[ \"\\ua3t@\" ]"; + char const doc[] = R"([ "\ua3t@" ])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 3\n" @@ -2948,7 +2948,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { "See Line 1, Column 9 for detail.\n"); } { - char const doc[] = "[ \"\\ua3t\" ]"; + char const doc[] = R"([ "\ua3t" ])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT( @@ -2960,7 +2960,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseString) { { b.settings_["allowSingleQuotes"] = true; CharReaderPtr charreader(b.newCharReader()); - char const doc[] = "{'a': 'x\\ty', \"b\":'x\\\\y'}"; + char const doc[] = R"({'a': 'x\ty', "b":'x\\y'})"; bool ok = charreader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -3007,7 +3007,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { Json::Value root; Json::String errs; { - char const doc[] = "{ \"property\" : \"value\" "; + char const doc[] = R"({ "property" : "value" )"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 24\n" @@ -3015,7 +3015,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseObjectWithErrors) { JSONTEST_ASSERT_EQUAL("value", root["property"]); } { - char const doc[] = "{ \"property\" : \"value\" ,"; + char const doc[] = R"({ "property" : "value" ,)"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 25\n" @@ -3038,7 +3038,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseArrayWithErrors) { JSONTEST_ASSERT_EQUAL("value", root[0]); } { - char const doc[] = "[ \"value1\" \"value2\" ]"; + char const doc[] = R"([ "value1" "value2" ])"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == "* Line 1, Column 12\n" @@ -3052,7 +3052,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithOneError) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = "{ \"property\" :: \"value\" }"; + char const doc[] = R"({ "property" :: "value" })"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == @@ -3078,7 +3078,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { CharReaderPtr reader(b.newCharReader()); Json::String errs; Json::Value root; - char const doc[] = "{ \"property\" : \"v\\alue\" }"; + char const doc[] = R"({ "property" : "v\alue" })"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(!ok); JSONTEST_ASSERT(errs == @@ -3089,7 +3089,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithDetailError) { JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { Json::CharReaderBuilder b; Json::Value root; - char const doc[] = "{ \"property\" : \"value\" }"; + char const doc[] = R"({ "property" : "value" })"; { b.settings_["stackLimit"] = 2; CharReaderPtr reader(b.newCharReader()); @@ -3109,7 +3109,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderTest, parseWithStackLimit) { } JSONTEST_FIXTURE_LOCAL(CharReaderTest, testOperator) { - const std::string styled = "{ \"property\" : \"value\" }"; + const std::string styled = R"({ "property" : "value" })"; std::istringstream iss(styled); Json::Value root; iss >> root; @@ -3122,7 +3122,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderStrictModeTest, dupKeys) { Json::CharReaderBuilder b; Json::Value root; char const doc[] = - "{ \"property\" : \"value\", \"key\" : \"val1\", \"key\" : \"val2\" }"; + R"({ "property" : "value", "key" : "val1", "key" : "val2" })"; { b.strictMode(&b.settings_); CharReaderPtr reader(b.newCharReader()); @@ -3141,7 +3141,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderFailIfExtraTest, issue164) { // This is interpreted as a string value followed by a colon. Json::CharReaderBuilder b; Json::Value root; - char const doc[] = " \"property\" : \"value\" }"; + char const doc[] = R"( "property" : "value" })"; { b.settings_["failIfExtra"] = false; CharReaderPtr reader(b.newCharReader()); @@ -3445,8 +3445,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { Json::String errs; CharReaderPtr reader(b.newCharReader()); { - char const doc[] = - "{\"a\":NaN,\"b\":Infinity,\"c\":-Infinity,\"d\":+Infinity}"; + char const doc[] = R"({"a":NaN,"b":Infinity,"c":-Infinity,"d":+Infinity})"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -3497,7 +3496,7 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { } { - char const doc[] = "{\"posInf\": +Infinity, \"NegInf\": -Infinity}"; + char const doc[] = R"({"posInf": +Infinity, "NegInf": -Infinity})"; bool ok = reader->parse(doc, doc + std::strlen(doc), &root, &errs); JSONTEST_ASSERT(ok); JSONTEST_ASSERT_STRING_EQUAL("", errs); @@ -3719,7 +3718,7 @@ JSONTEST_FIXTURE_LOCAL(IteratorTest, constness) { for (; iter != value.end(); ++iter) { out << *iter << ','; } - Json::String expected = "\" 9\",\"10\",\"11\","; + Json::String expected = R"(" 9","10","11",)"; JSONTEST_ASSERT_STRING_EQUAL(expected, out.str()); } From 2e54e8ff1c9d3438297bdfd33b1a305fc7cbae98 Mon Sep 17 00:00:00 2001 From: Stefano Fiorentino Date: Fri, 24 Apr 2020 05:52:56 +0200 Subject: [PATCH 269/410] adding myself to AUTHORS as per commits (#1109) commits: ff923658c4d9f1492617557148369b34c71ba623 5907cef86ca699a842d0a8cad4c018b4da5d6e17 --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 3723d546a..6cddf9796 100644 --- a/AUTHORS +++ b/AUTHORS @@ -97,6 +97,7 @@ selaselah Sergiy80 sergzub Stefan Schweter +Stefano Fiorentino Steffen Kieß Steven Hahn Stuart Eichert From 8b20b7a317b671fadcdff760dce7e341312503aa Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Mon, 30 Dec 2019 11:37:14 -0500 Subject: [PATCH 270/410] amalgamate: add version.h and allocator.h to the forwards header Required to get JSONCPP_USING_SECURE_MEMORY and the SecureAllocator available for the definition of Allocator. --- amalgamate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/amalgamate.py b/amalgamate.py index fedee1eae..4a328ab5a 100755 --- a/amalgamate.py +++ b/amalgamate.py @@ -99,6 +99,8 @@ def amalgamate_source(source_top_dir=None, header.add_text("/// If defined, indicates that the source file is amalgamated") header.add_text("/// to prevent private header inclusion.") header.add_text("#define JSON_IS_AMALGAMATION") + header.add_file(os.path.join(INCLUDE_PATH, "version.h")) + header.add_file(os.path.join(INCLUDE_PATH, "allocator.h")) header.add_file(os.path.join(INCLUDE_PATH, "config.h")) header.add_file(os.path.join(INCLUDE_PATH, "forwards.h")) header.add_text("#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED") From 1ff6bb65a0a845dfe4e29fef01f5f42ddfe4f67a Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Fri, 24 Apr 2020 00:58:35 -0500 Subject: [PATCH 271/410] ninja test --- CONTRIBUTING.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 08428b6f8..9c9fc6a04 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,8 +27,13 @@ Then, #LIB_TYPE=static meson --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . build-${LIB_TYPE} ninja -v -C build-${LIB_TYPE} - cd build-${LIB_TYPE} - meson test --no-rebuild --print-errorlogs + + ninja -C build-static/ test + + # Or + #cd build-${LIB_TYPE} + #meson test --no-rebuild --print-errorlogs + sudo ninja install ## Building and testing with other build systems From 411d88fae895d7d2dbc06dcccc80d4f747746c2b Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Fri, 24 Apr 2020 01:45:19 -0500 Subject: [PATCH 272/410] Stop checking status; raise instead --- test/runjsontests.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/runjsontests.py b/test/runjsontests.py index dfdeca3ea..26caf0cfb 100644 --- a/test/runjsontests.py +++ b/test/runjsontests.py @@ -62,6 +62,10 @@ def safeReadFile(path): except IOError as e: return '' % (path,e) +class FailError(Exception): + def __init__(self, msg): + super(Exception, self).__init__(msg) + def runAllTests(jsontest_executable_path, input_dir = None, use_valgrind=False, with_json_checker=False, writerClass='StyledWriter'): @@ -161,10 +165,9 @@ def runAllTests(jsontest_executable_path, input_dir = None, print() print('Test results: %d passed, %d failed.' % (len(tests)-len(failed_tests), len(failed_tests))) - return 1 + raise FailError(repr(failed_tests)) else: print('All %d tests passed.' % len(tests)) - return 0 def main(): from optparse import OptionParser @@ -187,24 +190,21 @@ def main(): input_path = os.path.normpath(os.path.abspath(args[1])) else: input_path = None - status = runAllTests(jsontest_executable_path, input_path, + runAllTests(jsontest_executable_path, input_path, use_valgrind=options.valgrind, with_json_checker=options.with_json_checker, writerClass='StyledWriter') - if status: - sys.exit(status) - status = runAllTests(jsontest_executable_path, input_path, + runAllTests(jsontest_executable_path, input_path, use_valgrind=options.valgrind, with_json_checker=options.with_json_checker, writerClass='StyledStreamWriter') - if status: - sys.exit(status) - status = runAllTests(jsontest_executable_path, input_path, + runAllTests(jsontest_executable_path, input_path, use_valgrind=options.valgrind, with_json_checker=options.with_json_checker, writerClass='BuiltStyledStreamWriter') - if status: - sys.exit(status) if __name__ == '__main__': - main() + try: + main() + except FailError: + sys.exit(1) From 9e23f66f614d23c4c2b540d2d62ce3b2725d422a Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 14 Nov 2019 10:41:25 -0800 Subject: [PATCH 273/410] Issue 1102: Fixup test suite, fix broken tests A recent PR broken the JsonChecker tests by adding support for trailing commas. This didn't end up breaking the build, because those tests aren't run, except locally and only using CMake. This patch fixes the tests by adding exclusions for trailing comma tests, as well as updates Meson to run these tests as part of `ninja test`. See issue #1102. --- meson.build | 10 +++++++++ test/runjsontests.py | 53 ++++++++++++++------------------------------ 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/meson.build b/meson.build index c29320307..e2e92ad54 100644 --- a/meson.build +++ b/meson.build @@ -105,3 +105,13 @@ test( jsontestrunner, join_paths(meson.current_source_dir(), 'test/data')] ) +test( + 'jsonchecker_jsontestrunner', + python, + args : [ + '-B', + join_paths(meson.current_source_dir(), 'test/runjsontests.py'), + '--with-json-checker', + jsontestrunner, + join_paths(meson.current_source_dir(), 'test/data')] + ) diff --git a/test/runjsontests.py b/test/runjsontests.py index 26caf0cfb..fb1fb399b 100644 --- a/test/runjsontests.py +++ b/test/runjsontests.py @@ -73,45 +73,26 @@ def runAllTests(jsontest_executable_path, input_dir = None, input_dir = os.path.join(os.getcwd(), 'data') tests = glob(os.path.join(input_dir, '*.json')) if with_json_checker: - all_test_jsonchecker = glob(os.path.join(input_dir, '../jsonchecker', '*.json')) - # These tests fail with strict json support, but pass with jsoncpp extra lieniency - """ - Failure details: - * Test ../jsonchecker/fail25.json - Parsing should have failed: - [" tab character in string "] - - * Test ../jsonchecker/fail13.json - Parsing should have failed: - {"Numbers cannot have leading zeroes": 013} - - * Test ../jsonchecker/fail18.json - Parsing should have failed: - [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] - - * Test ../jsonchecker/fail8.json - Parsing should have failed: - ["Extra close"]] - - * Test ../jsonchecker/fail7.json - Parsing should have failed: - ["Comma after the close"], - - * Test ../jsonchecker/fail10.json - Parsing should have failed: - {"Extra value after close": true} "misplaced quoted value" - - * Test ../jsonchecker/fail27.json - Parsing should have failed: - ["line - break"] - """ - known_differences_withjsonchecker = [ "fail25.json", "fail13.json", "fail18.json", "fail8.json", - "fail7.json", "fail10.json", "fail27.json" ] - test_jsonchecker = [ test for test in all_test_jsonchecker if os.path.basename(test) not in known_differences_withjsonchecker ] + all_tests = glob(os.path.join(input_dir, '../jsonchecker', '*.json')) + # These tests fail with strict json support, but pass with JsonCPP's + # extra leniency features. When adding a new exclusion to this list, + # remember to add the test's number and reasoning here: + known = ["fail{}.json".format(n) for n in [ + 4, 9, # fail because we allow trailing commas + 7, # fails because we allow commas after close + 8, # fails because we allow extra close + 10, # fails because we allow extra values after close + 13, # fails because we allow leading zeroes in numbers + 18, # fails because we allow deeply nested values + 25, # fails because we allow tab characters in strings. + 27, # fails because we allow string line breaks + ]] + test_jsonchecker = [ test for test in all_tests + if os.path.basename(test) not in known] else: test_jsonchecker = [] + failed_tests = [] valgrind_path = use_valgrind and VALGRIND_CMD or '' for input_path in tests + test_jsonchecker: From b3492219385ba41f9f8167a68e3f56a2b6cdd7a9 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Thu, 14 Nov 2019 10:52:13 -0800 Subject: [PATCH 274/410] Cleanup test configurations --- meson.build | 5 +++-- test/runjsontests.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/meson.build b/meson.build index e2e92ad54..7bacdfcda 100644 --- a/meson.build +++ b/meson.build @@ -103,7 +103,7 @@ test( '-B', join_paths(meson.current_source_dir(), 'test/runjsontests.py'), jsontestrunner, - join_paths(meson.current_source_dir(), 'test/data')] + join_paths(meson.current_source_dir(), 'test/data')], ) test( 'jsonchecker_jsontestrunner', @@ -113,5 +113,6 @@ test( join_paths(meson.current_source_dir(), 'test/runjsontests.py'), '--with-json-checker', jsontestrunner, - join_paths(meson.current_source_dir(), 'test/data')] + join_paths(meson.current_source_dir(), 'test/data')], + workdir : join_paths(meson.current_source_dir(), 'test/data'), ) diff --git a/test/runjsontests.py b/test/runjsontests.py index fb1fb399b..5496e2c58 100644 --- a/test/runjsontests.py +++ b/test/runjsontests.py @@ -84,7 +84,7 @@ def runAllTests(jsontest_executable_path, input_dir = None, 10, # fails because we allow extra values after close 13, # fails because we allow leading zeroes in numbers 18, # fails because we allow deeply nested values - 25, # fails because we allow tab characters in strings. + 25, # fails because we allow tab characters in strings 27, # fails because we allow string line breaks ]] test_jsonchecker = [ test for test in all_tests From a0b8c3ecb418a8d5fcf992a3250fd3634b5cb563 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Fri, 24 Apr 2020 09:24:22 -0500 Subject: [PATCH 275/410] Do not run colliding tests at same time --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index 7bacdfcda..975d56cda 100644 --- a/meson.build +++ b/meson.build @@ -108,6 +108,7 @@ test( test( 'jsonchecker_jsontestrunner', python, + is_parallel : false, args : [ '-B', join_paths(meson.current_source_dir(), 'test/runjsontests.py'), From 91f1553f2c65e8c3d200fa309efe784673c27125 Mon Sep 17 00:00:00 2001 From: bcsgh <33939446+bcsgh@users.noreply.github.com> Date: Mon, 23 Mar 2020 17:34:46 -0700 Subject: [PATCH 276/410] Make throwRuntimeError/throwLogicError print msg when built with JSON_USE_EXCEPTION=0 --- src/lib_json/json_value.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 71dba6e8c..0872ff548 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -211,8 +212,14 @@ JSONCPP_NORETURN void throwLogicError(String const& msg) { throw LogicError(msg); } #else // !JSON_USE_EXCEPTION -JSONCPP_NORETURN void throwRuntimeError(String const& msg) { abort(); } -JSONCPP_NORETURN void throwLogicError(String const& msg) { abort(); } +JSONCPP_NORETURN void throwRuntimeError(String const& msg) { + std::cerr << msg << std::endl; + abort(); +} +JSONCPP_NORETURN void throwLogicError(String const& msg) { + std::cerr << msg << std::endl; + abort(); +} #endif // ////////////////////////////////////////////////////////////////// From 83946a28db3d13ffe8184bdae23287a81c09fd7f Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Tue, 28 Apr 2020 15:16:05 +0800 Subject: [PATCH 277/410] Ignore byte order mark in the head of UTF-8 text. (#1149) * Ignore bom at the beginning of the UTF-8 text --- src/lib_json/json_reader.cpp | 19 +++++++++++++++++++ src/test_lib_json/main.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 10be6d2cf..341162bcd 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -871,6 +871,7 @@ class OurFeatures { bool failIfExtra_; bool rejectDupKeys_; bool allowSpecialFloats_; + bool allowBom_; size_t stackLimit_; }; // OurFeatures @@ -939,6 +940,7 @@ class OurReader { bool readToken(Token& token); void skipSpaces(); + void skipBom(bool allowBom); bool match(const Char* pattern, int patternLength); bool readComment(); bool readCStyleComment(bool* containsNewLineResult); @@ -1022,6 +1024,8 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, nodes_.pop(); nodes_.push(&root); + // skip byte order mark if it exists at the beginning of the UTF-8 text. + skipBom(features_.allowBom_); bool successful = readValue(); nodes_.pop(); Token token; @@ -1268,6 +1272,17 @@ void OurReader::skipSpaces() { } } +void OurReader::skipBom(bool allowBom) { + // If BOM is not allowed, then skip it. + // The default value is: false + if (!allowBom) { + if (strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) { + begin_ += 3; + current_ = begin_; + } + } +} + bool OurReader::match(const Char* pattern, int patternLength) { if (end_ - current_ < patternLength) return false; @@ -1885,6 +1900,7 @@ CharReader* CharReaderBuilder::newCharReader() const { features.failIfExtra_ = settings_["failIfExtra"].asBool(); features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); + features.allowBom_ = settings_["allowBom"].asBool(); return new OurCharReader(collectComments, features); } static void getValidReaderKeys(std::set* valid_keys) { @@ -1900,6 +1916,7 @@ static void getValidReaderKeys(std::set* valid_keys) { valid_keys->insert("failIfExtra"); valid_keys->insert("rejectDupKeys"); valid_keys->insert("allowSpecialFloats"); + valid_keys->insert("allowBom"); } bool CharReaderBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; @@ -1934,6 +1951,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings) { (*settings)["failIfExtra"] = true; (*settings)["rejectDupKeys"] = true; (*settings)["allowSpecialFloats"] = false; + (*settings)["allowBom"] = false; //! [CharReaderBuilderStrictMode] } // static @@ -1950,6 +1968,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { (*settings)["failIfExtra"] = false; (*settings)["rejectDupKeys"] = false; (*settings)["allowSpecialFloats"] = false; + (*settings)["allowBom"] = false; //! [CharReaderBuilderDefaults] } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index f0b84fcc7..ede39ee89 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3577,6 +3577,32 @@ JSONTEST_FIXTURE_LOCAL(BuilderTest, settings) { } } +struct BomTest : JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(BomTest, skipBom) { + const std::string with_bom = "\xEF\xBB\xBF{\"key\" : \"value\"}"; + Json::Value root; + JSONCPP_STRING errs; + std::istringstream iss(with_bom); + bool ok = parseFromStream(Json::CharReaderBuilder(), iss, &root, &errs); + // The default behavior is to skip the BOM, so we can parse it normally. + JSONTEST_ASSERT(ok); + JSONTEST_ASSERT(errs.empty()); + JSONTEST_ASSERT_STRING_EQUAL(root["key"].asString(), "value"); +} +JSONTEST_FIXTURE_LOCAL(BomTest, allowBom) { + const std::string with_bom = "\xEF\xBB\xBF{\"key\" : \"value\"}"; + Json::Value root; + JSONCPP_STRING errs; + std::istringstream iss(with_bom); + Json::CharReaderBuilder b; + b.settings_["allowBom"] = true; + bool ok = parseFromStream(b, iss, &root, &errs); + // Detect the BOM, and failed on it. + JSONTEST_ASSERT(!ok); + JSONTEST_ASSERT(!errs.empty()); +} + struct IteratorTest : JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(IteratorTest, convert) { From 2cb16b35dcfe0703272c9bbe777ad09546846a04 Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Tue, 28 Apr 2020 17:30:08 +0800 Subject: [PATCH 278/410] allowBom -> skipBom (#1162) --- src/lib_json/json_reader.cpp | 21 ++++++++++----------- src/test_lib_json/main.cpp | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 341162bcd..02a7d54ca 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -871,7 +871,7 @@ class OurFeatures { bool failIfExtra_; bool rejectDupKeys_; bool allowSpecialFloats_; - bool allowBom_; + bool skipBom_; size_t stackLimit_; }; // OurFeatures @@ -940,7 +940,7 @@ class OurReader { bool readToken(Token& token); void skipSpaces(); - void skipBom(bool allowBom); + void skipBom(bool skipBom); bool match(const Char* pattern, int patternLength); bool readComment(); bool readCStyleComment(bool* containsNewLineResult); @@ -1025,7 +1025,7 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, nodes_.push(&root); // skip byte order mark if it exists at the beginning of the UTF-8 text. - skipBom(features_.allowBom_); + skipBom(features_.skipBom_); bool successful = readValue(); nodes_.pop(); Token token; @@ -1272,10 +1272,9 @@ void OurReader::skipSpaces() { } } -void OurReader::skipBom(bool allowBom) { - // If BOM is not allowed, then skip it. - // The default value is: false - if (!allowBom) { +void OurReader::skipBom(bool skipBom) { + // The default behavior is to skip BOM. + if (skipBom) { if (strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) { begin_ += 3; current_ = begin_; @@ -1900,7 +1899,7 @@ CharReader* CharReaderBuilder::newCharReader() const { features.failIfExtra_ = settings_["failIfExtra"].asBool(); features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); - features.allowBom_ = settings_["allowBom"].asBool(); + features.skipBom_ = settings_["skipBom"].asBool(); return new OurCharReader(collectComments, features); } static void getValidReaderKeys(std::set* valid_keys) { @@ -1916,7 +1915,7 @@ static void getValidReaderKeys(std::set* valid_keys) { valid_keys->insert("failIfExtra"); valid_keys->insert("rejectDupKeys"); valid_keys->insert("allowSpecialFloats"); - valid_keys->insert("allowBom"); + valid_keys->insert("skipBom"); } bool CharReaderBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; @@ -1951,7 +1950,7 @@ void CharReaderBuilder::strictMode(Json::Value* settings) { (*settings)["failIfExtra"] = true; (*settings)["rejectDupKeys"] = true; (*settings)["allowSpecialFloats"] = false; - (*settings)["allowBom"] = false; + (*settings)["skipBom"] = true; //! [CharReaderBuilderStrictMode] } // static @@ -1968,7 +1967,7 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { (*settings)["failIfExtra"] = false; (*settings)["rejectDupKeys"] = false; (*settings)["allowSpecialFloats"] = false; - (*settings)["allowBom"] = false; + (*settings)["skipBom"] = true; //! [CharReaderBuilderDefaults] } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index ede39ee89..e6fe43d79 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3590,13 +3590,13 @@ JSONTEST_FIXTURE_LOCAL(BomTest, skipBom) { JSONTEST_ASSERT(errs.empty()); JSONTEST_ASSERT_STRING_EQUAL(root["key"].asString(), "value"); } -JSONTEST_FIXTURE_LOCAL(BomTest, allowBom) { +JSONTEST_FIXTURE_LOCAL(BomTest, notSkipBom) { const std::string with_bom = "\xEF\xBB\xBF{\"key\" : \"value\"}"; Json::Value root; JSONCPP_STRING errs; std::istringstream iss(with_bom); Json::CharReaderBuilder b; - b.settings_["allowBom"] = true; + b.settings_["skipBom"] = false; bool ok = parseFromStream(b, iss, &root, &errs); // Detect the BOM, and failed on it. JSONTEST_ASSERT(!ok); From a3afd74b80715a0a1f2d7b5c47b90385b7e1b136 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 18 Feb 2020 18:04:04 -0700 Subject: [PATCH 279/410] Don't use unique variable for postfix The more general CMake way to handle library suffixing is to set CMAKE__POSTFIX, so setting the Debug output suffix name should be more correctly done by the caller or CMake configurer by setting the desired value in CMAKE_DEBUG_POSTFIX. --- CMakeLists.txt | 2 -- src/lib_json/CMakeLists.txt | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b7e2e09ad..da6b51e17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,8 +103,6 @@ endif() # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) -set(DEBUG_LIBNAME_SUFFIX "" CACHE STRING "Optional suffix to append to the library name for a debug build") - set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL") configure_file("${PROJECT_SOURCE_DIR}/version.in" diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 401e1f7e8..1128381f2 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -84,8 +84,7 @@ endif() add_library(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) set_target_properties(jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) -set_target_properties(jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp - DEBUG_OUTPUT_NAME jsoncpp${DEBUG_LIBNAME_SUFFIX}) +set_target_properties(jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp) set_target_properties(jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) # Set library's runtime search path on OSX From c648b0378addd7834c1c530ea20853303c1de535 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 18 Feb 2020 18:04:59 -0700 Subject: [PATCH 280/410] Consolidate setting of jsoncpp target properties --- src/lib_json/CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 1128381f2..e22fb1c37 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -81,11 +81,13 @@ if(BUILD_SHARED_LIBS) endif() endif() - add_library(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) -set_target_properties(jsoncpp_lib PROPERTIES VERSION ${JSONCPP_VERSION} SOVERSION ${JSONCPP_SOVERSION}) -set_target_properties(jsoncpp_lib PROPERTIES OUTPUT_NAME jsoncpp) -set_target_properties(jsoncpp_lib PROPERTIES POSITION_INDEPENDENT_CODE ON) +set_target_properties( jsoncpp_lib PROPERTIES + OUTPUT_NAME jsoncpp + VERSION ${JSONCPP_VERSION} + SOVERSION ${JSONCPP_SOVERSION} + POSITION_INDEPENDENT_CODE ON +) # Set library's runtime search path on OSX if(APPLE) From 5a0152ae1b0b6a683365e56306dcac613f0859a1 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 31 Dec 2019 15:42:19 -0700 Subject: [PATCH 281/410] Only set CMAKE_BUILD_TYPE for single config generators --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da6b51e17..714960bc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,8 +56,8 @@ endif() # ==== -# Ensures that CMAKE_BUILD_TYPE has a default value -if(NOT DEFINED CMAKE_BUILD_TYPE) +# Ensure that CMAKE_BUILD_TYPE has a value specified for single configuration generators. +if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") endif() From edc6239f3934d39ce635d2127790f464ca08a125 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 31 Dec 2019 16:03:32 -0700 Subject: [PATCH 282/410] Not needed to specify CMAKE_MACOSX_RPATH As of CMake 3.0 with CMP0042, MACOSX_RPATH is enabled by default. Since the validated version used by jsoncpp is later than 3.0, this is already covered. --- CMakeLists.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 714960bc2..4f3b60119 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,11 +95,6 @@ option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF) option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) -# Enable runtime search path support for dynamic libraries on OSX -if(APPLE) - set(CMAKE_MACOSX_RPATH 1) -endif() - # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) From 12ceb014850d2a7bbaf7f23cd4a1ab8f6571b17f Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 31 Dec 2019 16:07:22 -0700 Subject: [PATCH 283/410] Always use consistent CXX_STANDARD Since CMake has subdirectory variable scope, unilaterally set the CMAKE_CXX_STANDARD variable to use C++11. This covers cases with the library being included externally, both in cases of only C++98 being specified, as well as later versions being specified (since the CXX_STANDARD itself isn't a library dependency, only the PUBLIC target_compile_features on jsoncpp_lib). The previous direct check for C++98 is handled by requiring C++11 on this library; should the compiler being used not support C++11 then CMake will issue an error. --- CMakeLists.txt | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f3b60119..e636eebc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,24 +37,11 @@ foreach(pold "") # Currently Empty endif() endforeach() -# ==== Define language standard configurations requiring at least c++11 standard -if(CMAKE_CXX_STANDARD EQUAL "98") - message(FATAL_ERROR "CMAKE_CXX_STANDARD:STRING=98 is not supported.") -endif() - -##### -## Set the default target properties -if(NOT CMAKE_CXX_STANDARD) - set(CMAKE_CXX_STANDARD 11) # Supported values are ``11``, ``14``, and ``17``. -endif() -if(NOT CMAKE_CXX_STANDARD_REQUIRED) - set(CMAKE_CXX_STANDARD_REQUIRED ON) -endif() -if(NOT CMAKE_CXX_EXTENSIONS) - set(CMAKE_CXX_EXTENSIONS OFF) -endif() - -# ==== +# Build the library with C++11 standard support, independent from other including +# software which may use a different CXX_STANDARD or CMAKE_CXX_STANDARD. +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # Ensure that CMAKE_BUILD_TYPE has a value specified for single configuration generators. if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES) From 30eb5ce128d4880febbb82c71c62952380be542a Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 31 Dec 2019 20:23:08 -0700 Subject: [PATCH 284/410] Check compiler using CMAKE_CXX_COMPILER_ID Since the introduction of CMAKE_COMPILER_IS_GNUCXX CMake has suggested using CMAKE_CXX_COMPILER_ID for more general checks. --- src/lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index e22fb1c37..f2377208c 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -1,4 +1,4 @@ -if(CMAKE_COMPILER_IS_GNUCXX) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") #Get compiler version. execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GNUCXX_VERSION From 8a5e792f206626a102d8e08d8b3a0db68b9876c2 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 31 Dec 2019 20:38:39 -0700 Subject: [PATCH 285/410] Add Clang support, be explicit about MSVC flags --- example/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 51c32182d..017f56030 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -10,9 +10,9 @@ set(EXAMPLES add_definitions(-D_GLIBCXX_USE_CXX11_ABI) set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") -else() +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") add_definitions( -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS From 9abf11935c02543f6f7481a4aa09305feb1bbb05 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 18 Feb 2020 16:55:45 -0700 Subject: [PATCH 286/410] Remove unused CMake variable EXTRA_CXX_FLAGS is never defined, making this a noop. Further, COMPILE_OPTIONS is invalid to set as a DIRECTORY property. --- example/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 017f56030..2636e88f6 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -8,7 +8,6 @@ set(EXAMPLES streamWrite ) add_definitions(-D_GLIBCXX_USE_CXX11_ABI) -set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${EXTRA_CXX_FLAGS}) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") From 524234e479daf2eb406521dcf9eb30d94554c21b Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 20 Jan 2020 13:21:14 -0700 Subject: [PATCH 287/410] Use non-version checked add_compile_options Commit aebc7fa added version checks for CMake compatibility. In reality, only the add_compile_definitions need the check - add_compile_options itself has been supported since 3.0. Tested and confirmed built successfully with CMake 3.8.0. --- CMakeLists.txt | 60 +++++++------------------------------ example/CMakeLists.txt | 2 +- src/lib_json/CMakeLists.txt | 2 +- 3 files changed, 12 insertions(+), 52 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e636eebc6..bc7553aec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,23 +95,11 @@ macro(use_compilation_warning_as_error) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # warnings when compiled in release configuration. - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options($<$:/WX>) - else() - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /WX ") - endif() + add_compile_options($<$:/WX>) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Werror) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") - endif() + add_compile_options(-Werror) if(JSONCPP_WITH_STRICT_ISO) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-pedantic-errors) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") - endif() + add_compile_options(-pedantic-errors) endif() endif() endmacro() @@ -122,57 +110,29 @@ include_directories(${jsoncpp_SOURCE_DIR}/include) if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options($<$:/W4>) - else() - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4 ") - endif() + add_compile_options($<$:/W4>) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare") - endif() + add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Wextra) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra") - endif() + add_compile_options(-Wall -Wconversion -Wshadow -Wextra) # not yet ready for -Wsign-conversion if(JSONCPP_WITH_STRICT_ISO) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wpedantic) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") - endif() + add_compile_options(-Wpedantic) endif() if(JSONCPP_WITH_WARNING_AS_ERROR) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Werror=conversion) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=conversion") - endif() + add_compile_options(-Werror=conversion) endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wshadow -Wextra -Werror=conversion") - endif() + add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_options(-Wpedantic) - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") - endif() + add_compile_options(-Wpedantic) endif() endif() diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 2636e88f6..d252a5069 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -10,7 +10,7 @@ set(EXAMPLES add_definitions(-D_GLIBCXX_USE_CXX11_ABI) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra ") + add_compile_options(-Wall -Wextra) elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") add_definitions( -D_SCL_SECURE_NO_WARNINGS diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index f2377208c..caa9cc039 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -6,7 +6,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") #-Werror=* was introduced -after- GCC 4.1.2 if(GNUCXX_VERSION VERSION_GREATER 4.1.2) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=strict-aliasing") + add_compile_options("-Werror=strict-aliasing") endif() endif() From 3f0d63b5a9487feb2b75f13b05c4930a668da08d Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Tue, 18 Feb 2020 13:56:26 -0700 Subject: [PATCH 288/410] Use internal CMake compiler version directly --- src/lib_json/CMakeLists.txt | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index caa9cc039..b3306659b 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -1,13 +1,6 @@ -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - #Get compiler version. - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion - OUTPUT_VARIABLE GNUCXX_VERSION - ) - +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.1.2) #-Werror=* was introduced -after- GCC 4.1.2 - if(GNUCXX_VERSION VERSION_GREATER 4.1.2) - add_compile_options("-Werror=strict-aliasing") - endif() + add_compile_options("-Werror=strict-aliasing") endif() include(CheckIncludeFileCXX) From e9b0b96be677f011d0e9e3d153b25f3274bdb2e0 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Wed, 19 Feb 2020 09:14:08 -0700 Subject: [PATCH 289/410] Remove redundant cmake_minimum_required from example This is already covered by the toplevel CMake, which also serves to provide a consistent minimum version. --- example/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index d252a5069..230d1bd7b 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,6 +1,4 @@ #vim: et ts =4 sts = 4 sw = 4 tw = 0 -cmake_minimum_required(VERSION 3.1) - set(EXAMPLES readFromString readFromStream From a4fb5db54389e618a4968a3feb7f20d5ce853232 Mon Sep 17 00:00:00 2001 From: xkszltl Date: Thu, 30 Apr 2020 10:31:54 +0800 Subject: [PATCH 290/410] Put ".exe" and ".dll" together to make test usable in build dir. (#1166) --- CMakeLists.txt | 5 +++++ src/test_lib_json/CMakeLists.txt | 27 ++++++++------------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bc7553aec..cd978bb79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,11 @@ option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir.") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir.") +set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.") +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") + set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL") configure_file("${PROJECT_SOURCE_DIR}/version.in" diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index c9730d0d2..b803db669 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -21,28 +21,17 @@ target_link_libraries(jsoncpp_test jsoncpp_lib) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) +## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp +add_test(NAME jsoncpp_test + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ +) +set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) + # Run unit tests in post-build # (default cmake workflow hides away the test result into a file, resulting in poor dev workflow?!?) if(JSONCPP_WITH_POST_BUILD_UNITTEST) - if(BUILD_SHARED_LIBS) - # First, copy the shared lib, for Microsoft. - # Then, run the test executable. - add_custom_command(TARGET jsoncpp_test - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ - COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ - ) - else() - # Just run the test executable. - add_custom_command(TARGET jsoncpp_test - POST_BUILD - COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ - ) - endif() - ## Create tests for dashboard submission, allows easy review of CI results https://my.cdash.org/index.php?project=jsoncpp - add_test(NAME jsoncpp_test + add_custom_command(TARGET jsoncpp_test + POST_BUILD COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ) endif() - -set_target_properties(jsoncpp_test PROPERTIES OUTPUT_NAME jsoncpp_test) From 8b7ea09b8055df01866a5ce4142b12ed8f9f13eb Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Thu, 30 Apr 2020 17:58:07 +0800 Subject: [PATCH 291/410] Bump soversion to 24 (#1167) --- CMakeLists.txt | 2 +- meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cd978bb79..01b8c9d42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ project(JSONCPP LANGUAGES CXX) message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set(JSONCPP_SOVERSION 23) +set(JSONCPP_SOVERSION 24) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) diff --git a/meson.build b/meson.build index 975d56cda..75ec97446 100644 --- a/meson.build +++ b/meson.build @@ -50,7 +50,7 @@ jsoncpp_lib = library( 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp', ]), - soversion : 23, + soversion : 24, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) From d2d4c74a03036c18d7171993bfaa6e0bea38e07d Mon Sep 17 00:00:00 2001 From: Chen <50514813+dota17@users.noreply.github.com> Date: Thu, 30 Apr 2020 18:05:17 +0800 Subject: [PATCH 292/410] Update README.md and add dota17 to AUTHORS list. (#1168) * update README * add dota17 to AUTHORS list --- AUTHORS | 1 + README.md | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/AUTHORS b/AUTHORS index 6cddf9796..e1fa0fc3a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -21,6 +21,7 @@ Braden McDorman Brandon Myers Brendan Drew chason +chenguoping Chris Gilling Christopher Dawes Christopher Dunn diff --git a/README.md b/README.md index b6fc76913..393bb300b 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,14 @@ format to store user input files. * `1.y.z` is built with C++11. * `0.y.z` can be used with older compilers. +* `00.11.z` can be used both in old and new compilers. * Major versions maintain binary-compatibility. +### Special note +The branch `00.11.z`is a new branch, its major version number `00` is to show that it is +different from `0.y.z` and `1.y.z`, the main purpose of this branch is to make a balance +between the other two branches. Thus, users can use some new features in this new branch +that introduced in 1.y.z, but can hardly applied into 0.y.z. ## Using JsonCpp in your project From b8cb8889aab726a35c49472228256f7bb1d44388 Mon Sep 17 00:00:00 2001 From: Edward Brey Date: Thu, 7 May 2020 20:00:12 -0500 Subject: [PATCH 293/410] Added current dir specifier for PowerShell (#1169) The `./` is needed before `vcpkg install jsoncpp` when installing with PowerShell. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 393bb300b..5bff8dca2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ You can download and install JsonCpp using the [vcpkg](https://github.com/Micros cd vcpkg ./bootstrap-vcpkg.sh ./vcpkg integrate install - vcpkg install jsoncpp + ./vcpkg install jsoncpp The JsonCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. From e36cff19f098723a45a98f53bba113da3c3781f3 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Tue, 12 May 2020 16:19:36 -0700 Subject: [PATCH 294/410] clang-tidy + any_of usage (#1171) * [clang-tidy] change functions to static Found with readability-convert-member-functions-to-static Signed-off-by: Rosen Penev * optimize JsonWriter::validate #1171 * do the same for json_reader Signed-off-by: Rosen Penev * use std::any_of Also simplified two loops. Signed-off-by: Rosen Penev Co-authored-by: Billy Donahue --- src/lib_json/json_reader.cpp | 65 ++++++++++++++++-------------------- src/lib_json/json_writer.cpp | 59 +++++++++++++++----------------- src/test_lib_json/main.cpp | 4 +-- 3 files changed, 56 insertions(+), 72 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 02a7d54ca..2dca4ca87 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -10,6 +10,7 @@ #include #include #endif // if !defined(JSON_IS_AMALGAMATION) +#include #include #include #include @@ -77,10 +78,7 @@ Features Features::strictMode() { // //////////////////////////////// bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { - for (; begin < end; ++begin) - if (*begin == '\n' || *begin == '\r') - return true; - return false; + return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; }); } // Class Reader @@ -998,10 +996,7 @@ class OurReader { bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end) { - for (; begin < end; ++begin) - if (*begin == '\n' || *begin == '\r') - return true; - return false; + return std::any_of(begin, end, [](char b) { return b == '\n' || b == '\r'; }); } OurReader::OurReader(OurFeatures const& features) : features_(features) {} @@ -1902,38 +1897,34 @@ CharReader* CharReaderBuilder::newCharReader() const { features.skipBom_ = settings_["skipBom"].asBool(); return new OurCharReader(collectComments, features); } -static void getValidReaderKeys(std::set* valid_keys) { - valid_keys->clear(); - valid_keys->insert("collectComments"); - valid_keys->insert("allowComments"); - valid_keys->insert("allowTrailingCommas"); - valid_keys->insert("strictRoot"); - valid_keys->insert("allowDroppedNullPlaceholders"); - valid_keys->insert("allowNumericKeys"); - valid_keys->insert("allowSingleQuotes"); - valid_keys->insert("stackLimit"); - valid_keys->insert("failIfExtra"); - valid_keys->insert("rejectDupKeys"); - valid_keys->insert("allowSpecialFloats"); - valid_keys->insert("skipBom"); -} + bool CharReaderBuilder::validate(Json::Value* invalid) const { - Json::Value my_invalid; - if (!invalid) - invalid = &my_invalid; // so we do not need to test for NULL - Json::Value& inv = *invalid; - std::set valid_keys; - getValidReaderKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); - size_t n = keys.size(); - for (size_t i = 0; i < n; ++i) { - String const& key = keys[i]; - if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; - } + static const auto& valid_keys = *new std::set{ + "collectComments", + "allowComments", + "allowTrailingCommas", + "strictRoot", + "allowDroppedNullPlaceholders", + "allowNumericKeys", + "allowSingleQuotes", + "stackLimit", + "failIfExtra", + "rejectDupKeys", + "allowSpecialFloats", + "skipBom", + }; + for (auto si = settings_.begin(); si != settings_.end(); ++si) { + auto key = si.name(); + if (valid_keys.count(key)) + continue; + if (invalid) + (*invalid)[std::move(key)] = *si; + else + return false; } - return inv.empty(); + return invalid ? invalid->empty() : true; } + Value& CharReaderBuilder::operator[](const String& key) { return settings_[key]; } diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 56195dc15..cb528b8b6 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -7,7 +7,9 @@ #include "json_tool.h" #include #endif // if !defined(JSON_IS_AMALGAMATION) +#include #include +#include #include #include #include @@ -176,14 +178,9 @@ String valueToString(bool value) { return value ? "true" : "false"; } static bool isAnyCharRequiredQuoting(char const* s, size_t n) { assert(s || !n); - char const* const end = s + n; - for (char const* cur = s; cur < end; ++cur) { - if (*cur == '\\' || *cur == '\"' || - static_cast(*cur) < ' ' || - static_cast(*cur) >= 0x80) - return true; - } - return false; + return std::any_of(s, s + n, [](int c) { + return c == '\\' || c == '"' || !std::isprint(c); + }); } static unsigned int utf8ToCodepoint(const char*& s, const char* e) { @@ -1198,34 +1195,30 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const { endingLineFeedSymbol, usf, emitUTF8, pre, precisionType); } -static void getValidWriterKeys(std::set* valid_keys) { - valid_keys->clear(); - valid_keys->insert("indentation"); - valid_keys->insert("commentStyle"); - valid_keys->insert("enableYAMLCompatibility"); - valid_keys->insert("dropNullPlaceholders"); - valid_keys->insert("useSpecialFloats"); - valid_keys->insert("emitUTF8"); - valid_keys->insert("precision"); - valid_keys->insert("precisionType"); -} + bool StreamWriterBuilder::validate(Json::Value* invalid) const { - Json::Value my_invalid; - if (!invalid) - invalid = &my_invalid; // so we do not need to test for NULL - Json::Value& inv = *invalid; - std::set valid_keys; - getValidWriterKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); - size_t n = keys.size(); - for (size_t i = 0; i < n; ++i) { - String const& key = keys[i]; - if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; - } + static const auto& valid_keys = *new std::set{ + "indentation", + "commentStyle", + "enableYAMLCompatibility", + "dropNullPlaceholders", + "useSpecialFloats", + "emitUTF8", + "precision", + "precisionType", + }; + for (auto si = settings_.begin(); si != settings_.end(); ++si) { + auto key = si.name(); + if (valid_keys.count(key)) + continue; + if (invalid) + (*invalid)[std::move(key)] = *si; + else + return false; } - return inv.empty(); + return invalid ? invalid->empty() : true; } + Value& StreamWriterBuilder::operator[](const String& key) { return settings_[key]; } diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index e6fe43d79..73850cfd8 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3286,11 +3286,11 @@ struct CharReaderAllowDropNullTest : JsonTest::TestCase { return [=](const Value& root) { JSONTEST_ASSERT_EQUAL(root, v); }; } - ValueCheck objGetAnd(std::string idx, ValueCheck f) { + static ValueCheck objGetAnd(std::string idx, ValueCheck f) { return [=](const Value& root) { f(root.get(idx, true)); }; } - ValueCheck arrGetAnd(int idx, ValueCheck f) { + static ValueCheck arrGetAnd(int idx, ValueCheck f) { return [=](const Value& root) { f(root[idx]); }; } }; From 75b360af4ae3949c003e39d57dad43238e3178c2 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Wed, 13 May 2020 18:37:02 -0400 Subject: [PATCH 295/410] spot fix #1171: isprint argument must be representable as unsigned char (#1173) --- src/lib_json/json_writer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index cb528b8b6..56ee65ef6 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -178,7 +178,7 @@ String valueToString(bool value) { return value ? "true" : "false"; } static bool isAnyCharRequiredQuoting(char const* s, size_t n) { assert(s || !n); - return std::any_of(s, s + n, [](int c) { + return std::any_of(s, s + n, [](unsigned char c) { return c == '\\' || c == '"' || !std::isprint(c); }); } From c161f4ac69633deb2ed43bc8569cb9b183f63c32 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 21 May 2020 11:30:59 -0400 Subject: [PATCH 296/410] Escape control chars even if emitting UTF8 (#1178) * Escape control chars even if emitting UTF8 See #1176 Fixes #1175 * review comments * fix test by stopping early enough to punt on utf8-input. --- src/lib_json/json_writer.cpp | 49 +++++++++++++++------------- src/test_lib_json/main.cpp | 62 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 22 deletions(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 56ee65ef6..03a777f90 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -262,6 +262,14 @@ static String toHex16Bit(unsigned int x) { return result; } +static void appendRaw(String& result, unsigned ch) { + result += static_cast(ch); +} + +static void appendHex(String& result, unsigned ch) { + result.append("\\u").append(toHex16Bit(ch)); +} + static String valueToQuotedStringN(const char* value, unsigned length, bool emitUTF8 = false) { if (value == nullptr) @@ -310,29 +318,26 @@ static String valueToQuotedStringN(const char* value, unsigned length, // sequence from occurring. default: { if (emitUTF8) { - result += *c; + unsigned codepoint = static_cast(*c); + if (codepoint < 0x20) { + appendHex(result, codepoint); + } else { + appendRaw(result, codepoint); + } } else { - unsigned int codepoint = utf8ToCodepoint(c, end); - const unsigned int FIRST_NON_CONTROL_CODEPOINT = 0x20; - const unsigned int LAST_NON_CONTROL_CODEPOINT = 0x7F; - const unsigned int FIRST_SURROGATE_PAIR_CODEPOINT = 0x10000; - // don't escape non-control characters - // (short escape sequence are applied above) - if (FIRST_NON_CONTROL_CODEPOINT <= codepoint && - codepoint <= LAST_NON_CONTROL_CODEPOINT) { - result += static_cast(codepoint); - } else if (codepoint < - FIRST_SURROGATE_PAIR_CODEPOINT) { // codepoint is in Basic - // Multilingual Plane - result += "\\u"; - result += toHex16Bit(codepoint); - } else { // codepoint is not in Basic Multilingual Plane - // convert to surrogate pair first - codepoint -= FIRST_SURROGATE_PAIR_CODEPOINT; - result += "\\u"; - result += toHex16Bit((codepoint >> 10) + 0xD800); - result += "\\u"; - result += toHex16Bit((codepoint & 0x3FF) + 0xDC00); + unsigned codepoint = utf8ToCodepoint(c, end); // modifies `c` + if (codepoint < 0x20) { + appendHex(result, codepoint); + } else if (codepoint < 0x80) { + appendRaw(result, codepoint); + } else if (codepoint < 0x10000) { + // Basic Multilingual Plane + appendHex(result, codepoint); + } else { + // Extended Unicode. Encode 20 bits as a surrogate pair. + codepoint -= 0x10000; + appendHex(result, 0xd800 + ((codepoint >> 10) & 0x3ff)); + appendHex(result, 0xdc00 + (codepoint & 0x3ff)); } } } break; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 73850cfd8..639b5a24e 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2640,6 +2640,68 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) { "\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}"); } +// Control chars should be escaped regardless of UTF-8 input encoding. +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, escapeControlCharacters) { + auto uEscape = [](unsigned ch) { + static const char h[] = "0123456789abcdef"; + std::string r = "\\u"; + r += h[(ch >> (3 * 4)) & 0xf]; + r += h[(ch >> (2 * 4)) & 0xf]; + r += h[(ch >> (1 * 4)) & 0xf]; + r += h[(ch >> (0 * 4)) & 0xf]; + return r; + }; + auto shortEscape = [](unsigned ch) -> const char* { + switch (ch) { + case '\"': + return "\\\""; + case '\\': + return "\\\\"; + case '\b': + return "\\b"; + case '\f': + return "\\f"; + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\t': + return "\\t"; + default: + return nullptr; + } + }; + + Json::StreamWriterBuilder b; + + for (bool emitUTF8 : {true, false}) { + b.settings_["emitUTF8"] = emitUTF8; + + for (unsigned i = 0; i != 0x100; ++i) { + if (!emitUTF8 && i >= 0x80) + break; // The algorithm would try to parse UTF-8, so stop here. + + std::string raw({static_cast(i)}); + std::string esc = raw; + if (i < 0x20) + esc = uEscape(i); + if (const char* shEsc = shortEscape(i)) + esc = shEsc; + + // std::cout << "emit=" << emitUTF8 << ", i=" << std::hex << i << std::dec + // << std::endl; + + Json::Value root; + root["test"] = raw; + JSONTEST_ASSERT_STRING_EQUAL( + std::string("{\n\t\"test\" : \"").append(esc).append("\"\n}"), + Json::writeString(b, root)) + << ", emit=" << emitUTF8 << ", i=" << i << ", raw=\"" << raw << "\"" + << ", esc=\"" << esc << "\""; + } + } +} + struct ReaderTest : JsonTest::TestCase { void setStrictMode() { reader = std::unique_ptr( From 6aba23f4a8628d599a9ef7fa4811c4ff6e4070e2 Mon Sep 17 00:00:00 2001 From: kabeer27 <32016558+kabeer27@users.noreply.github.com> Date: Fri, 29 May 2020 19:20:26 +0530 Subject: [PATCH 297/410] Fixes Oss-Fuzz issue: 21916 (#1180) * Fix heap-buffer-overflow in json_reader --- src/lib_json/json_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 2dca4ca87..23cbe60e1 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1270,7 +1270,7 @@ void OurReader::skipSpaces() { void OurReader::skipBom(bool skipBom) { // The default behavior is to skip BOM. if (skipBom) { - if (strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) { + if ((end_ - begin_) >= 3 && strncmp(begin_, "\xEF\xBB\xBF", 3) == 0) { begin_ += 3; current_ = begin_; } From 9be589598595963f94ba264d7b416d0533421106 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Sat, 30 May 2020 20:20:20 -0700 Subject: [PATCH 298/410] Issue 1182: Fix fuzzing bug (#1183) This patch fixes a fuzzing bug by resolving a bad fallthrough in the setComment logic. The result is that we get a proper error instead of an assert, making the library friendlier to use and less likely to cause issue for consumers. See related Chromium project bug: https://bugs.chromium.org/p/chromium/issues/detail?id=989851 Issue: 1182 --- src/lib_json/json_reader.cpp | 7 +++++-- test/data/fail_invalid_quote.json | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 test/data/fail_invalid_quote.json diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 23cbe60e1..19922a823 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1175,8 +1175,11 @@ bool OurReader::readToken(Token& token) { if (features_.allowSingleQuotes_) { token.type_ = tokenString; ok = readStringSingleQuote(); - break; - } // else fall through + } else { + // If we don't allow single quotes, this is a failure case. + ok = false; + } + break; case '/': token.type_ = tokenComment; ok = readComment(); diff --git a/test/data/fail_invalid_quote.json b/test/data/fail_invalid_quote.json new file mode 100644 index 000000000..dae27f53f --- /dev/null +++ b/test/data/fail_invalid_quote.json @@ -0,0 +1 @@ +{'//this is bad JSON.'} \ No newline at end of file From b3189a0800e2d6af9c507d149c37a65dec72199d Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 11 Jun 2020 17:43:44 -0400 Subject: [PATCH 299/410] avoid isprint, because it is locale specific (#1189) * avoid isprint `std::isprint` is locale-specific and the JSON-spec is not. In particular, isprint('\t') is true in Windows CP1252. Has bitten others, e.g. https://github.com/laurikari/tre/issues/64 Fixes #1187 * semicolon (rookie mistake!) --- src/lib_json/json_writer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 03a777f90..8bf02dbdb 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -175,11 +175,11 @@ String valueToString(double value, unsigned int precision, String valueToString(bool value) { return value ? "true" : "false"; } -static bool isAnyCharRequiredQuoting(char const* s, size_t n) { +static bool doesAnyCharRequireEscaping(char const* s, size_t n) { assert(s || !n); return std::any_of(s, s + n, [](unsigned char c) { - return c == '\\' || c == '"' || !std::isprint(c); + return c == '\\' || c == '"' || c < 0x20 || c > 0x7F; }); } @@ -275,7 +275,7 @@ static String valueToQuotedStringN(const char* value, unsigned length, if (value == nullptr) return ""; - if (!isAnyCharRequiredQuoting(value, length)) + if (!doesAnyCharRequireEscaping(value, length)) return String("\"") + value + "\""; // We have to walk value and escape any special characters. // Appending to String is not efficient, but this should be rare. From 632044ad956b9ca55703d98d852bc815077f6afc Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 11 Jun 2020 18:14:03 -0400 Subject: [PATCH 300/410] Billy donahue avoid isprint (#1191) * avoid isprint `std::isprint` is locale-specific and the JSON-spec is not. In particular, isprint('\t') is true in Windows CP1252. Has bitten others, e.g. https://github.com/laurikari/tre/issues/64 Fixes #1187 * semicolon (rookie mistake!) * Windows tab escape testing with custom locale (#1190) Co-authored-by: Nikolay Baklicharov --- src/test_lib_json/main.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 639b5a24e..991c2473d 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2702,6 +2702,34 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, escapeControlCharacters) { } } +#ifdef _WIN32 +JSONTEST_FIXTURE_LOCAL(StreamWriterTest, escapeTabCharacterWindows) { + // Get the current locale before changing it + std::string currentLocale = setlocale(LC_ALL, NULL); + setlocale(LC_ALL, "English_United States.1252"); + + Json::Value root; + root["test"] = "\tTabTesting\t"; + + Json::StreamWriterBuilder b; + + JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " + "\"\\tTabTesting\\t\"\n}"); + + b.settings_["emitUTF8"] = true; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " + "\"\\tTabTesting\\t\"\n}"); + + b.settings_["emitUTF8"] = false; + JSONTEST_ASSERT(Json::writeString(b, root) == "{\n\t\"test\" : " + "\"\\tTabTesting\\t\"\n}"); + + // Restore the locale + if (!currentLocale.empty()) + setlocale(LC_ALL, currentLocale.c_str()); +} +#endif + struct ReaderTest : JsonTest::TestCase { void setStrictMode() { reader = std::unique_ptr( From c8453d39d1d98ddafd15267d9d55223cdc48f2b1 Mon Sep 17 00:00:00 2001 From: nathanruiz Date: Wed, 24 Jun 2020 07:52:28 +1000 Subject: [PATCH 301/410] Delete nullptr Json::Value constructor (#1194) This patch adds an explicit ctor with a std::nullptr_t argument, that is `delete`-d. This keeps Json::Value from exposing a coding error when automatically promoted to a const char* type. --- include/json/value.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/json/value.h b/include/json/value.h index dffc51a85..df1eba6ac 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -342,6 +342,7 @@ class JSON_API Value { Value(const StaticString& value); Value(const String& value); Value(bool value); + Value(std::nullptr_t ptr) = delete; Value(const Value& other); Value(Value&& other); ~Value(); From cfc1ad72ad7e0a6d625686182bce1aefa118b308 Mon Sep 17 00:00:00 2001 From: Chen Date: Mon, 13 Jul 2020 20:33:58 +0800 Subject: [PATCH 302/410] Enhance cmake script (#1197) * BUILD_TYPE corresponds to Release/Debug but LIB_TYPE corresponds to shared/static. * Add support to build shared, static and object lib at the same time. --- .travis_scripts/cmake_builder.sh | 2 +- CMakeLists.txt | 12 +-- src/jsontestrunner/CMakeLists.txt | 4 +- src/lib_json/CMakeLists.txt | 132 ++++++++++++++++++++++-------- src/test_lib_json/CMakeLists.txt | 4 +- 5 files changed, 114 insertions(+), 40 deletions(-) diff --git a/.travis_scripts/cmake_builder.sh b/.travis_scripts/cmake_builder.sh index ccb33312e..f3d4e46b6 100755 --- a/.travis_scripts/cmake_builder.sh +++ b/.travis_scripts/cmake_builder.sh @@ -66,7 +66,7 @@ cmake --version echo ${CXX} ${CXX} --version _COMPILER_NAME=`basename ${CXX}` -if [ "${BUILD_TYPE}" == "shared" ]; then +if [ "${LIB_TYPE}" = "shared" ]; then _CMAKE_BUILD_SHARED_LIBS=ON else _CMAKE_BUILD_SHARED_LIBS=OFF diff --git a/CMakeLists.txt b/CMakeLists.txt index 01b8c9d42..b8d53a63d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,19 +59,19 @@ if(CCACHE_EXECUTABLE) set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE) endif() -project(JSONCPP +project(jsoncpp # Note: version must be updated in three places when doing a release. This # annoying process ensures that amalgamate, CMake, and meson all report the # correct version. # 1. ./meson.build # 2. ./include/json/version.h # 3. ./CMakeLists.txt - # IMPORTANT: also update the JSONCPP_SOVERSION!! + # IMPORTANT: also update the PROJECT_SOVERSION!! VERSION 1.9.3 # [.[.[.]]] LANGUAGES CXX) -message(STATUS "JsonCpp Version: ${JSONCPP_VERSION_MAJOR}.${JSONCPP_VERSION_MINOR}.${JSONCPP_VERSION_PATCH}") -set(JSONCPP_SOVERSION 24) +message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") +set(PROJECT_SOVERSION 24) option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) @@ -80,7 +80,9 @@ option(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF) -option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." OFF) +option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." ON) +option(BUILD_STATIC_LIBS "Build jsoncpp_lib as a static library." ON) +option(BUILD_OBJECT_LIBS "Build jsoncpp_lib as a object library." ON) # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) diff --git a/src/jsontestrunner/CMakeLists.txt b/src/jsontestrunner/CMakeLists.txt index d24aa6f46..1fc71ea87 100644 --- a/src/jsontestrunner/CMakeLists.txt +++ b/src/jsontestrunner/CMakeLists.txt @@ -19,8 +19,10 @@ if(BUILD_SHARED_LIBS) else() add_definitions(-DJSON_DLL) endif() + target_link_libraries(jsontestrunner_exe jsoncpp_lib) +else() + target_link_libraries(jsontestrunner_exe jsoncpp_static) endif() -target_link_libraries(jsontestrunner_exe jsoncpp_lib) set_target_properties(jsontestrunner_exe PROPERTIES OUTPUT_NAME jsontestrunner_exe) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index b3306659b..cea92efe8 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -50,7 +50,7 @@ set(PUBLIC_HEADERS source_group("Public API" FILES ${PUBLIC_HEADERS}) -set(jsoncpp_sources +set(JSONCPP_SOURCES json_tool.h json_reader.cpp json_valueiterator.inl @@ -65,32 +65,10 @@ else() set(INSTALL_EXPORT) endif() - -if(BUILD_SHARED_LIBS) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) - add_compile_definitions(JSON_DLL_BUILD) - else() - add_definitions(-DJSON_DLL_BUILD) - endif() -endif() - -add_library(jsoncpp_lib ${PUBLIC_HEADERS} ${jsoncpp_sources}) -set_target_properties( jsoncpp_lib PROPERTIES - OUTPUT_NAME jsoncpp - VERSION ${JSONCPP_VERSION} - SOVERSION ${JSONCPP_SOVERSION} - POSITION_INDEPENDENT_CODE ON -) - -# Set library's runtime search path on OSX -if(APPLE) - set_target_properties(jsoncpp_lib PROPERTIES INSTALL_RPATH "@loader_path/.") -endif() - # Specify compiler features required when compiling a given target. # See https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES # for complete list of features available -target_compile_features(jsoncpp_lib PUBLIC +list(APPEND REQUIRED_FEATURES cxx_std_11 # Compiler mode is aware of C++ 11. #MSVC 1900 cxx_alignas # Alignment control alignas, as defined in N2341. #MSVC 1900 cxx_alignof # Alignment control alignof, as defined in N2341. @@ -137,16 +115,106 @@ target_compile_features(jsoncpp_lib PUBLIC cxx_variadic_templates # Variadic templates, as defined in N2242. ) -install(TARGETS jsoncpp_lib ${INSTALL_EXPORT} + +if(BUILD_SHARED_LIBS) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0) + add_compile_definitions(JSON_DLL_BUILD) + else() + add_definitions(-DJSON_DLL_BUILD) + endif() + + set(SHARED_LIB ${PROJECT_NAME}_lib) + add_library(${SHARED_LIB} SHARED ${PUBLIC_HEADERS} ${JSONCPP_SOURCES}) + set_target_properties(${SHARED_LIB} PROPERTIES + OUTPUT_NAME jsoncpp + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_SOVERSION} + POSITION_INDEPENDENT_CODE ON + ) + + # Set library's runtime search path on OSX + if(APPLE) + set_target_properties(${SHARED_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.") + endif() + + target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES}) + + if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + target_include_directories(${SHARED_LIB} PUBLIC + $ + $ + $ + ) + endif() + + list(APPEND CMAKE_TARGETS ${SHARED_LIB}) +endif() + +if(BUILD_STATIC_LIBS) + set(STATIC_LIB ${PROJECT_NAME}_static) + add_library(${STATIC_LIB} STATIC ${PUBLIC_HEADERS} ${JSONCPP_SOURCES}) + + # avoid name clashes on windows as the shared import lib is alse named jsoncpp.lib + if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) + set(STATIC_SUFFIX "_static") + endif() + + set_target_properties(${STATIC_LIB} PROPERTIES + OUTPUT_NAME jsoncpp${STATIC_SUFFIX} + VERSION ${PROJECT_VERSION} + ) + + # Set library's runtime search path on OSX + if(APPLE) + set_target_properties(${STATIC_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.") + endif() + + target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES}) + + if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + target_include_directories(${STATIC_LIB} PUBLIC + $ + $ + $ + ) + endif() + + list(APPEND CMAKE_TARGETS ${STATIC_LIB}) +endif() + +if(BUILD_OBJECT_LIBS) + set(OBJECT_LIB ${PROJECT_NAME}_object) + add_library(${OBJECT_LIB} OBJECT ${PUBLIC_HEADERS} ${JSONCPP_SOURCES}) + + set_target_properties(${OBJECT_LIB} PROPERTIES + OUTPUT_NAME jsoncpp + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_SOVERSION} + POSITION_INDEPENDENT_CODE ON + ) + + # Set library's runtime search path on OSX + if(APPLE) + set_target_properties(${OBJECT_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.") + endif() + + target_compile_features(${OBJECT_LIB} PUBLIC ${REQUIRED_FEATURES}) + + if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) + target_include_directories(${OBJECT_LIB} PUBLIC + $ + $ + $ + ) + endif() + + list(APPEND CMAKE_TARGETS ${OBJECT_LIB}) +endif() + +install(TARGETS ${CMAKE_TARGETS} ${INSTALL_EXPORT} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + OBJECTS DESTINATION ${CMAKE_INSTALL_LIBDIR} ) -if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories(jsoncpp_lib PUBLIC - $ - $ - $ - ) -endif() diff --git a/src/test_lib_json/CMakeLists.txt b/src/test_lib_json/CMakeLists.txt index b803db669..1c3fce913 100644 --- a/src/test_lib_json/CMakeLists.txt +++ b/src/test_lib_json/CMakeLists.txt @@ -15,8 +15,10 @@ if(BUILD_SHARED_LIBS) else() add_definitions( -DJSON_DLL ) endif() + target_link_libraries(jsoncpp_test jsoncpp_lib) +else() + target_link_libraries(jsoncpp_test jsoncpp_static) endif() -target_link_libraries(jsoncpp_test jsoncpp_lib) # another way to solve issue #90 #set_target_properties(jsoncpp_test PROPERTIES COMPILE_FLAGS -ffloat-store) From bf0cfa5b46263b202aceb4d4e2fd000e87d4c96f Mon Sep 17 00:00:00 2001 From: Chen Date: Tue, 14 Jul 2020 16:37:22 +0800 Subject: [PATCH 303/410] hot fix for building static lib (#1203) Fix #1197 --- src/lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index cea92efe8..af2647652 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -169,7 +169,7 @@ if(BUILD_STATIC_LIBS) set_target_properties(${STATIC_LIB} PROPERTIES INSTALL_RPATH "@loader_path/.") endif() - target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES}) + target_compile_features(${STATIC_LIB} PUBLIC ${REQUIRED_FEATURES}) if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) target_include_directories(${STATIC_LIB} PUBLIC From 5be07bdc5e2d5b7715ecbc73749af3e625674dcb Mon Sep 17 00:00:00 2001 From: Ben Wolsieffer Date: Mon, 20 Jul 2020 08:36:30 -0400 Subject: [PATCH 304/410] Fix generation of pkg-config file with absolute includedir/libdir. (#1199) --- .gitignore | 1 - CMakeLists.txt | 7 +++++++ cmake/JoinPaths.cmake | 23 +++++++++++++++++++++++ pkg-config/jsoncpp.pc.in | 4 ++-- 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 cmake/JoinPaths.cmake diff --git a/.gitignore b/.gitignore index 91121c230..68f40b06e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,7 +28,6 @@ # CMake-generated files: CMakeFiles/ -*.cmake /pkg-config/jsoncpp.pc jsoncpp_lib_static.dir/ diff --git a/CMakeLists.txt b/CMakeLists.txt index b8d53a63d..96d3c9e43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,8 @@ if(NOT DEFINED CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES) "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.") endif() +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + # --------------------------------------------------------------------------- # use ccache if found, has to be done before project() # --------------------------------------------------------------------------- @@ -148,6 +150,11 @@ if(JSONCPP_WITH_WARNING_AS_ERROR) endif() if(JSONCPP_WITH_PKGCONFIG_SUPPORT) + include(JoinPaths) + + join_paths(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}") + join_paths(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}") + configure_file( "pkg-config/jsoncpp.pc.in" "pkg-config/jsoncpp.pc" diff --git a/cmake/JoinPaths.cmake b/cmake/JoinPaths.cmake new file mode 100644 index 000000000..2b376b733 --- /dev/null +++ b/cmake/JoinPaths.cmake @@ -0,0 +1,23 @@ +# This module provides a function for joining paths +# known from most languages +# +# SPDX-License-Identifier: (MIT OR CC0-1.0) +# Copyright 2020 Jan Tojnar +# https://github.com/jtojnar/cmake-snips +# +# Modelled after Python’s os.path.join +# https://docs.python.org/3.7/library/os.path.html#os.path.join +# Windows not supported +function(join_paths joined_path first_path_segment) + set(temp_path "${first_path_segment}") + foreach(current_segment IN LISTS ARGN) + if(NOT ("${current_segment}" STREQUAL "")) + if(IS_ABSOLUTE "${current_segment}") + set(temp_path "${current_segment}") + else() + set(temp_path "${temp_path}/${current_segment}") + endif() + endif() + endforeach() + set(${joined_path} "${temp_path}" PARENT_SCOPE) +endfunction() diff --git a/pkg-config/jsoncpp.pc.in b/pkg-config/jsoncpp.pc.in index d4fa9ef26..632a377f5 100644 --- a/pkg-config/jsoncpp.pc.in +++ b/pkg-config/jsoncpp.pc.in @@ -1,7 +1,7 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@ -includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ +libdir=@libdir_for_pc_file@ +includedir=@includedir_for_pc_file@ Name: jsoncpp Description: A C++ library for interacting with JSON From 45733df96cde1af55145909ce5f1c910df98a9be Mon Sep 17 00:00:00 2001 From: Daniel Engberg Date: Wed, 3 Jun 2020 12:19:51 +0200 Subject: [PATCH 305/410] meson: Don't specifically look for python3 Not all distributions provide Python as python3 and as Meson already depends on 3.5+ just use what Meson uses. References: https://mesonbuild.com/Getting-meson.html https://mesonbuild.com/Python-module.html#find_installation Signed-off-by: Daniel Engberg --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 75ec97446..5191d23b5 100644 --- a/meson.build +++ b/meson.build @@ -73,7 +73,7 @@ if meson.is_subproject() or not get_option('tests') subdir_done() endif -python = import('python').find_installation('python3') +python = import('python').find_installation() jsoncpp_test = executable( 'jsoncpp_test', files([ From 9059f5cad030ba11d37818847443a53918c327b1 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 25 Sep 2020 19:19:16 -0700 Subject: [PATCH 306/410] Roll version numbers for 1.9.4 release (#1223) --- CMakeLists.txt | 2 +- include/json/version.h | 2 +- meson.build | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96d3c9e43..51b74fcc9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ project(jsoncpp # 2. ./include/json/version.h # 3. ./CMakeLists.txt # IMPORTANT: also update the PROJECT_SOVERSION!! - VERSION 1.9.3 # [.[.[.]]] + VERSION 1.9.4 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") diff --git a/include/json/version.h b/include/json/version.h index 0f2983411..5b9783d96 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,7 +9,7 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.3" +#define JSONCPP_VERSION_STRING "1.9.4" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 #define JSONCPP_VERSION_PATCH 3 diff --git a/meson.build b/meson.build index 5191d23b5..08e0f299e 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ project( # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - version : '1.9.3', + version : '1.9.4', default_options : [ 'buildtype=release', 'cpp_std=c++11', From 72db27698627d8358ba745ee7f919ad6eeaec772 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 1 Oct 2020 12:21:48 -0400 Subject: [PATCH 307/410] version.h: fix the version number in the header Fixes: #1224 --- include/json/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/json/version.h b/include/json/version.h index 5b9783d96..87cf7e2fb 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -12,7 +12,7 @@ #define JSONCPP_VERSION_STRING "1.9.4" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 3 +#define JSONCPP_VERSION_PATCH 4 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ From c60ebf787aaef3c1cf8d58be01d0d3d508e04255 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Thu, 1 Oct 2020 12:22:04 -0400 Subject: [PATCH 308/410] test: ensure the version numbers agree --- src/test_lib_json/main.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 991c2473d..540e66bf4 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3916,6 +3916,16 @@ JSONTEST_FIXTURE_LOCAL(MemberTemplateIs, BehavesSameAsNamedIs) { } } +class VersionTest : public JsonTest::TestCase {}; + +JSONTEST_FIXTURE_LOCAL(VersionTest, VersionNumbersMatch) { + std::ostringstream vstr; + vstr << JSONCPP_VERSION_MAJOR << '.' + << JSONCPP_VERSION_MINOR << '.' + << JSONCPP_VERSION_PATCH; + JSONTEST_ASSERT_EQUAL(vstr.str(), std::string(JSONCPP_VERSION_STRING)); +} + #if defined(__GNUC__) #pragma GCC diagnostic pop #endif From 5d1cb30e40210ec382db41922f25b254ab6e6d31 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 10 Oct 2020 10:29:19 -0500 Subject: [PATCH 309/410] clang-format --- .travis_scripts/run-clang-format.py | 2 +- reformat.sh | 1 + src/test_lib_json/main.cpp | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 reformat.sh diff --git a/.travis_scripts/run-clang-format.py b/.travis_scripts/run-clang-format.py index 68179aafd..605b5aad1 100755 --- a/.travis_scripts/run-clang-format.py +++ b/.travis_scripts/run-clang-format.py @@ -353,4 +353,4 @@ def main(): if __name__ == '__main__': - sys.exit(main()) \ No newline at end of file + sys.exit(main()) diff --git a/reformat.sh b/reformat.sh new file mode 100644 index 000000000..cdc03b1ea --- /dev/null +++ b/reformat.sh @@ -0,0 +1 @@ +find src -name '*.cpp' -or -name '*.h' | xargs clang-format -i diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 540e66bf4..f29692396 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3920,8 +3920,7 @@ class VersionTest : public JsonTest::TestCase {}; JSONTEST_FIXTURE_LOCAL(VersionTest, VersionNumbersMatch) { std::ostringstream vstr; - vstr << JSONCPP_VERSION_MAJOR << '.' - << JSONCPP_VERSION_MINOR << '.' + vstr << JSONCPP_VERSION_MAJOR << '.' << JSONCPP_VERSION_MINOR << '.' << JSONCPP_VERSION_PATCH; JSONTEST_ASSERT_EQUAL(vstr.str(), std::string(JSONCPP_VERSION_STRING)); } From 1664b6bbf848ef13b330ced6f0c7ba63d70805d5 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 10 Oct 2020 09:06:43 -0500 Subject: [PATCH 310/410] Try meson/ninja from pypi This lets us simplify linux a little. However, we still want to test cmake, so there is only so much we can simplify. For OSX, we still need `clang-format` from homebrew. * Add PYTHONUSERBASE/bin to PATH for linux --- .travis.yml | 2 ++ .travis_scripts/travis.before_install.osx.sh | 1 - .travis_scripts/travis.install.linux.sh | 11 +++-------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0554dc93b..1e1e1793f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,8 @@ matrix: CC="clang" LIB_TYPE=static BUILD_TYPE=release + PYTHONUSERBASE="$(pwd)/LOCAL" + PATH="$PYTHONUSERBASE/bin:$PATH" # before_install and install steps only needed for linux meson builds before_install: - source ./.travis_scripts/travis.before_install.${TRAVIS_OS_NAME}.sh diff --git a/.travis_scripts/travis.before_install.osx.sh b/.travis_scripts/travis.before_install.osx.sh index 5d83c0c71..e69de29bb 100644 --- a/.travis_scripts/travis.before_install.osx.sh +++ b/.travis_scripts/travis.before_install.osx.sh @@ -1 +0,0 @@ -# NOTHING TO DO HERE diff --git a/.travis_scripts/travis.install.linux.sh b/.travis_scripts/travis.install.linux.sh index 7c5846f1a..6495fefe9 100644 --- a/.travis_scripts/travis.install.linux.sh +++ b/.travis_scripts/travis.install.linux.sh @@ -1,10 +1,5 @@ set -vex -wget https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-linux.zip -unzip -q ninja-linux.zip -d build - -pip3 install meson -echo ${PATH} -ls /usr/local -ls /usr/local/bin -export PATH="${PWD}"/build:/usr/local/bin:/usr/bin:${PATH} +pip3 install --user meson ninja +which meson +which ninja From bb9db78fe27591afacd0df7a9b6b69bdfeec20ea Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 10 Oct 2020 11:20:19 -0500 Subject: [PATCH 311/410] Do not allow failures on osx --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1e1e1793f..6d7ccde74 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,8 +22,6 @@ addons: - clang-8 - valgrind matrix: - allow_failures: - - os: osx include: - name: Mac clang meson static release testing os: osx From 30170d651c108400b1b9ed626ba715a5d95c5fd2 Mon Sep 17 00:00:00 2001 From: Christian Ledergerber Date: Tue, 13 Oct 2020 17:55:58 +0200 Subject: [PATCH 312/410] Fix c++20 compilation problem for clang10 and fix potential bug due to compiler optimization --- include/json/allocator.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/json/allocator.h b/include/json/allocator.h index 0f5c224b9..95ef8a5ec 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -35,11 +35,10 @@ template class SecureAllocator { * Release memory which was allocated for N items at pointer P. * * The memory block is filled with zeroes before being released. - * The pointer argument is tagged as "volatile" to prevent the - * compiler optimizing out this critical step. */ - void deallocate(volatile pointer p, size_type n) { - std::memset(p, 0, n * sizeof(T)); + void deallocate(pointer p, size_type n) { + // memset_s is used because memset may be optimized away by the compiler + memset_s(p, n * sizeof(T), 0, n * sizeof(T)); // free using "global operator delete" ::operator delete(p); } From ceae0e3867fe16e1227b4a39fe6951ee005591dc Mon Sep 17 00:00:00 2001 From: Marcel Opprecht Date: Fri, 6 Nov 2020 22:22:26 +0100 Subject: [PATCH 313/410] Fix clang-tidy warnings (#1231) * Fix clang-tidy warnings Signed-off-by: Marcel Opprecht * Fixup/clang-format Co-authored-by: Marcel Opprecht Co-authored-by: Jordan Bayles --- CONTRIBUTING.md | 4 +++- include/json/value.h | 12 ++++++------ reformat.sh | 0 src/lib_json/json_reader.cpp | 2 +- src/lib_json/json_value.cpp | 13 +++++++------ src/lib_json/json_writer.cpp | 2 +- 6 files changed, 18 insertions(+), 15 deletions(-) mode change 100644 => 100755 reformat.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9c9fc6a04..d72fe9708 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -143,7 +143,9 @@ bool Reader::decodeNumber(Token& token) { ``` Before submitting your code, ensure that you meet the versioning requirements above, follow the style guide of the file you are modifying (or the above rules for new files), and run clang format. Meson exposes clang format with the following command: - ``` ninja -v -C build-${LIB_TYPE}/ clang-format ``` + +For convenience, you can also run the `reformat.sh` script located in the root directory. + diff --git a/include/json/value.h b/include/json/value.h index df1eba6ac..ec9af5666 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -263,10 +263,10 @@ class JSON_API Value { CZString(ArrayIndex index); CZString(char const* str, unsigned length, DuplicationPolicy allocate); CZString(CZString const& other); - CZString(CZString&& other); + CZString(CZString&& other) noexcept; ~CZString(); CZString& operator=(const CZString& other); - CZString& operator=(CZString&& other); + CZString& operator=(CZString&& other) noexcept; bool operator<(CZString const& other) const; bool operator==(CZString const& other) const; @@ -344,13 +344,13 @@ class JSON_API Value { Value(bool value); Value(std::nullptr_t ptr) = delete; Value(const Value& other); - Value(Value&& other); + Value(Value&& other) noexcept; ~Value(); /// \note Overwrite existing comments. To preserve comments, use /// #swapPayload(). Value& operator=(const Value& other); - Value& operator=(Value&& other); + Value& operator=(Value&& other) noexcept; /// Swap everything. void swap(Value& other); @@ -635,9 +635,9 @@ class JSON_API Value { public: Comments() = default; Comments(const Comments& that); - Comments(Comments&& that); + Comments(Comments&& that) noexcept; Comments& operator=(const Comments& that); - Comments& operator=(Comments&& that); + Comments& operator=(Comments&& that) noexcept; bool has(CommentPlacement slot) const; String get(CommentPlacement slot) const; void set(CommentPlacement slot, String comment); diff --git a/reformat.sh b/reformat.sh old mode 100644 new mode 100755 diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 19922a823..a34017d99 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1921,7 +1921,7 @@ bool CharReaderBuilder::validate(Json::Value* invalid) const { if (valid_keys.count(key)) continue; if (invalid) - (*invalid)[std::move(key)] = *si; + (*invalid)[key] = *si; else return false; } diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 0872ff548..bfa9263fd 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -259,7 +259,7 @@ Value::CZString::CZString(const CZString& other) { storage_.length_ = other.storage_.length_; } -Value::CZString::CZString(CZString&& other) +Value::CZString::CZString(CZString&& other) noexcept : cstr_(other.cstr_), index_(other.index_) { other.cstr_ = nullptr; } @@ -285,7 +285,7 @@ Value::CZString& Value::CZString::operator=(const CZString& other) { return *this; } -Value::CZString& Value::CZString::operator=(CZString&& other) { +Value::CZString& Value::CZString::operator=(CZString&& other) noexcept { cstr_ = other.cstr_; index_ = other.index_; other.cstr_ = nullptr; @@ -433,7 +433,7 @@ Value::Value(const Value& other) { dupMeta(other); } -Value::Value(Value&& other) { +Value::Value(Value&& other) noexcept { initBasic(nullValue); swap(other); } @@ -448,7 +448,7 @@ Value& Value::operator=(const Value& other) { return *this; } -Value& Value::operator=(Value&& other) { +Value& Value::operator=(Value&& other) noexcept { other.swap(*this); return *this; } @@ -1373,14 +1373,15 @@ bool Value::isObject() const { return type() == objectValue; } Value::Comments::Comments(const Comments& that) : ptr_{cloneUnique(that.ptr_)} {} -Value::Comments::Comments(Comments&& that) : ptr_{std::move(that.ptr_)} {} +Value::Comments::Comments(Comments&& that) noexcept + : ptr_{std::move(that.ptr_)} {} Value::Comments& Value::Comments::operator=(const Comments& that) { ptr_ = cloneUnique(that.ptr_); return *this; } -Value::Comments& Value::Comments::operator=(Comments&& that) { +Value::Comments& Value::Comments::operator=(Comments&& that) noexcept { ptr_ = std::move(that.ptr_); return *this; } diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 8bf02dbdb..c9ae416fc 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -1217,7 +1217,7 @@ bool StreamWriterBuilder::validate(Json::Value* invalid) const { if (valid_keys.count(key)) continue; if (invalid) - (*invalid)[std::move(key)] = *si; + (*invalid)[key] = *si; else return false; } From 8954092f0af9538f3cde47aceb459dbe4d6e2241 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 6 Nov 2020 15:35:51 -0600 Subject: [PATCH 314/410] ENH: Prevent cmake in source builds (#1091) * ENH: Prevent cmake in source builds Building directly inside the root of the source tree can cause problems where the build intermediate files overwrite or conflict with the intended source code files. This modification identifies this problem and issues failure messages and suggestions to over come the problem with more robust build suggestion. Co-authored-by: Jordan Bayles --- CMakeLists.txt | 3 ++ CONTRIBUTING.md | 3 +- appveyor.yml | 11 +++++-- include/PreventInBuildInstalls.cmake | 9 ++++++ include/PreventInSourceBuilds.cmake | 45 ++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 include/PreventInBuildInstalls.cmake create mode 100644 include/PreventInSourceBuilds.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 51b74fcc9..f1db5e318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,9 @@ project(jsoncpp message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") set(PROJECT_SOVERSION 24) +include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake) + option(JSONCPP_WITH_TESTS "Compile and (for jsoncpp_check) run JsonCpp test executables" ON) option(JSONCPP_WITH_POST_BUILD_UNITTEST "Automatically run unit-tests as a post build step" ON) option(JSONCPP_WITH_WARNING_AS_ERROR "Force compilation to fail if a warning occurs" OFF) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d72fe9708..8d992bee7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ If you wish to install to a directory other than /usr/local, set an environment DESTDIR=/path/to/install/dir Then, - +```sh cd jsoncpp/ BUILD_TYPE=debug #BUILD_TYPE=release @@ -35,6 +35,7 @@ Then, #meson test --no-rebuild --print-errorlogs sudo ninja install +``` ## Building and testing with other build systems See https://github.com/open-source-parsers/jsoncpp/wiki/Building diff --git a/appveyor.yml b/appveyor.yml index 0b9c8fe3f..cccce4298 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,7 @@ clone_folder: c:\projects\jsoncpp environment: + matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 CMAKE_GENERATOR: Visual Studio 14 2015 @@ -13,11 +14,15 @@ environment: build_script: - cmake --version - - cd c:\projects\jsoncpp - - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX:PATH=%CD:\=/%/install -DBUILD_SHARED_LIBS:BOOL=ON . + # The build script starts in root. + - set JSONCPP_FOLDER=%cd% + - set JSONCPP_BUILD_FOLDER=%JSONCPP_FOLDER%\build\release + - mkdir -p %JSONCPP_BUILD_FOLDER% + - cd %JSONCPP_BUILD_FOLDER% + - cmake -G "%CMAKE_GENERATOR%" -DCMAKE_INSTALL_PREFIX:PATH=%CD:\=/%/install -DBUILD_SHARED_LIBS:BOOL=ON %JSONCPP_FOLDER% # Use ctest to make a dashboard build: # - ctest -D Experimental(Start|Update|Configure|Build|Test|Coverage|MemCheck|Submit) - # NOTE: Testing on window is not yet finished: + # NOTE: Testing on windows is not yet finished: # - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalTest -D ExperimentalSubmit - ctest -C Release -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild -D ExperimentalSubmit # Final step is to verify that installation succeeds diff --git a/include/PreventInBuildInstalls.cmake b/include/PreventInBuildInstalls.cmake new file mode 100644 index 000000000..accfea64c --- /dev/null +++ b/include/PreventInBuildInstalls.cmake @@ -0,0 +1,9 @@ +string(TOLOWER "${CMAKE_INSTALL_PREFIX}" _PREFIX) +string(TOLOWER "${ITK_BINARY_DIR}" _BUILD) +if("${_PREFIX}" STREQUAL "${_BUILD}") + message(FATAL_ERROR + "The current CMAKE_INSTALL_PREFIX points at the build tree:\n" + " ${CMAKE_INSTALL_PREFIX}\n" + "This is not supported." + ) +endif() diff --git a/include/PreventInSourceBuilds.cmake b/include/PreventInSourceBuilds.cmake new file mode 100644 index 000000000..7ddda546a --- /dev/null +++ b/include/PreventInSourceBuilds.cmake @@ -0,0 +1,45 @@ +# +# This function will prevent in-source builds +function(AssureOutOfSourceBuilds) + # make sure the user doesn't play dirty with symlinks + get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + + # disallow in-source builds + if("${srcdir}" STREQUAL "${bindir}") + message("######################################################") + message("# jsoncpp should not be configured & built in the jsoncpp source directory") + message("# You must run cmake in a build directory.") + message("# For example:") + message("# mkdir jsoncpp-Sandbox ; cd jsoncpp-sandbox") + message("# git clone https://github.com/open-source-parsers/jsoncpp.git # or download & unpack the source tarball") + message("# mkdir jsoncpp-build") + message("# this will create the following directory structure") + message("#") + message("# jsoncpp-Sandbox") + message("# +--jsoncpp") + message("# +--jsoncpp-build") + message("#") + message("# Then you can proceed to configure and build") + message("# by using the following commands") + message("#") + message("# cd jsoncpp-build") + message("# cmake ../jsoncpp # or ccmake, or cmake-gui ") + message("# make") + message("#") + message("# NOTE: Given that you already tried to make an in-source build") + message("# CMake have already created several files & directories") + message("# in your source tree. run 'git status' to find them and") + message("# remove them by doing:") + message("#") + message("# cd jsoncpp-Sandbox/jsoncpp") + message("# git clean -n -d") + message("# git clean -f -d") + message("# git checkout --") + message("#") + message("######################################################") + message(FATAL_ERROR "Quitting configuration") + endif() +endfunction() + +AssureOutOfSourceBuilds() From 940982438d01fe2575acef8dd98a9b6893ccc9bb Mon Sep 17 00:00:00 2001 From: Lei Date: Wed, 16 Dec 2020 03:08:05 +0800 Subject: [PATCH 315/410] =?UTF-8?q?Fix=20a=20precision=20bug=20of=20valueT?= =?UTF-8?q?oString,=20prevent=20to=20give=20an=20error=20result=E2=80=A6?= =?UTF-8?q?=20(#1246)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix a precision bug of valueToString, prevent to give an error result on input of wanted precision 0 and a double value which end of zero before decimal point ,such as 1230.01,12300.1; Add test cases for double valueToString with precision 0; * Delete a test case with platform differences in the previous commit * Fix clang-format. * Fix clang-format! Co-authored-by: lilei --- .gitignore | 2 ++ src/lib_json/json_tool.h | 10 +++++++--- src/lib_json/json_writer.cpp | 12 +++++++----- src/test_lib_json/main.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 68f40b06e..2444e6a68 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ /libs/ /doc/doxyfile /dist/ +/.cache/ # MSVC project files: *.sln @@ -30,6 +31,7 @@ CMakeFiles/ /pkg-config/jsoncpp.pc jsoncpp_lib_static.dir/ +compile_commands.json # In case someone runs cmake in the root-dir: /CMakeCache.txt diff --git a/src/lib_json/json_tool.h b/src/lib_json/json_tool.h index 2d7b7d9a0..b952c1916 100644 --- a/src/lib_json/json_tool.h +++ b/src/lib_json/json_tool.h @@ -116,14 +116,18 @@ template void fixNumericLocaleInput(Iter begin, Iter end) { * Return iterator that would be the new end of the range [begin,end), if we * were to delete zeros in the end of string, but not the last zero before '.'. */ -template Iter fixZerosInTheEnd(Iter begin, Iter end) { +template +Iter fixZerosInTheEnd(Iter begin, Iter end, unsigned int precision) { for (; begin != end; --end) { if (*(end - 1) != '0') { return end; } // Don't delete the last zero before the decimal point. - if (begin != (end - 1) && *(end - 2) == '.') { - return end; + if (begin != (end - 1) && begin != (end - 2) && *(end - 2) == '.') { + if (precision) { + return end; + } + return end - 2; } } return end; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index c9ae416fc..18e7a42cb 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -154,16 +154,18 @@ String valueToString(double value, bool useSpecialFloats, buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end()); - // strip the zero padding from the right - if (precisionType == PrecisionType::decimalPlaces) { - buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end()); - } - // try to ensure we preserve the fact that this was given to us as a double on // input if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) { buffer += ".0"; } + + // strip the zero padding from the right + if (precisionType == PrecisionType::decimalPlaces) { + buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end(), precision), + buffer.end()); + } + return buffer; } } // namespace diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index f29692396..be9c4a73d 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -2005,6 +2005,34 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, precision) { result = Json::writeString(b, v); JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 0; + b.settings_["precisionType"] = "decimal"; + v = 123.56345694873740545068; + expected = "124"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 1; + b.settings_["precisionType"] = "decimal"; + v = 1230.001; + expected = "1230.0"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 0; + b.settings_["precisionType"] = "decimal"; + v = 1230.001; + expected = "1230"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + + b.settings_["precision"] = 0; + b.settings_["precisionType"] = "decimal"; + v = 1231.5; + expected = "1232"; + result = Json::writeString(b, v); + JSONTEST_ASSERT_STRING_EQUAL(expected, result); + b.settings_["precision"] = 10; b.settings_["precisionType"] = "decimal"; v = 0.23300000; From be4a512887e350adc8b1ae19bc2cb81d15c8846f Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sat, 9 Jan 2021 22:39:07 -0600 Subject: [PATCH 316/410] Remove trailing space characters (#1256) Also add two newlines (rebased from `aaronfranke/formatting`) resolves #1220 Co-authored-by: Aaron Franke --- .clang-tidy | 2 +- .travis_scripts/run-clang-format.sh | 2 +- LICENSE | 14 ++++++------ devtools/antglob.py | 2 +- devtools/fixeol.py | 4 ++-- devtools/licenseupdater.py | 4 ++-- doxybuild.py | 4 ++-- example/README.md | 4 ++-- test/data/legacy_test_array_06.json | 2 +- test/data/legacy_test_complex_01.json | 22 +++++++++---------- test/data/legacy_test_object_03.json | 2 +- test/data/legacy_test_object_04.json | 2 +- .../legacy_test_preserve_comment_01.expected | 2 +- .../data/legacy_test_preserve_comment_01.json | 2 +- test/pyjsontestrunner.py | 8 +++---- 15 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index be3d06a52..99e914df9 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -4,7 +4,7 @@ WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false FormatStyle: none -CheckOptions: +CheckOptions: - key: modernize-use-using.IgnoreMacros value: '0' ... diff --git a/.travis_scripts/run-clang-format.sh b/.travis_scripts/run-clang-format.sh index 91972840d..ded76aaf5 100755 --- a/.travis_scripts/run-clang-format.sh +++ b/.travis_scripts/run-clang-format.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -python $DIR/run-clang-format.py -r $DIR/../src/**/ $DIR/../include/**/ \ No newline at end of file +python $DIR/run-clang-format.py -r $DIR/../src/**/ $DIR/../include/**/ diff --git a/LICENSE b/LICENSE index 89280a6c4..c41a1d1c7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,25 +1,25 @@ -The JsonCpp library's source code, including accompanying documentation, +The JsonCpp library's source code, including accompanying documentation, tests and demonstration applications, are licensed under the following conditions... -Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all -jurisdictions which recognize such a disclaimer. In such jurisdictions, +Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all +jurisdictions which recognize such a disclaimer. In such jurisdictions, this software is released into the Public Domain. In jurisdictions which do not recognize Public Domain property (e.g. Germany as of 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and The JsonCpp Authors, and is released under the terms of the MIT License (see below). -In jurisdictions which recognize Public Domain property, the user of this -software may choose to accept it either as 1) Public Domain, 2) under the -conditions of the MIT License (see below), or 3) under the terms of dual +In jurisdictions which recognize Public Domain property, the user of this +software may choose to accept it either as 1) Public Domain, 2) under the +conditions of the MIT License (see below), or 3) under the terms of dual Public Domain/MIT License conditions described here, as they choose. The MIT License is about as close to Public Domain as a license can get, and is described in clear, concise terms at: http://en.wikipedia.org/wiki/MIT_License - + The full text of the MIT License follows: ======================================================================== diff --git a/devtools/antglob.py b/devtools/antglob.py index 98437658c..bd2d7aee9 100644 --- a/devtools/antglob.py +++ b/devtools/antglob.py @@ -146,7 +146,7 @@ def glob_impl(root_dir_path): entry_type = is_file and FILE_LINK or DIR_LINK else: entry_type = is_file and FILE or DIR -## print '=> type: %d' % entry_type, +## print '=> type: %d' % entry_type, if (entry_type & entry_type_filter) != 0: ## print ' => KEEP' yield os.path.join(dir_path, entry) diff --git a/devtools/fixeol.py b/devtools/fixeol.py index 45252a07d..11e1ce2a1 100644 --- a/devtools/fixeol.py +++ b/devtools/fixeol.py @@ -32,8 +32,8 @@ def fix_source_eol(path, is_dry_run = True, verbose = True, eol = '\n'): if verbose: print(is_dry_run and ' NEED FIX' or ' FIXED') return True -## -## +## +## ## ##def _do_fix(is_dry_run = True): ## from waftools import antglob diff --git a/devtools/licenseupdater.py b/devtools/licenseupdater.py index 36bdb5c09..d9b662e01 100644 --- a/devtools/licenseupdater.py +++ b/devtools/licenseupdater.py @@ -20,7 +20,7 @@ def update_license(path, dry_run, show_diff): dry_run: if True, just print the path of the file that would be updated, but don't change it. show_diff: if True, print the path of the file that would be modified, - as well as the change made to the file. + as well as the change made to the file. """ with open(path, 'rt') as fin: original_text = fin.read().replace('\r\n','\n') @@ -51,7 +51,7 @@ def update_license_in_source_directories(source_dirs, dry_run, show_diff): dry_run: if True, just print the path of the file that would be updated, but don't change it. show_diff: if True, print the path of the file that would be modified, - as well as the change made to the file. + as well as the change made to the file. """ from devtools import antglob prune_dirs = antglob.prune_dirs + 'scons-local* ./build* ./libs ./dist' diff --git a/doxybuild.py b/doxybuild.py index 862c1f43f..254ab714b 100644 --- a/doxybuild.py +++ b/doxybuild.py @@ -46,7 +46,7 @@ def do_subst_in_file(targetfile, sourcefile, dict): with open(sourcefile, 'r') as f: contents = f.read() for (k,v) in list(dict.items()): - v = v.replace('\\','\\\\') + v = v.replace('\\','\\\\') contents = re.sub(k, v, contents) with open(targetfile, 'w') as f: f.write(contents) @@ -158,7 +158,7 @@ def main(): Generates doxygen documentation in build/doxygen. Optionally makes a tarball of the documentation to dist/. - Must be started in the project top directory. + Must be started in the project top directory. """ from optparse import OptionParser parser = OptionParser(usage=usage) diff --git a/example/README.md b/example/README.md index b1ae4c875..92b925c96 100644 --- a/example/README.md +++ b/example/README.md @@ -1,8 +1,8 @@ -***NOTE*** +***NOTE*** If you get linker errors about undefined references to symbols that involve types in the `std::__cxx11` namespace or the tag `[abi:cxx11]` then it probably indicates that you are trying to link together object files that were compiled with different -values for the _GLIBCXX_USE_CXX11_ABI marco. This commonly happens when linking to a third-party library that was compiled with +values for the _GLIBCXX_USE_CXX11_ABI marco. This commonly happens when linking to a third-party library that was compiled with an older version of GCC. If the third-party library cannot be rebuilt with the new ABI, then you need to recompile your code with the old ABI,just like: **g++ stringWrite.cpp -ljsoncpp -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -o stringWrite** diff --git a/test/data/legacy_test_array_06.json b/test/data/legacy_test_array_06.json index 7f6c516af..1fda03bb1 100644 --- a/test/data/legacy_test_array_06.json +++ b/test/data/legacy_test_array_06.json @@ -1,4 +1,4 @@ -[ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", +[ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "ccccccccccccccccccccccc", "dddddddddddddddddddddddddddddddddddddddddddddddddddd" ] \ No newline at end of file diff --git a/test/data/legacy_test_complex_01.json b/test/data/legacy_test_complex_01.json index cc0f30f5c..2c4a869ab 100644 --- a/test/data/legacy_test_complex_01.json +++ b/test/data/legacy_test_complex_01.json @@ -1,17 +1,17 @@ -{ +{ "count" : 1234, "name" : { "aka" : "T.E.S.T.", "id" : 123987 }, - "attribute" : [ - "random", - "short", - "bold", - 12, - { "height" : 7, "width" : 64 } + "attribute" : [ + "random", + "short", + "bold", + 12, + { "height" : 7, "width" : 64 } ], - "test": { "1" : - { "2" : - { "3" : { "coord" : [ 1,2] } - } + "test": { "1" : + { "2" : + { "3" : { "coord" : [ 1,2] } + } } } } diff --git a/test/data/legacy_test_object_03.json b/test/data/legacy_test_object_03.json index 4fcd4d821..90dba2af8 100644 --- a/test/data/legacy_test_object_03.json +++ b/test/data/legacy_test_object_03.json @@ -1,4 +1,4 @@ -{ +{ "count" : 1234, "name" : "test", "attribute" : "random" diff --git a/test/data/legacy_test_object_04.json b/test/data/legacy_test_object_04.json index 450762d71..9e43ff89b 100644 --- a/test/data/legacy_test_object_04.json +++ b/test/data/legacy_test_object_04.json @@ -1,3 +1,3 @@ -{ +{ "" : 1234 } diff --git a/test/data/legacy_test_preserve_comment_01.expected b/test/data/legacy_test_preserve_comment_01.expected index 2797aa7d6..d6c11b4c9 100644 --- a/test/data/legacy_test_preserve_comment_01.expected +++ b/test/data/legacy_test_preserve_comment_01.expected @@ -6,6 +6,6 @@ /* Comment before 'second' */ .second=2 -/* A comment at +/* A comment at the end of the file. */ diff --git a/test/data/legacy_test_preserve_comment_01.json b/test/data/legacy_test_preserve_comment_01.json index fabd55dd9..21b5ea7fa 100644 --- a/test/data/legacy_test_preserve_comment_01.json +++ b/test/data/legacy_test_preserve_comment_01.json @@ -9,6 +9,6 @@ "second" : 2 } -/* A comment at +/* A comment at the end of the file. */ diff --git a/test/pyjsontestrunner.py b/test/pyjsontestrunner.py index bd749b530..8acdbd2de 100644 --- a/test/pyjsontestrunner.py +++ b/test/pyjsontestrunner.py @@ -15,7 +15,7 @@ if len(sys.argv) != 2: print("Usage: %s input-json-file", sys.argv[0]) sys.exit(3) - + input_path = sys.argv[1] base_path = os.path.splitext(input_path)[0] actual_path = base_path + '.actual' @@ -23,7 +23,7 @@ rewrite_actual_path = base_path + '.actual-rewrite' def valueTreeToString(fout, value, path = '.'): - ty = type(value) + ty = type(value) if ty is types.DictType: fout.write('%s={}\n' % path) suffix = path[-1] != '.' and '.' or '' @@ -49,7 +49,7 @@ def valueTreeToString(fout, value, path = '.'): fout.write('%s=null\n' % path) else: assert False and "Unexpected value type" - + def parseAndSaveValueTree(input, actual_path): root = json.loads(input) fout = file(actual_path, 'wt') @@ -62,7 +62,7 @@ def rewriteValueTree(value, rewrite_path): #rewrite = rewrite[1:-1] # Somehow the string is quoted ! jsonpy bug ? file(rewrite_path, 'wt').write(rewrite + '\n') return rewrite - + input = file(input_path, 'rt').read() root = parseAndSaveValueTree(input, actual_path) rewrite = rewriteValueTree(json.write(root), rewrite_path) From 5c4219b8ae2d14a6bd12e895e2ce1b2503fffd4d Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Sun, 10 Jan 2021 00:17:35 -0600 Subject: [PATCH 317/410] Update version in dox We should automate this, but for now we can at least update: make -f dev.makefile update-version make -f dev.makefile dox # Then, go to jsoncpp-doc repo, add, and push. * https://github.com/open-source-parsers/jsoncpp-docs/issues/2 --- .gitignore | 3 +++ dev.makefile | 4 +++- get_version.pl | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 get_version.pl diff --git a/.gitignore b/.gitignore index 2444e6a68..9682782fa 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ compile_commands.json # DS_Store .DS_Store + +# temps +/version diff --git a/dev.makefile b/dev.makefile index 1a4be6a91..545ff2730 100644 --- a/dev.makefile +++ b/dev.makefile @@ -1,9 +1,11 @@ # This is only for jsoncpp developers/contributors. # We use this to sign releases, generate documentation, etc. -VER?=$(shell cat version.txt) +VER?=$(shell cat version) default: @echo "VER=${VER}" +update-version: + perl get_version.pl meson.build >| version sign: jsoncpp-${VER}.tar.gz gpg --armor --detach-sign $< gpg --verify $<.asc diff --git a/get_version.pl b/get_version.pl new file mode 100644 index 000000000..19b6a543b --- /dev/null +++ b/get_version.pl @@ -0,0 +1,5 @@ +while (<>) { + if (/version : '(.+)',/) { + print "$1"; + } +} From fe9663e7edaf5c179af9c42ffd47428b83f8842a Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Mon, 21 Dec 2020 04:41:37 -0500 Subject: [PATCH 318/410] `Json::ValueIterator` operators `*` and `->` need to be const Fixes #1249. --- include/json/value.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index ec9af5666..7ec418571 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -918,8 +918,8 @@ class JSON_API ValueIterator : public ValueIteratorBase { * because the returned references/pointers can be used * to change state of the base class. */ - reference operator*() { return deref(); } - pointer operator->() { return &deref(); } + reference operator*() const { return const_cast(deref()); } + pointer operator->() const { return const_cast(&deref()); } }; inline void swap(Value& a, Value& b) { a.swap(b); } From eab8ebe6448dc2b9769d985c42bfd2a5d7788843 Mon Sep 17 00:00:00 2001 From: Riccardo Corsi Date: Mon, 4 Jan 2021 15:10:05 +0100 Subject: [PATCH 319/410] Disable also Visual Studio warning C4275 (std::exception used as base class in dll-interface class) when building as DLL and JSONCPP_DISABLE_DLL_INTERFACE_WARNING is defined. --- include/json/value.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/json/value.h b/include/json/value.h index 7ec418571..0edeb050c 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -50,7 +50,7 @@ // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma warning(push) -#pragma warning(disable : 4251) +#pragma warning(disable : 4251 4275) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) #pragma pack(push, 8) From c9a976238b8b184a5a2e3b6bfa513ba1657a327b Mon Sep 17 00:00:00 2001 From: GermanAizek Date: Fri, 15 Jan 2021 13:19:59 +0300 Subject: [PATCH 320/410] minor fixes for 64 bits and refactor code --- src/jsontestrunner/main.cpp | 1 + src/lib_json/json_writer.cpp | 29 ++++++++++++++--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index 3452c5986..df717ffd5 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -335,6 +335,7 @@ int main(int argc, const char* argv[]) { std::cerr << "Unhandled exception:" << std::endl << e.what() << std::endl; return 1; } + return 0; } #if defined(__GNUC__) diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 18e7a42cb..0dd160e45 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -68,7 +68,7 @@ #if !defined(isnan) // IEEE standard states that NaN values will not compare to themselves -#define isnan(x) (x != x) +#define isnan(x) ((x) != (x)) #endif #if !defined(__APPLE__) @@ -272,7 +272,7 @@ static void appendHex(String& result, unsigned ch) { result.append("\\u").append(toHex16Bit(ch)); } -static String valueToQuotedStringN(const char* value, unsigned length, +static String valueToQuotedStringN(const char* value, size_t length, bool emitUTF8 = false) { if (value == nullptr) return ""; @@ -350,7 +350,7 @@ static String valueToQuotedStringN(const char* value, unsigned length, } String valueToQuotedString(const char* value) { - return valueToQuotedStringN(value, static_cast(strlen(value))); + return valueToQuotedStringN(value, strlen(value)); } // Class Writer @@ -399,7 +399,7 @@ void FastWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - document_ += valueToQuotedStringN(str, static_cast(end - str)); + document_ += valueToQuotedStringN(str, static_cast(end - str)); break; } case booleanValue: @@ -422,8 +422,7 @@ void FastWriter::writeValue(const Value& value) { const String& name = *it; if (it != members.begin()) document_ += ','; - document_ += valueToQuotedStringN(name.data(), - static_cast(name.length())); + document_ += valueToQuotedStringN(name.data(), name.length()); document_ += yamlCompatibilityEnabled_ ? ": " : ":"; writeValue(value[name]); } @@ -468,7 +467,7 @@ void StyledWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast(end - str))); + pushValue(valueToQuotedStringN(str, static_cast(end - str))); else pushValue(""); break; @@ -509,7 +508,7 @@ void StyledWriter::writeValue(const Value& value) { } void StyledWriter::writeArrayValue(const Value& value) { - unsigned size = value.size(); + size_t size = value.size(); if (size == 0) pushValue("[]"); else { @@ -518,7 +517,7 @@ void StyledWriter::writeArrayValue(const Value& value) { writeWithIndent("["); indent(); bool hasChildValue = !childValues_.empty(); - unsigned index = 0; + ArrayIndex index = 0; for (;;) { const Value& childValue = value[index]; writeCommentBeforeValue(childValue); @@ -541,7 +540,7 @@ void StyledWriter::writeArrayValue(const Value& value) { { assert(childValues_.size() == size); document_ += "[ "; - for (unsigned index = 0; index < size; ++index) { + for (size_t index = 0; index < size; ++index) { if (index > 0) document_ += ", "; document_ += childValues_[index]; @@ -686,7 +685,7 @@ void StyledStreamWriter::writeValue(const Value& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast(end - str))); + pushValue(valueToQuotedStringN(str, static_cast(end - str))); else pushValue(""); break; @@ -960,8 +959,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { char const* end; bool ok = value.getString(&str, &end); if (ok) - pushValue(valueToQuotedStringN(str, static_cast(end - str), - emitUTF8_)); + pushValue( + valueToQuotedStringN(str, static_cast(end - str), emitUTF8_)); else pushValue(""); break; @@ -984,8 +983,8 @@ void BuiltStyledStreamWriter::writeValue(Value const& value) { String const& name = *it; Value const& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedStringN( - name.data(), static_cast(name.length()), emitUTF8_)); + writeWithIndent( + valueToQuotedStringN(name.data(), name.length(), emitUTF8_)); *sout_ << colonSymbol_; writeValue(childValue); if (++it == members.end()) { From ac2870298ed5b5a96a688d9df07461b31f83e906 Mon Sep 17 00:00:00 2001 From: Derick Vigne Date: Tue, 26 Jan 2021 14:59:12 -0500 Subject: [PATCH 321/410] Fixed pkg-config Version --- pkg-config/jsoncpp.pc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg-config/jsoncpp.pc.in b/pkg-config/jsoncpp.pc.in index 632a377f5..2a2221069 100644 --- a/pkg-config/jsoncpp.pc.in +++ b/pkg-config/jsoncpp.pc.in @@ -5,7 +5,7 @@ includedir=@includedir_for_pc_file@ Name: jsoncpp Description: A C++ library for interacting with JSON -Version: @JSONCPP_VERSION@ +Version: @PROJECT_VERSION@ URL: https://github.com/open-source-parsers/jsoncpp Libs: -L${libdir} -ljsoncpp Cflags: -I${includedir} From da9e17d25766b1bb0dcad1b81de35b6e3a2b5cb0 Mon Sep 17 00:00:00 2001 From: Yixing Lao Date: Sun, 17 Jan 2021 18:57:28 -0800 Subject: [PATCH 322/410] allow selection of Windows MSVC runtime --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1db5e318..1ad82f9c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,9 @@ else() set(JSONCPP_CMAKE_POLICY_VERSION "${JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION}") endif() cmake_policy(VERSION ${JSONCPP_CMAKE_POLICY_VERSION}) +if(POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) +endif() # # Now enumerate specific policies newer than JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION # that may need to be individually set to NEW/OLD @@ -85,6 +88,7 @@ option(JSONCPP_WITH_STRICT_ISO "Issue all the warnings demanded by strict ISO C option(JSONCPP_WITH_PKGCONFIG_SUPPORT "Generate and install .pc files" ON) option(JSONCPP_WITH_CMAKE_PACKAGE "Generate and install cmake package files" ON) option(JSONCPP_WITH_EXAMPLE "Compile JsonCpp example" OFF) +option(JSONCPP_STATIC_WINDOWS_RUNTIME "Use static (MT/MTd) Windows runtime" OFF) option(BUILD_SHARED_LIBS "Build jsoncpp_lib as a shared library." ON) option(BUILD_STATIC_LIBS "Build jsoncpp_lib as a static library." ON) option(BUILD_OBJECT_LIBS "Build jsoncpp_lib as a object library." ON) @@ -123,6 +127,9 @@ if(MSVC) # Only enabled in debug because some old versions of VS STL generate # unreachable code warning when compiled in release configuration. add_compile_options($<$:/W4>) + if (JSONCPP_STATIC_WINDOWS_RUNTIME) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif() endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") From fda274ddd297a53110d43189c2d69fee8f748da9 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Tue, 9 Feb 2021 23:50:37 -0500 Subject: [PATCH 323/410] Fix Value::resize to fill all array elements (#1265) * Fix Value::resize to fill all array elements Fixes #1264 --- src/lib_json/json_value.cpp | 3 ++- src/test_lib_json/main.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index bfa9263fd..378ea7982 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -912,7 +912,8 @@ void Value::resize(ArrayIndex newSize) { if (newSize == 0) clear(); else if (newSize > oldSize) - this->operator[](newSize - 1); + for (ArrayIndex i = oldSize; i < newSize; ++i) + (*this)[i]; else { for (ArrayIndex index = newSize; index < oldSize; ++index) { value_.map_->erase(index); diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index be9c4a73d..e8bc7bcba 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -12,6 +12,7 @@ #include "fuzz.h" #include "jsontest.h" +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include using CharReaderPtr = std::unique_ptr; @@ -347,6 +349,17 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { JSONTEST_ASSERT_EQUAL(array.size(), 0); } } + +JSONTEST_FIXTURE_LOCAL(ValueTest, resizePopulatesAllMissingElements) { + int n = 10; + Json::Value v; + v.resize(n); + JSONTEST_ASSERT_EQUAL(n, v.size()); + JSONTEST_ASSERT_EQUAL(n, std::distance(v.begin(), v.end())); + for (const Json::Value& e : v) + JSONTEST_ASSERT_EQUAL(e, Json::Value{}); +} + JSONTEST_FIXTURE_LOCAL(ValueTest, getArrayValue) { Json::Value array; for (Json::ArrayIndex i = 0; i < 5; i++) From 09c5ecd84fb754ac6ba1b661c6967f959a3100c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sven=20K=C3=B6hler?= Date: Wed, 3 Feb 2021 23:42:12 +0100 Subject: [PATCH 324/410] only append _static suffix for microsoft toolchains --- src/lib_json/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index af2647652..ae406c04d 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -156,7 +156,11 @@ if(BUILD_STATIC_LIBS) # avoid name clashes on windows as the shared import lib is alse named jsoncpp.lib if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) - set(STATIC_SUFFIX "_static") + if (MSVC) + set(STATIC_SUFFIX "_static") + else() + set(STATIC_SUFFIX "") + endif() endif() set_target_properties(${STATIC_LIB} PROPERTIES From b1bd848241880ccea2d940f67343a899b9f65d5d Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Sat, 20 Feb 2021 16:07:34 -0500 Subject: [PATCH 325/410] fix sign-conversion warning (#1268) Use ArrayIndex instead of int. Fixes #1266 --- src/test_lib_json/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index e8bc7bcba..d0f5364ac 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -351,7 +351,7 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, resizeArray) { } JSONTEST_FIXTURE_LOCAL(ValueTest, resizePopulatesAllMissingElements) { - int n = 10; + Json::ArrayIndex n = 10; Json::Value v; v.resize(n); JSONTEST_ASSERT_EQUAL(n, v.size()); From 1ee39a6752de999e02fa07482196dc99a90bcada Mon Sep 17 00:00:00 2001 From: PinkD <443657547@qq.com> Date: Tue, 2 Mar 2021 23:57:54 +0800 Subject: [PATCH 326/410] add comment for emitUTF8 in header --- include/json/writer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/json/writer.h b/include/json/writer.h index fb0852a0c..99d74c731 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -110,6 +110,8 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { * - Number of precision digits for formatting of real values. * - "precisionType": "significant"(default) or "decimal" * - Type of precision for formatting of real values. + * - "emitUTF8": false or true + * - If true, outputs raw UTF8 strings instead of escaping them. * You can examine 'settings_` yourself * to see the defaults. You can also write and read them just like any From 94cda30dbddc1859f111848fdd05dfb85d3287c7 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Thu, 18 Mar 2021 05:22:35 -0400 Subject: [PATCH 327/410] Rearrange Comments::set (#1278) * slightly optimize Comments::set Avoid allocation if the set is going to be rejected anyway. Prototype suggestion from #1277 review thread --- src/lib_json/json_value.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 378ea7982..aa2b744ca 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1398,13 +1398,11 @@ String Value::Comments::get(CommentPlacement slot) const { } void Value::Comments::set(CommentPlacement slot, String comment) { - if (!ptr_) { + if (slot >= CommentPlacement::numberOfCommentPlacement) + return; + if (!ptr_) ptr_ = std::unique_ptr(new Array()); - } - // check comments array boundry. - if (slot < CommentPlacement::numberOfCommentPlacement) { - (*ptr_)[slot] = std::move(comment); - } + (*ptr_)[slot] = std::move(comment); } void Value::setComment(String comment, CommentPlacement placement) { From b6407955712b51837cc3dc07ee5e6143761027c6 Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Sat, 27 Feb 2021 18:25:11 +0100 Subject: [PATCH 328/410] - exported targets go to separate generated file and package config file generated from template to use automatic package resolving and resolution logic CMake provides helpers to generate config file. Generated config file has usefull macro check_required_components() to set necessary variables like PackageName_FOUND if requirements has been satisfied. An absence of dedicated config file confuses user project as necessary variables are not set. --- CMakeLists.txt | 6 ++++-- jsoncppConfig.cmake.in | 10 ++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 jsoncppConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ad82f9c6..23aaeeec9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,11 +177,13 @@ if(JSONCPP_WITH_CMAKE_PACKAGE) include(CMakePackageConfigHelpers) install(EXPORT jsoncpp DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp - FILE jsoncppConfig.cmake) + FILE jsoncpp-targets.cmake) + configure_package_config_file(jsoncppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) + write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) endif() diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in new file mode 100644 index 000000000..e3fa4b961 --- /dev/null +++ b/jsoncppConfig.cmake.in @@ -0,0 +1,10 @@ +cmake_policy(PUSH) +cmake_policy(VERSION 3.0) + +@PACKAGE_INIT@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-targets.cmake" ) + +check_required_components(JsonCpp) + +cmake_policy(POP) \ No newline at end of file From 62f3e034755c43759da819781bc23882a2ea3e01 Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Sat, 27 Feb 2021 22:35:57 +0100 Subject: [PATCH 329/410] - declare namespaced export target to simplify the library usage When the static libary is available use it as exported alias, otherwise use shared library. Cmake takes care about import library when Windows platform DLL is used --- jsoncppConfig.cmake.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in index e3fa4b961..9caa006be 100644 --- a/jsoncppConfig.cmake.in +++ b/jsoncppConfig.cmake.in @@ -5,6 +5,12 @@ cmake_policy(VERSION 3.0) include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-targets.cmake" ) +if(TARGET jsoncpp_static) + add_library(JsonCpp::JsonCpp ALIAS jsoncpp_static) +elseif(TARGET jsoncpp_lib) + add_library(JsonCpp::JsonCpp ALIAS jsoncpp_lib) +endif() + check_required_components(JsonCpp) cmake_policy(POP) \ No newline at end of file From cee42e0bd7ddd58e4a1fd7dd3137610e580964b3 Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Sun, 28 Feb 2021 00:25:48 +0100 Subject: [PATCH 330/410] - empty line at end of file --- jsoncppConfig.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in index 9caa006be..789687bb3 100644 --- a/jsoncppConfig.cmake.in +++ b/jsoncppConfig.cmake.in @@ -13,4 +13,4 @@ endif() check_required_components(JsonCpp) -cmake_policy(POP) \ No newline at end of file +cmake_policy(POP) From a3914b792f86d60ab2cc42f50f2d9e329bcf3eb1 Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Sat, 6 Mar 2021 13:49:53 +0100 Subject: [PATCH 331/410] - narrowed lines to be aligned with overall file line width --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23aaeeec9..60939051d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,12 +178,14 @@ if(JSONCPP_WITH_CMAKE_PACKAGE) install(EXPORT jsoncpp DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp FILE jsoncpp-targets.cmake) - configure_package_config_file(jsoncppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) + configure_package_config_file(jsoncppConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake + install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) endif() From 2af4a4c6c83fc519b190cf2d9797fd8dc3b31e1d Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Fri, 2 Apr 2021 22:30:43 +0200 Subject: [PATCH 332/410] - workaround for CMake < 3.18 ALIAS target limitation to not point to non-GLOBAL IMPORTED target --- jsoncppConfig.cmake.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in index 789687bb3..c1cc6ca0b 100644 --- a/jsoncppConfig.cmake.in +++ b/jsoncppConfig.cmake.in @@ -6,9 +6,11 @@ cmake_policy(VERSION 3.0) include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-targets.cmake" ) if(TARGET jsoncpp_static) - add_library(JsonCpp::JsonCpp ALIAS jsoncpp_static) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED ) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static") elseif(TARGET jsoncpp_lib) - add_library(JsonCpp::JsonCpp ALIAS jsoncpp_lib) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED ) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib") endif() check_required_components(JsonCpp) From 993e4e2828993b017e6e3f5fff99697eead4d134 Mon Sep 17 00:00:00 2001 From: Sergey Rachev Date: Wed, 14 Apr 2021 20:50:43 +0200 Subject: [PATCH 333/410] - isolated namespace targets into separate file --- CMakeLists.txt | 1 + jsoncpp-namespaced-targets.cmake | 7 +++++++ jsoncppConfig.cmake.in | 9 +-------- 3 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 jsoncpp-namespaced-targets.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 60939051d..48b035006 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,6 +186,7 @@ if(JSONCPP_WITH_CMAKE_PACKAGE) COMPATIBILITY SameMajorVersion) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/jsoncppConfig.cmake + ${CMAKE_CURRENT_SOURCE_DIR}/jsoncpp-namespaced-targets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/jsoncpp) endif() diff --git a/jsoncpp-namespaced-targets.cmake b/jsoncpp-namespaced-targets.cmake new file mode 100644 index 000000000..ac1504e00 --- /dev/null +++ b/jsoncpp-namespaced-targets.cmake @@ -0,0 +1,7 @@ +if (TARGET jsoncpp_static) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static") +elseif (TARGET jsoncpp_lib) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib") +endif () \ No newline at end of file diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in index c1cc6ca0b..76570bc30 100644 --- a/jsoncppConfig.cmake.in +++ b/jsoncppConfig.cmake.in @@ -4,14 +4,7 @@ cmake_policy(VERSION 3.0) @PACKAGE_INIT@ include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-targets.cmake" ) - -if(TARGET jsoncpp_static) - add_library(JsonCpp::JsonCpp INTERFACE IMPORTED ) - set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static") -elseif(TARGET jsoncpp_lib) - add_library(JsonCpp::JsonCpp INTERFACE IMPORTED ) - set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib") -endif() +include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-namespaced-targets.cmake" ) check_required_components(JsonCpp) From ed1ab7ac452b0fe51f3b0a8364770774175a060e Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 5 May 2021 00:27:30 -0500 Subject: [PATCH 334/410] Avoid getline(s, EOF) Fixes #1288 --- src/lib_json/json_reader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index a34017d99..a6a3f4e30 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -104,8 +104,7 @@ bool Reader::parse(std::istream& is, Value& root, bool collectComments) { // Since String is reference-counted, this at least does not // create an extra copy. - String doc; - std::getline(is, doc, static_cast EOF); + String doc(std::istreambuf_iterator(is), {}); return parse(doc.data(), doc.data() + doc.size(), root, collectComments); } From 5fabc5e6d2221594a674425bac054de86a1c43a8 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Thu, 6 May 2021 03:55:25 +0200 Subject: [PATCH 335/410] conversion errors only if warnings as errors enabled (#1284) --- CMakeLists.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48b035006..584ecd026 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,7 +134,11 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # using regular Clang or AppleClang - add_compile_options(-Wall -Wconversion -Wshadow -Werror=conversion -Werror=sign-compare) + add_compile_options(-Wall -Wconversion -Wshadow) + + if(JSONCPP_WITH_WARNING_AS_ERROR) + add_compile_options(-Werror=conversion -Werror=sign-compare) + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # using GCC add_compile_options(-Wall -Wconversion -Wshadow -Wextra) @@ -148,9 +152,11 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # using Intel compiler - add_compile_options(-Wall -Wconversion -Wshadow -Wextra -Werror=conversion) + add_compile_options(-Wall -Wconversion -Wshadow -Wextra) - if(JSONCPP_WITH_STRICT_ISO AND NOT JSONCPP_WITH_WARNING_AS_ERROR) + if(JSONCPP_WITH_WARNING_AS_ERROR) + add_compile_options(-Werror=conversion) + elseif(JSONCPP_WITH_STRICT_ISO) add_compile_options(-Wpedantic) endif() endif() From 375a1119f8bbbf42e5275f31b281b5d87f2e17f2 Mon Sep 17 00:00:00 2001 From: Mariusz Glebocki Date: Thu, 6 May 2021 04:03:02 +0200 Subject: [PATCH 336/410] Add support for Bazel build system (#1275) Co-authored-by: Christopher Dunn --- BUILD.bazel | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 BUILD.bazel diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 000000000..6d7ac3da9 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,37 @@ +licenses(["unencumbered"]) # Public Domain or MIT + +exports_files(["LICENSE"]) + +cc_library( + name = "jsoncpp", + srcs = [ + "src/lib_json/json_reader.cpp", + "src/lib_json/json_tool.h", + "src/lib_json/json_value.cpp", + "src/lib_json/json_writer.cpp", + ], + hdrs = [ + "include/json/allocator.h", + "include/json/assertions.h", + "include/json/config.h", + "include/json/json_features.h", + "include/json/forwards.h", + "include/json/json.h", + "include/json/reader.h", + "include/json/value.h", + "include/json/version.h", + "include/json/writer.h", + ], + copts = [ + "-DJSON_USE_EXCEPTION=0", + "-DJSON_HAS_INT64", + ], + includes = ["include"], + visibility = ["//visibility:public"], + deps = [":private"], +) + +cc_library( + name = "private", + textual_hdrs = ["src/lib_json/json_valueiterator.inl"], +) From 65bb1b1c1d8019dc72279c12bb74df92925dfd5e Mon Sep 17 00:00:00 2001 From: Frank Dana Date: Wed, 23 Jun 2021 11:03:44 -0700 Subject: [PATCH 337/410] CMake: Remove ancient version checks (#1299) The minimum version for the project is CMake 3.8.0, so there's no point in keeping legacy code for pre-3.0 or pre-2.8 CMake. --- src/lib_json/CMakeLists.txt | 54 +++++++++++++------------------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index ae406c04d..f0e9d0a5b 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -11,20 +11,10 @@ include(CheckCXXSymbolExists) check_include_file_cxx(clocale HAVE_CLOCALE) check_cxx_symbol_exists(localeconv clocale HAVE_LOCALECONV) -if(CMAKE_VERSION VERSION_LESS 3.0.0) - # The "LANGUAGE CXX" parameter is not supported in CMake versions below 3, - # so the C compiler and header has to be used. - check_include_file(locale.h HAVE_LOCALE_H) - set(CMAKE_EXTRA_INCLUDE_FILES locale.h) - check_type_size("struct lconv" LCONV_SIZE) - unset(CMAKE_EXTRA_INCLUDE_FILES) - check_struct_has_member("struct lconv" decimal_point locale.h HAVE_DECIMAL_POINT) -else() - set(CMAKE_EXTRA_INCLUDE_FILES clocale) - check_type_size(lconv LCONV_SIZE LANGUAGE CXX) - unset(CMAKE_EXTRA_INCLUDE_FILES) - check_struct_has_member(lconv decimal_point clocale HAVE_DECIMAL_POINT LANGUAGE CXX) -endif() +set(CMAKE_EXTRA_INCLUDE_FILES clocale) +check_type_size(lconv LCONV_SIZE LANGUAGE CXX) +unset(CMAKE_EXTRA_INCLUDE_FILES) +check_struct_has_member(lconv decimal_point clocale HAVE_DECIMAL_POINT LANGUAGE CXX) if(NOT (HAVE_CLOCALE AND HAVE_LCONV_SIZE AND HAVE_DECIMAL_POINT AND HAVE_LOCALECONV)) message(WARNING "Locale functionality is not supported") @@ -139,13 +129,11 @@ if(BUILD_SHARED_LIBS) target_compile_features(${SHARED_LIB} PUBLIC ${REQUIRED_FEATURES}) - if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories(${SHARED_LIB} PUBLIC - $ - $ - $ - ) - endif() + target_include_directories(${SHARED_LIB} PUBLIC + $ + $ + $ + ) list(APPEND CMAKE_TARGETS ${SHARED_LIB}) endif() @@ -175,13 +163,11 @@ if(BUILD_STATIC_LIBS) target_compile_features(${STATIC_LIB} PUBLIC ${REQUIRED_FEATURES}) - if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories(${STATIC_LIB} PUBLIC - $ - $ - $ - ) - endif() + target_include_directories(${STATIC_LIB} PUBLIC + $ + $ + $ + ) list(APPEND CMAKE_TARGETS ${STATIC_LIB}) endif() @@ -204,13 +190,11 @@ if(BUILD_OBJECT_LIBS) target_compile_features(${OBJECT_LIB} PUBLIC ${REQUIRED_FEATURES}) - if(NOT CMAKE_VERSION VERSION_LESS 2.8.11) - target_include_directories(${OBJECT_LIB} PUBLIC - $ - $ - $ - ) - endif() + target_include_directories(${OBJECT_LIB} PUBLIC + $ + $ + $ + ) list(APPEND CMAKE_TARGETS ${OBJECT_LIB}) endif() From c39fbdac0f0f6638d5cfca43988750a1aac512db Mon Sep 17 00:00:00 2001 From: Jack Ullery <46848683+jack-ullery@users.noreply.github.com> Date: Thu, 12 Aug 2021 21:08:46 +0000 Subject: [PATCH 338/410] minor fix for code examples (#1317) --- example/readFromString/readFromString.cpp | 1 + example/streamWrite/streamWrite.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp index c27bbd5ae..0b29a4e86 100644 --- a/example/readFromString/readFromString.cpp +++ b/example/readFromString/readFromString.cpp @@ -1,5 +1,6 @@ #include "json/json.h" #include +#include /** * \brief Parse a raw string into Value object using the CharReaderBuilder * class, or the legacy Reader class. diff --git a/example/streamWrite/streamWrite.cpp b/example/streamWrite/streamWrite.cpp index 6f7f7972a..a72f5a52e 100644 --- a/example/streamWrite/streamWrite.cpp +++ b/example/streamWrite/streamWrite.cpp @@ -1,5 +1,6 @@ #include "json/json.h" #include +#include /** \brief Write the Value object to a stream. * Example Usage: * $g++ streamWrite.cpp -ljsoncpp -std=c++11 -o streamWrite From 94a6220f7c738d6711d325fd29bb8a60b97fd77e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 21 Sep 2021 06:55:25 +0100 Subject: [PATCH 339/410] Document skipBom in CharReaderBuilder (#1332) --- include/json/reader.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/json/reader.h b/include/json/reader.h index 917546608..250468f1b 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -324,6 +324,9 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * - `"allowSpecialFloats": false or true` * - If true, special float values (NaNs and infinities) are allowed and * their values are lossfree restorable. + * - `"skipBom": false or true` + * - If true, if the input starts with the Unicode byte order mark (BOM), + * it is skipped. * * You can examine 'settings_` yourself to see the defaults. You can also * write and read them just like any JSON Value. From fa747b1ae34338e764ede2d104803eae5af0a4a0 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Tue, 26 Oct 2021 16:04:17 -0500 Subject: [PATCH 340/410] clang-format is not available by default --- .travis.yml | 2 +- .travis_scripts/meson_builder.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d7ccde74..23acd4e57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ # Build matrix / environment variables are explained on: -# http://about.travis-ci.org/docs/user/build-configuration/ +# http://about.travis-ci.com/docs/user/build-configuration/ # This file can be validated on: http://www.yamllint.com/ # Or using the Ruby based travel command line tool: # gem install travis --no-rdoc --no-ri diff --git a/.travis_scripts/meson_builder.sh b/.travis_scripts/meson_builder.sh index 1fdd8f65d..bc74732f6 100755 --- a/.travis_scripts/meson_builder.sh +++ b/.travis_scripts/meson_builder.sh @@ -64,7 +64,7 @@ ninja --version _COMPILER_NAME=`basename ${CXX}` _BUILD_DIR_NAME="build-${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}" -./.travis_scripts/run-clang-format.sh +#./.travis_scripts/run-clang-format.sh meson --fatal-meson-warnings --werror --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" ninja -v -j 2 -C "${_BUILD_DIR_NAME}" From 29f9853455002bba46262ded9c1b57656796af75 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Mon, 25 Oct 2021 23:49:43 +0200 Subject: [PATCH 341/410] Fix cmake config for POSITION_INDEPENDENT_CODE enabling it just when BUILD_SHARED_LIBS is ON --- src/lib_json/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index f0e9d0a5b..b7596e80b 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -119,7 +119,7 @@ if(BUILD_SHARED_LIBS) OUTPUT_NAME jsoncpp VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_SOVERSION} - POSITION_INDEPENDENT_CODE ON + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} ) # Set library's runtime search path on OSX @@ -180,7 +180,7 @@ if(BUILD_OBJECT_LIBS) OUTPUT_NAME jsoncpp VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_SOVERSION} - POSITION_INDEPENDENT_CODE ON + POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS} ) # Set library's runtime search path on OSX From 54a5432c01fb2d2e266229b758b240aa2358d4e7 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 3 Nov 2021 11:35:15 -0500 Subject: [PATCH 342/410] Drop compile-time deprecation warning --- include/json/reader.h | 7 +++---- include/json/writer.h | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index 250468f1b..be0d7676a 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -33,8 +33,7 @@ namespace Json { * \deprecated Use CharReader and CharReaderBuilder. */ -class JSONCPP_DEPRECATED( - "Use CharReader and CharReaderBuilder instead.") JSON_API Reader { +class JSON_API Reader { public: using Char = char; using Location = const Char*; @@ -51,13 +50,13 @@ class JSONCPP_DEPRECATED( }; /** \brief Constructs a Reader allowing all features for parsing. + * \deprecated Use CharReader and CharReaderBuilder. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. + * \deprecated Use CharReader and CharReaderBuilder. */ - JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead") Reader(const Features& features); /** \brief Read a Value from a JSON diff --git a/include/json/writer.h b/include/json/writer.h index 99d74c731..88a3b12e9 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -147,7 +147,7 @@ class JSON_API StreamWriterBuilder : public StreamWriter::Factory { /** \brief Abstract class for writers. * \deprecated Use StreamWriter. (And really, this is an implementation detail.) */ -class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { +class JSON_API Writer { public: virtual ~Writer(); @@ -167,7 +167,7 @@ class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer { #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter +class JSON_API FastWriter : public Writer { public: FastWriter(); @@ -227,7 +227,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class JSON_API StyledWriter : public Writer { public: StyledWriter(); @@ -296,7 +296,7 @@ class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API +class JSON_API StyledStreamWriter { public: /** From c4904b2c0d461f84fba88a760161212651e4f536 Mon Sep 17 00:00:00 2001 From: Christopher Dunn Date: Wed, 3 Nov 2021 11:39:54 -0500 Subject: [PATCH 343/410] Bump micro version --- CMakeLists.txt | 4 ++-- include/json/version.h | 4 ++-- meson.build | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 584ecd026..2841277c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,11 +72,11 @@ project(jsoncpp # 2. ./include/json/version.h # 3. ./CMakeLists.txt # IMPORTANT: also update the PROJECT_SOVERSION!! - VERSION 1.9.4 # [.[.[.]]] + VERSION 1.9.5 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -set(PROJECT_SOVERSION 24) +set(PROJECT_SOVERSION 25) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake) diff --git a/include/json/version.h b/include/json/version.h index 87cf7e2fb..e931d0383 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.4" +#define JSONCPP_VERSION_STRING "1.9.5" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 4 +#define JSONCPP_VERSION_PATCH 5 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/meson.build b/meson.build index 08e0f299e..f68db30dd 100644 --- a/meson.build +++ b/meson.build @@ -50,7 +50,7 @@ jsoncpp_lib = library( 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp', ]), - soversion : 24, + soversion : 25, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) From 2d55c7445ffedf30db62231f223137ef02e611a9 Mon Sep 17 00:00:00 2001 From: Tero Kinnunen Date: Wed, 15 Dec 2021 04:00:28 +0200 Subject: [PATCH 344/410] Parse large floats as infinity (#1349) (#1353) Return 1.9.1 functionality where values too large to fit in double are converted to positive or negative infinity. Commit 645cd04 changed functionality so that large floats cause parse error, while version 1.9.1 accepted them as infinite. This is problematic because writer outputs infinity values as `1e+9999`, which could no longer be parsed back. Fixed also legacy Reader even though it did not parse large values even before breaking change, due to problematic output/parse asymmetry. `>>` operator sets value to numeric_limits::max/lowest value if representation is too large to fit to double. [1][2] In macos value appears to be parsed to infinity. > | value in *val* | description | > |--------------------------|-------------| > | numeric_limits::max() | The sequence represents a value too large for the type of val | > | numeric_limits::lowest() | The sequence represents a value too large negative for the type of val | [1] https://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ [2] https://www.cplusplus.com/reference/locale/num_get/get/ Signed-off-by: Tero Kinnunen Co-authored-by: Tero Kinnunen --- src/lib_json/json_reader.cpp | 18 +++++++++++++++--- test/data/legacy_test_real_13.expected | 3 +++ test/data/legacy_test_real_13.json | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test/data/legacy_test_real_13.expected create mode 100644 test/data/legacy_test_real_13.json diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index a6a3f4e30..896bf1b91 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -12,6 +12,7 @@ #endif // if !defined(JSON_IS_AMALGAMATION) #include #include +#include #include #include #include @@ -600,9 +601,15 @@ bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; String buffer(token.start_, token.end_); IStringStream is(buffer); - if (!(is >> value)) - return addError( + if (!(is >> value)) { + if (value == std::numeric_limits::max()) + value = std::numeric_limits::infinity(); + else if (value == std::numeric_limits::lowest()) + value = -std::numeric_limits::infinity(); + else if (!std::isinf(value)) + return addError( "'" + String(token.start_, token.end_) + "' is not a number.", token); + } decoded = value; return true; } @@ -1647,7 +1654,12 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { const String buffer(token.start_, token.end_); IStringStream is(buffer); if (!(is >> value)) { - return addError( + if (value == std::numeric_limits::max()) + value = std::numeric_limits::infinity(); + else if (value == std::numeric_limits::lowest()) + value = -std::numeric_limits::infinity(); + else if (!std::isinf(value)) + return addError( "'" + String(token.start_, token.end_) + "' is not a number.", token); } decoded = value; diff --git a/test/data/legacy_test_real_13.expected b/test/data/legacy_test_real_13.expected new file mode 100644 index 000000000..8d3f03faa --- /dev/null +++ b/test/data/legacy_test_real_13.expected @@ -0,0 +1,3 @@ +.=[] +.[0]=-inf +.[1]=inf diff --git a/test/data/legacy_test_real_13.json b/test/data/legacy_test_real_13.json new file mode 100644 index 000000000..287258a81 --- /dev/null +++ b/test/data/legacy_test_real_13.json @@ -0,0 +1 @@ +[-1e+9999, 1e+9999] From a1f1613bdd81bf28289e8d3fbeb4eb78b82fb203 Mon Sep 17 00:00:00 2001 From: luzpaz Date: Tue, 14 Dec 2021 21:04:47 -0500 Subject: [PATCH 345/410] Fix various typos (#1350) Found via `codespell -q 3 -L alue,alse` Co-authored-by: Christopher Dunn Co-authored-by: Jordan Bayles --- CMakeLists.txt | 2 +- CONTRIBUTING.md | 2 +- include/json/writer.h | 4 ++-- src/lib_json/CMakeLists.txt | 2 +- src/lib_json/json_reader.cpp | 2 +- src/test_lib_json/jsontest.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2841277c0..fd8bcf2b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ # policies that provide successful builds. By setting JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION # to a value greater than the oldest policies, all policies between # JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION (used for this build) -# are set to their NEW behaivor, thereby suppressing policy warnings related to policies +# are set to their NEW behavior, thereby suppressing policy warnings related to policies # between the JSONCPP_OLDEST_VALIDATED_POLICIES_VERSION and CMAKE_VERSION. # # CMake versions greater than the JSONCPP_NEWEST_VALIDATED_POLICIES_VERSION policies will diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8d992bee7..5f5c032a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,7 +77,7 @@ See `doxybuild.py --help` for options. To add a test, you need to create two files in test/data: * a `TESTNAME.json` file, that contains the input document in JSON format. -* a `TESTNAME.expected` file, that contains a flatened representation of the +* a `TESTNAME.expected` file, that contains a flattened representation of the input document. The `TESTNAME.expected` file format is as follows: diff --git a/include/json/writer.h b/include/json/writer.h index 88a3b12e9..03f99065f 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -217,7 +217,7 @@ class JSON_API FastWriter * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their *#CommentPlacement. * * \sa Reader, Value, Value::setComment() @@ -286,7 +286,7 @@ class JSON_API * - otherwise, it the values do not fit on one line, or the array contains * object or non empty array, then print one value per line. * - * If the Value have comments then they are outputed according to their + * If the Value have comments then they are outputted according to their #CommentPlacement. * * \sa Reader, Value, Value::setComment() diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index b7596e80b..3cf66eb34 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -142,7 +142,7 @@ if(BUILD_STATIC_LIBS) set(STATIC_LIB ${PROJECT_NAME}_static) add_library(${STATIC_LIB} STATIC ${PUBLIC_HEADERS} ${JSONCPP_SOURCES}) - # avoid name clashes on windows as the shared import lib is alse named jsoncpp.lib + # avoid name clashes on windows as the shared import lib is also named jsoncpp.lib if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) if (MSVC) set(STATIC_SUFFIX "_static") diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 896bf1b91..1ac5e81ab 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1614,7 +1614,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { const auto digit(static_cast(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If - // a) we've only just touched the limit, meaing value == threshold, + // a) we've only just touched the limit, meaning value == threshold, // b) this is the last digit, or // c) it's small enough to fit in that rounding delta, we're okay. // Otherwise treat this number as a double to avoid overflow. diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index 4e8af0f25..a2385fa3f 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -74,7 +74,7 @@ class TestResult { /// Removes the last PredicateContext added to the predicate stack /// chained list. - /// Next messages will be targed at the PredicateContext that was removed. + /// Next messages will be targeted at the PredicateContext that was removed. TestResult& popPredicateContext(); bool failed() const; From 42e892d96e47b1f6e29844cc705e148ec4856448 Mon Sep 17 00:00:00 2001 From: Jessica Clarke Date: Wed, 12 Jan 2022 21:27:16 +0000 Subject: [PATCH 346/410] Use default rather than hard-coded 8 for maximum aggregate member alignment (#1378) On CHERI, and thus Arm's Morello prototype, pointers are represented as hardware capabilities. These capabilities are comprised of not just an integer address, as is the representation for traditional pointers, but also bounds, permissions and other metadata, plus a tag bit used as the validity bit, which provides fine-grained spatial and referential safety for C and C++ in hardware. This tag bit is not part of the data itself and is instead kept on the side, flowing with the capability between registers and the memory subsystem, and any attempt to amplify the privilege of or corrupt a capability clears this tag (or, in some cases, traps), rendering them impossible to forge; you can only create capabilities that are (possibly trivial) subsets of existing ones. When the capability is stored in memory, this tag bit needs to be preserved, which is done through the use of tagged memory. Every capability-sized word gains an additional non-addressable (from the CPU's perspective; depending on the implementation the tag bits may be stored in a small block of memory carved out of normal DRAM that the CPU is blocked from accessing) bit. This means that capabilities can only be stored to aligned locations; attempting to store them to unaligned locations will trap with an alignment fault or, if you end up using a memcpy call, will copy the raw bytes of the capability's representation but lose the tag, so when it is eventually loaded back as a capability and dereferenced it will fault. Since, on 64-bit architectures, our capabilities, used to implement C language pointers, are 128-bit quantities, this means they need 16-byte alignment. Currently the various #pragma pack directives, used to work around (extremely broken and bogus) code that includes jsoncpp in a context where the maximum alignment has been overridden, hard-code 8 as the maximum alignment to use, and so do not sufficiently align CHERI / Morello capabilities on 64-bit architectures. On Windows x64, the default is also not 8 but 16 (ARM64 is supposedly 8), so this is slightly dodgy to do there too, but in practice likely not an issue so long as you don't use any 128-bit types there. Instead of hard-coding a width, use a directive that resets the packing back to the default. Unfortunately, whilst GCC and Clang both accept using #pragma pack(push, 0) as shorthand like for any non-zero value, MSVC does not, so this needs to be two directives. --- include/json/allocator.h | 3 ++- include/json/json_features.h | 3 ++- include/json/reader.h | 3 ++- include/json/value.h | 3 ++- include/json/writer.h | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/json/allocator.h b/include/json/allocator.h index 95ef8a5ec..75406428f 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -9,7 +9,8 @@ #include #include -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace Json { template class SecureAllocator { diff --git a/include/json/json_features.h b/include/json/json_features.h index 7c7e9f5de..e4a61d6f1 100644 --- a/include/json/json_features.h +++ b/include/json/json_features.h @@ -10,7 +10,8 @@ #include "forwards.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace Json { diff --git a/include/json/reader.h b/include/json/reader.h index be0d7676a..46975d86f 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -23,7 +23,8 @@ #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace Json { diff --git a/include/json/value.h b/include/json/value.h index 0edeb050c..57ecb13f5 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -53,7 +53,8 @@ #pragma warning(disable : 4251 4275) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() /** \brief JSON (JavaScript Object Notation). */ diff --git a/include/json/writer.h b/include/json/writer.h index 03f99065f..7d8cf4d63 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -20,7 +20,8 @@ #pragma warning(disable : 4251) #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) -#pragma pack(push, 8) +#pragma pack(push) +#pragma pack() namespace Json { From 8190e061bc2d95da37479a638aa2c9e483e58ec6 Mon Sep 17 00:00:00 2001 From: mwestphal Date: Thu, 14 Jul 2022 23:57:37 +0200 Subject: [PATCH 347/410] Fix wrong usage of doxygen groups (#1417) --- include/json/value.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 57ecb13f5..15c517e12 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -437,7 +437,7 @@ class JSON_API Value { /// \post type() is arrayValue void resize(ArrayIndex newSize); - //@{ + ///@{ /// Access an array element (zero based index). If the array contains less /// than index element, then null value are inserted in the array so that /// its size is index+1. @@ -445,15 +445,15 @@ class JSON_API Value { /// this from the operator[] which takes a string.) Value& operator[](ArrayIndex index); Value& operator[](int index); - //@} + ///@} - //@{ + ///@{ /// Access an array element (zero based index). /// (You may need to say 'value[0u]' to get your compiler to distinguish /// this from the operator[] which takes a string.) const Value& operator[](ArrayIndex index) const; const Value& operator[](int index) const; - //@} + ///@} /// If the array contains at least index+1 elements, returns the element /// value, otherwise returns defaultValue. From 3d9bf8ee54855396e20b4e221ad28f71625bb76c Mon Sep 17 00:00:00 2001 From: Jakob Widauer Date: Wed, 7 Jun 2023 18:11:01 +0200 Subject: [PATCH 348/410] feat: adds front and back methods to Value type (#1458) Value::front and Value::back --- include/json/value.h | 24 ++++++++++++++++++++++++ src/test_lib_json/main.cpp | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 15c517e12..9a302c161 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -585,6 +585,22 @@ class JSON_API Value { iterator begin(); iterator end(); + /// \brief Returns a reference to the first element in the `Value`. + /// Requires that this value holds an array or json object, with at least one element. + const Value& front() const; + + /// \brief Returns a reference to the first element in the `Value`. + /// Requires that this value holds an array or json object, with at least one element. + Value& front(); + + /// \brief Returns a reference to the last element in the `Value`. + /// Requires that value holds an array or json object, with at least one element. + const Value& back() const; + + /// \brief Returns a reference to the last element in the `Value`. + /// Requires that this value holds an array or json object, with at least one element. + Value& back(); + // Accessors for the [start, limit) range of bytes within the JSON text from // which this value was parsed, if any. void setOffsetStart(ptrdiff_t start); @@ -925,6 +941,14 @@ class JSON_API ValueIterator : public ValueIteratorBase { inline void swap(Value& a, Value& b) { a.swap(b); } +inline const Value& Value::front() const { return *begin(); } + +inline Value& Value::front() { return *begin(); } + +inline const Value& Value::back() const { return *(--end()); } + +inline Value& Value::back() { return *(--end()); } + } // namespace Json #pragma pack(pop) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index d0f5364ac..a6f21c45a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -310,10 +310,14 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrays) { const Json::Value& constArray = array1_; JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray[index0]); JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray[0]); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray.front()); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), constArray.back()); // Access through non-const reference JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[index0]); JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_[0]); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_.front()); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), array1_.back()); array1_[2] = Json::Value(17); JSONTEST_ASSERT_EQUAL(Json::Value(), array1_[1]); @@ -356,6 +360,8 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, resizePopulatesAllMissingElements) { v.resize(n); JSONTEST_ASSERT_EQUAL(n, v.size()); JSONTEST_ASSERT_EQUAL(n, std::distance(v.begin(), v.end())); + JSONTEST_ASSERT_EQUAL(v.front(), Json::Value{}); + JSONTEST_ASSERT_EQUAL(v.back(), Json::Value{}); for (const Json::Value& e : v) JSONTEST_ASSERT_EQUAL(e, Json::Value{}); } @@ -406,6 +412,8 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[0]); // check append JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[1]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[2]); + JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array.front()); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); // insert lvalue at the head JSONTEST_ASSERT(array.insert(0, str1)); @@ -413,6 +421,8 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index0"), array[1]); JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[2]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[3]); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); // checking address for (Json::ArrayIndex i = 0; i < 3; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); @@ -425,6 +435,8 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index4"), array[2]); JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); + JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array.back()); // checking address for (Json::ArrayIndex i = 0; i < 4; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); @@ -438,6 +450,8 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, arrayInsertAtRandomIndex) { JSONTEST_ASSERT_EQUAL(Json::Value("index1"), array[3]); JSONTEST_ASSERT_EQUAL(Json::Value("index2"), array[4]); JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array[5]); + JSONTEST_ASSERT_EQUAL(Json::Value("index3"), array.front()); + JSONTEST_ASSERT_EQUAL(Json::Value("index5"), array.back()); // checking address for (Json::ArrayIndex i = 0; i < 5; i++) { JSONTEST_ASSERT_EQUAL(vec[i], &array[i]); From 69098a18b9af0c47549d9a271c054d13ca92b006 Mon Sep 17 00:00:00 2001 From: Mykola Date: Tue, 27 Jun 2023 16:42:38 +0200 Subject: [PATCH 349/410] Avoid using cmake glob vars if we are a subproject (#1459) If jsoncpp is a subproject (like a git submodule), setting the global cmake variables affect the entire project (changes the structure of the output folders) and these changes prevent it. --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fd8bcf2b2..8920544a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,10 +96,12 @@ option(BUILD_OBJECT_LIBS "Build jsoncpp_lib as a object library." ON) # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir.") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir.") -set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Archive output dir.") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" CACHE PATH "Library output dir.") + set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "PDB (MSVC debug symbol)output dir.") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") +endif() set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL") From cd8173c6d3076dd06e2d0e62a4b55b995c498515 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 11:39:17 -0700 Subject: [PATCH 350/410] Create c-cpp.yml --- .github/workflows/c-cpp.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml new file mode 100644 index 000000000..fbf32ec92 --- /dev/null +++ b/.github/workflows/c-cpp.yml @@ -0,0 +1,23 @@ +name: C/C++ CI + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: configure + run: ./configure + - name: make + run: make + - name: make check + run: make check + - name: make distcheck + run: make distcheck From 01b11d2e4b9cb81959dd567d35b4b363e8932e4e Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 11:40:13 -0700 Subject: [PATCH 351/410] Create meson_build_and_run (#1553) --- .github/workflows/meson_build_and_run | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/meson_build_and_run diff --git a/.github/workflows/meson_build_and_run b/.github/workflows/meson_build_and_run new file mode 100644 index 000000000..98df7a85a --- /dev/null +++ b/.github/workflows/meson_build_and_run @@ -0,0 +1,29 @@ +name: Meson Build +uses: BSFishy/meson-build@v1.0.3 + +run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 +on: [push] + +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo " The job was automatically triggered by a ${{ github.event_name }} event." + - uses: actions/checkout@v4 + - uses: actions/setup-python@v1 + - uses: BSFishy/meson-build@v1.0.3 + with: + action: build + action: test + action: tidy + + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v4 + - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - run: echo "🍏 This job's status is ${{ job.status }}." From 79ade9024889ef9be0eb4833711f4eb0d0dec62b Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 11:46:57 -0700 Subject: [PATCH 352/410] Rename meson_build_and_run to meson.yml --- .github/workflows/{meson_build_and_run => meson.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{meson_build_and_run => meson.yml} (100%) diff --git a/.github/workflows/meson_build_and_run b/.github/workflows/meson.yml similarity index 100% rename from .github/workflows/meson_build_and_run rename to .github/workflows/meson.yml From 6668fa51eecd0b3caac657e3e1252b446f543bc6 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 11:50:31 -0700 Subject: [PATCH 353/410] Delete .github/workflows/c-cpp.yml --- .github/workflows/c-cpp.yml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .github/workflows/c-cpp.yml diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml deleted file mode 100644 index fbf32ec92..000000000 --- a/.github/workflows/c-cpp.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: C/C++ CI - -on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: configure - run: ./configure - - name: make - run: make - - name: make check - run: make check - - name: make distcheck - run: make distcheck From 5c003ecaccbf84550cfa055e9b9f524403854953 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 15:48:18 -0700 Subject: [PATCH 354/410] Fix clang format issues (#1555) --- include/json/allocator.h | 4 +++- include/json/reader.h | 6 +++--- include/json/value.h | 12 ++++++++---- include/json/writer.h | 11 ++++------- src/lib_json/json_reader.cpp | 4 ++-- src/lib_json/json_writer.cpp | 5 +++-- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/json/allocator.h b/include/json/allocator.h index 75406428f..f4fcc1c68 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -69,7 +69,9 @@ template class SecureAllocator { // Boilerplate SecureAllocator() {} template SecureAllocator(const SecureAllocator&) {} - template struct rebind { using other = SecureAllocator; }; + template struct rebind { + using other = SecureAllocator; + }; }; template diff --git a/include/json/reader.h b/include/json/reader.h index 46975d86f..10c6a4ff4 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -51,12 +51,12 @@ class JSON_API Reader { }; /** \brief Constructs a Reader allowing all features for parsing. - * \deprecated Use CharReader and CharReaderBuilder. + * \deprecated Use CharReader and CharReaderBuilder. */ Reader(); /** \brief Constructs a Reader allowing the specified feature set for parsing. - * \deprecated Use CharReader and CharReaderBuilder. + * \deprecated Use CharReader and CharReaderBuilder. */ Reader(const Features& features); @@ -272,7 +272,7 @@ class JSON_API CharReader { */ virtual CharReader* newCharReader() const = 0; }; // Factory -}; // CharReader +}; // CharReader /** \brief Build a CharReader implementation. * diff --git a/include/json/value.h b/include/json/value.h index 9a302c161..120dea890 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -586,19 +586,23 @@ class JSON_API Value { iterator end(); /// \brief Returns a reference to the first element in the `Value`. - /// Requires that this value holds an array or json object, with at least one element. + /// Requires that this value holds an array or json object, with at least one + /// element. const Value& front() const; /// \brief Returns a reference to the first element in the `Value`. - /// Requires that this value holds an array or json object, with at least one element. + /// Requires that this value holds an array or json object, with at least one + /// element. Value& front(); /// \brief Returns a reference to the last element in the `Value`. - /// Requires that value holds an array or json object, with at least one element. + /// Requires that value holds an array or json object, with at least one + /// element. const Value& back() const; /// \brief Returns a reference to the last element in the `Value`. - /// Requires that this value holds an array or json object, with at least one element. + /// Requires that this value holds an array or json object, with at least one + /// element. Value& back(); // Accessors for the [start, limit) range of bytes within the JSON text from diff --git a/include/json/writer.h b/include/json/writer.h index 7d8cf4d63..655ebfffb 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -64,7 +64,7 @@ class JSON_API StreamWriter { */ virtual StreamWriter* newStreamWriter() const = 0; }; // Factory -}; // StreamWriter +}; // StreamWriter /** \brief Write into stringstream, then return string, for convenience. * A StreamWriter will be created from the factory, used, and then deleted. @@ -168,8 +168,7 @@ class JSON_API Writer { #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSON_API FastWriter - : public Writer { +class JSON_API FastWriter : public Writer { public: FastWriter(); ~FastWriter() override = default; @@ -228,8 +227,7 @@ class JSON_API FastWriter #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSON_API - StyledWriter : public Writer { +class JSON_API StyledWriter : public Writer { public: StyledWriter(); ~StyledWriter() override = default; @@ -297,8 +295,7 @@ class JSON_API #pragma warning(push) #pragma warning(disable : 4996) // Deriving from deprecated class #endif -class JSON_API - StyledStreamWriter { +class JSON_API StyledStreamWriter { public: /** * \param indentation Each level will be indented by this amount extra. diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 1ac5e81ab..8dcd2b52e 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -608,7 +608,7 @@ bool Reader::decodeDouble(Token& token, Value& decoded) { value = -std::numeric_limits::infinity(); else if (!std::isinf(value)) return addError( - "'" + String(token.start_, token.end_) + "' is not a number.", token); + "'" + String(token.start_, token.end_) + "' is not a number.", token); } decoded = value; return true; @@ -1660,7 +1660,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { value = -std::numeric_limits::infinity(); else if (!std::isinf(value)) return addError( - "'" + String(token.start_, token.end_) + "' is not a number.", token); + "'" + String(token.start_, token.end_) + "' is not a number.", token); } decoded = value; return true; diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 0dd160e45..239c429a1 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -132,8 +132,9 @@ String valueToString(double value, bool useSpecialFloats, if (!isfinite(value)) { static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"}, {"null", "-1e+9999", "1e+9999"}}; - return reps[useSpecialFloats ? 0 : 1] - [isnan(value) ? 0 : (value < 0) ? 1 : 2]; + return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 + : (value < 0) ? 1 + : 2]; } String buffer(size_t(36), '\0'); From d2a9495fda6a2c1eb668faf7c997515462dde5d7 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 15:50:23 -0700 Subject: [PATCH 355/410] Delete .travis.yml (#1557) --- .travis.yml | 71 ----------------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 23acd4e57..000000000 --- a/.travis.yml +++ /dev/null @@ -1,71 +0,0 @@ -# Build matrix / environment variables are explained on: -# http://about.travis-ci.com/docs/user/build-configuration/ -# This file can be validated on: http://www.yamllint.com/ -# Or using the Ruby based travel command line tool: -# gem install travis --no-rdoc --no-ri -# travis lint .travis.yml -language: cpp -sudo: false -addons: - homebrew: - packages: - - clang-format - - meson - - ninja - update: false # do not update homebrew by default - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-xenial-8 - packages: - - clang-format-8 - - clang-8 - - valgrind -matrix: - include: - - name: Mac clang meson static release testing - os: osx - osx_image: xcode11 - compiler: clang - env: - CXX="clang++" - CC="clang" - LIB_TYPE=static - BUILD_TYPE=release - script: ./.travis_scripts/meson_builder.sh - - name: Linux xenial clang meson static release testing - os: linux - dist: xenial - compiler: clang - env: - CXX="clang++" - CC="clang" - LIB_TYPE=static - BUILD_TYPE=release - PYTHONUSERBASE="$(pwd)/LOCAL" - PATH="$PYTHONUSERBASE/bin:$PATH" - # before_install and install steps only needed for linux meson builds - before_install: - - source ./.travis_scripts/travis.before_install.${TRAVIS_OS_NAME}.sh - install: - - source ./.travis_scripts/travis.install.${TRAVIS_OS_NAME}.sh - script: ./.travis_scripts/meson_builder.sh - - name: Linux xenial gcc cmake coverage - os: linux - dist: xenial - compiler: gcc - env: - CXX=g++ - CC=gcc - DO_Coverage=ON - BUILD_TOOL="Unix Makefiles" - BUILD_TYPE=Debug - LIB_TYPE=shared - DESTDIR=/tmp/cmake_json_cpp - before_install: - - pip install --user cpp-coveralls - script: ./.travis_scripts/cmake_builder.sh - after_success: - - coveralls --include src/lib_json --include include -notifications: - email: false From 73c94501edfb06e8d6503853ae432d6315b1a26c Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 15:50:39 -0700 Subject: [PATCH 356/410] Delete .travis_scripts directory (#1556) --- .travis_scripts/cmake_builder.sh | 130 ------- .travis_scripts/meson_builder.sh | 83 ---- .travis_scripts/run-clang-format.py | 356 ------------------ .travis_scripts/run-clang-format.sh | 4 - .../travis.before_install.linux.sh | 8 - .travis_scripts/travis.before_install.osx.sh | 0 .travis_scripts/travis.install.linux.sh | 5 - .travis_scripts/travis.install.osx.sh | 1 - 8 files changed, 587 deletions(-) delete mode 100755 .travis_scripts/cmake_builder.sh delete mode 100755 .travis_scripts/meson_builder.sh delete mode 100755 .travis_scripts/run-clang-format.py delete mode 100755 .travis_scripts/run-clang-format.sh delete mode 100644 .travis_scripts/travis.before_install.linux.sh delete mode 100644 .travis_scripts/travis.before_install.osx.sh delete mode 100644 .travis_scripts/travis.install.linux.sh delete mode 100644 .travis_scripts/travis.install.osx.sh diff --git a/.travis_scripts/cmake_builder.sh b/.travis_scripts/cmake_builder.sh deleted file mode 100755 index f3d4e46b6..000000000 --- a/.travis_scripts/cmake_builder.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env sh -# This script can be used on the command line directly to configure several -# different build environments. -# This is called by `.travis.yml` via Travis CI. -# Travis supplies $TRAVIS_OS_NAME. -# http://docs.travis-ci.com/user/multi-os/ -# Our .travis.yml also defines: - -# - BUILD_TYPE=Release/Debug -# - LIB_TYPE=static/shared -# -# Optional environmental variables -# - DESTDIR <- used for setting the install prefix -# - BUILD_TOOL=["Unix Makefile"|"Ninja"] -# - BUILDNAME <- how to identify this build on the dashboard -# - DO_MemCheck <- if set, try to use valgrind -# - DO_Coverage <- if set, try to do dashboard coverage testing -# - -env_set=1 -if ${BUILD_TYPE+false}; then - echo "BUILD_TYPE not set in environment." - env_set=0 -fi -if ${LIB_TYPE+false}; then - echo "LIB_TYPE not set in environment." - env_set=0 -fi -if ${CXX+false}; then - echo "CXX not set in environment." - env_set=0 -fi - - -if [ ${env_set} -eq 0 ]; then - echo "USAGE: CXX=$(which clang++) BUILD_TYPE=[Release|Debug] LIB_TYPE=[static|shared] $0" - echo "" - echo "Examples:" - echo " CXX=$(which clang++) BUILD_TYPE=Release LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=Release LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=Debug LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" - - echo " CXX=$(which g++) BUILD_TYPE=Release LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=Debug LIB_TYPE=shared DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=Release LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=Debug LIB_TYPE=static DESTDIR=/tmp/cmake_json_cpp $0" - - exit -1 -fi - -if ${DESTDIR+false}; then - DESTDIR="/usr/local" -fi - -# -e: fail on error -# -v: show commands -# -x: show expanded commands -set -vex - -env | sort - -which cmake -cmake --version - -echo ${CXX} -${CXX} --version -_COMPILER_NAME=`basename ${CXX}` -if [ "${LIB_TYPE}" = "shared" ]; then - _CMAKE_BUILD_SHARED_LIBS=ON -else - _CMAKE_BUILD_SHARED_LIBS=OFF -fi - -CTEST_TESTING_OPTION="-D ExperimentalTest" -# - DO_MemCheck <- if set, try to use valgrind -if ! ${DO_MemCheck+false}; then - valgrind --version - CTEST_TESTING_OPTION="-D ExperimentalMemCheck" -else -# - DO_Coverage <- if set, try to do dashboard coverage testing - if ! ${DO_Coverage+false}; then - export CXXFLAGS="-fprofile-arcs -ftest-coverage" - export LDFLAGS="-fprofile-arcs -ftest-coverage" - CTEST_TESTING_OPTION="-D ExperimentalTest -D ExperimentalCoverage" - #gcov --version - fi -fi - -# Ninja = Generates build.ninja files. -if ${BUILD_TOOL+false}; then - BUILD_TOOL="Ninja" - export _BUILD_EXE=ninja - which ninja - ninja --version -else -# Unix Makefiles = Generates standard UNIX makefiles. - export _BUILD_EXE=make -fi - -_BUILD_DIR_NAME="build-cmake_${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}_${_BUILD_EXE}" -mkdir -p ${_BUILD_DIR_NAME} -cd "${_BUILD_DIR_NAME}" - if ${BUILDNAME+false}; then - _HOSTNAME=`hostname -s` - BUILDNAME="${_HOSTNAME}_${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}_${_BUILD_EXE}" - fi - cmake \ - -G "${BUILD_TOOL}" \ - -DBUILDNAME:STRING="${BUILDNAME}" \ - -DCMAKE_CXX_COMPILER:PATH=${CXX} \ - -DCMAKE_BUILD_TYPE:STRING=${BUILD_TYPE} \ - -DBUILD_SHARED_LIBS:BOOL=${_CMAKE_BUILD_SHARED_LIBS} \ - -DCMAKE_INSTALL_PREFIX:PATH=${DESTDIR} \ - ../ - - ctest -C ${BUILD_TYPE} -D ExperimentalStart -D ExperimentalConfigure -D ExperimentalBuild ${CTEST_TESTING_OPTION} -D ExperimentalSubmit - # Final step is to verify that installation succeeds - cmake --build . --config ${BUILD_TYPE} --target install - - if [ "${DESTDIR}" != "/usr/local" ]; then - ${_BUILD_EXE} install - fi -cd - - -if ${CLEANUP+false}; then - echo "Skipping cleanup: build directory will persist." -else - rm -r "${_BUILD_DIR_NAME}" -fi diff --git a/.travis_scripts/meson_builder.sh b/.travis_scripts/meson_builder.sh deleted file mode 100755 index bc74732f6..000000000 --- a/.travis_scripts/meson_builder.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env sh -# This script can be used on the command line directly to configure several -# different build environments. -# This is called by `.travis.yml` via Travis CI. -# Travis supplies $TRAVIS_OS_NAME. -# http://docs.travis-ci.com/user/multi-os/ -# Our .travis.yml also defines: - -# - BUILD_TYPE=release/debug -# - LIB_TYPE=static/shared - -env_set=1 -if ${BUILD_TYPE+false}; then - echo "BUILD_TYPE not set in environment." - env_set=0 -fi -if ${LIB_TYPE+false}; then - echo "LIB_TYPE not set in environment." - env_set=0 -fi -if ${CXX+false}; then - echo "CXX not set in environment." - env_set=0 -fi - - -if [ ${env_set} -eq 0 ]; then - echo "USAGE: CXX=$(which clang++) BUILD_TYPE=[release|debug] LIB_TYPE=[static|shared] $0" - echo "" - echo "Examples:" - echo " CXX=$(which clang++) BUILD_TYPE=release LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=debug LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=release LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which clang++) BUILD_TYPE=debug LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" - - echo " CXX=$(which g++) BUILD_TYPE=release LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=debug LIB_TYPE=shared DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=release LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" - echo " CXX=$(which g++) BUILD_TYPE=debug LIB_TYPE=static DESTDIR=/tmp/meson_json_cpp $0" - - exit -1 -fi - -if ${DESTDIR+false}; then - DESTDIR="/usr/local" -fi - -# -e: fail on error -# -v: show commands -# -x: show expanded commands -set -vex - - -env | sort - -which python3 -which meson -which ninja -echo ${CXX} -${CXX} --version -python3 --version -meson --version -ninja --version -_COMPILER_NAME=`basename ${CXX}` -_BUILD_DIR_NAME="build-${BUILD_TYPE}_${LIB_TYPE}_${_COMPILER_NAME}" - -#./.travis_scripts/run-clang-format.sh -meson --fatal-meson-warnings --werror --buildtype ${BUILD_TYPE} --default-library ${LIB_TYPE} . "${_BUILD_DIR_NAME}" -ninja -v -j 2 -C "${_BUILD_DIR_NAME}" - -cd "${_BUILD_DIR_NAME}" - meson test --no-rebuild --print-errorlogs - - if [ "${DESTDIR}" != "/usr/local" ]; then - ninja install - fi -cd - - -if ${CLEANUP+false}; then - echo "Skipping cleanup: build directory will persist." -else - rm -r "${_BUILD_DIR_NAME}" -fi diff --git a/.travis_scripts/run-clang-format.py b/.travis_scripts/run-clang-format.py deleted file mode 100755 index 605b5aad1..000000000 --- a/.travis_scripts/run-clang-format.py +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env python -"""A wrapper script around clang-format, suitable for linting multiple files -and to use for continuous integration. -This is an alternative API for the clang-format command line. -It runs over multiple files and directories in parallel. -A diff output is produced and a sensible exit code is returned. - -NOTE: pulled from https://github.com/Sarcasm/run-clang-format, which is -licensed under the MIT license. -""" - -from __future__ import print_function, unicode_literals - -import argparse -import codecs -import difflib -import fnmatch -import io -import multiprocessing -import os -import signal -import subprocess -import sys -import traceback - -from functools import partial - -try: - from subprocess import DEVNULL # py3k -except ImportError: - DEVNULL = open(os.devnull, "wb") - - -DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx' - - -class ExitStatus: - SUCCESS = 0 - DIFF = 1 - TROUBLE = 2 - - -def list_files(files, recursive=False, extensions=None, exclude=None): - if extensions is None: - extensions = [] - if exclude is None: - exclude = [] - - out = [] - for file in files: - if recursive and os.path.isdir(file): - for dirpath, dnames, fnames in os.walk(file): - fpaths = [os.path.join(dirpath, fname) for fname in fnames] - for pattern in exclude: - # os.walk() supports trimming down the dnames list - # by modifying it in-place, - # to avoid unnecessary directory listings. - dnames[:] = [ - x for x in dnames - if - not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) - ] - fpaths = [ - x for x in fpaths if not fnmatch.fnmatch(x, pattern) - ] - for f in fpaths: - ext = os.path.splitext(f)[1][1:] - if ext in extensions: - out.append(f) - else: - out.append(file) - return out - - -def make_diff(file, original, reformatted): - return list( - difflib.unified_diff( - original, - reformatted, - fromfile='{}\t(original)'.format(file), - tofile='{}\t(reformatted)'.format(file), - n=3)) - - -class DiffError(Exception): - def __init__(self, message, errs=None): - super(DiffError, self).__init__(message) - self.errs = errs or [] - - -class UnexpectedError(Exception): - def __init__(self, message, exc=None): - super(UnexpectedError, self).__init__(message) - self.formatted_traceback = traceback.format_exc() - self.exc = exc - - -def run_clang_format_diff_wrapper(args, file): - try: - ret = run_clang_format_diff(args, file) - return ret - except DiffError: - raise - except Exception as e: - raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__, - e), e) - - -def run_clang_format_diff(args, file): - try: - with io.open(file, 'r', encoding='utf-8') as f: - original = f.readlines() - except IOError as exc: - raise DiffError(str(exc)) - invocation = [args.clang_format_executable, file] - - # Use of utf-8 to decode the process output. - # - # Hopefully, this is the correct thing to do. - # - # It's done due to the following assumptions (which may be incorrect): - # - clang-format will returns the bytes read from the files as-is, - # without conversion, and it is already assumed that the files use utf-8. - # - if the diagnostics were internationalized, they would use utf-8: - # > Adding Translations to Clang - # > - # > Not possible yet! - # > Diagnostic strings should be written in UTF-8, - # > the client can translate to the relevant code page if needed. - # > Each translation completely replaces the format string - # > for the diagnostic. - # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation - # - # It's not pretty, due to Python 2 & 3 compatibility. - encoding_py3 = {} - if sys.version_info[0] >= 3: - encoding_py3['encoding'] = 'utf-8' - - try: - proc = subprocess.Popen( - invocation, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - universal_newlines=True, - **encoding_py3) - except OSError as exc: - raise DiffError( - "Command '{}' failed to start: {}".format( - subprocess.list2cmdline(invocation), exc - ) - ) - proc_stdout = proc.stdout - proc_stderr = proc.stderr - if sys.version_info[0] < 3: - # make the pipes compatible with Python 3, - # reading lines should output unicode - encoding = 'utf-8' - proc_stdout = codecs.getreader(encoding)(proc_stdout) - proc_stderr = codecs.getreader(encoding)(proc_stderr) - # hopefully the stderr pipe won't get full and block the process - outs = list(proc_stdout.readlines()) - errs = list(proc_stderr.readlines()) - proc.wait() - if proc.returncode: - raise DiffError( - "Command '{}' returned non-zero exit status {}".format( - subprocess.list2cmdline(invocation), proc.returncode - ), - errs, - ) - return make_diff(file, original, outs), errs - - -def bold_red(s): - return '\x1b[1m\x1b[31m' + s + '\x1b[0m' - - -def colorize(diff_lines): - def bold(s): - return '\x1b[1m' + s + '\x1b[0m' - - def cyan(s): - return '\x1b[36m' + s + '\x1b[0m' - - def green(s): - return '\x1b[32m' + s + '\x1b[0m' - - def red(s): - return '\x1b[31m' + s + '\x1b[0m' - - for line in diff_lines: - if line[:4] in ['--- ', '+++ ']: - yield bold(line) - elif line.startswith('@@ '): - yield cyan(line) - elif line.startswith('+'): - yield green(line) - elif line.startswith('-'): - yield red(line) - else: - yield line - - -def print_diff(diff_lines, use_color): - if use_color: - diff_lines = colorize(diff_lines) - if sys.version_info[0] < 3: - sys.stdout.writelines((l.encode('utf-8') for l in diff_lines)) - else: - sys.stdout.writelines(diff_lines) - - -def print_trouble(prog, message, use_colors): - error_text = 'error:' - if use_colors: - error_text = bold_red(error_text) - print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) - - -def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument( - '--clang-format-executable', - metavar='EXECUTABLE', - help='path to the clang-format executable', - default='clang-format') - parser.add_argument( - '--extensions', - help='comma separated list of file extensions (default: {})'.format( - DEFAULT_EXTENSIONS), - default=DEFAULT_EXTENSIONS) - parser.add_argument( - '-r', - '--recursive', - action='http://github.com/store_true', - help='run recursively over directories') - parser.add_argument('files', metavar='file', nargs='+') - parser.add_argument( - '-q', - '--quiet', - action='http://github.com/store_true') - parser.add_argument( - '-j', - metavar='N', - type=int, - default=0, - help='run N clang-format jobs in parallel' - ' (default number of cpus + 1)') - parser.add_argument( - '--color', - default='auto', - choices=['auto', 'always', 'never'], - help='show colored diff (default: auto)') - parser.add_argument( - '-e', - '--exclude', - metavar='PATTERN', - action='http://github.com/append', - default=[], - help='exclude paths matching the given glob-like pattern(s)' - ' from recursive search') - - args = parser.parse_args() - - # use default signal handling, like diff return SIGINT value on ^C - # https://bugs.python.org/issue14229#msg156446 - signal.signal(signal.SIGINT, signal.SIG_DFL) - try: - signal.SIGPIPE - except AttributeError: - # compatibility, SIGPIPE does not exist on Windows - pass - else: - signal.signal(signal.SIGPIPE, signal.SIG_DFL) - - colored_stdout = False - colored_stderr = False - if args.color == 'always': - colored_stdout = True - colored_stderr = True - elif args.color == 'auto': - colored_stdout = sys.stdout.isatty() - colored_stderr = sys.stderr.isatty() - - version_invocation = [args.clang_format_executable, str("--version")] - try: - subprocess.check_call(version_invocation, stdout=DEVNULL) - except subprocess.CalledProcessError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - return ExitStatus.TROUBLE - except OSError as e: - print_trouble( - parser.prog, - "Command '{}' failed to start: {}".format( - subprocess.list2cmdline(version_invocation), e - ), - use_colors=colored_stderr, - ) - return ExitStatus.TROUBLE - - retcode = ExitStatus.SUCCESS - files = list_files( - args.files, - recursive=args.recursive, - exclude=args.exclude, - extensions=args.extensions.split(',')) - - if not files: - return - - njobs = args.j - if njobs == 0: - njobs = multiprocessing.cpu_count() + 1 - njobs = min(len(files), njobs) - - if njobs == 1: - # execute directly instead of in a pool, - # less overhead, simpler stacktraces - it = (run_clang_format_diff_wrapper(args, file) for file in files) - pool = None - else: - pool = multiprocessing.Pool(njobs) - it = pool.imap_unordered( - partial(run_clang_format_diff_wrapper, args), files) - while True: - try: - outs, errs = next(it) - except StopIteration: - break - except DiffError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - retcode = ExitStatus.TROUBLE - sys.stderr.writelines(e.errs) - except UnexpectedError as e: - print_trouble(parser.prog, str(e), use_colors=colored_stderr) - sys.stderr.write(e.formatted_traceback) - retcode = ExitStatus.TROUBLE - # stop at the first unexpected error, - # something could be very wrong, - # don't process all files unnecessarily - if pool: - pool.terminate() - break - else: - sys.stderr.writelines(errs) - if outs == []: - continue - if not args.quiet: - print_diff(outs, use_color=colored_stdout) - if retcode == ExitStatus.SUCCESS: - retcode = ExitStatus.DIFF - return retcode - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/.travis_scripts/run-clang-format.sh b/.travis_scripts/run-clang-format.sh deleted file mode 100755 index ded76aaf5..000000000 --- a/.travis_scripts/run-clang-format.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env bash - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -python $DIR/run-clang-format.py -r $DIR/../src/**/ $DIR/../include/**/ diff --git a/.travis_scripts/travis.before_install.linux.sh b/.travis_scripts/travis.before_install.linux.sh deleted file mode 100644 index 9b556de15..000000000 --- a/.travis_scripts/travis.before_install.linux.sh +++ /dev/null @@ -1,8 +0,0 @@ -set -vex - -# Preinstalled versions of python are dependent on which Ubuntu distribution -# you are running. The below version needs to be updated whenever we roll -# the Ubuntu version used in Travis. -# https://docs.travis-ci.com/user/languages/python/ - -pyenv global 3.7.1 diff --git a/.travis_scripts/travis.before_install.osx.sh b/.travis_scripts/travis.before_install.osx.sh deleted file mode 100644 index e69de29bb..000000000 diff --git a/.travis_scripts/travis.install.linux.sh b/.travis_scripts/travis.install.linux.sh deleted file mode 100644 index 6495fefe9..000000000 --- a/.travis_scripts/travis.install.linux.sh +++ /dev/null @@ -1,5 +0,0 @@ -set -vex - -pip3 install --user meson ninja -which meson -which ninja diff --git a/.travis_scripts/travis.install.osx.sh b/.travis_scripts/travis.install.osx.sh deleted file mode 100644 index 5d83c0c71..000000000 --- a/.travis_scripts/travis.install.osx.sh +++ /dev/null @@ -1 +0,0 @@ -# NOTHING TO DO HERE From c8166ddf1c21f4daa3fb975f51e62d1bdf36e76e Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 16:30:33 -0700 Subject: [PATCH 357/410] add comment space directive (#1558) --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index 2a8066958..b7cf99793 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,4 @@ BasedOnStyle: LLVM DerivePointerAlignment: false PointerAlignment: Left - +SpacesBeforeTrailingComments: 1 From 255ebc54af0ebc940ac7d80b789ee77864c8b936 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 16:52:59 -0700 Subject: [PATCH 358/410] Create clang-format.yml --- .github/workflows/clang-format.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .github/workflows/clang-format.yml diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 000000000..50f471696 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,19 @@ +name: clang-format Check +on: [push, pull_request] +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + strategy: + matrix: + path: + - 'src' + - 'examples' + - 'include' + steps: + - uses: actions/checkout@v4 + - name: Run clang-format style check for C/C++/Protobuf programs. + uses: jidicula/clang-format-action@v4.13.0 + with: + clang-format-version: '13' + check-path: ${{ matrix.path }} From cc28be059046a43e631977690efe06472e1477b7 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 16:54:56 -0700 Subject: [PATCH 359/410] Update clang-format.yml --- .github/workflows/clang-format.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 50f471696..a413ecab9 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,8 +1,8 @@ -name: clang-format Check +name: clang-format check on: [push, pull_request] jobs: formatting-check: - name: Formatting Check + name: formatting check runs-on: ubuntu-latest strategy: matrix: @@ -12,7 +12,7 @@ jobs: - 'include' steps: - uses: actions/checkout@v4 - - name: Run clang-format style check for C/C++/Protobuf programs. + - name: runs clang-format style check for C/C++/Protobuf programs. uses: jidicula/clang-format-action@v4.13.0 with: clang-format-version: '13' From 4290915354de66f99ec3e80b4e319f2d6b11c299 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 16:56:02 -0700 Subject: [PATCH 360/410] Update clang-format.yml --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index a413ecab9..5f078ff00 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -15,5 +15,5 @@ jobs: - name: runs clang-format style check for C/C++/Protobuf programs. uses: jidicula/clang-format-action@v4.13.0 with: - clang-format-version: '13' + clang-format-version: '18' check-path: ${{ matrix.path }} From ccea7db6c3336ac0410d3f988fbf823f5d2d77da Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 17:07:11 -0700 Subject: [PATCH 361/410] Clang format updates (#1560) * add comment space directive * Fix clang format issue * wrap in clang-format off --- src/test_lib_json/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index a6f21c45a..1ef33bb5a 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3632,12 +3632,12 @@ JSONTEST_FIXTURE_LOCAL(CharReaderAllowSpecialFloatsTest, issue209) { for (const auto& td : test_data) { bool ok = reader->parse(&*td.in.begin(), &*td.in.begin() + td.in.size(), &root, &errs); - JSONTEST_ASSERT(td.ok == ok) << "line:" << td.line << "\n" - << " expected: {" - << "ok:" << td.ok << ", in:\'" << td.in << "\'" - << "}\n" - << " actual: {" - << "ok:" << ok << "}\n"; + // clang-format off + JSONTEST_ASSERT(td.ok == ok) << + "line:" << td.line << "\n " << + "expected: {ok:" << td.ok << ", in:\'" << td.in << "\'}\n " << + "actual: {ok:" << ok << "}\n"; + // clang-format on } { From 65d92a43136c2b950c0f30425231097678b067f6 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 17:10:48 -0700 Subject: [PATCH 362/410] Update meson.yml (#1554) * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml Switch to clang-format-check * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml Add multilple OSes * Update meson.yml Add ninja version * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml --- .github/workflows/meson.yml | 48 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 98df7a85a..fbe8138dd 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -1,29 +1,33 @@ -name: Meson Build -uses: BSFishy/meson-build@v1.0.3 - -run-name: ${{ github.actor }} is testing out GitHub Actions 🚀 +name: meson build and test +run-name: update pushed to ${{ github.ref }} on: [push] jobs: - Explore-GitHub-Actions: - runs-on: ubuntu-latest + publish: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: - - run: echo " The job was automatically triggered by a ${{ github.event_name }} event." - - uses: actions/checkout@v4 - - uses: actions/setup-python@v1 - - uses: BSFishy/meson-build@v1.0.3 + - name: checkout repository + uses: actions/checkout@v4 + + - name: setup python + uses: actions/setup-python@v5 + + - name: meson build + uses: BSFishy/meson-build@v1.0.3 with: + meson-version: 1.5.1 + ninja-version: 1.11.1.1 action: build + + - name: meson test + uses: BSFishy/meson-build@v1.0.3 + with: + meson-version: 1.5.1 + ninja-version: 1.11.1.1 action: test - action: tidy - - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v4 - - run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." From 073ad7e96e1b45c7c82ee330da239714f1ac51d4 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 17:19:04 -0700 Subject: [PATCH 363/410] Update meson.yml --- .github/workflows/meson.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index fbe8138dd..8314dbc13 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -1,6 +1,6 @@ name: meson build and test run-name: update pushed to ${{ github.ref }} -on: [push] +on: [check_run, pull_request, push] jobs: publish: From c3a986600f9975a33e3573d85b48db63011d3711 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 17:19:14 -0700 Subject: [PATCH 364/410] Update clang-format.yml --- .github/workflows/clang-format.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 5f078ff00..221f8b839 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,5 +1,6 @@ name: clang-format check -on: [push, pull_request] +on: [check_run, pull_request, push] + jobs: formatting-check: name: formatting check From 0a9b9d9c6ea04847af83c32930176ec42ba6c842 Mon Sep 17 00:00:00 2001 From: vslashg Date: Mon, 9 Sep 2024 20:30:16 -0400 Subject: [PATCH 365/410] Fix a parser bug where tokens are misidentified as commas. (#1502) * Fix a parser bug where tokens are misidentified as commas. In the old and new readers, when parsing an object, a comment followed by any non-`}` token is treated as a comma. The new unit test required changing the runjsontests.py flag regime so that failure tests could be run with default settings. * Honor allowComments==false mode. Much of the comment handling in the parsers is bespoke, and does not honor this flag. By unfiying it under a common API, the parser is simplified and strict mode is now more correctly strict. Note that allowComments mode does not allow for comments in arbitrary locations; they are allowed only in certain positions. Rectifying this is a bigger effort, since collectComments mode requires storing the comments somewhere, and it's not immediately clear where in the DOM all such comments should live. --------- Co-authored-by: Jordan Bayles --- include/json/reader.h | 2 +- src/jsontestrunner/main.cpp | 7 ++- src/lib_json/json_reader.cpp | 74 +++++++++------------------ test/data/fail_strict_comment_01.json | 4 ++ test/data/fail_strict_comment_02.json | 4 ++ test/data/fail_strict_comment_03.json | 3 ++ test/data/fail_test_object_02.json | 1 + test/runjsontests.py | 9 ++-- 8 files changed, 49 insertions(+), 55 deletions(-) create mode 100644 test/data/fail_strict_comment_01.json create mode 100644 test/data/fail_strict_comment_02.json create mode 100644 test/data/fail_strict_comment_03.json create mode 100644 test/data/fail_test_object_02.json diff --git a/include/json/reader.h b/include/json/reader.h index 10c6a4ff4..85539d161 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -190,6 +190,7 @@ class JSON_API Reader { using Errors = std::deque; bool readToken(Token& token); + bool readTokenSkippingComments(Token& token); void skipSpaces(); bool match(const Char* pattern, int patternLength); bool readComment(); @@ -221,7 +222,6 @@ class JSON_API Reader { int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); static bool containsNewLine(Location begin, Location end); static String normalizeEOL(Location begin, Location end); diff --git a/src/jsontestrunner/main.cpp b/src/jsontestrunner/main.cpp index df717ffd5..ab6a80039 100644 --- a/src/jsontestrunner/main.cpp +++ b/src/jsontestrunner/main.cpp @@ -240,11 +240,14 @@ static int parseCommandLine(int argc, const char* argv[], Options* opts) { return printUsage(argv); } int index = 1; - if (Json::String(argv[index]) == "--json-checker") { - opts->features = Json::Features::strictMode(); + if (Json::String(argv[index]) == "--parse-only") { opts->parseOnly = true; ++index; } + if (Json::String(argv[index]) == "--strict") { + opts->features = Json::Features::strictMode(); + ++index; + } if (Json::String(argv[index]) == "--json-config") { printConfig(); return 3; diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 8dcd2b52e..b12c6b837 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -129,7 +129,7 @@ bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, bool successful = readValue(); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); if (collectComments_ && !commentsBefore_.empty()) root.setComment(commentsBefore_, commentAfter); if (features_.strictRoot_) { @@ -157,7 +157,7 @@ bool Reader::readValue() { throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); bool successful = true; if (collectComments_ && !commentsBefore_.empty()) { @@ -225,14 +225,14 @@ bool Reader::readValue() { return successful; } -void Reader::skipCommentTokens(Token& token) { +bool Reader::readTokenSkippingComments(Token& token) { + bool success = readToken(token); if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); + while (success && token.type_ == tokenComment) { + success = readToken(token); + } } + return success; } bool Reader::readToken(Token& token) { @@ -446,12 +446,7 @@ bool Reader::readObject(Token& token) { Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; + while (readTokenSkippingComments(tokenName)) { if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); @@ -480,15 +475,11 @@ bool Reader::readObject(Token& token) { return recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { + if (!readTokenSkippingComments(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) { return addErrorAndRecover("Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } @@ -518,10 +509,7 @@ bool Reader::readArray(Token& token) { Token currentToken; // Accept Comment after last item in the array. - ok = readToken(currentToken); - while (currentToken.type_ == tokenComment && ok) { - ok = readToken(currentToken); - } + ok = readTokenSkippingComments(currentToken); bool badTokenType = (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { @@ -943,6 +931,7 @@ class OurReader { using Errors = std::deque; bool readToken(Token& token); + bool readTokenSkippingComments(Token& token); void skipSpaces(); void skipBom(bool skipBom); bool match(const Char* pattern, int patternLength); @@ -976,7 +965,6 @@ class OurReader { int& column) const; String getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); - void skipCommentTokens(Token& token); static String normalizeEOL(Location begin, Location end); static bool containsNewLine(Location begin, Location end); @@ -1030,7 +1018,7 @@ bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, bool successful = readValue(); nodes_.pop(); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); if (features_.failIfExtra_ && (token.type_ != tokenEndOfStream)) { addError("Extra non-whitespace after JSON value.", token); return false; @@ -1058,7 +1046,7 @@ bool OurReader::readValue() { if (nodes_.size() > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + readTokenSkippingComments(token); bool successful = true; if (collectComments_ && !commentsBefore_.empty()) { @@ -1145,14 +1133,14 @@ bool OurReader::readValue() { return successful; } -void OurReader::skipCommentTokens(Token& token) { +bool OurReader::readTokenSkippingComments(Token& token) { + bool success = readToken(token); if (features_.allowComments_) { - do { - readToken(token); - } while (token.type_ == tokenComment); - } else { - readToken(token); + while (success && token.type_ == tokenComment) { + success = readToken(token); + } } + return success; } bool OurReader::readToken(Token& token) { @@ -1449,12 +1437,7 @@ bool OurReader::readObject(Token& token) { Value init(objectValue); currentValue().swapPayload(init); currentValue().setOffsetStart(token.start_ - begin_); - while (readToken(tokenName)) { - bool initialTokenOk = true; - while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); - if (!initialTokenOk) - break; + while (readTokenSkippingComments(tokenName)) { if (tokenName.type_ == tokenObjectEnd && (name.empty() || features_.allowTrailingCommas_)) // empty object or trailing comma @@ -1491,15 +1474,11 @@ bool OurReader::readObject(Token& token) { return recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || - (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && - comma.type_ != tokenComment)) { + if (!readTokenSkippingComments(comma) || + (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator)) { return addErrorAndRecover("Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } - bool finalizeTokenOk = true; - while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } @@ -1533,10 +1512,7 @@ bool OurReader::readArray(Token& token) { Token currentToken; // Accept Comment after last item in the array. - ok = readToken(currentToken); - while (currentToken.type_ == tokenComment && ok) { - ok = readToken(currentToken); - } + ok = readTokenSkippingComments(currentToken); bool badTokenType = (currentToken.type_ != tokenArraySeparator && currentToken.type_ != tokenArrayEnd); if (!ok || badTokenType) { diff --git a/test/data/fail_strict_comment_01.json b/test/data/fail_strict_comment_01.json new file mode 100644 index 000000000..b7e0a5e75 --- /dev/null +++ b/test/data/fail_strict_comment_01.json @@ -0,0 +1,4 @@ +{ + "a": "aaa", + "b": "bbb" // comments not allowed in strict mode +} diff --git a/test/data/fail_strict_comment_02.json b/test/data/fail_strict_comment_02.json new file mode 100644 index 000000000..699a7f731 --- /dev/null +++ b/test/data/fail_strict_comment_02.json @@ -0,0 +1,4 @@ +{ + "a": "aaa", // comments not allowed in strict mode + "b": "bbb" +} diff --git a/test/data/fail_strict_comment_03.json b/test/data/fail_strict_comment_03.json new file mode 100644 index 000000000..5f0fabf1f --- /dev/null +++ b/test/data/fail_strict_comment_03.json @@ -0,0 +1,3 @@ +{ + "array" : [1, 2, 3 /* comments not allowed in strict mode */] +} diff --git a/test/data/fail_test_object_02.json b/test/data/fail_test_object_02.json new file mode 100644 index 000000000..afe62c5b5 --- /dev/null +++ b/test/data/fail_test_object_02.json @@ -0,0 +1 @@ +{"one": 1 /* } */ { "two" : 2 } diff --git a/test/runjsontests.py b/test/runjsontests.py index 5496e2c58..49cc7a960 100644 --- a/test/runjsontests.py +++ b/test/runjsontests.py @@ -97,14 +97,17 @@ def runAllTests(jsontest_executable_path, input_dir = None, valgrind_path = use_valgrind and VALGRIND_CMD or '' for input_path in tests + test_jsonchecker: expect_failure = os.path.basename(input_path).startswith('fail') - is_json_checker_test = (input_path in test_jsonchecker) or expect_failure + is_json_checker_test = input_path in test_jsonchecker + is_parse_only = is_json_checker_test or expect_failure + is_strict_test = ('_strict_' in os.path.basename(input_path)) or is_json_checker_test print('TESTING:', input_path, end=' ') - options = is_json_checker_test and '--json-checker' or '' + options = is_parse_only and '--parse-only' or '' + options += is_strict_test and ' --strict' or '' options += ' --json-writer %s'%writerClass cmd = '%s%s %s "%s"' % ( valgrind_path, jsontest_executable_path, options, input_path) status, process_output = getStatusOutput(cmd) - if is_json_checker_test: + if is_parse_only: if expect_failure: if not status: print('FAILED') From 3c2205cd97838d3c4143107992967e23f0c958b8 Mon Sep 17 00:00:00 2001 From: vslashg Date: Mon, 9 Sep 2024 20:32:17 -0400 Subject: [PATCH 366/410] Fix out-of-bounds read. (#1503) getLocationLIneAndColumn would read past the end of the provided buffer if generating an error message at the end of the stream, if the final character was `\r`. Co-authored-by: Jordan Bayles --- src/lib_json/json_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index b12c6b837..86ed030a3 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -761,7 +761,7 @@ void Reader::getLocationLineAndColumn(Location location, int& line, while (current < location && current != end_) { Char c = *current++; if (c == '\r') { - if (*current == '\n') + if (current != end_ && *current == '\n') ++current; lastLineStart = current; ++line; @@ -1801,7 +1801,7 @@ void OurReader::getLocationLineAndColumn(Location location, int& line, while (current < location && current != end_) { Char c = *current++; if (c == '\r') { - if (*current == '\n') + if (current != end_ && *current == '\n') ++current; lastLineStart = current; ++line; From e1a3c64fef7351b49ad612c8b355a42666a7ff44 Mon Sep 17 00:00:00 2001 From: vslashg Date: Mon, 9 Sep 2024 20:34:55 -0400 Subject: [PATCH 367/410] Fix asserts in Value::setComment (#1445) The existing asserts seem to not be what was intended; they appear to have been mistranslated in pull/877. The first assert for `comment.empty()` was previously a check that a provided `const char*` parameter was not null. The function this replaced accepted empty strings, and the if() statement at the start of this function handles them. The second assert for `comment[0] == '\0'` was written when `comment` was a `const char*`, and was testing for empty c-string input. This PR replaces it with `comment.empty()` to match the original intent. Co-authored-by: Jordan Bayles --- src/lib_json/json_value.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index aa2b744ca..26cd843cc 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1410,9 +1410,8 @@ void Value::setComment(String comment, CommentPlacement placement) { // Always discard trailing newline, to aid indentation. comment.pop_back(); } - JSON_ASSERT(!comment.empty()); JSON_ASSERT_MESSAGE( - comment[0] == '\0' || comment[0] == '/', + comment.empty() || comment[0] == '/', "in Json::Value::setComment(): Comments must start with /"); comments_.set(placement, std::move(comment)); } From 034976a19dbd7ffe37aa1c3821855d4cde868fcb Mon Sep 17 00:00:00 2001 From: Philip Top Date: Mon, 9 Sep 2024 17:38:22 -0700 Subject: [PATCH 368/410] add a valueToQuotedString overload (#1397) * add a valueToQuotedString overload to take a string length to support things like a string_view more directly. * Apply suggestions from code review Co-authored-by: Billy Donahue --------- Co-authored-by: Billy Donahue Co-authored-by: Jordan Bayles --- include/json/writer.h | 1 + src/lib_json/json_writer.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/json/writer.h b/include/json/writer.h index 655ebfffb..7c56a2107 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -351,6 +351,7 @@ String JSON_API valueToString( PrecisionType precisionType = PrecisionType::significantDigits); String JSON_API valueToString(bool value); String JSON_API valueToQuotedString(const char* value); +String JSON_API valueToQuotedString(const char* value, size_t length); /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 239c429a1..5bb5dd117 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -354,6 +354,10 @@ String valueToQuotedString(const char* value) { return valueToQuotedStringN(value, strlen(value)); } +String valueToQuotedString(const char* value, size_t length) { + return valueToQuotedStringN(value, length); +} + // Class Writer // ////////////////////////////////////////////////////////////////// Writer::~Writer() = default; @@ -491,7 +495,7 @@ void StyledWriter::writeValue(const Value& value) { const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); + writeWithIndent(valueToQuotedString(name.c_str(), name.size())); document_ += " : "; writeValue(childValue); if (++it == members.end()) { @@ -709,7 +713,7 @@ void StyledStreamWriter::writeValue(const Value& value) { const String& name = *it; const Value& childValue = value[name]; writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); + writeWithIndent(valueToQuotedString(name.c_str(), name.size())); *document_ << " : "; writeValue(childValue); if (++it == members.end()) { From 78893d396180bc558dc3b204fae929f0714748a6 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 18:19:48 -0700 Subject: [PATCH 369/410] Update clang-format.yml --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 221f8b839..497b9d64e 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,5 +1,5 @@ name: clang-format check -on: [check_run, pull_request, push] +on: [check_run, push] jobs: formatting-check: From 57de64bf69f3e8fc715bfeb4dbe0bca27b6c4862 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 18:29:28 -0700 Subject: [PATCH 370/410] Add code coverage (#1561) * Add code coverage * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml * Update meson.yml --- .github/workflows/meson.yml | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 8314dbc13..1899470f2 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -1,6 +1,6 @@ name: meson build and test run-name: update pushed to ${{ github.ref }} -on: [check_run, pull_request, push] +on: [check_run, push] jobs: publish: @@ -31,3 +31,35 @@ jobs: meson-version: 1.5.1 ninja-version: 1.11.1.1 action: test + + coverage: + runs-on: ubuntu-latest + + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: setup python + uses: actions/setup-python@v5 + + - name: meson build + uses: BSFishy/meson-build@v1.0.3 + with: + meson-version: 1.5.1 + ninja-version: 1.11.1.1 + setup-options: -Db_coverage=true + action: build + + - name: meson test + uses: BSFishy/meson-build@v1.0.3 + with: + meson-version: 1.5.1 + ninja-version: 1.11.1.1 + setup-options: -Db_coverage=true + action: test + + - name: generate code coverage report + uses: threeal/gcovr-action@v1.0.0 + with: + coveralls-send: true + github-token: ${{ secrets.GITHUB_TOKEN }} From caf5fb0742e99c35abdfb127dde749138adc2715 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 18:35:36 -0700 Subject: [PATCH 371/410] Update meson.yml (#1562) --- .github/workflows/meson.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 1899470f2..48d496c73 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -1,6 +1,6 @@ name: meson build and test run-name: update pushed to ${{ github.ref }} -on: [check_run, push] +on: [check_run, push, pull_request] jobs: publish: From badbbc7185cde8270e6005bcdb6686363fe00557 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 18:35:49 -0700 Subject: [PATCH 372/410] Update clang-format.yml --- .github/workflows/clang-format.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 497b9d64e..221f8b839 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -1,5 +1,5 @@ name: clang-format check -on: [check_run, push] +on: [check_run, pull_request, push] jobs: formatting-check: From fd1abe4cca7f496438f92d797371dabe14e49373 Mon Sep 17 00:00:00 2001 From: Andrea Pappacoda Date: Tue, 10 Sep 2024 03:42:23 +0200 Subject: [PATCH 373/410] build(meson): use find_program('python3') (#1386) If you really want to be sure to always find python3 when running Meson (and not some other implementation like [Muon](https://muon.build)) it is a bit better to use `find_program('python3')`, as described in https://mesonbuild.com/Reference-manual_functions.html#find_program : "if the "python3" program is requested and it is not found in the system, Meson will return its current interpreter Co-authored-by: Jordan Bayles --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index f68db30dd..fb2b47cd9 100644 --- a/meson.build +++ b/meson.build @@ -73,7 +73,7 @@ if meson.is_subproject() or not get_option('tests') subdir_done() endif -python = import('python').find_installation() +python = find_program('python3') jsoncpp_test = executable( 'jsoncpp_test', files([ From d39b0dff0c5673ed6b21a7808773cd45b661aae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20R=C3=B6hling?= Date: Tue, 10 Sep 2024 03:42:54 +0200 Subject: [PATCH 374/410] Bump CMake policy version to avoid deprecation warning (#1499) Starting with CMake 3.27, there will be a warning for compat levels below CMake 3.5. Co-authored-by: Jordan Bayles --- jsoncppConfig.cmake.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsoncppConfig.cmake.in b/jsoncppConfig.cmake.in index 76570bc30..fdd9fea6b 100644 --- a/jsoncppConfig.cmake.in +++ b/jsoncppConfig.cmake.in @@ -1,5 +1,5 @@ cmake_policy(PUSH) -cmake_policy(VERSION 3.0) +cmake_policy(VERSION 3.0...3.26) @PACKAGE_INIT@ From c857395951c1d5e80b0ac62f760d698f03b209f2 Mon Sep 17 00:00:00 2001 From: NotWearingPants <26556598+NotWearingPants@users.noreply.github.com> Date: Tue, 10 Sep 2024 04:43:32 +0300 Subject: [PATCH 375/410] Update link in amalgamate.py (#1335) --- amalgamate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amalgamate.py b/amalgamate.py index 4a328ab5a..1d1e48810 100755 --- a/amalgamate.py +++ b/amalgamate.py @@ -63,7 +63,7 @@ def amalgamate_source(source_top_dir=None, """ print("Amalgamating header...") header = AmalgamationFile(source_top_dir) - header.add_text("/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).") + header.add_text("/// Json-cpp amalgamated header (https://github.com/open-source-parsers/jsoncpp/).") header.add_text('/// It is intended to be used with #include "%s"' % header_include_path) header.add_file("LICENSE", wrap_in_comment=True) header.add_text("#ifndef JSON_AMALGAMATED_H_INCLUDED") @@ -90,7 +90,7 @@ def amalgamate_source(source_top_dir=None, forward_header_include_path = base + "-forwards" + ext print("Amalgamating forward header...") header = AmalgamationFile(source_top_dir) - header.add_text("/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).") + header.add_text("/// Json-cpp amalgamated forward header (https://github.com/open-source-parsers/jsoncpp/).") header.add_text('/// It is intended to be used with #include "%s"' % forward_header_include_path) header.add_text("/// This header provides forward declaration for all JsonCpp types.") header.add_file("LICENSE", wrap_in_comment=True) @@ -112,7 +112,7 @@ def amalgamate_source(source_top_dir=None, print("Amalgamating source...") source = AmalgamationFile(source_top_dir) - source.add_text("/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).") + source.add_text("/// Json-cpp amalgamated source (https://github.com/open-source-parsers/jsoncpp/).") source.add_text('/// It is intended to be used with #include "%s"' % header_include_path) source.add_file("LICENSE", wrap_in_comment=True) source.add_text("") From c04c0c2131e2c0e90eb731b58877eef39bcf8e47 Mon Sep 17 00:00:00 2001 From: martinduffy1 <106178409+martinduffy1@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:48:54 -0400 Subject: [PATCH 376/410] CharReader: Add StructuredError (#1409) * CharReader: Add Structured Error Add getStructuredError to CharReader * run clang format --------- Co-authored-by: Jordan Bayles Co-authored-by: Jordan Bayles --- include/json/reader.h | 27 +++++++++++++++- src/lib_json/json_reader.cpp | 60 ++++++++++++++++++++++++------------ src/test_lib_json/main.cpp | 30 ++++++++++++++++++ 3 files changed, 97 insertions(+), 20 deletions(-) diff --git a/include/json/reader.h b/include/json/reader.h index 85539d161..38b9360cf 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -244,6 +244,12 @@ class JSON_API Reader { */ class JSON_API CharReader { public: + struct JSON_API StructuredError { + ptrdiff_t offset_start; + ptrdiff_t offset_limit; + String message; + }; + virtual ~CharReader() = default; /** \brief Read a Value from a JSON * document. The document must be a UTF-8 encoded string containing the @@ -262,7 +268,12 @@ class JSON_API CharReader { * error occurred. */ virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, - String* errs) = 0; + String* errs); + + /** \brief Returns a vector of structured errors encountered while parsing. + * Each parse call resets the stored list of errors. + */ + std::vector getStructuredErrors() const; class JSON_API Factory { public: @@ -272,6 +283,20 @@ class JSON_API CharReader { */ virtual CharReader* newCharReader() const = 0; }; // Factory + +protected: + class Impl { + public: + virtual ~Impl() = default; + virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) = 0; + virtual std::vector getStructuredErrors() const = 0; + }; + + explicit CharReader(std::unique_ptr impl) : _impl(std::move(impl)) {} + +private: + std::unique_ptr _impl; }; // CharReader /** \brief Build a CharReader implementation. diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 86ed030a3..4ab4dffd3 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -878,17 +878,12 @@ class OurReader { public: using Char = char; using Location = const Char*; - struct StructuredError { - ptrdiff_t offset_start; - ptrdiff_t offset_limit; - String message; - }; explicit OurReader(OurFeatures const& features); bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); String getFormattedErrorMessages() const; - std::vector getStructuredErrors() const; + std::vector getStructuredErrors() const; private: OurReader(OurReader const&); // no impl @@ -1836,10 +1831,11 @@ String OurReader::getFormattedErrorMessages() const { return formattedMessage; } -std::vector OurReader::getStructuredErrors() const { - std::vector allErrors; +std::vector +OurReader::getStructuredErrors() const { + std::vector allErrors; for (const auto& error : errors_) { - OurReader::StructuredError structured; + CharReader::StructuredError structured; structured.offset_start = error.token_.start_ - begin_; structured.offset_limit = error.token_.end_ - begin_; structured.message = error.message_; @@ -1849,20 +1845,36 @@ std::vector OurReader::getStructuredErrors() const { } class OurCharReader : public CharReader { - bool const collectComments_; - OurReader reader_; public: OurCharReader(bool collectComments, OurFeatures const& features) - : collectComments_(collectComments), reader_(features) {} - bool parse(char const* beginDoc, char const* endDoc, Value* root, - String* errs) override { - bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); - if (errs) { - *errs = reader_.getFormattedErrorMessages(); + : CharReader( + std::unique_ptr(new OurImpl(collectComments, features))) {} + +protected: + class OurImpl : public Impl { + public: + OurImpl(bool collectComments, OurFeatures const& features) + : collectComments_(collectComments), reader_(features) {} + + bool parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) override { + bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); + if (errs) { + *errs = reader_.getFormattedErrorMessages(); + } + return ok; } - return ok; - } + + std::vector + getStructuredErrors() const override { + return reader_.getStructuredErrors(); + } + + private: + bool const collectComments_; + OurReader reader_; + }; }; CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); } @@ -1952,6 +1964,16 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { //! [CharReaderBuilderDefaults] } +std::vector +CharReader::getStructuredErrors() const { + return _impl->getStructuredErrors(); +} + +bool CharReader::parse(char const* beginDoc, char const* endDoc, Value* root, + String* errs) { + return _impl->parse(beginDoc, endDoc, root, errs); +} + ////////////////////////////////// // global functions diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 1ef33bb5a..fa41d19ed 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -3917,6 +3917,36 @@ JSONTEST_FIXTURE_LOCAL(FuzzTest, fuzzDoesntCrash) { example.size())); } +struct ParseWithStructuredErrorsTest : JsonTest::TestCase { + void testErrors( + const std::string& doc, bool success, + const std::vector& expectedErrors) { + Json::CharReaderBuilder b; + CharReaderPtr reader(b.newCharReader()); + Json::Value root; + JSONTEST_ASSERT_EQUAL( + reader->parse(doc.data(), doc.data() + doc.length(), &root, nullptr), + success); + auto actualErrors = reader->getStructuredErrors(); + JSONTEST_ASSERT_EQUAL(expectedErrors.size(), actualErrors.size()); + for (std::size_t i = 0; i < actualErrors.size(); i++) { + const auto& a = actualErrors[i]; + const auto& e = expectedErrors[i]; + JSONTEST_ASSERT_EQUAL(a.offset_start, e.offset_start); + JSONTEST_ASSERT_EQUAL(a.offset_limit, e.offset_limit); + JSONTEST_ASSERT_STRING_EQUAL(a.message, e.message); + } + } +}; + +JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, success) { + testErrors("{}", true, {}); +} + +JSONTEST_FIXTURE_LOCAL(ParseWithStructuredErrorsTest, singleError) { + testErrors("{ 1 : 2 }", false, {{2, 3, "Missing '}' or object member name"}}); +} + int main(int argc, const char* argv[]) { JsonTest::Runner runner; From 483f1c310e36db6d53868f9a4f8b9c0f90faba5b Mon Sep 17 00:00:00 2001 From: Pavel Tsynk <36221942+TsynkPavel@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:50:38 +0700 Subject: [PATCH 377/410] Fix compile on windows with clang (#1480) Co-authored-by: Jordan Bayles --- src/lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 3cf66eb34..ce8100b29 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -144,7 +144,7 @@ if(BUILD_STATIC_LIBS) # avoid name clashes on windows as the shared import lib is also named jsoncpp.lib if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) - if (MSVC) + if (WIN32) set(STATIC_SUFFIX "_static") else() set(STATIC_SUFFIX "") From 31754ce2e25056c0bbf6599c49059d2778e9109c Mon Sep 17 00:00:00 2001 From: Pavel Tsynk <36221942+TsynkPavel@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:51:11 +0700 Subject: [PATCH 378/410] Fixed setting JSONCPP_USE_SECURE_MEMORY definition (#1479) * Fixed setting JSONCPP_USE_SECURE_MEMORY definition * fix indent * Fix passing from command line * simplified definition --------- Co-authored-by: Jordan Bayles --- CMakeLists.txt | 4 +++- include/json/version.h | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8920544a3..ac0a8eda2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,7 +103,9 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") endif() -set(JSONCPP_USE_SECURE_MEMORY "0" CACHE STRING "-D...=1 to use memory-wiping allocator for STL") +if(JSONCPP_USE_SECURE_MEMORY) + add_definitions("-DJSONCPP_USE_SECURE_MEMORY=1") +endif() configure_file("${PROJECT_SOURCE_DIR}/version.in" "${PROJECT_BINARY_DIR}/version" diff --git a/include/json/version.h b/include/json/version.h index e931d0383..9e9541191 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -18,10 +18,9 @@ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ (JSONCPP_VERSION_PATCH << 8)) -#ifdef JSONCPP_USING_SECURE_MEMORY -#undef JSONCPP_USING_SECURE_MEMORY -#endif +#if !defined(JSONCPP_USE_SECURE_MEMORY) #define JSONCPP_USING_SECURE_MEMORY 0 +#endif // If non-zero, the library zeroes any memory that it has allocated before // it frees its memory. From 742c645ab31088f95edd112ffc65eca839cdf8ff Mon Sep 17 00:00:00 2001 From: Kapandaria Date: Tue, 10 Sep 2024 04:51:35 +0300 Subject: [PATCH 379/410] Update readFromString.cpp (#1477) Print the error to screen Co-authored-by: Jordan Bayles --- example/readFromString/readFromString.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/readFromString/readFromString.cpp b/example/readFromString/readFromString.cpp index 0b29a4e86..878f9eb92 100644 --- a/example/readFromString/readFromString.cpp +++ b/example/readFromString/readFromString.cpp @@ -25,7 +25,7 @@ int main() { const std::unique_ptr reader(builder.newCharReader()); if (!reader->parse(rawJson.c_str(), rawJson.c_str() + rawJsonLength, &root, &err)) { - std::cout << "error" << std::endl; + std::cout << "error: " << err << std::endl; return EXIT_FAILURE; } } From 62f7f3efe650dde5f6075a8dcecbfe358ba530e8 Mon Sep 17 00:00:00 2001 From: Pedro Kaj Kjellerup Nacht Date: Mon, 9 Sep 2024 22:53:23 -0300 Subject: [PATCH 380/410] Add security policy (#1484) Signed-off-by: Pedro Kaj Kjellerup Nacht --- SECURITY.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..67af8830b --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +If you have discovered a security vulnerability in this project, please report it +privately. **Do not disclose it as a public issue.** This gives us time to work with you +to fix the issue before public exposure, reducing the chance that the exploit will be +used before a patch is released. + +Please submit the report by filling out +[this form](https://github.com/open-source-parsers/jsoncpp/security/advisories/new). + +Please provide the following information in your report: + +- A description of the vulnerability and its impact +- How to reproduce the issue + +This project is maintained by volunteers on a reasonable-effort basis. As such, +we ask that you give us 90 days to work on a fix before public exposure. From a4a083c30751a178b7cdfe1bee685d0ec1c2ed28 Mon Sep 17 00:00:00 2001 From: SpaceIm <30052553+SpaceIm@users.noreply.github.com> Date: Tue, 10 Sep 2024 03:57:51 +0200 Subject: [PATCH 381/410] remove ccache micro management (#1448) Co-authored-by: Jordan Bayles --- CMakeLists.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac0a8eda2..a37e726f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,16 +54,6 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -# --------------------------------------------------------------------------- -# use ccache if found, has to be done before project() -# --------------------------------------------------------------------------- -find_program(CCACHE_EXECUTABLE "ccache" HINTS /usr/local/bin /opt/local/bin) -if(CCACHE_EXECUTABLE) - message(STATUS "use ccache") - set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE) - set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE PATH "ccache" FORCE) -endif() - project(jsoncpp # Note: version must be updated in three places when doing a release. This # annoying process ensures that amalgamate, CMake, and meson all report the From d791737ccd74beb4c6bf3f0fa499db74c2791192 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 19:05:11 -0700 Subject: [PATCH 382/410] Create cmake.yml (#1563) * Create cmake.yml * Update cmake.yml * Update cmake.yml --- .github/workflows/cmake.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/cmake.yml diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..675493b8f --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,18 @@ +name: cmake +on: [push] +jobs: + publish: + runs-on: ${{ matrix.os }} + + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + steps: + - name: checkout project + uses: actions/checkout@v4 + + - name: build project + uses: threeal/cmake-action@v2.0.0 + From d13801e83239924c281119316aefb8f611d9bfd0 Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 19:06:30 -0700 Subject: [PATCH 383/410] Update meson.yml (#1564) --- .github/workflows/meson.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/meson.yml b/.github/workflows/meson.yml index 48d496c73..22fe32f72 100644 --- a/.github/workflows/meson.yml +++ b/.github/workflows/meson.yml @@ -3,7 +3,7 @@ run-name: update pushed to ${{ github.ref }} on: [check_run, push, pull_request] jobs: - publish: + meson-publish: runs-on: ${{ matrix.os }} strategy: @@ -32,7 +32,7 @@ jobs: ninja-version: 1.11.1.1 action: test - coverage: + meson-coverage: runs-on: ubuntu-latest steps: From 8d1ea7054f4a0984fc84e406f9253b9cafacd64a Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Mon, 9 Sep 2024 19:07:04 -0700 Subject: [PATCH 384/410] Update cmake.yml --- .github/workflows/cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 675493b8f..91f387a50 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,7 +1,7 @@ name: cmake -on: [push] +on: [check_run, push, pull_request] jobs: - publish: + cmake-publish: runs-on: ${{ matrix.os }} strategy: From fdb529bd0613308591352ac1d4e765c4d33710c9 Mon Sep 17 00:00:00 2001 From: jedav Date: Mon, 9 Sep 2024 19:53:56 -0700 Subject: [PATCH 385/410] Move removeIndex's result instead of copying (#1516) Currently removeIndex copies the removed value into removed and then destructs the original, which can cause significant performance overhead. Co-authored-by: Jordan Bayles --- src/lib_json/json_value.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 26cd843cc..a5e2dd8e4 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1205,7 +1205,7 @@ bool Value::removeIndex(ArrayIndex index, Value* removed) { return false; } if (removed) - *removed = it->second; + *removed = std::move(it->second); ArrayIndex oldSize = size(); // shift left all items left, into the place of the "removed" for (ArrayIndex i = index; i < (oldSize - 1); ++i) { From 2072e2b4e394f90ca9cbea32db53231900c01618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20M=C3=BCller?= <34514239+appgurueu@users.noreply.github.com> Date: Tue, 10 Sep 2024 04:56:37 +0200 Subject: [PATCH 386/410] Use current source / binary dir when assuring out of source builds (#1527) Co-authored-by: Jordan Bayles --- include/PreventInSourceBuilds.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/PreventInSourceBuilds.cmake b/include/PreventInSourceBuilds.cmake index 7ddda546a..be5d0dd41 100644 --- a/include/PreventInSourceBuilds.cmake +++ b/include/PreventInSourceBuilds.cmake @@ -2,8 +2,8 @@ # This function will prevent in-source builds function(AssureOutOfSourceBuilds) # make sure the user doesn't play dirty with symlinks - get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) - get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) + get_filename_component(srcdir "${CMAKE_CURRENT_SOURCE_DIR}" REALPATH) + get_filename_component(bindir "${CMAKE_CURRENT_BINARY_DIR}" REALPATH) # disallow in-source builds if("${srcdir}" STREQUAL "${bindir}") From 48d2e106a71b91a1259127ae0ca4d759e11ea890 Mon Sep 17 00:00:00 2001 From: Bartosz Brachaczek Date: Tue, 10 Sep 2024 05:00:06 +0200 Subject: [PATCH 387/410] Opportunistically take advantage of C++20 move-in/out-of stringstream (#1457) * Opportunistically take advantage of C++20 move-out-of stringstream * Opportunistically take advantage of C++20 move-in/out-of stringstream --------- Co-authored-by: Jordan Bayles --- src/lib_json/json_reader.cpp | 8 +++----- src/lib_json/json_writer.cpp | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 4ab4dffd3..8ef29f07c 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -587,8 +587,7 @@ bool Reader::decodeDouble(Token& token) { bool Reader::decodeDouble(Token& token, Value& decoded) { double value = 0; - String buffer(token.start_, token.end_); - IStringStream is(buffer); + IStringStream is(String(token.start_, token.end_)); if (!(is >> value)) { if (value == std::numeric_limits::max()) value = std::numeric_limits::infinity(); @@ -1622,8 +1621,7 @@ bool OurReader::decodeDouble(Token& token) { bool OurReader::decodeDouble(Token& token, Value& decoded) { double value = 0; - const String buffer(token.start_, token.end_); - IStringStream is(buffer); + IStringStream is(String(token.start_, token.end_)); if (!(is >> value)) { if (value == std::numeric_limits::max()) value = std::numeric_limits::infinity(); @@ -1981,7 +1979,7 @@ bool parseFromStream(CharReader::Factory const& fact, IStream& sin, Value* root, String* errs) { OStringStream ssin; ssin << sin.rdbuf(); - String doc = ssin.str(); + String doc = std::move(ssin).str(); char const* begin = doc.data(); char const* end = begin + doc.size(); // Note that we do not actually need a null-terminator. diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index 5bb5dd117..ee45c43ba 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -1251,7 +1251,7 @@ String writeString(StreamWriter::Factory const& factory, Value const& root) { OStringStream sout; StreamWriterPtr const writer(factory.newStreamWriter()); writer->write(root, &sout); - return sout.str(); + return std::move(sout).str(); } OStream& operator<<(OStream& sout, Value const& root) { From fa0dff18fdef3dc7cd0ab0376a2aa19f878dbbc2 Mon Sep 17 00:00:00 2001 From: Roelof Oomen Date: Tue, 10 Sep 2024 05:02:24 +0200 Subject: [PATCH 388/410] Protect target JsonCpp::JsonCpp against multi-include (#1435) * Protect target JsonCpp::JsonCpp against multi-include Fixes #1356 * Simplify (@BillyDonahue) --------- Co-authored-by: Jordan Bayles --- jsoncpp-namespaced-targets.cmake | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/jsoncpp-namespaced-targets.cmake b/jsoncpp-namespaced-targets.cmake index ac1504e00..70a79ee7f 100644 --- a/jsoncpp-namespaced-targets.cmake +++ b/jsoncpp-namespaced-targets.cmake @@ -1,7 +1,9 @@ -if (TARGET jsoncpp_static) - add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) - set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static") -elseif (TARGET jsoncpp_lib) - add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) - set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib") -endif () \ No newline at end of file +if (NOT TARGET JsonCpp::JsonCpp) + if (TARGET jsoncpp_static) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_static") + elseif (TARGET jsoncpp_lib) + add_library(JsonCpp::JsonCpp INTERFACE IMPORTED) + set_target_properties(JsonCpp::JsonCpp PROPERTIES INTERFACE_LINK_LIBRARIES "jsoncpp_lib") + endif () +endif () From f4590227862e62264b98b88fd8c82558002f9df7 Mon Sep 17 00:00:00 2001 From: matthieugleg <156894466+matthieugleg@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:06:22 +0200 Subject: [PATCH 389/410] Update CMakeLists.txt (#1528) Remove build directory from include Co-authored-by: Jordan Bayles --- src/lib_json/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index ce8100b29..152635348 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -132,7 +132,6 @@ if(BUILD_SHARED_LIBS) target_include_directories(${SHARED_LIB} PUBLIC $ $ - $ ) list(APPEND CMAKE_TARGETS ${SHARED_LIB}) @@ -166,7 +165,6 @@ if(BUILD_STATIC_LIBS) target_include_directories(${STATIC_LIB} PUBLIC $ $ - $ ) list(APPEND CMAKE_TARGETS ${STATIC_LIB}) @@ -193,7 +191,6 @@ if(BUILD_OBJECT_LIBS) target_include_directories(${OBJECT_LIB} PUBLIC $ $ - $ ) list(APPEND CMAKE_TARGETS ${OBJECT_LIB}) From 4b1bd4405e0d5ebfcc6252f0246e28d56290611e Mon Sep 17 00:00:00 2001 From: Woodrow Douglass Date: Mon, 9 Sep 2024 23:08:12 -0400 Subject: [PATCH 390/410] Create a jsoncppConfig.cmake file, even if building under meson (#1486) * Create a jsoncppConfig.cmake file, even if building under meson * Hardcode many fewer things in the meson-generated cmake files * use join_paths for constructing paths in the output Config.cmake --------- Co-authored-by: Jordan Bayles --- jsoncppConfig.cmake.meson.in | 8 ++++++++ meson.build | 39 +++++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 jsoncppConfig.cmake.meson.in diff --git a/jsoncppConfig.cmake.meson.in b/jsoncppConfig.cmake.meson.in new file mode 100644 index 000000000..0f4866d6d --- /dev/null +++ b/jsoncppConfig.cmake.meson.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +@MESON_SHARED_TARGET@ +@MESON_STATIC_TARGET@ + +include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-namespaced-targets.cmake" ) + +check_required_components(JsonCpp) diff --git a/meson.build b/meson.build index fb2b47cd9..80703618f 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ project( 'cpp_std=c++11', 'warning_level=1'], license : 'Public Domain', - meson_version : '>= 0.49.0') + meson_version : '>= 0.54.0') jsoncpp_headers = files([ @@ -62,6 +62,43 @@ import('pkgconfig').generate( filebase : 'jsoncpp', description : 'A C++ library for interacting with JSON') +cmakeconf = configuration_data() +cmakeconf.set('MESON_LIB_DIR', get_option('libdir')) +cmakeconf.set('MESON_INCLUDE_DIR', get_option('includedir')) + +fs = import('fs') +if get_option('default_library') == 'shared' + shared_name = fs.name(jsoncpp_lib.full_path()) +endif +if get_option('default_library') == 'static' + static_name = fs.name(jsoncpp_lib.full_path()) +endif +if get_option('default_library') == 'both' + shared_name = fs.name(jsoncpp_lib.get_shared_lib().full_path()) + static_name = fs.name(jsoncpp_lib.get_static_lib().full_path()) +endif + +if get_option('default_library') == 'shared' or get_option('default_library') == 'both' + cmakeconf.set('MESON_SHARED_TARGET', ''' +add_library(jsoncpp_lib IMPORTED SHARED) +set_target_properties(jsoncpp_lib PROPERTIES + IMPORTED_LOCATION "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('libdir'), shared_name) + '''" + INTERFACE_INCLUDE_DIRECTORIES "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('includedir')) + '")') +endif +if get_option('default_library') == 'static' or get_option('default_library') == 'both' + cmakeconf.set('MESON_STATIC_TARGET', ''' +add_library(jsoncpp_static IMPORTED STATIC) +set_target_properties(jsoncpp_static PROPERTIES + IMPORTED_LOCATION "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('libdir'), static_name) + '''" + INTERFACE_INCLUDE_DIRECTORIES "''' + join_paths('${PACKAGE_PREFIX_DIR}', get_option('includedir')) + '")') +endif + +import('cmake').configure_package_config_file( + name: 'jsoncpp', + input: 'jsoncppConfig.cmake.meson.in', + configuration: cmakeconf) +install_data('jsoncpp-namespaced-targets.cmake', install_dir : join_paths(get_option('libdir'), 'cmake', jsoncpp_lib.name())) + # for libraries bundling jsoncpp jsoncpp_dep = declare_dependency( include_directories : jsoncpp_include_directories, From 162ead383d1fc920a01b2f333e6e69fa089c2541 Mon Sep 17 00:00:00 2001 From: Kerem TAN <56820099+KeremTAN@users.noreply.github.com> Date: Tue, 10 Sep 2024 06:08:55 +0300 Subject: [PATCH 391/410] include/json/value.h is changed (#1462) Co-authored-by: Jordan Bayles --- include/json/value.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 120dea890..f1232c47f 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -3,8 +3,8 @@ // recognized in your jurisdiction. // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE -#ifndef JSON_H_INCLUDED -#define JSON_H_INCLUDED +#ifndef JSON_VALUE_H_INCLUDED +#define JSON_VALUE_H_INCLUDED #if !defined(JSON_IS_AMALGAMATION) #include "forwards.h" From 99e8ca69b129ff0b65bded458404820c6a35d898 Mon Sep 17 00:00:00 2001 From: Rudi Heitbaum Date: Tue, 10 Sep 2024 13:09:10 +1000 Subject: [PATCH 392/410] meson.build: fix the version number (#1432) Co-authored-by: Jordan Bayles --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 80703618f..e6ba08c47 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ project( # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - version : '1.9.4', + version : '1.9.5', default_options : [ 'buildtype=release', 'cpp_std=c++11', From 3aa1192a0071ba640f249566c1d4ba2cf391a21c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 10 Sep 2024 05:11:44 +0200 Subject: [PATCH 393/410] Introduce CharReaderBuilder::ecma404Mode (#1333) * Introduce CharReaderBuilder::ecma404Mode * Bump micro version --------- Co-authored-by: Jordan Bayles Co-authored-by: Billy Donahue Co-authored-by: Jordan Bayles --- CMakeLists.txt | 4 ++-- include/json/reader.h | 6 ++++++ include/json/version.h | 4 ++-- meson.build | 4 ++-- src/lib_json/json_reader.cpp | 16 ++++++++++++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a37e726f7..f11425c08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,11 +62,11 @@ project(jsoncpp # 2. ./include/json/version.h # 3. ./CMakeLists.txt # IMPORTANT: also update the PROJECT_SOVERSION!! - VERSION 1.9.5 # [.[.[.]]] + VERSION 1.9.6 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -set(PROJECT_SOVERSION 25) +set(PROJECT_SOVERSION 26) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake) diff --git a/include/json/reader.h b/include/json/reader.h index 38b9360cf..d745378fc 100644 --- a/include/json/reader.h +++ b/include/json/reader.h @@ -385,6 +385,12 @@ class JSON_API CharReaderBuilder : public CharReader::Factory { * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode */ static void strictMode(Json::Value* settings); + /** ECMA-404 mode. + * \pre 'settings' != NULL (but Json::null is fine) + * \remark Defaults: + * \snippet src/lib_json/json_reader.cpp CharReaderBuilderECMA404Mode + */ + static void ecma404Mode(Json::Value* settings); }; /** Consume entire stream and use its begin/end. diff --git a/include/json/version.h b/include/json/version.h index 9e9541191..38faedf11 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.5" +#define JSONCPP_VERSION_STRING "1.9.6" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 5 +#define JSONCPP_VERSION_PATCH 6 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/meson.build b/meson.build index e6ba08c47..561b41ce7 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ project( # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - version : '1.9.5', + version : '1.9.6', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -50,7 +50,7 @@ jsoncpp_lib = library( 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp', ]), - soversion : 25, + soversion : 26, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 8ef29f07c..10c97aecb 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -1961,6 +1961,22 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) { (*settings)["skipBom"] = true; //! [CharReaderBuilderDefaults] } +// static +void CharReaderBuilder::ecma404Mode(Json::Value* settings) { + //! [CharReaderBuilderECMA404Mode] + (*settings)["allowComments"] = false; + (*settings)["allowTrailingCommas"] = false; + (*settings)["strictRoot"] = false; + (*settings)["allowDroppedNullPlaceholders"] = false; + (*settings)["allowNumericKeys"] = false; + (*settings)["allowSingleQuotes"] = false; + (*settings)["stackLimit"] = 1000; + (*settings)["failIfExtra"] = true; + (*settings)["rejectDupKeys"] = false; + (*settings)["allowSpecialFloats"] = false; + (*settings)["skipBom"] = false; + //! [CharReaderBuilderECMA404Mode] +} std::vector CharReader::getStructuredErrors() const { From 2067f66d662ef0925733ba95595a3cf988a2d32d Mon Sep 17 00:00:00 2001 From: zeroxia Date: Tue, 10 Sep 2024 11:14:17 +0800 Subject: [PATCH 394/410] cmake export configuration: allow repeating find_package(jsoncpp) calls (#1491) In jsoncpp-namspaced-targets.cmake, it creates JsonCpp::JsonCpp imported library without first checking whether it was already created by former call to find_package(JsonCpp). As CMake allows repeated call to find_package(), the error of "another target with the same name already exists" should be fixed. Co-authored-by: xiazuoling.xzl Co-authored-by: Jordan Bayles From 7f36cdb3ead60cdc77ec4e6a104bd2f653730b30 Mon Sep 17 00:00:00 2001 From: Timofey <45315126+petukhovtd@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:14:36 +0700 Subject: [PATCH 395/410] Added Value::find with String key (#1467) * Added Value::find with String key * Fix codestyle --------- Co-authored-by: Jordan Bayles Co-authored-by: Petukhov Timofey --- include/json/value.h | 3 +++ src/lib_json/json_value.cpp | 5 ++++- src/test_lib_json/main.cpp | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/json/value.h b/include/json/value.h index f1232c47f..c8e1aae2e 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -513,6 +513,9 @@ class JSON_API Value { /// and operator[]const /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 Value const* find(char const* begin, char const* end) const; + /// Most general and efficient version of isMember()const, get()const, + /// and operator[]const + Value const* find(const String& key) const; /// Most general and efficient version of object-mutators. /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index a5e2dd8e4..5bd8d9a27 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1092,6 +1092,9 @@ Value const* Value::find(char const* begin, char const* end) const { return nullptr; return &(*it).second; } +Value const* Value::find(const String& key) const { + return find(key.data(), key.data() + key.length()); +} Value* Value::demand(char const* begin, char const* end) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::demand(begin, end): requires " @@ -1105,7 +1108,7 @@ const Value& Value::operator[](const char* key) const { return *found; } Value const& Value::operator[](const String& key) const { - Value const* found = find(key.data(), key.data() + key.length()); + Value const* found = find(key); if (!found) return nullSingleton(); return *found; diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index fa41d19ed..55ab2241d 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -220,11 +220,20 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { JSONTEST_ASSERT(foundId != nullptr); JSONTEST_ASSERT_EQUAL(Json::Value(1234), *foundId); + const std::string stringIdKey = "id"; + const Json::Value* stringFoundId = object1_.find(stringIdKey); + JSONTEST_ASSERT(stringFoundId != nullptr); + JSONTEST_ASSERT_EQUAL(Json::Value(1234), *stringFoundId); + const char unknownIdKey[] = "unknown id"; const Json::Value* foundUnknownId = object1_.find(unknownIdKey, unknownIdKey + strlen(unknownIdKey)); JSONTEST_ASSERT_EQUAL(nullptr, foundUnknownId); + const std::string stringUnknownIdKey = "unknown id"; + const Json::Value* stringFoundUnknownId = object1_.find(stringUnknownIdKey); + JSONTEST_ASSERT_EQUAL(nullptr, stringFoundUnknownId); + // Access through demand() const char yetAnotherIdKey[] = "yet another id"; const Json::Value* foundYetAnotherId = From 89e2973c754a9c02a49974d839779b151e95afd6 Mon Sep 17 00:00:00 2001 From: Scotty1701 <37419120+Scotty1701@users.noreply.github.com> Date: Mon, 9 Sep 2024 20:18:29 -0700 Subject: [PATCH 396/410] Don't use build dir build interfaces (#1419) Do not export a location in the build directory as a build interface. This location is not created until the build step is run and can interfere with the CMake configuration step if including in another project. Co-authored-by: Jordan Bayles From 76ff1db84d5f3b7515eb3934126b78d178057af9 Mon Sep 17 00:00:00 2001 From: Paolo Monteverde Date: Thu, 12 Sep 2024 01:47:59 +0200 Subject: [PATCH 397/410] Fixes PreventInSourceBuilds.cmake to work with add_subdirectory (#1383) Co-authored-by: Jordan Bayles From 54fc4e28ed98ecaa8ce79d39d72bc9e3f8b35c13 Mon Sep 17 00:00:00 2001 From: YaalLek <140312422+YaalLek@users.noreply.github.com> Date: Thu, 12 Sep 2024 02:53:22 +0300 Subject: [PATCH 398/410] json_value.cpp bug in the edges of uint/int (#1519) * json_value.cpp bug in the edges of uint/int Fixing bug of sending a number that is a bit bigger than max it returns 0: https://stackoverflow.com/questions/77261400/jsoncpp-do-not-protect-from-uint64-overflow-and-have-weird-behavior/77261716#77261716 * Update json_value.cpp Fixing bug of sending a number that is a bit bigger than max it returns 0: https://stackoverflow.com/questions/77261400/jsoncpp-do-not-protect-from-uint64-overflow-and-have-weird-behavior/77261716#77261716 * Update test cases * json_value.cpp bug in the edges of uint/int Fixing bug of sending a number that is a bit bigger than max it returns 0: https://stackoverflow.com/questions/77261400/jsoncpp-do-not-protect-from-uint64-overflow-and-have-weird-behavior/77261716#77261716 * Run clang tidy --------- Co-authored-by: Jordan Bayles --- src/lib_json/json_value.cpp | 25 ++++++++++++++++++++----- src/test_lib_json/main.cpp | 8 ++------ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 5bd8d9a27..72ba8e59f 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -87,7 +87,8 @@ template static inline bool InRange(double d, T min, U max) { // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn - return d >= static_cast(min) && d <= static_cast(max); + return d >= static_cast(min) && d <= static_cast(max) && + !(static_cast(d) == min && d != static_cast(min)); } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) static inline double integerToDouble(Json::UInt64 value) { @@ -101,7 +102,8 @@ template static inline double integerToDouble(T value) { template static inline bool InRange(double d, T min, U max) { - return d >= integerToDouble(min) && d <= integerToDouble(max); + return d >= integerToDouble(min) && d <= integerToDouble(max) && + !(static_cast(d) == min && d != integerToDouble(min)); } #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) @@ -705,6 +707,11 @@ Value::Int64 Value::asInt64() const { JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); return Int64(value_.uint_); case realValue: + // If the double value is in proximity to minInt64, it will be rounded to + // minInt64. The correct value in this scenario is indeterminable + JSON_ASSERT_MESSAGE( + value_.real_ != minInt64, + "Double value is minInt64, precise value cannot be determined"); JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), "double out of Int64 range"); return Int64(value_.real_); @@ -1311,8 +1318,12 @@ bool Value::isInt64() const { // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a // double, so double(maxInt64) will be rounded up to 2^63. Therefore we // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && - value_.real_ < double(maxInt64) && IsIntegral(value_.real_); + // minInt64 is -2^63 which can be represented as a double, but since double + // values in its proximity are also rounded to -2^63, we require the value + // to be strictly greater than the limit to avoid returning 'true' for + // values that are not in the range + return value_.real_ > double(minInt64) && value_.real_ < double(maxInt64) && + IsIntegral(value_.real_); default: break; } @@ -1350,7 +1361,11 @@ bool Value::isIntegral() const { // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && + // minInt64 is -2^63 which can be represented as a double, but since double + // values in its proximity are also rounded to -2^63, we require the value + // to be strictly greater than the limit to avoid returning 'true' for + // values that are not in the range + return value_.real_ > double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); #else return value_.real_ >= minInt && value_.real_ <= maxUInt && diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 55ab2241d..5a0ce01ce 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -1191,15 +1191,13 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, integers) { JSONTEST_ASSERT_EQUAL(true, val.asBool()); JSONTEST_ASSERT_STRING_EQUAL("-9223372036854775808", val.asString()); - // int64 min (floating point constructor). Note that kint64min *is* exactly - // representable as a double. + // int64 min (floating point constructor). Since double values in proximity of + // kint64min are rounded to kint64min, we don't check for conversion to int64. val = Json::Value(double(kint64min)); JSONTEST_ASSERT_EQUAL(Json::realValue, val.type()); checks = IsCheck(); - checks.isInt64_ = true; - checks.isIntegral_ = true; checks.isDouble_ = true; checks.isNumeric_ = true; JSONTEST_ASSERT_PRED(checkIs(val, checks)); @@ -1208,8 +1206,6 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, integers) { JSONTEST_ASSERT(!val.isConvertibleTo(Json::intValue)); JSONTEST_ASSERT(!val.isConvertibleTo(Json::uintValue)); - JSONTEST_ASSERT_EQUAL(kint64min, val.asInt64()); - JSONTEST_ASSERT_EQUAL(kint64min, val.asLargestInt()); JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asDouble()); JSONTEST_ASSERT_EQUAL(-9223372036854775808.0, val.asFloat()); JSONTEST_ASSERT_EQUAL(true, val.asBool()); From 871f0cc43bbd9ccf4e4a67df5a7751f53b49d99e Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Wed, 11 Sep 2024 17:01:27 -0700 Subject: [PATCH 399/410] Release 1.9.6 and move versions to 1.9.7 (#1566) * Release 1.9.6 and move versions to 1.9.7 This patch updates versions to be for version 1.9.7. * remove log.txt --- CMakeLists.txt | 4 ++-- include/json/version.h | 4 ++-- meson.build | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f11425c08..c958250e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,11 +62,11 @@ project(jsoncpp # 2. ./include/json/version.h # 3. ./CMakeLists.txt # IMPORTANT: also update the PROJECT_SOVERSION!! - VERSION 1.9.6 # [.[.[.]]] + VERSION 1.9.7 # [.[.[.]]] LANGUAGES CXX) message(STATUS "JsonCpp Version: ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") -set(PROJECT_SOVERSION 26) +set(PROJECT_SOVERSION 27) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInSourceBuilds.cmake) include(${CMAKE_CURRENT_SOURCE_DIR}/include/PreventInBuildInstalls.cmake) diff --git a/include/json/version.h b/include/json/version.h index 38faedf11..25745cce1 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -9,10 +9,10 @@ // 3. /CMakeLists.txt // IMPORTANT: also update the SOVERSION!! -#define JSONCPP_VERSION_STRING "1.9.6" +#define JSONCPP_VERSION_STRING "1.9.7" #define JSONCPP_VERSION_MAJOR 1 #define JSONCPP_VERSION_MINOR 9 -#define JSONCPP_VERSION_PATCH 6 +#define JSONCPP_VERSION_PATCH 7 #define JSONCPP_VERSION_QUALIFIER #define JSONCPP_VERSION_HEXA \ ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \ diff --git a/meson.build b/meson.build index 561b41ce7..8e8d57e3c 100644 --- a/meson.build +++ b/meson.build @@ -9,7 +9,7 @@ project( # 2. /include/json/version.h # 3. /CMakeLists.txt # IMPORTANT: also update the SOVERSION!! - version : '1.9.6', + version : '1.9.7', default_options : [ 'buildtype=release', 'cpp_std=c++11', @@ -50,7 +50,7 @@ jsoncpp_lib = library( 'src/lib_json/json_value.cpp', 'src/lib_json/json_writer.cpp', ]), - soversion : 26, + soversion : 27, install : true, include_directories : jsoncpp_include_directories, cpp_args: dll_export_flag) From 07e3d1b076aff1700daf188cd8a00b25b9712af9 Mon Sep 17 00:00:00 2001 From: Pavel Tsynk <36221942+TsynkPavel@users.noreply.github.com> Date: Thu, 12 Sep 2024 07:43:25 +0700 Subject: [PATCH 400/410] Fix deallocate for working on old compiers (#1478) Co-authored-by: Jordan Bayles --- CMakeLists.txt | 6 ++++++ include/json/allocator.h | 11 ++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c958250e7..6104c5ce5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,12 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Executable/dll output dir.") endif() +include(CheckFunctionExists) +check_function_exists(memset_s HAVE_MEMSET_S) +if(HAVE_MEMSET_S) + add_definitions("-DHAVE_MEMSET_S=1") +endif() + if(JSONCPP_USE_SECURE_MEMORY) add_definitions("-DJSONCPP_USE_SECURE_MEMORY=1") endif() diff --git a/include/json/allocator.h b/include/json/allocator.h index f4fcc1c68..459c34c61 100644 --- a/include/json/allocator.h +++ b/include/json/allocator.h @@ -6,6 +6,7 @@ #ifndef JSON_ALLOCATOR_H_INCLUDED #define JSON_ALLOCATOR_H_INCLUDED +#include #include #include @@ -38,8 +39,16 @@ template class SecureAllocator { * The memory block is filled with zeroes before being released. */ void deallocate(pointer p, size_type n) { - // memset_s is used because memset may be optimized away by the compiler + // These constructs will not be removed by the compiler during optimization, + // unlike memset. +#if defined(HAVE_MEMSET_S) memset_s(p, n * sizeof(T), 0, n * sizeof(T)); +#elif defined(_WIN32) + RtlSecureZeroMemory(p, n * sizeof(T)); +#else + std::fill_n(reinterpret_cast(p), n, 0); +#endif + // free using "global operator delete" ::operator delete(p); } From 8214f717e7c7d361f002b6c3d1b1086ddd096315 Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Thu, 12 Sep 2024 19:58:39 +0200 Subject: [PATCH 401/410] Fix typo in JSONCPP_USE_SECURE_MEMORY vs JSONCPP_USING_SECURE_MEMORY (#1567) --- include/json/config.h | 2 +- include/json/value.h | 2 +- include/json/version.h | 2 +- src/lib_json/json_value.cpp | 8 ++++---- src/test_lib_json/jsontest.cpp | 2 +- src/test_lib_json/jsontest.h | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/json/config.h b/include/json/config.h index 6359273a2..7f6e2431b 100644 --- a/include/json/config.h +++ b/include/json/config.h @@ -127,7 +127,7 @@ using LargestUInt = UInt64; template using Allocator = - typename std::conditional, + typename std::conditional, std::allocator>::type; using String = std::basic_string, Allocator>; using IStringStream = diff --git a/include/json/value.h b/include/json/value.h index c8e1aae2e..073ed30d9 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -375,7 +375,7 @@ class JSON_API Value { int compare(const Value& other) const; const char* asCString() const; ///< Embedded zeroes could cause you trouble! -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY unsigned getCStringLength() const; // Allows you to understand the length of // the CString #endif diff --git a/include/json/version.h b/include/json/version.h index 25745cce1..42e8780a3 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -19,7 +19,7 @@ (JSONCPP_VERSION_PATCH << 8)) #if !defined(JSONCPP_USE_SECURE_MEMORY) -#define JSONCPP_USING_SECURE_MEMORY 0 +#define JSONCPP_USE_SECURE_MEMORY 0 #endif // If non-zero, the library zeroes any memory that it has allocated before // it frees its memory. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 72ba8e59f..e53643a6d 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -165,7 +165,7 @@ inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, /** Free the string duplicated by * duplicateStringValue()/duplicateAndPrefixStringValue(). */ -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { unsigned length = 0; char const* valueDecoded; @@ -180,10 +180,10 @@ static inline void releaseStringValue(char* value, unsigned length) { memset(value, 0, size); free(value); } -#else // !JSONCPP_USING_SECURE_MEMORY +#else // !JSONCPP_USE_SECURE_MEMORY static inline void releasePrefixedStringValue(char* value) { free(value); } static inline void releaseStringValue(char* value, unsigned) { free(value); } -#endif // JSONCPP_USING_SECURE_MEMORY +#endif // JSONCPP_USE_SECURE_MEMORY } // namespace Json @@ -601,7 +601,7 @@ const char* Value::asCString() const { return this_str; } -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY unsigned Value::getCStringLength() const { JSON_ASSERT_MESSAGE(type() == stringValue, "in Json::Value::asCString(): requires stringValue"); diff --git a/src/test_lib_json/jsontest.cpp b/src/test_lib_json/jsontest.cpp index 0b7d12b97..508067a77 100644 --- a/src/test_lib_json/jsontest.cpp +++ b/src/test_lib_json/jsontest.cpp @@ -410,7 +410,7 @@ Json::String ToJsonString(const char* toConvert) { Json::String ToJsonString(Json::String in) { return in; } -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY Json::String ToJsonString(std::string in) { return Json::String(in.data(), in.data() + in.length()); } diff --git a/src/test_lib_json/jsontest.h b/src/test_lib_json/jsontest.h index a2385fa3f..69e3264b9 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -185,7 +185,7 @@ TestResult& checkEqual(TestResult& result, T expected, U actual, Json::String ToJsonString(const char* toConvert); Json::String ToJsonString(Json::String in); -#if JSONCPP_USING_SECURE_MEMORY +#if JSONCPP_USE_SECURE_MEMORY Json::String ToJsonString(std::string in); #endif From bd25fc5ea0e14d19e1451632205c8b99ec0b1c09 Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Mon, 30 Sep 2024 18:23:00 -0400 Subject: [PATCH 402/410] fix(build): remove `check_required_components` for meson build (#1570) Signed-off-by: Rui Chen --- jsoncppConfig.cmake.meson.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/jsoncppConfig.cmake.meson.in b/jsoncppConfig.cmake.meson.in index 0f4866d6d..be8852d0c 100644 --- a/jsoncppConfig.cmake.meson.in +++ b/jsoncppConfig.cmake.meson.in @@ -4,5 +4,3 @@ @MESON_STATIC_TARGET@ include ( "${CMAKE_CURRENT_LIST_DIR}/jsoncpp-namespaced-targets.cmake" ) - -check_required_components(JsonCpp) From 2b3815c90d163d34bed75dbc657f9545cb3d382f Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Tue, 3 Dec 2024 08:00:25 +0100 Subject: [PATCH 403/410] the cgi module was removed from Python3.13 (#1578) --- devtools/batchbuild.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/devtools/batchbuild.py b/devtools/batchbuild.py index 0eb0690e8..bf8be48df 100644 --- a/devtools/batchbuild.py +++ b/devtools/batchbuild.py @@ -9,7 +9,7 @@ import string import subprocess import sys -import cgi +import html class BuildDesc: def __init__(self, prepend_envs=None, variables=None, build_type=None, generator=None): @@ -195,12 +195,12 @@ def generate_html_report(html_report_path, builds): for variable in variables: build_types = sorted(build_types_by_variable[variable]) nb_build_type = len(build_types_by_variable[variable]) - th_vars.append('%s' % (nb_build_type, cgi.escape(' '.join(variable)))) + th_vars.append('%s' % (nb_build_type, html.escape(' '.join(variable)))) for build_type in build_types: - th_build_types.append('%s' % cgi.escape(build_type)) + th_build_types.append('%s' % html.escape(build_type)) tr_builds = [] for generator in sorted(builds_by_generator): - tds = [ '%s\n' % cgi.escape(generator) ] + tds = [ '%s\n' % html.escape(generator) ] for variable in variables: build_types = sorted(build_types_by_variable[variable]) for build_type in build_types: From 3f86349128b044598ce9a19c1ef92f2b7f4131bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=BCtzel?= Date: Tue, 3 Dec 2024 08:19:05 +0100 Subject: [PATCH 404/410] Fix name of static library when targeting MinGW. (#1579) Co-authored-by: Jordan Bayles --- src/lib_json/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_json/CMakeLists.txt b/src/lib_json/CMakeLists.txt index 152635348..3037eb020 100644 --- a/src/lib_json/CMakeLists.txt +++ b/src/lib_json/CMakeLists.txt @@ -143,7 +143,7 @@ if(BUILD_STATIC_LIBS) # avoid name clashes on windows as the shared import lib is also named jsoncpp.lib if(NOT DEFINED STATIC_SUFFIX AND BUILD_SHARED_LIBS) - if (WIN32) + if (MSVC OR ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC")) set(STATIC_SUFFIX "_static") else() set(STATIC_SUFFIX "") From dca8a24cf8da1fc61b5cf0422cad03474124196c Mon Sep 17 00:00:00 2001 From: Jens Mertelmeyer Date: Thu, 5 Dec 2024 07:28:16 +0100 Subject: [PATCH 405/410] Fix comparison warnings caused by 54fc4e2 (#1575) Co-authored-by: Jordan Bayles --- src/lib_json/json_value.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index e53643a6d..d9dee50cb 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -684,7 +684,7 @@ Value::UInt Value::asUInt() const { JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); return UInt(value_.uint_); case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0u, maxUInt), "double out of UInt range"); return UInt(value_.real_); case nullValue: @@ -733,7 +733,7 @@ Value::UInt64 Value::asUInt64() const { case uintValue: return UInt64(value_.uint_); case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0u, maxUInt64), "double out of UInt64 range"); return UInt64(value_.real_); case nullValue: @@ -844,7 +844,7 @@ bool Value::isConvertibleTo(ValueType other) const { type() == booleanValue || type() == nullValue; case uintValue: return isUInt() || - (type() == realValue && InRange(value_.real_, 0, maxUInt)) || + (type() == realValue && InRange(value_.real_, 0u, maxUInt)) || type() == booleanValue || type() == nullValue; case realValue: return isNumeric() || type() == booleanValue || type() == nullValue; From 07a8fe6a235a91e9ad9bd69fae25a3ed07162ac0 Mon Sep 17 00:00:00 2001 From: Billy Donahue Date: Fri, 10 Jan 2025 18:17:00 -0500 Subject: [PATCH 406/410] Drop pre-C++11 alternatives (#1593) * Assume C++11 We already assume C++11 elsewhere, so all pre-11 `#ifdef` branches are dead code at this point. Fixes issue #1591 because we can just use `std::isfinite` etc. assume C++11 in json_reader.cpp as well apply clang-format * valueToString: simplify lookup of special float name --- AUTHORS | 2 +- src/lib_json/json_reader.cpp | 11 ----- src/lib_json/json_writer.cpp | 79 ++++-------------------------------- 3 files changed, 9 insertions(+), 83 deletions(-) diff --git a/AUTHORS b/AUTHORS index e1fa0fc3a..7a3def276 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,7 +16,7 @@ Baruch Siach Ben Boeckel Benjamin Knecht Bernd Kuhls -Billy Donahue +Billy Donahue Braden McDorman Brandon Myers Brendan Drew diff --git a/src/lib_json/json_reader.cpp b/src/lib_json/json_reader.cpp index 10c97aecb..5b6299906 100644 --- a/src/lib_json/json_reader.cpp +++ b/src/lib_json/json_reader.cpp @@ -23,13 +23,6 @@ #include #include -#if __cplusplus >= 201103L - -#if !defined(sscanf) -#define sscanf std::sscanf -#endif - -#endif //__cplusplus #if defined(_MSC_VER) #if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) @@ -53,11 +46,7 @@ static size_t const stackLimit_g = namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) using CharReaderPtr = std::unique_ptr; -#else -using CharReaderPtr = std::auto_ptr; -#endif // Implementation of class Features // //////////////////////////////// diff --git a/src/lib_json/json_writer.cpp b/src/lib_json/json_writer.cpp index ee45c43ba..ac14eb11f 100644 --- a/src/lib_json/json_writer.cpp +++ b/src/lib_json/json_writer.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include @@ -17,67 +19,6 @@ #include #include -#if __cplusplus >= 201103L -#include -#include - -#if !defined(isnan) -#define isnan std::isnan -#endif - -#if !defined(isfinite) -#define isfinite std::isfinite -#endif - -#else -#include -#include - -#if defined(_MSC_VER) -#if !defined(isnan) -#include -#define isnan _isnan -#endif - -#if !defined(isfinite) -#include -#define isfinite _finite -#endif - -#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES) -#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 -#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES - -#endif //_MSC_VER - -#if defined(__sun) && defined(__SVR4) // Solaris -#if !defined(isfinite) -#include -#define isfinite finite -#endif -#endif - -#if defined(__hpux) -#if !defined(isfinite) -#if defined(__ia64) && !defined(finite) -#define isfinite(x) \ - ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) -#endif -#endif -#endif - -#if !defined(isnan) -// IEEE standard states that NaN values will not compare to themselves -#define isnan(x) ((x) != (x)) -#endif - -#if !defined(__APPLE__) -#if !defined(isfinite) -#define isfinite finite -#endif -#endif -#endif - #if defined(_MSC_VER) // Disable warning about strdup being deprecated. #pragma warning(disable : 4996) @@ -85,11 +26,7 @@ namespace Json { -#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) using StreamWriterPtr = std::unique_ptr; -#else -using StreamWriterPtr = std::auto_ptr; -#endif String valueToString(LargestInt value) { UIntToStringBuffer buffer; @@ -129,12 +66,12 @@ String valueToString(double value, bool useSpecialFloats, // Print into the buffer. We need not request the alternative representation // that always has a decimal point because JSON doesn't distinguish the // concepts of reals and integers. - if (!isfinite(value)) { - static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"}, - {"null", "-1e+9999", "1e+9999"}}; - return reps[useSpecialFloats ? 0 : 1][isnan(value) ? 0 - : (value < 0) ? 1 - : 2]; + if (!std::isfinite(value)) { + if (std::isnan(value)) + return useSpecialFloats ? "NaN" : "null"; + if (value < 0) + return useSpecialFloats ? "-Infinity" : "-1e+9999"; + return useSpecialFloats ? "Infinity" : "1e+9999"; } String buffer(size_t(36), '\0'); From 60ccc1f5deb671e95d2a6cc761f6d03f3c8ade07 Mon Sep 17 00:00:00 2001 From: evalon32 <34560232+evalon32@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:25:25 -0500 Subject: [PATCH 407/410] feat: support std::string_view in Value API (#1584) This adds direct support for `std::string_view` when available (C++17 and above). The current API can be used with `std::string_view` via the low-level two-pointer methods, but is not ergonomic. E.g., compare: ``` Json::Value node; std::string foo, bar, baz; std::string_view foo_sv, bar_sv, baz_sv; // Efficient & readable: node[foo][bar][baz]; // Less efficient, less readable: node[std::string(foo_sv)][std::string(bar_sv)][std::string(baz_sv)]; // Efficient, but a lot less readable: *node.demand(foo_sv.data(), foo_sv.data() + foo_sv.size()) ->demand(bar_sv.data(), bar_sv.data() + bar_sv.size()) ->demand(baz_sv.data(), baz_sv.data() + baz_sv.size()) // After this change, efficient & readable: node[foo_sv][bar_sv][baz_sv]; ``` * The constructor can take a `std::string_view` parameter. The existing overloads taking `const std::string&` and `const char*` are still necessary to support assignment from those types. * `operator[]`, `get()`, `isMember()` and `removeMember()` take a `std::string_view` parameter. This supersedes the overloads taking `const std::string&` and `const char*`. The overloads taking a pair of pointers (begin, end) are preserved for source compatibility. * `getString()` has an overload with a `std::string_view` output parameter. The one with a pair of pointers is preserved for source compatibility. Signed-off-by: Lev Kandel Co-authored-by: Jordan Bayles --- include/json/value.h | 61 +++++++++++++++++++++++++++---- src/lib_json/json_value.cpp | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 7 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 073ed30d9..307493298 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -39,6 +39,10 @@ #endif #endif +#if __cplusplus >= 201703L +#define JSONCPP_HAS_STRING_VIEW 1 +#endif + #include #include #include @@ -46,6 +50,10 @@ #include #include +#ifdef JSONCPP_HAS_STRING_VIEW +#include +#endif + // Disable warning C4251: : needs to have dll-interface to // be used by... #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) @@ -342,6 +350,9 @@ class JSON_API Value { */ Value(const StaticString& value); Value(const String& value); +#ifdef JSONCPP_HAS_STRING_VIEW + Value(std::string_view value); +#endif Value(bool value); Value(std::nullptr_t ptr) = delete; Value(const Value& other); @@ -384,6 +395,12 @@ class JSON_API Value { * \return false if !string. (Seg-fault if str or end are NULL.) */ bool getString(char const** begin, char const** end) const; +#ifdef JSONCPP_HAS_STRING_VIEW + /** Get string_view of string-value. + * \return false if !string. (Seg-fault if str is NULL.) + */ + bool getString(std::string_view* str) const; +#endif Int asInt() const; UInt asUInt() const; #if defined(JSON_HAS_INT64) @@ -470,6 +487,15 @@ class JSON_API Value { bool insert(ArrayIndex index, const Value& newValue); bool insert(ArrayIndex index, Value&& newValue); +#ifdef JSONCPP_HAS_STRING_VIEW + /// Access an object value by name, create a null member if it does not exist. + /// \param key may contain embedded nulls. + Value& operator[](std::string_view key); + /// Access an object value by name, returns null if there is no member with + /// that name. + /// \param key may contain embedded nulls. + const Value& operator[](std::string_view key) const; +#else /// Access an object value by name, create a null member if it does not exist. /// \note Because of our implementation, keys are limited to 2^30 -1 chars. /// Exceeding that will cause an exception. @@ -484,6 +510,7 @@ class JSON_API Value { /// that name. /// \param key may contain embedded nulls. const Value& operator[](const String& key) const; +#endif /** \brief Access an object value by name, create a null member if it does not * exist. * @@ -497,18 +524,24 @@ class JSON_API Value { * \endcode */ Value& operator[](const StaticString& key); +#ifdef JSONCPP_HAS_STRING_VIEW /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy - Value get(const char* key, const Value& defaultValue) const; + Value get(std::string_view key, const Value& defaultValue) const; +#else /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy - /// \note key may contain embedded nulls. - Value get(const char* begin, const char* end, - const Value& defaultValue) const; + Value get(const char* key, const Value& defaultValue) const; /// Return the member named key if it exist, defaultValue otherwise. /// \note deep copy /// \param key may contain embedded nulls. Value get(const String& key, const Value& defaultValue) const; +#endif + /// Return the member named key if it exist, defaultValue otherwise. + /// \note deep copy + /// \note key may contain embedded nulls. + Value get(const char* begin, const char* end, + const Value& defaultValue) const; /// Most general and efficient version of isMember()const, get()const, /// and operator[]const /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 @@ -525,20 +558,28 @@ class JSON_API Value { /// Do nothing if it did not exist. /// \pre type() is objectValue or nullValue /// \post type() is unchanged +#if JSONCPP_HAS_STRING_VIEW + void removeMember(std::string_view key); +#else void removeMember(const char* key); /// Same as removeMember(const char*) /// \param key may contain embedded nulls. void removeMember(const String& key); - /// Same as removeMember(const char* begin, const char* end, Value* removed), - /// but 'key' is null-terminated. - bool removeMember(const char* key, Value* removed); +#endif /** \brief Remove the named map member. * * Update 'removed' iff removed. * \param key may contain embedded nulls. * \return true iff removed (no exceptions) */ +#if JSONCPP_HAS_STRING_VIEW + bool removeMember(std::string_view key, Value* removed); +#else bool removeMember(String const& key, Value* removed); + /// Same as removeMember(const char* begin, const char* end, Value* removed), + /// but 'key' is null-terminated. + bool removeMember(const char* key, Value* removed); +#endif /// Same as removeMember(String const& key, Value* removed) bool removeMember(const char* begin, const char* end, Value* removed); /** \brief Remove the indexed array element. @@ -549,12 +590,18 @@ class JSON_API Value { */ bool removeIndex(ArrayIndex index, Value* removed); +#ifdef JSONCPP_HAS_STRING_VIEW + /// Return true if the object has a member named key. + /// \param key may contain embedded nulls. + bool isMember(std::string_view key) const; +#else /// Return true if the object has a member named key. /// \note 'key' must be null-terminated. bool isMember(const char* key) const; /// Return true if the object has a member named key. /// \param key may contain embedded nulls. bool isMember(const String& key) const; +#endif /// Same as isMember(String const& key)const bool isMember(const char* begin, const char* end) const; diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index d9dee50cb..527d716f2 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -17,6 +17,10 @@ #include #include +#ifdef JSONCPP_HAS_STRING_VIEW +#include +#endif + // Provide implementation equivalent of std::snprintf for older _MSC compilers #if defined(_MSC_VER) && _MSC_VER < 1900 #include @@ -420,6 +424,14 @@ Value::Value(const String& value) { value.data(), static_cast(value.length())); } +#ifdef JSONCPP_HAS_STRING_VIEW +Value::Value(std::string_view value) { + initBasic(stringValue, true); + value_.string_ = duplicateAndPrefixStringValue( + value.data(), static_cast(value.length())); +} +#endif + Value::Value(const StaticString& value) { initBasic(stringValue); value_.string_ = const_cast(value.c_str()); @@ -627,6 +639,21 @@ bool Value::getString(char const** begin, char const** end) const { return true; } +#ifdef JSONCPP_HAS_STRING_VIEW +bool Value::getString(std::string_view* str) const { + if (type() != stringValue) + return false; + if (value_.string_ == nullptr) + return false; + const char* begin; + unsigned length; + decodePrefixedString(this->isAllocated(), this->value_.string_, &length, + &begin); + *str = std::string_view(begin, length); + return true; +} +#endif + String Value::asString() const { switch (type()) { case nullValue: @@ -1108,6 +1135,17 @@ Value* Value::demand(char const* begin, char const* end) { "objectValue or nullValue"); return &resolveReference(begin, end); } +#ifdef JSONCPP_HAS_STRING_VIEW +const Value& Value::operator[](std::string_view key) const { + Value const* found = find(key.data(), key.data() + key.length()); + if (!found) + return nullSingleton(); + return *found; +} +Value& Value::operator[](std::string_view key) { + return resolveReference(key.data(), key.data() + key.length()); +} +#else const Value& Value::operator[](const char* key) const { Value const* found = find(key, key + strlen(key)); if (!found) @@ -1128,6 +1166,7 @@ Value& Value::operator[](const char* key) { Value& Value::operator[](const String& key) { return resolveReference(key.data(), key.data() + key.length()); } +#endif Value& Value::operator[](const StaticString& key) { return resolveReference(key.c_str()); @@ -1167,12 +1206,18 @@ Value Value::get(char const* begin, char const* end, Value const* found = find(begin, end); return !found ? defaultValue : *found; } +#ifdef JSONCPP_HAS_STRING_VIEW +Value Value::get(std::string_view key, const Value& defaultValue) const { + return get(key.data(), key.data() + key.length(), defaultValue); +} +#else Value Value::get(char const* key, Value const& defaultValue) const { return get(key, key + strlen(key), defaultValue); } Value Value::get(String const& key, Value const& defaultValue) const { return get(key.data(), key.data() + key.length(), defaultValue); } +#endif bool Value::removeMember(const char* begin, const char* end, Value* removed) { if (type() != objectValue) { @@ -1188,12 +1233,31 @@ bool Value::removeMember(const char* begin, const char* end, Value* removed) { value_.map_->erase(it); return true; } +#ifdef JSONCPP_HAS_STRING_VIEW +bool Value::removeMember(std::string_view key, Value* removed) { + return removeMember(key.data(), key.data() + key.length(), removed); +} +#else bool Value::removeMember(const char* key, Value* removed) { return removeMember(key, key + strlen(key), removed); } bool Value::removeMember(String const& key, Value* removed) { return removeMember(key.data(), key.data() + key.length(), removed); } +#endif + +#ifdef JSONCPP_HAS_STRING_VIEW +void Value::removeMember(std::string_view key) { + JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, + "in Json::Value::removeMember(): requires objectValue"); + if (type() == nullValue) + return; + + CZString actualKey(key.data(), unsigned(key.length()), + CZString::noDuplication); + value_.map_->erase(actualKey); +} +#else void Value::removeMember(const char* key) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::removeMember(): requires objectValue"); @@ -1204,6 +1268,7 @@ void Value::removeMember(const char* key) { value_.map_->erase(actualKey); } void Value::removeMember(const String& key) { removeMember(key.c_str()); } +#endif bool Value::removeIndex(ArrayIndex index, Value* removed) { if (type() != arrayValue) { @@ -1233,12 +1298,18 @@ bool Value::isMember(char const* begin, char const* end) const { Value const* value = find(begin, end); return nullptr != value; } +#ifdef JSONCPP_HAS_STRING_VIEW +bool Value::isMember(std::string_view key) const { + return isMember(key.data(), key.data() + key.length()); +} +#else bool Value::isMember(char const* key) const { return isMember(key, key + strlen(key)); } bool Value::isMember(String const& key) const { return isMember(key.data(), key.data() + key.length()); } +#endif Value::Members Value::getMemberNames() const { JSON_ASSERT_MESSAGE( From ba004477a6f260dedbe6ef6470b3760192e8d232 Mon Sep 17 00:00:00 2001 From: SwintonStreet Date: Fri, 10 Jan 2025 23:38:47 +0000 Subject: [PATCH 408/410] Added Value::findType with String key (#1574) This adds a convenience function to return a member if it has a specific json type. All isType values are supported. Co-authored-by: Jordan Bayles --- include/json/value.h | 23 ++++++++++ src/lib_json/json_value.cpp | 38 ++++++++++++++++ src/test_lib_json/main.cpp | 86 +++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) diff --git a/include/json/value.h b/include/json/value.h index 307493298..5f6544329 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -549,6 +549,29 @@ class JSON_API Value { /// Most general and efficient version of isMember()const, get()const, /// and operator[]const Value const* find(const String& key) const; + + /// Calls find and only returns a valid pointer if the type is found + template + Value const* findValue(const String& key) const { + Value const* found = find(key); + if (!found || !(found->*TMemFn)()) + return nullptr; + return found; + } + + Value const* findNull(const String& key) const; + Value const* findBool(const String& key) const; + Value const* findInt(const String& key) const; + Value const* findInt64(const String& key) const; + Value const* findUInt(const String& key) const; + Value const* findUInt64(const String& key) const; + Value const* findIntegral(const String& key) const; + Value const* findDouble(const String& key) const; + Value const* findNumeric(const String& key) const; + Value const* findString(const String& key) const; + Value const* findArray(const String& key) const; + Value const* findObject(const String& key) const; + /// Most general and efficient version of object-mutators. /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30 /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue. diff --git a/src/lib_json/json_value.cpp b/src/lib_json/json_value.cpp index 527d716f2..a875d28b2 100644 --- a/src/lib_json/json_value.cpp +++ b/src/lib_json/json_value.cpp @@ -1129,6 +1129,44 @@ Value const* Value::find(char const* begin, char const* end) const { Value const* Value::find(const String& key) const { return find(key.data(), key.data() + key.length()); } + +Value const* Value::findNull(const String& key) const { + return findValue(key); +} +Value const* Value::findBool(const String& key) const { + return findValue(key); +} +Value const* Value::findInt(const String& key) const { + return findValue(key); +} +Value const* Value::findInt64(const String& key) const { + return findValue(key); +} +Value const* Value::findUInt(const String& key) const { + return findValue(key); +} +Value const* Value::findUInt64(const String& key) const { + return findValue(key); +} +Value const* Value::findIntegral(const String& key) const { + return findValue(key); +} +Value const* Value::findDouble(const String& key) const { + return findValue(key); +} +Value const* Value::findNumeric(const String& key) const { + return findValue(key); +} +Value const* Value::findString(const String& key) const { + return findValue(key); +} +Value const* Value::findArray(const String& key) const { + return findValue(key); +} +Value const* Value::findObject(const String& key) const { + return findValue(key); +} + Value* Value::demand(char const* begin, char const* end) { JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue, "in Json::Value::demand(begin, end): requires " diff --git a/src/test_lib_json/main.cpp b/src/test_lib_json/main.cpp index 5a0ce01ce..60f149d5e 100644 --- a/src/test_lib_json/main.cpp +++ b/src/test_lib_json/main.cpp @@ -76,6 +76,8 @@ struct ValueTest : JsonTest::TestCase { Json::Value float_{0.00390625f}; Json::Value array1_; Json::Value object1_; + Json::Value object2_; + Json::Value object3_; Json::Value emptyString_{""}; Json::Value string1_{"a"}; Json::Value string_{"sometext with space"}; @@ -85,6 +87,34 @@ struct ValueTest : JsonTest::TestCase { ValueTest() { array1_.append(1234); object1_["id"] = 1234; + + // object2 with matching values + object2_["null"] = Json::nullValue; + object2_["bool"] = true; + object2_["int"] = Json::Int{Json::Value::maxInt}; + object2_["int64"] = Json::Int64{Json::Value::maxInt64}; + object2_["uint"] = Json::UInt{Json::Value::maxUInt}; + object2_["uint64"] = Json::UInt64{Json::Value::maxUInt64}; + object2_["integral"] = 1234; + object2_["double"] = 1234.56789; + object2_["numeric"] = 0.12345f; + object2_["string"] = "string"; + object2_["array"] = Json::arrayValue; + object2_["object"] = Json::objectValue; + + // object3 with not matching values + object3_["object"] = Json::nullValue; + object3_["null"] = true; + object3_["bool"] = Json::Int{Json::Value::maxInt}; + object3_["int"] = "not_an_int"; + object3_["int64"] = "not_an_int64"; + object3_["uint"] = "not_an_uint"; + object3_["uin64"] = "not_an_uint64"; + object3_["integral"] = 1234.56789; + object3_["double"] = false; + object3_["numeric"] = "string"; + object3_["string"] = Json::arrayValue; + object3_["array"] = Json::objectValue; } struct IsCheck { @@ -234,6 +264,62 @@ JSONTEST_FIXTURE_LOCAL(ValueTest, objects) { const Json::Value* stringFoundUnknownId = object1_.find(stringUnknownIdKey); JSONTEST_ASSERT_EQUAL(nullptr, stringFoundUnknownId); + // Access through find() + const Json::Value* nullFound = object2_.findNull("null"); + JSONTEST_ASSERT(nullFound != nullptr); + JSONTEST_ASSERT_EQUAL(Json::nullValue, *nullFound); + JSONTEST_ASSERT(object3_.findNull("null") == nullptr); + + const Json::Value* boolFound = object2_.findBool("bool"); + JSONTEST_ASSERT(boolFound != nullptr); + JSONTEST_ASSERT_EQUAL(true, *boolFound); + JSONTEST_ASSERT(object3_.findBool("bool") == nullptr); + + const Json::Value* intFound = object2_.findInt("int"); + JSONTEST_ASSERT(intFound != nullptr); + JSONTEST_ASSERT_EQUAL(Json::Int{Json::Value::maxInt}, *intFound); + JSONTEST_ASSERT(object3_.findInt("int") == nullptr); + + const Json::Value* int64Found = object2_.findInt64("int64"); + JSONTEST_ASSERT(int64Found != nullptr); + JSONTEST_ASSERT_EQUAL(Json::Int64{Json::Value::maxInt64}, *int64Found); + JSONTEST_ASSERT(object3_.findInt64("int64") == nullptr); + + const Json::Value* uintFound = object2_.findUInt("uint"); + JSONTEST_ASSERT(uintFound != nullptr); + JSONTEST_ASSERT_EQUAL(Json::UInt{Json::Value::maxUInt}, *uintFound); + JSONTEST_ASSERT(object3_.findUInt("uint") == nullptr); + + const Json::Value* uint64Found = object2_.findUInt64("uint64"); + JSONTEST_ASSERT(uint64Found != nullptr); + JSONTEST_ASSERT_EQUAL(Json::UInt64{Json::Value::maxUInt64}, *uint64Found); + JSONTEST_ASSERT(object3_.findUInt64("uint64") == nullptr); + + const Json::Value* integralFound = object2_.findIntegral("integral"); + JSONTEST_ASSERT(integralFound != nullptr); + JSONTEST_ASSERT_EQUAL(1234, *integralFound); + JSONTEST_ASSERT(object3_.findIntegral("integral") == nullptr); + + const Json::Value* doubleFound = object2_.findDouble("double"); + JSONTEST_ASSERT(doubleFound != nullptr); + JSONTEST_ASSERT_EQUAL(1234.56789, *doubleFound); + JSONTEST_ASSERT(object3_.findDouble("double") == nullptr); + + const Json::Value* numericFound = object2_.findNumeric("numeric"); + JSONTEST_ASSERT(numericFound != nullptr); + JSONTEST_ASSERT_EQUAL(0.12345f, *numericFound); + JSONTEST_ASSERT(object3_.findNumeric("numeric") == nullptr); + + const Json::Value* stringFound = object2_.findString("string"); + JSONTEST_ASSERT(stringFound != nullptr); + JSONTEST_ASSERT_EQUAL(std::string{"string"}, *stringFound); + JSONTEST_ASSERT(object3_.findString("string") == nullptr); + + const Json::Value* arrayFound = object2_.findArray("array"); + JSONTEST_ASSERT(arrayFound != nullptr); + JSONTEST_ASSERT_EQUAL(Json::arrayValue, *arrayFound); + JSONTEST_ASSERT(object3_.findArray("array") == nullptr); + // Access through demand() const char yetAnotherIdKey[] = "yet another id"; const Json::Value* foundYetAnotherId = From 037752d9a1e48c8b7e5a62ee895a352166df03e3 Mon Sep 17 00:00:00 2001 From: bcsgh <33939446+bcsgh@users.noreply.github.com> Date: Wed, 12 Mar 2025 15:57:16 -0700 Subject: [PATCH 409/410] Set up for Bazel module builds. (#1597) * Set up for Bazel module builds. Note: the MODULE.bazel is copied from https://github.com/bazelbuild/bazel-central-registry/blob/main/modules/jsoncpp/1.9.6/MODULE.bazel * More tweaks to .gitignore --- .gitignore | 4 ++++ CMakeLists.txt | 3 ++- MODULE.bazel | 14 ++++++++++++++ include/json/version.h | 3 ++- meson.build | 3 ++- 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 MODULE.bazel diff --git a/.gitignore b/.gitignore index 9682782fa..69868f413 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ compile_commands.json # temps /version + +# Bazel output paths +/bazel-* +/MODULE.bazel.lock diff --git a/CMakeLists.txt b/CMakeLists.txt index 6104c5ce5..5ab9c52a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,12 +55,13 @@ endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") project(jsoncpp - # Note: version must be updated in three places when doing a release. This + # Note: version must be updated in four places when doing a release. This # annoying process ensures that amalgamate, CMake, and meson all report the # correct version. # 1. ./meson.build # 2. ./include/json/version.h # 3. ./CMakeLists.txt + # 4. ./MODULE.bazel # IMPORTANT: also update the PROJECT_SOVERSION!! VERSION 1.9.7 # [.[.[.]]] LANGUAGES CXX) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..03f192dd4 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,14 @@ +module( + name = "jsoncpp", + + # Note: version must be updated in four places when doing a release. This + # annoying process ensures that amalgamate, CMake, and meson all report the + # correct version. + # 1. /meson.build + # 2. /include/json/version.h + # 3. /CMakeLists.txt + # 4. /MODULE.bazel + # IMPORTANT: also update the SOVERSION!! + version = "1.9.7", + compatibility_level = 1, +) diff --git a/include/json/version.h b/include/json/version.h index 42e8780a3..555152c8c 100644 --- a/include/json/version.h +++ b/include/json/version.h @@ -1,12 +1,13 @@ #ifndef JSON_VERSION_H_INCLUDED #define JSON_VERSION_H_INCLUDED -// Note: version must be updated in three places when doing a release. This +// Note: version must be updated in four places when doing a release. This // annoying process ensures that amalgamate, CMake, and meson all report the // correct version. // 1. /meson.build // 2. /include/json/version.h // 3. /CMakeLists.txt +// 4. /MODULE.bazel // IMPORTANT: also update the SOVERSION!! #define JSONCPP_VERSION_STRING "1.9.7" diff --git a/meson.build b/meson.build index 8e8d57e3c..2648c3071 100644 --- a/meson.build +++ b/meson.build @@ -2,12 +2,13 @@ project( 'jsoncpp', 'cpp', - # Note: version must be updated in three places when doing a release. This + # Note: version must be updated in four places when doing a release. This # annoying process ensures that amalgamate, CMake, and meson all report the # correct version. # 1. /meson.build # 2. /include/json/version.h # 3. /CMakeLists.txt + # 4. /MODULE.bazel # IMPORTANT: also update the SOVERSION!! version : '1.9.7', default_options : [ From ca98c98457b1163cca1f7d8db62827c115fec6d1 Mon Sep 17 00:00:00 2001 From: bcsgh <33939446+bcsgh@users.noreply.github.com> Date: Tue, 18 Mar 2025 16:15:37 -0700 Subject: [PATCH 410/410] Add a BUILD.bazel file for //example. (#1602) --- example/BUILD.bazel | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 example/BUILD.bazel diff --git a/example/BUILD.bazel b/example/BUILD.bazel new file mode 100644 index 000000000..38e7dfcf7 --- /dev/null +++ b/example/BUILD.bazel @@ -0,0 +1,33 @@ +cc_binary( + name = "readFromStream_ok", + srcs = ["readFromStream/readFromStream.cpp"], + deps = ["//:jsoncpp"], + args = ["$(location :readFromStream/withComment.json)"], + data = ["readFromStream/withComment.json"], +) + +cc_binary( + name = "readFromStream_err", + srcs = ["readFromStream/readFromStream.cpp"], + deps = ["//:jsoncpp"], + args = ["$(location :readFromStream/errorFormat.json)"], + data = ["readFromStream/errorFormat.json"], +) + +cc_binary( + name = "readFromString", + srcs = ["readFromString/readFromString.cpp"], + deps = ["//:jsoncpp"], +) + +cc_binary( + name = "streamWrite", + srcs = ["streamWrite/streamWrite.cpp"], + deps = ["//:jsoncpp"], +) + +cc_binary( + name = "stringWrite", + srcs = ["stringWrite/stringWrite.cpp"], + deps = ["//:jsoncpp"], +)