From ad573a9ceb0e4373f77ef6e28e7f6e777ff64c8b Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 6 Dec 2014 20:59:12 +0500 Subject: [PATCH] Change result, pos, newpos and paramindex variables to local in builtin/common/misc_helpers.lua --- builtin/common/misc_helpers.lua | 8 +- src/json/UPDATING | 0 src/json/json-forwards.h | 261 ++++++++++++++++++++++++++++ src/json/json.h | 139 +++++++++++++-- src/json/jsoncpp.cpp | 291 ++++++++++++++++++++++++-------- 5 files changed, 619 insertions(+), 80 deletions(-) mode change 100644 => 100755 src/json/UPDATING create mode 100644 src/json/json-forwards.h diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index e1dc28965..2f6f58b5b 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -532,15 +532,15 @@ if INIT == "mainmenu" then local arg = {n=select('#', ...), ...} if arg.n >= 1 then -- Insert positional parameters ($1, $2, ...) - result = '' - pos = 1 + local result = '' + local pos = 1 while pos <= text:len() do - newpos = text:find('[$]', pos) + local newpos = text:find('[$]', pos) if newpos == nil then result = result .. text:sub(pos) pos = text:len() + 1 else - paramindex = tonumber(text:sub(newpos+1, newpos+1)) + local paramindex = tonumber(text:sub(newpos+1, newpos+1)) result = result .. text:sub(pos, newpos-1) .. tostring(arg[paramindex]) pos = newpos + 2 end diff --git a/src/json/UPDATING b/src/json/UPDATING old mode 100644 new mode 100755 diff --git a/src/json/json-forwards.h b/src/json/json-forwards.h new file mode 100644 index 000000000..a3ba0fa05 --- /dev/null +++ b/src/json/json-forwards.h @@ -0,0 +1,261 @@ +/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/). +/// It is intented to be used with #include +/// This header provides forward declaration for all JsonCpp types. + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + +/* +The JsonCpp library's source code, including accompanying documentation, +tests and demonstration applications, are licensed under the following +conditions... + +The author (Baptiste Lepilleur) explicitly disclaims 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 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 +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: + +======================================================================== +Copyright (c) 2007-2010 Baptiste Lepilleur + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +======================================================================== +(END LICENSE TEXT) + +The MIT license is compatible with both the GPL and commercial +software, affording one all of the rights of Public Domain with the +minor nuisance of being required to keep the above copyright notice +and license text in the source code. Note also that by accepting the +Public Domain "license" you can re-license your copy using whatever +license you like. + +*/ + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: LICENSE +// ////////////////////////////////////////////////////////////////////// + + + + + +#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED +# define JSON_FORWARD_AMALGATED_H_INCLUDED +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +#define JSON_IS_AMALGAMATION + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// 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_CONFIG_H_INCLUDED +# define JSON_CONFIG_H_INCLUDED + +/// 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 defined, indicates that Json specific container should be used +/// (hash table & simple deque container with customizable allocator). +/// THIS FEATURE IS STILL EXPERIMENTAL! There is know bugs: See #3177332 +//# define JSON_VALUE_USE_INTERNAL_MAP 1 +/// Force usage of standard new/malloc based allocator instead of memory pool based allocator. +/// The memory pools allocator used optimization (initializing Value and ValueInternalLink +/// as if it was a POD) that may cause some validation tool to report errors. +/// Only has effects if JSON_VALUE_USE_INTERNAL_MAP is defined. +//# define JSON_USE_SIMPLE_INTERNAL_ALLOCATOR 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 +# define JSON_USE_EXCEPTION 1 +# endif + +/// If defined, indicates that the source file is amalgated +/// to prevent private header inclusion. +/// Remarks: it is automatically defined in the generated amalgated 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) +# define JSON_API __declspec(dllexport) +# define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +# endif // if defined(_MSC_VER) +# elif defined(JSON_DLL) +# if defined(_MSC_VER) +# 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 + +// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for integer +// Storages, and 64 bits integer support is disabled. +// #define JSON_NO_INT64 1 + +#if defined(_MSC_VER) && _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 // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 + +#if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 +/// Indicates that the following function is deprecated. +# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message)) +#endif + +#if !defined(JSONCPP_DEPRECATED) +# define JSONCPP_DEPRECATED(message) +#endif // if !defined(JSONCPP_DEPRECATED) + +namespace Json { + typedef int Int; + typedef unsigned int UInt; +# if defined(JSON_NO_INT64) + typedef int LargestInt; + typedef unsigned int LargestUInt; +# 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; +# else // if defined(_MSC_VER) // Other platforms, use long long + typedef long long int Int64; + typedef unsigned long long int UInt64; +# endif // if defined(_MSC_VER) + typedef Int64 LargestInt; + typedef UInt64 LargestUInt; +# define JSON_HAS_INT64 +# endif // if defined(JSON_NO_INT64) +} // end namespace Json + + +#endif // JSON_CONFIG_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/config.h +// ////////////////////////////////////////////////////////////////////// + + + + + + +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + +// Copyright 2007-2010 Baptiste Lepilleur +// 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_FORWARDS_H_INCLUDED +# define JSON_FORWARDS_H_INCLUDED + +#if !defined(JSON_IS_AMALGAMATION) +# include "config.h" +#endif // if !defined(JSON_IS_AMALGAMATION) + +namespace Json { + + // writer.h + class FastWriter; + class StyledWriter; + + // reader.h + class Reader; + + // features.h + class Features; + + // value.h + typedef unsigned int ArrayIndex; + class StaticString; + class Path; + class PathArgument; + class Value; + class ValueIteratorBase; + class ValueIterator; + class ValueConstIterator; +#ifdef JSON_VALUE_USE_INTERNAL_MAP + class ValueMapAllocator; + class ValueInternalLink; + class ValueInternalArray; + class ValueInternalMap; +#endif // #ifdef JSON_VALUE_USE_INTERNAL_MAP + +} // namespace Json + + +#endif // JSON_FORWARDS_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/forwards.h +// ////////////////////////////////////////////////////////////////////// + + + + + +#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED diff --git a/src/json/json.h b/src/json/json.h index 396aafa82..04e7dee65 100644 --- a/src/json/json.h +++ b/src/json/json.h @@ -78,6 +78,34 @@ license you like. /// to prevent private header inclusion. #define JSON_IS_AMALGAMATION +// ////////////////////////////////////////////////////////////////////// +// Beginning of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + +// DO NOT EDIT. This file is generated by CMake from "version" +// and "version.h.in" files. +// Run CMake configure step to update it. +#ifndef JSON_VERSION_H_INCLUDED +# define JSON_VERSION_H_INCLUDED + +# define JSONCPP_VERSION_STRING "0.6.0-dev" +# define JSONCPP_VERSION_MAJOR 0 +# define JSONCPP_VERSION_MINOR 6 +# define JSONCPP_VERSION_PATCH 0 +# define JSONCPP_VERSION_QUALIFIER -dev +# define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8)) + +#endif // JSON_VERSION_H_INCLUDED + +// ////////////////////////////////////////////////////////////////////// +// End of content of file: include/json/version.h +// ////////////////////////////////////////////////////////////////////// + + + + + + // ////////////////////////////////////////////////////////////////////// // Beginning of content of file: include/json/config.h // ////////////////////////////////////////////////////////////////////// @@ -130,10 +158,17 @@ license you like. # ifdef JSON_IN_CPPTL # define JSON_API CPPTL_API # elif defined(JSON_DLL_BUILD) -# define JSON_API __declspec(dllexport) +# if defined(_MSC_VER) +# define JSON_API __declspec(dllexport) +# define JSONCPP_DISABLE_DLL_INTERFACE_WARNING +# endif // if defined(_MSC_VER) # elif defined(JSON_DLL) -# define JSON_API __declspec(dllimport) -# else +# if defined(_MSC_VER) +# 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 @@ -145,6 +180,9 @@ license you like. // 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 // if defined(_MSC_VER) && _MSC_VER < 1200 // MSVC 6 #if defined(_MSC_VER) && _MSC_VER >= 1500 // MSVC 2008 @@ -296,6 +334,12 @@ namespace Json { /// \c true if root must be either an array or an object value. Default: \c false. bool strictRoot_; + + /// \c true if dropped null placeholders are allowed. Default: \c false. + bool allowDroppedNullPlaceholders_; + + /// \c true if numeric object key are allowed. Default: \c false. + bool allowNumericKeys_; }; } // namespace Json @@ -338,6 +382,13 @@ namespace Json { # include # endif +// Disable warning C4251: : needs to have dll-interface to be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(push) +# pragma warning(disable:4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + + /** \brief JSON (JavaScript Object Notation). */ namespace Json { @@ -752,6 +803,13 @@ namespace Json { iterator begin(); iterator end(); + // Accessors for the [start, limit) range of bytes within the JSON text from + // which this value was parsed, if any. + void setOffsetStart( size_t start ); + void setOffsetLimit( size_t limit ); + size_t getOffsetStart() const; + size_t getOffsetLimit() const; + private: Value &resolveReference( const char *key, bool isStatic ); @@ -819,12 +877,17 @@ namespace Json { int memberNameIsStatic_ : 1; // used by the ValueInternalMap container. # endif CommentInfo *comments_; + + // [start, limit) byte offsets in the source JSON text from which this Value + // was extracted. + size_t start_; + size_t limit_; }; /** \brief Experimental and untested: represents an element of the "path" to access a node. */ - class PathArgument + class JSON_API PathArgument { public: friend class Path; @@ -857,7 +920,7 @@ namespace Json { * - ".%" => member name is provided as parameter * - ".[%]" => index is provied as parameter */ - class Path + class JSON_API Path { public: Path( const std::string &path, @@ -1233,9 +1296,10 @@ public: // overridden from ValueArrayAllocator /** \brief base class for Value iterators. * */ - class ValueIteratorBase + class JSON_API ValueIteratorBase { public: + typedef std::bidirectional_iterator_tag iterator_category; typedef unsigned int size_t; typedef int difference_type; typedef ValueIteratorBase SelfType; @@ -1303,10 +1367,11 @@ public: // overridden from ValueArrayAllocator /** \brief const iterator for object and array value. * */ - class ValueConstIterator : public ValueIteratorBase + class JSON_API ValueConstIterator : public ValueIteratorBase { friend class Value; public: + typedef const Value value_type; typedef unsigned int size_t; typedef int difference_type; typedef const Value &reference; @@ -1361,10 +1426,11 @@ public: // overridden from ValueArrayAllocator /** \brief Iterator for object and array value. */ - class ValueIterator : public ValueIteratorBase + 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; @@ -1423,6 +1489,11 @@ public: // overridden from ValueArrayAllocator } // namespace Json +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + + #endif // CPPTL_JSON_H_INCLUDED // ////////////////////////////////////////////////////////////////////// @@ -1451,9 +1522,17 @@ public: // overridden from ValueArrayAllocator # include "value.h" #endif // if !defined(JSON_IS_AMALGAMATION) # include +# include # include # include +// Disable warning C4251: : needs to have dll-interface to be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(push) +# pragma warning(disable:4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + + namespace Json { /** \brief Unserialize a JSON document into a Value. @@ -1465,6 +1544,19 @@ namespace Json { typedef char Char; typedef const Char *Location; + /** \brief An error tagged with where in the JSON text it was encountered. + * + * The offsets give the [start, limit) range of bytes within the text. Note + * that this is bytes, not codepoints. + * + */ + struct StructuredError + { + size_t offset_start; + size_t offset_limit; + std::string message; + }; + /** \brief Constructs a Reader allowing all features * for parsing. */ @@ -1527,6 +1619,14 @@ namespace Json { */ std::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. + */ + std::vector getStructuredErrors() const; + private: enum TokenType { @@ -1578,9 +1678,11 @@ namespace Json { 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, std::string &decoded ); bool decodeDouble( Token &token ); + bool decodeDouble( Token &token, Value &decoded ); bool decodeUnicodeCodePoint( Token &token, Location ¤t, Location end, @@ -1646,10 +1748,15 @@ namespace Json { \throw std::exception on parse error. \see Json::operator<<() */ - std::istream& operator>>( std::istream&, Value& ); + JSON_API std::istream& operator>>( std::istream&, Value& ); } // namespace Json +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + + #endif // CPPTL_JSON_READER_H_INCLUDED // ////////////////////////////////////////////////////////////////////// @@ -1679,6 +1786,13 @@ namespace Json { # include # include +// Disable warning C4251: : needs to have dll-interface to be used by... +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(push) +# pragma warning(disable:4251) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + + namespace Json { class Value; @@ -1850,11 +1964,15 @@ namespace Json { /// \brief Output using the StyledStreamWriter. /// \see Json::operator>>() - std::ostream& operator<<( std::ostream&, const Value &root ); + JSON_API std::ostream& operator<<( std::ostream&, const Value &root ); } // namespace Json +#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) +# pragma warning(pop) +#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) + #endif // JSON_WRITER_H_INCLUDED @@ -1886,6 +2004,7 @@ namespace Json { #endif // if !defined(JSON_IS_AMALGAMATION) #if JSON_USE_EXCEPTION +# include #define JSON_ASSERT( condition ) assert( condition ); // @todo <= change this into an exception throw #define JSON_FAIL_MESSAGE( message ) throw std::runtime_error( message ); #else // JSON_USE_EXCEPTION diff --git a/src/json/jsoncpp.cpp b/src/json/jsoncpp.cpp index 7a04736de..f53d7bf7d 100644 --- a/src/json/jsoncpp.cpp +++ b/src/json/jsoncpp.cpp @@ -73,7 +73,7 @@ license you like. -#include "json.h" +#include // ////////////////////////////////////////////////////////////////////// @@ -202,7 +202,7 @@ uintToString( LargestUInt value, #include #include #include -#include +#include #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 #pragma warning( disable : 4996 ) // disable warning about strdup being deprecated. @@ -216,6 +216,8 @@ namespace Json { Features::Features() : allowComments_( true ) , strictRoot_( false ) + , allowDroppedNullPlaceholders_ ( false ) + , allowNumericKeys_ ( false ) { } @@ -233,6 +235,8 @@ Features::strictMode() Features features; features.allowComments_ = false; features.strictRoot_ = true; + features.allowDroppedNullPlaceholders_ = false; + features.allowNumericKeys_ = false; return features; } @@ -379,6 +383,17 @@ Reader::readValue() if ( collectComments_ && !commentsBefore_.empty() ) { + // Remove newline characters at the end of the comments + size_t lastNonNewline = commentsBefore_.find_last_not_of("\r\n"); + if (lastNonNewline != std::string::npos) + { + commentsBefore_.erase(lastNonNewline+1); + } + else + { + commentsBefore_.clear(); + } + currentValue().setComment( commentsBefore_, commentBefore ); commentsBefore_ = ""; } @@ -388,9 +403,11 @@ Reader::readValue() { case tokenObjectBegin: successful = readObject( token ); + currentValue().setOffsetLimit(current_ - begin_); break; case tokenArrayBegin: successful = readArray( token ); + currentValue().setOffsetLimit(current_ - begin_); break; case tokenNumber: successful = decodeNumber( token ); @@ -400,14 +417,34 @@ Reader::readValue() break; case tokenTrue: currentValue() = true; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); break; case tokenFalse: currentValue() = false; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); break; case tokenNull: currentValue() = Value(); + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); break; + case tokenArraySeparator: + if ( features_.allowDroppedNullPlaceholders_ ) + { + // "Un-read" the current token and mark the current value as a null + // token. + current_--; + currentValue() = Value(); + currentValue().setOffsetStart(current_ - begin_ - 1); + currentValue().setOffsetLimit(current_ - begin_); + break; + } + // Else, fall through... default: + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return addError( "Syntax error: value, object or array expected.", token ); } @@ -656,11 +693,12 @@ Reader::readString() bool -Reader::readObject( Token &/*tokenStart*/ ) +Reader::readObject( Token &tokenStart ) { Token tokenName; std::string name; currentValue() = Value( objectValue ); + currentValue().setOffsetStart(tokenStart.start_ - begin_); while ( readToken( tokenName ) ) { bool initialTokenOk = true; @@ -670,12 +708,24 @@ Reader::readObject( Token &/*tokenStart*/ ) break; if ( tokenName.type_ == tokenObjectEnd && name.empty() ) // empty object return true; - if ( tokenName.type_ != tokenString ) - break; - name = ""; - if ( !decodeString( tokenName, name ) ) - return recoverFromError( tokenObjectEnd ); + if ( tokenName.type_ == tokenString ) + { + if ( !decodeString( tokenName, name ) ) + return recoverFromError( tokenObjectEnd ); + } + else if ( tokenName.type_ == tokenNumber && + features_.allowNumericKeys_ ) + { + Value numberName; + if ( !decodeNumber( tokenName, numberName ) ) + return recoverFromError( tokenObjectEnd ); + name = numberName.asString(); + } + else + { + break; + } Token colon; if ( !readToken( colon ) || colon.type_ != tokenMemberSeparator ) @@ -715,9 +765,10 @@ Reader::readObject( Token &/*tokenStart*/ ) bool -Reader::readArray( Token &/*tokenStart*/ ) +Reader::readArray( Token &tokenStart ) { currentValue() = Value( arrayValue ); + currentValue().setOffsetStart(tokenStart.start_ - begin_); skipSpaces(); if ( *current_ == ']' ) // empty array { @@ -759,6 +810,19 @@ Reader::readArray( Token &/*tokenStart*/ ) bool Reader::decodeNumber( Token &token ) +{ + Value decoded; + if ( !decodeNumber( token, decoded ) ) + return false; + currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + + +bool +Reader::decodeNumber( Token &token, Value &decoded ) { bool isDouble = false; for ( Location inspect = token.start_; inspect != token.end_; ++inspect ) @@ -768,7 +832,7 @@ Reader::decodeNumber( Token &token ) || ( *inspect == '-' && inspect != token.start_ ); } if ( isDouble ) - return decodeDouble( token ); + return decodeDouble( token, decoded ); // Attempts to parse the number as an integer. If the number is // larger than the maximum supported value of an integer then // we decode the number as a double. @@ -796,23 +860,36 @@ Reader::decodeNumber( Token &token ) current != token.end_ || digit > maxIntegerValue % 10) { - return decodeDouble( token ); + return decodeDouble( token, decoded ); } } value = value * 10 + digit; } if ( isNegative ) - currentValue() = -Value::LargestInt( value ); + decoded = -Value::LargestInt( value ); else if ( value <= Value::LargestUInt(Value::maxInt) ) - currentValue() = Value::LargestInt( value ); + decoded = Value::LargestInt( value ); else - currentValue() = value; + decoded = value; return true; } bool Reader::decodeDouble( Token &token ) +{ + Value decoded; + if ( !decodeDouble( token, decoded ) ) + return false; + currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); + return true; +} + + +bool +Reader::decodeDouble( Token &token, Value &decoded ) { double value = 0; const int bufferSize = 32; @@ -846,7 +923,7 @@ Reader::decodeDouble( Token &token ) if ( count != 1 ) return addError( "'" + std::string( token.start_, token.end_ ) + "' is not a number.", token ); - currentValue() = value; + decoded = value; return true; } @@ -858,6 +935,8 @@ Reader::decodeString( Token &token ) if ( !decodeString( token, decoded ) ) return false; currentValue() = decoded; + currentValue().setOffsetStart(token.start_ - begin_); + currentValue().setOffsetLimit(token.end_ - begin_); return true; } @@ -1057,7 +1136,11 @@ Reader::getLocationLineAndColumn( Location location ) const int line, column; getLocationLineAndColumn( location, line, column ); char buffer[18+16+16+1]; - sprintf( buffer, "Line %d, Column %d", line, column ); +#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) + sprintf_s(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#else + snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); +#endif return buffer; } @@ -1088,6 +1171,25 @@ 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; + Reader::StructuredError structured; + structured.offset_start = error.token_.start_ - begin_; + structured.offset_limit = error.token_.end_ - begin_; + structured.message = error.message_; + allErrors.push_back(structured); + } + return allErrors; +} + + std::istream& operator>>( std::istream &sin, Value &root ) { Json::Reader reader; @@ -1105,6 +1207,7 @@ std::istream& operator>>( std::istream &sin, Value &root ) } // namespace Json +// vim: et ts=3 sts=3 sw=3 tw=0 // ////////////////////////////////////////////////////////////////////// // End of content of file: src/lib_json/json_reader.cpp @@ -1246,6 +1349,7 @@ private: # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED +// vim: et ts=3 sts=3 sw=3 tw=0 // ////////////////////////////////////////////////////////////////////// // End of content of file: src/lib_json/json_batchallocator.h @@ -1411,6 +1515,7 @@ ValueIteratorBase::copy( const SelfType &other ) { #ifndef JSON_VALUE_USE_INTERNAL_MAP current_ = other.current_; + isNull_ = other.isNull_; #else if ( isArray_ ) iterator_.array_ = other.iterator_.array_; @@ -1559,6 +1664,7 @@ ValueIterator::operator =( const SelfType &other ) } } // namespace Json +// vim: et ts=3 sts=3 sw=3 tw=0 // ////////////////////////////////////////////////////////////////////// // End of content of file: src/lib_json/json_valueiterator.inl @@ -1589,7 +1695,6 @@ ValueIterator::operator =( const SelfType &other ) #include #include #include -#include #include #include #ifdef JSON_USE_CPPTL @@ -1666,7 +1771,7 @@ duplicateStringValue( const char *value, length = Value::maxInt - 1; char *newString = static_cast( malloc( length + 1 ) ); - JSON_ASSERT_MESSAGE( newString != 0, "Failed to allocate string value buffer" ); + JSON_ASSERT_MESSAGE( newString != 0, "in Json::Value::duplicateStringValue(): Failed to allocate string value buffer" ); memcpy( newString, value, length ); newString[length] = 0; return newString; @@ -1730,7 +1835,7 @@ Value::CommentInfo::setComment( const char *text ) if ( comment_ ) releaseStringValue( comment_ ); JSON_ASSERT( text != 0 ); - JSON_ASSERT_MESSAGE( text[0]=='\0' || text[0]=='/', "Comments must start with /"); + 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 ); } @@ -1849,6 +1954,8 @@ Value::Value( ValueType type ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { switch ( type ) { @@ -1893,6 +2000,8 @@ Value::Value( UInt value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.uint_ = value; } @@ -1904,6 +2013,8 @@ Value::Value( Int value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.int_ = value; } @@ -1917,6 +2028,8 @@ Value::Value( Int64 value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.int_ = value; } @@ -1929,6 +2042,8 @@ Value::Value( UInt64 value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.uint_ = value; } @@ -1941,6 +2056,8 @@ Value::Value( double value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.real_ = value; } @@ -1952,6 +2069,8 @@ Value::Value( const char *value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.string_ = duplicateStringValue( value ); } @@ -1965,6 +2084,8 @@ Value::Value( const char *beginValue, , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.string_ = duplicateStringValue( beginValue, (unsigned int)(endValue - beginValue) ); @@ -1978,6 +2099,8 @@ Value::Value( const std::string &value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.string_ = duplicateStringValue( value.c_str(), (unsigned int)value.length() ); @@ -1991,6 +2114,8 @@ Value::Value( const StaticString &value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.string_ = const_cast( value.c_str() ); } @@ -2004,6 +2129,8 @@ Value::Value( const CppTL::ConstString &value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.string_ = duplicateStringValue( value, value.length() ); } @@ -2016,6 +2143,8 @@ Value::Value( bool value ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( 0 ) + , limit_( 0 ) { value_.bool_ = value; } @@ -2028,6 +2157,8 @@ Value::Value( const Value &other ) , itemIsUsed_( 0 ) #endif , comments_( 0 ) + , start_( other.start_ ) + , limit_( other.limit_ ) { switch ( type_ ) { @@ -2045,7 +2176,10 @@ Value::Value( const Value &other ) allocated_ = true; } else + { value_.string_ = 0; + allocated_ = false; + } break; #ifndef JSON_VALUE_USE_INTERNAL_MAP case arrayValue: @@ -2129,6 +2263,8 @@ Value::swap( Value &other ) int temp2 = allocated_; allocated_ = other.allocated_; other.allocated_ = temp2; + std::swap( start_, other.start_ ); + std::swap( limit_, other.limit_ ); } ValueType @@ -2264,7 +2400,7 @@ Value::operator !=( const Value &other ) const const char * Value::asCString() const { - JSON_ASSERT( type_ == stringValue ); + JSON_ASSERT_MESSAGE( type_ == stringValue, "in Json::Value::asCString(): requires stringValue" ); return value_.string_; } @@ -2598,8 +2734,9 @@ Value::operator!() const void Value::clear() { - JSON_ASSERT( 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_ ) { #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2623,7 +2760,7 @@ Value::clear() void Value::resize( ArrayIndex newSize ) { - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == arrayValue, "in Json::Value::resize(): requires arrayValue" ); if ( type_ == nullValue ) *this = Value( arrayValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2649,7 +2786,7 @@ Value::resize( ArrayIndex newSize ) Value & Value::operator[]( ArrayIndex index ) { - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == arrayValue, "in Json::Value::operator[](ArrayIndex): requires arrayValue" ); if ( type_ == nullValue ) *this = Value( arrayValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2670,7 +2807,7 @@ Value::operator[]( ArrayIndex index ) Value & Value::operator[]( int index ) { - JSON_ASSERT( index >= 0 ); + JSON_ASSERT_MESSAGE( index >= 0, "in Json::Value::operator[](int index): index cannot be negative" ); return (*this)[ ArrayIndex(index) ]; } @@ -2678,7 +2815,7 @@ Value::operator[]( int index ) const Value & Value::operator[]( ArrayIndex index ) const { - JSON_ASSERT( type_ == nullValue || type_ == arrayValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == arrayValue, "in Json::Value::operator[](ArrayIndex)const: requires arrayValue" ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2697,7 +2834,7 @@ Value::operator[]( ArrayIndex index ) const const Value & Value::operator[]( int index ) const { - JSON_ASSERT( index >= 0 ); + JSON_ASSERT_MESSAGE( index >= 0, "in Json::Value::operator[](int index) const: index cannot be negative" ); return (*this)[ ArrayIndex(index) ]; } @@ -2713,7 +2850,7 @@ Value & Value::resolveReference( const char *key, bool isStatic ) { - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::resolveReference(): requires objectValue" ); if ( type_ == nullValue ) *this = Value( objectValue ); #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2753,7 +2890,7 @@ Value::isValidIndex( ArrayIndex index ) const const Value & Value::operator[]( const char *key ) const { - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::operator[](char const*)const: requires objectValue" ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2831,7 +2968,7 @@ Value::get( const std::string &key, Value Value::removeMember( const char* key ) { - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::removeMember(): requires objectValue" ); if ( type_ == nullValue ) return null; #ifndef JSON_VALUE_USE_INTERNAL_MAP @@ -2895,7 +3032,7 @@ Value::isMember( const CppTL::ConstString &key ) const Value::Members Value::getMemberNames() const { - JSON_ASSERT( type_ == nullValue || type_ == objectValue ); + JSON_ASSERT_MESSAGE( type_ == nullValue || type_ == objectValue, "in Json::Value::getMemberNames(), value must be objectValue" ); if ( type_ == nullValue ) return Value::Members(); Members members; @@ -3128,6 +3265,34 @@ Value::getComment( CommentPlacement placement ) const } +void +Value::setOffsetStart( size_t start ) +{ + start_ = start; +} + + +void +Value::setOffsetLimit( size_t limit ) +{ + limit_ = limit; +} + + +size_t +Value::getOffsetStart() const +{ + return start_; +} + + +size_t +Value::getOffsetLimit() const +{ + return limit_; +} + + std::string Value::toStyledString() const { @@ -3377,7 +3542,7 @@ Path::makePath( const std::string &path, void -Path::addPathInArg( const std::string &path, +Path::addPathInArg( const std::string &/*path*/, const InArgs &in, InArgs::const_iterator &itInArg, PathArgument::Kind kind ) @@ -3398,8 +3563,8 @@ Path::addPathInArg( const std::string &path, void -Path::invalidPath( const std::string &path, - int location ) +Path::invalidPath( const std::string &/*path*/, + int /*location*/ ) { // Error: invalid path. } @@ -3493,6 +3658,7 @@ Path::make( Value &root ) const } // namespace Json +// vim: et ts=3 sts=3 sw=3 tw=0 // ////////////////////////////////////////////////////////////////////// // End of content of file: src/lib_json/json_value.cpp @@ -3582,40 +3748,19 @@ std::string valueToString( UInt value ) std::string valueToString( double value ) { + // Allocate a buffer that is more than large enough to store the 16 digits of + // precision requested below. char buffer[32]; + + // Print into the buffer. We need not request the alternative representation + // that always has a decimal point because JSON doesn't distingish the + // concepts of reals and integers. #if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__) // Use secure version with visual studio 2005 to avoid warning. - sprintf_s(buffer, sizeof(buffer), "%#.16g", value); -#else - sprintf(buffer, "%#.16g", value); + sprintf_s(buffer, sizeof(buffer), "%.16g", value); +#else + snprintf(buffer, sizeof(buffer), "%.16g", value); #endif - char* ch = buffer + strlen(buffer) - 1; - if (*ch != '0') return buffer; // nothing to truncate, so save time - while(ch > buffer && *ch == '0'){ - --ch; - } - char* last_nonzero = ch; - while(ch >= buffer){ - switch(*ch){ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - --ch; - continue; - case '.': - // Truncate zeroes to save bytes in output, but keep one. - *(last_nonzero+2) = '\0'; - return buffer; - default: - return buffer; - } - } + return buffer; } @@ -4013,7 +4158,20 @@ StyledWriter::writeCommentBeforeValue( const Value &root ) { if ( !root.hasComment( commentBefore ) ) return; - document_ += normalizeEOL( root.getComment( commentBefore ) ); + + document_ += "\n"; + writeIndent(); + std::string normalizedComment = normalizeEOL( root.getComment( commentBefore ) ); + std::string::const_iterator iter = normalizedComment.begin(); + while ( iter != normalizedComment.end() ) + { + document_ += *iter; + if ( *iter == '\n' && *(iter+1) == '/' ) + writeIndent(); + ++iter; + } + + // Comments are stripped of newlines, so add one here document_ += "\n"; } @@ -4356,6 +4514,7 @@ std::ostream& operator<<( std::ostream &sout, const Value &root ) } // namespace Json +// vim: et ts=3 sts=3 sw=3 tw=0 // ////////////////////////////////////////////////////////////////////// // End of content of file: src/lib_json/json_writer.cpp