blob: 98cd8fdd03b56256b7e7b1ec0493ba8f7d78e9f5 [file] [log] [blame]
Baptiste Lepilleur4cd8bae2007-03-15 22:11:38 +00001#include <json/json.h>
2#include <algorithm> // sort
3#include <stdio.h>
4
5#if defined(_MSC_VER) && _MSC_VER >= 1310
6# pragma warning( disable: 4996 ) // disable fopen deprecation warning
7#endif
8
9static std::string
10readInputTestFile( const char *path )
11{
12 FILE *file = fopen( path, "rb" );
13 if ( !file )
14 return std::string("");
15 fseek( file, 0, SEEK_END );
16 int size = ftell( file );
17 fseek( file, 0, SEEK_SET );
18 std::string text;
19 char *buffer = new char[size+1];
20 buffer[size] = 0;
21 if ( fread( buffer, 1, size, file ) == size )
22 text = buffer;
23 fclose( file );
24 delete[] buffer;
25 return text;
26}
27
28
29static void
30printValueTree( FILE *fout, Json::Value &value, const std::string &path = "." )
31{
32 switch ( value.type() )
33 {
34 case Json::nullValue:
35 fprintf( fout, "%s=null\n", path.c_str() );
36 break;
37 case Json::intValue:
38 fprintf( fout, "%s=%d\n", path.c_str(), value.asInt() );
39 break;
40 case Json::uintValue:
41 fprintf( fout, "%s=%u\n", path.c_str(), value.asUInt() );
42 break;
43 case Json::realValue:
44 fprintf( fout, "%s=%.16g\n", path.c_str(), value.asDouble() );
45 break;
46 case Json::stringValue:
47 fprintf( fout, "%s=\"%s\"\n", path.c_str(), value.asString().c_str() );
48 break;
49 case Json::booleanValue:
50 fprintf( fout, "%s=%s\n", path.c_str(), value.asBool() ? "true" : "false" );
51 break;
52 case Json::arrayValue:
53 {
54 fprintf( fout, "%s=[]\n", path.c_str() );
55 int size = value.size();
56 for ( int index =0; index < size; ++index )
57 {
58 static char buffer[16];
59 sprintf( buffer, "[%d]", index );
60 printValueTree( fout, value[index], path + buffer );
61 }
62 }
63 break;
64 case Json::objectValue:
65 {
66 fprintf( fout, "%s={}\n", path.c_str() );
67 Json::Value::Members members( value.getMemberNames() );
68 std::sort( members.begin(), members.end() );
69 std::string suffix = *(path.end()-1) == '.' ? "" : ".";
70 for ( Json::Value::Members::iterator it = members.begin();
71 it != members.end();
72 ++it )
73 {
74 const std::string &name = *it;
75 printValueTree( fout, value[name], path + suffix + name );
76 }
77 }
78 break;
79 default:
80 break;
81 }
82}
83
84
85static int
86parseAndSaveValueTree( const std::string &input,
87 const std::string &actual,
88 const std::string &kind,
89 Json::Value &root )
90{
91 Json::Reader reader;
92 bool parsingSuccessful = reader.parse( input, root );
93 if ( !parsingSuccessful )
94 {
95 printf( "Failed to parse %s file: \n%s\n",
96 kind.c_str(),
97 reader.getFormatedErrorMessages().c_str() );
98 return 1;
99 }
100
101 FILE *factual = fopen( actual.c_str(), "wt" );
102 if ( !factual )
103 {
104 printf( "Failed to create %s actual file.\n", kind.c_str() );
105 return 2;
106 }
107 printValueTree( factual, root );
108 fclose( factual );
109 return 0;
110}
111
112
113static int
114rewriteValueTree( const std::string &rewritePath,
115 const Json::Value &root,
116 std::string &rewrite )
117{
Baptiste Lepilleur2d4dd282007-03-17 22:14:59 +0000118 //Json::FastWriter writer;
119 //writer.enableYAMLCompatibility();
Baptiste Lepilleur4cd8bae2007-03-15 22:11:38 +0000120 Json::StyledWriter writer;
121 rewrite = writer.write( root );
122 FILE *fout = fopen( rewritePath.c_str(), "wt" );
123 if ( !fout )
124 {
125 printf( "Failed to create rewrite file: %s\n", rewritePath.c_str() );
126 return 2;
127 }
128 fprintf( fout, "%s\n", rewrite.c_str() );
129 fclose( fout );
130 return 0;
131}
132
133
134static std::string
135removeSuffix( const std::string &path,
136 const std::string &extension )
137{
138 if ( extension.length() >= path.length() )
139 return std::string("");
140 std::string suffix = path.substr( path.length() - extension.length() );
141 if ( suffix != extension )
142 return std::string("");
143 return path.substr( 0, path.length() - extension.length() );
144}
145
146int main( int argc, const char *argv[] )
147{
148 if ( argc != 2 )
149 {
150 printf( "Usage: %s input-json-file", argv[0] );
151 return 3;
152 }
153
154 std::string input = readInputTestFile( argv[1] );
155 if ( input.empty() )
156 {
157 printf( "Failed to read input or empty input: %s\n", argv[1] );
158 return 3;
159 }
160
161 std::string basePath = removeSuffix( argv[1], ".json" );
162 if ( basePath.empty() )
163 {
164 printf( "Bad input path. Path does not end with '.expected':\n%s\n", argv[1] );
165 return 3;
166 }
167
168 std::string actualPath = basePath + ".actual";
169 std::string rewritePath = basePath + ".rewrite";
170 std::string rewriteActualPath = basePath + ".actual-rewrite";
171
172 Json::Value root;
173 int exitCode = parseAndSaveValueTree( input, actualPath, "input", root );
174 if ( exitCode == 0 )
175 {
176 std::string rewrite;
177 exitCode = rewriteValueTree( rewritePath, root, rewrite );
178 if ( exitCode == 0 )
179 {
180 Json::Value rewriteRoot;
181 exitCode = parseAndSaveValueTree( rewrite, rewriteActualPath, "rewrite", rewriteRoot );
182 }
183 }
184
185 return exitCode;
Christopher Dunnbaca6c22007-03-23 03:31:35 +0000186}
187