From f34bf24bbd7bfdf67c1ada9b30728e7ced5afaec Mon Sep 17 00:00:00 2001 From: Jordan Bayles Date: Fri, 11 Oct 2019 11:19:00 -0700 Subject: [PATCH] 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 2a372fc..2a80669 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 b649b46..a63929e 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 dbf03cb..0820c89 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 0000000..68179aa --- /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='store_true', + help='run recursively over directories') + parser.add_argument('files', metavar='file', nargs='+') + parser.add_argument( + '-q', + '--quiet', + action='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='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 0000000..9197284 --- /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 0ff5968..cbb5950 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 fb2365a..359c1eb 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 @@ public: /** \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 @@ public: /// \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 @@ public: * 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 @@ private: 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 @@ private: 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 @@ private: 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 @@ public: * \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 @@ public: * 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 aa7bc54..a0a5a11 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -493,8 +493,8 @@ public: /// 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 @@ public: //# 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 @@ private: */ 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 @@ private: 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 @@ public: /// 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 9799a3b..a72c06a 100644 --- a/include/json/writer.h +++ b/include/json/writer.h @@ -145,7 +145,7 @@ public: /** \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 @@ public: #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 @@ private: #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 @@ private: #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 @@ public: * \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 d2d41aa..cb9db66 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 5d6207c..ac673ff 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 @@ public: }; 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 @@ private: 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 6ee999c..cf93ec7 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 4b91035..e16d84f 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 @@ private: 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 c0b5296..0cc500a 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 e9c11a4..5d213dc 100644 --- a/src/test_lib_json/jsontest.h +++ b/src/test_lib_json/jsontest.h @@ -68,8 +68,8 @@ public: 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 @@ public: 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 @@ private: }; 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