summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/jsoncpp/src/jsontestrunner/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/jsoncpp/src/jsontestrunner/main.cpp')
-rw-r--r--3rdparty/jsoncpp/src/jsontestrunner/main.cpp277
1 files changed, 277 insertions, 0 deletions
diff --git a/3rdparty/jsoncpp/src/jsontestrunner/main.cpp b/3rdparty/jsoncpp/src/jsontestrunner/main.cpp
new file mode 100644
index 00000000000..ba985877db4
--- /dev/null
+++ b/3rdparty/jsoncpp/src/jsontestrunner/main.cpp
@@ -0,0 +1,277 @@
+// 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
+
+/* This executable is used for testing parser/writer using real JSON files.
+ */
+
+#include <json/json.h>
+#include <algorithm> // sort
+#include <stdio.h>
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310
+#pragma warning(disable : 4996) // disable fopen deprecation warning
+#endif
+
+static std::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
+ buffer[sizeof(buffer) - 1] = 0;
+ std::string s(buffer);
+ std::string::size_type index = s.find_last_of("eE");
+ if (index != std::string::npos) {
+ std::string::size_type hasSign =
+ (s[index + 1] == '+' || s[index + 1] == '-') ? 1 : 0;
+ std::string::size_type exponentStartIndex = index + 1 + hasSign;
+ std::string normalized = s.substr(0, exponentStartIndex);
+ std::string::size_type indexDigit =
+ s.find_first_not_of('0', exponentStartIndex);
+ std::string exponent = "0";
+ if (indexDigit !=
+ std::string::npos) // There is an exponent different from 0
+ {
+ exponent = s.substr(indexDigit);
+ }
+ return normalized + exponent;
+ }
+ return s;
+}
+
+static std::string readInputTestFile(const char* path) {
+ FILE* file = fopen(path, "rb");
+ if (!file)
+ return std::string("");
+ fseek(file, 0, SEEK_END);
+ long size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+ std::string text;
+ char* buffer = new char[size + 1];
+ buffer[size] = 0;
+ if (fread(buffer, 1, size, file) == (unsigned long)size)
+ text = buffer;
+ fclose(file);
+ delete[] buffer;
+ return text;
+}
+
+static void
+printValueTree(FILE* fout, Json::Value& value, const std::string& path = ".") {
+ if (value.hasComment(Json::commentBefore)) {
+ fprintf(fout, "%s\n", value.getComment(Json::commentBefore).c_str());
+ }
+ switch (value.type()) {
+ case Json::nullValue:
+ fprintf(fout, "%s=null\n", path.c_str());
+ break;
+ case Json::intValue:
+ 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(),
+ Json::valueToString(value.asLargestUInt()).c_str());
+ break;
+ case Json::realValue:
+ fprintf(fout,
+ "%s=%s\n",
+ path.c_str(),
+ normalizeFloatingPointStr(value.asDouble()).c_str());
+ break;
+ case Json::stringValue:
+ fprintf(fout, "%s=\"%s\"\n", path.c_str(), value.asString().c_str());
+ break;
+ case Json::booleanValue:
+ fprintf(fout, "%s=%s\n", path.c_str(), value.asBool() ? "true" : "false");
+ break;
+ case Json::arrayValue: {
+ fprintf(fout, "%s=[]\n", path.c_str());
+ int size = value.size();
+ for (int index = 0; index < size; ++index) {
+ static char buffer[16];
+#if defined(_MSC_VER) && defined(__STDC_SECURE_LIB__)
+ sprintf_s(buffer, sizeof(buffer), "[%d]", index);
+#else
+ snprintf(buffer, sizeof(buffer), "[%d]", index);
+#endif
+ printValueTree(fout, value[index], path + buffer);
+ }
+ } break;
+ case Json::objectValue: {
+ fprintf(fout, "%s={}\n", path.c_str());
+ Json::Value::Members members(value.getMemberNames());
+ std::sort(members.begin(), members.end());
+ std::string suffix = *(path.end() - 1) == '.' ? "" : ".";
+ for (Json::Value::Members::iterator it = members.begin();
+ it != members.end();
+ ++it) {
+ const std::string& name = *it;
+ printValueTree(fout, value[name], path + suffix + name);
+ }
+ } break;
+ default:
+ break;
+ }
+
+ if (value.hasComment(Json::commentAfter)) {
+ fprintf(fout, "%s\n", value.getComment(Json::commentAfter).c_str());
+ }
+}
+
+static int parseAndSaveValueTree(const std::string& input,
+ const std::string& actual,
+ const std::string& kind,
+ Json::Value& root,
+ const Json::Features& features,
+ bool parseOnly) {
+ Json::Reader reader(features);
+ bool parsingSuccessful = reader.parse(input, root);
+ if (!parsingSuccessful) {
+ printf("Failed to parse %s file: \n%s\n",
+ kind.c_str(),
+ reader.getFormattedErrorMessages().c_str());
+ return 1;
+ }
+
+ if (!parseOnly) {
+ FILE* factual = fopen(actual.c_str(), "wt");
+ if (!factual) {
+ printf("Failed to create %s actual file.\n", kind.c_str());
+ return 2;
+ }
+ printValueTree(factual, root);
+ fclose(factual);
+ }
+ return 0;
+}
+
+static int rewriteValueTree(const std::string& rewritePath,
+ const Json::Value& root,
+ std::string& rewrite) {
+ // Json::FastWriter writer;
+ // writer.enableYAMLCompatibility();
+ Json::StyledWriter writer;
+ rewrite = writer.write(root);
+ FILE* fout = fopen(rewritePath.c_str(), "wt");
+ if (!fout) {
+ printf("Failed to create rewrite file: %s\n", rewritePath.c_str());
+ return 2;
+ }
+ fprintf(fout, "%s\n", rewrite.c_str());
+ fclose(fout);
+ return 0;
+}
+
+static std::string removeSuffix(const std::string& path,
+ const std::string& extension) {
+ if (extension.length() >= path.length())
+ return std::string("");
+ std::string suffix = path.substr(path.length() - extension.length());
+ if (suffix != extension)
+ return std::string("");
+ return path.substr(0, path.length() - extension.length());
+}
+
+static void printConfig() {
+// Print the configuration used to compile JsonCpp
+#if defined(JSON_NO_INT64)
+ printf("JSON_NO_INT64=1\n");
+#else
+ printf("JSON_NO_INT64=0\n");
+#endif
+}
+
+static int printUsage(const char* argv[]) {
+ printf("Usage: %s [--strict] input-json-file", argv[0]);
+ return 3;
+}
+
+int parseCommandLine(int argc,
+ const char* argv[],
+ Json::Features& features,
+ std::string& path,
+ bool& parseOnly) {
+ parseOnly = false;
+ if (argc < 2) {
+ return printUsage(argv);
+ }
+
+ int index = 1;
+ if (std::string(argv[1]) == "--json-checker") {
+ features = Json::Features::strictMode();
+ parseOnly = true;
+ ++index;
+ }
+
+ if (std::string(argv[1]) == "--json-config") {
+ printConfig();
+ return 3;
+ }
+
+ if (index == argc || index + 1 < argc) {
+ return printUsage(argv);
+ }
+
+ path = argv[index];
+ return 0;
+}
+
+int main(int argc, const char* argv[]) {
+ std::string path;
+ Json::Features features;
+ bool parseOnly;
+ int exitCode = parseCommandLine(argc, argv, features, path, parseOnly);
+ if (exitCode != 0) {
+ return exitCode;
+ }
+
+ try {
+ std::string input = readInputTestFile(path.c_str());
+ if (input.empty()) {
+ printf("Failed to read input or empty input: %s\n", path.c_str());
+ return 3;
+ }
+
+ std::string basePath = removeSuffix(argv[1], ".json");
+ if (!parseOnly && basePath.empty()) {
+ printf("Bad input path. Path does not end with '.expected':\n%s\n",
+ path.c_str());
+ return 3;
+ }
+
+ std::string actualPath = basePath + ".actual";
+ std::string rewritePath = basePath + ".rewrite";
+ std::string rewriteActualPath = basePath + ".actual-rewrite";
+
+ Json::Value root;
+ exitCode = parseAndSaveValueTree(
+ input, actualPath, "input", root, features, parseOnly);
+ if (exitCode == 0 && !parseOnly) {
+ std::string rewrite;
+ exitCode = rewriteValueTree(rewritePath, root, rewrite);
+ if (exitCode == 0) {
+ Json::Value rewriteRoot;
+ exitCode = parseAndSaveValueTree(rewrite,
+ rewriteActualPath,
+ "rewrite",
+ rewriteRoot,
+ features,
+ parseOnly);
+ }
+ }
+ }
+ catch (const std::exception& e) {
+ printf("Unhandled exception:\n%s\n", e.what());
+ exitCode = 1;
+ }
+
+ return exitCode;
+}