MACSio  0.9
Multi-purpose, Application-Centric, Scalable I/O Proxy App
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
test_parse.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include <assert.h>
6 
7 #include "json.h"
8 #include "json_tokener.h"
9 
10 static void test_basic_parse(void);
11 static void test_verbose_parse(void);
12 static void test_incremental_parse(void);
13 
14 int main(int argc, char **argv)
15 {
16  MC_SET_DEBUG(1);
17 
19  printf("==================================\n");
21  printf("==================================\n");
23  printf("==================================\n");
24 }
25 
26 static void test_basic_parse()
27 {
28  json_object *new_obj;
29 
30  new_obj = json_tokener_parse("\"\003\"");
31  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
32  json_object_put(new_obj);
33 
34  new_obj = json_tokener_parse("/* hello */\"foo\"");
35  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
36  json_object_put(new_obj);
37 
38  new_obj = json_tokener_parse("// hello\n\"foo\"");
39  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
40  json_object_put(new_obj);
41 
42  new_obj = json_tokener_parse("\"\\u0041\\u0042\\u0043\"");
43  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
44  json_object_put(new_obj);
45 
46  new_obj = json_tokener_parse("null");
47  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
48  json_object_put(new_obj);
49 
50  new_obj = json_tokener_parse("NaN");
51  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
52  json_object_put(new_obj);
53 
54  new_obj = json_tokener_parse("-NaN"); /* non-sensical, returns null */
55  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
56  json_object_put(new_obj);
57 
58  new_obj = json_tokener_parse("Inf"); /* must use full string, returns null */
59  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
60  json_object_put(new_obj);
61 
62  new_obj = json_tokener_parse("inf"); /* must use full string, returns null */
63  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
64  json_object_put(new_obj);
65 
66  new_obj = json_tokener_parse("Infinity");
67  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
68  json_object_put(new_obj);
69 
70  new_obj = json_tokener_parse("infinity");
71  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
72  json_object_put(new_obj);
73 
74  new_obj = json_tokener_parse("-Infinity");
75  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
76  json_object_put(new_obj);
77 
78  new_obj = json_tokener_parse("-infinity");
79  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
80  json_object_put(new_obj);
81 
82  new_obj = json_tokener_parse("True");
83  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
84  json_object_put(new_obj);
85 
86  new_obj = json_tokener_parse("12");
87  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
88  json_object_put(new_obj);
89 
90  new_obj = json_tokener_parse("12.3");
91  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
92  json_object_put(new_obj);
93 
94  new_obj = json_tokener_parse("[\"\\n\"]");
95  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
96  json_object_put(new_obj);
97 
98  new_obj = json_tokener_parse("[\"\\nabc\\n\"]");
99  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
100  json_object_put(new_obj);
101 
102  new_obj = json_tokener_parse("[null]");
103  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
104  json_object_put(new_obj);
105 
106  new_obj = json_tokener_parse("[]");
107  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
108  json_object_put(new_obj);
109 
110  new_obj = json_tokener_parse("[false]");
111  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
112  json_object_put(new_obj);
113 
114  new_obj = json_tokener_parse("[\"abc\",null,\"def\",12]");
115  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
116  json_object_put(new_obj);
117 
118  new_obj = json_tokener_parse("{}");
119  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
120  json_object_put(new_obj);
121 
122  new_obj = json_tokener_parse("{ \"foo\": \"bar\" }");
123  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
124  json_object_put(new_obj);
125 
126  new_obj = json_tokener_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }");
127  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
128  json_object_put(new_obj);
129 
130  new_obj = json_tokener_parse("{ \"foo\": [null, \"foo\"] }");
131  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
132  json_object_put(new_obj);
133 
134  new_obj = json_tokener_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }");
135  printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
136  json_object_put(new_obj);
137 }
138 
139 static void test_verbose_parse()
140 {
141  json_object *new_obj;
143 
144  new_obj = json_tokener_parse_verbose("{ foo }", &error);
146  assert (new_obj == NULL);
147 
148  new_obj = json_tokener_parse("{ foo }");
149  assert (new_obj == NULL);
150 
151  new_obj = json_tokener_parse("foo");
152  assert (new_obj == NULL);
153  new_obj = json_tokener_parse_verbose("foo", &error);
154  assert (new_obj == NULL);
155 
156  /* b/c the string starts with 'f' parsing return a boolean error */
157  assert (error == json_tokener_error_parse_boolean);
158 
159  printf("json_tokener_parse_versbose() OK\n");
160 }
161 
163  const char *string_to_parse;
164  int length;
168 } incremental_steps[] = {
169 
170  /* Check that full json messages can be parsed, both w/ and w/o a reset */
171  { "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 },
172  { "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 },
173  { "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 },
174 
175  /* Check a basic incremental parse */
176  { "{ \"foo", -1, -1, json_tokener_continue, 0 },
177  { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
178  { "\":13}}", -1, -1, json_tokener_success, 1 },
179 
180  /* Check that json_tokener_reset actually resets */
181  { "{ \"foo", -1, -1, json_tokener_continue, 1 },
182  { ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 },
183 
184  /* Check incremental parsing with trailing characters */
185  { "{ \"foo", -1, -1, json_tokener_continue, 0 },
186  { "\": {\"bar", -1, -1, json_tokener_continue, 0 },
187  { "\":13}}XXXX", 10, 6, json_tokener_success, 0 },
188  { "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 },
189 
190  /* Check that trailing characters can change w/o a reset */
191  { "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 },
192  { "\"Y\"", -1, -1, json_tokener_success, 1 },
193 
194  /* To stop parsing a number we need to reach a non-digit, e.g. a \0 */
195  { "1", 1, 1, json_tokener_continue, 0 },
196  { "2", 2, 1, json_tokener_success, 0 },
197 
198  /* Strings have a well defined end point, so we can stop at the quote */
199  { "\"blue\"", -1, -1, json_tokener_success, 0 },
200 
201  /* Check each of the escape sequences defined by the spec */
202  { "\"\\\"\"", -1, -1, json_tokener_success, 0 },
203  { "\"\\\\\"", -1, -1, json_tokener_success, 0 },
204  { "\"\\b\"", -1, -1, json_tokener_success, 0 },
205  { "\"\\f\"", -1, -1, json_tokener_success, 0 },
206  { "\"\\n\"", -1, -1, json_tokener_success, 0 },
207  { "\"\\r\"", -1, -1, json_tokener_success, 0 },
208  { "\"\\t\"", -1, -1, json_tokener_success, 0 },
209 
210  { "[1,2,3]", -1, -1, json_tokener_success, 0 },
211 
212  /* This behaviour doesn't entirely follow the json spec, but until we have
213  a way to specify how strict to be we follow Postel's Law and be liberal
214  in what we accept (up to a point). */
215  { "[1,2,3,]", -1, -1, json_tokener_success, 0 },
216  { "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 },
217 
218  { "[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3 },
219  { "{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3 },
220 
221  { NULL, -1, -1, json_tokener_success, 0 },
222 };
223 
225 {
226  json_object *new_obj;
227  enum json_tokener_error jerr;
228  json_tokener *tok;
229  const char *string_to_parse;
230  int ii;
231  int num_ok, num_error;
232 
233  num_ok = 0;
234  num_error = 0;
235 
236  printf("Starting incremental tests.\n");
237  printf("Note: quotes and backslashes seen in the output here are literal values passed\n");
238  printf(" to the parse functions. e.g. this is 4 characters: \"\\f\"\n");
239 
240  string_to_parse = "{ \"foo"; /* } */
241  printf("json_tokener_parse(%s) ... ", string_to_parse);
242  new_obj = json_tokener_parse(string_to_parse);
243  if (new_obj == NULL) printf("got error as expected\n");
244 
245  /* test incremental parsing in various forms */
246  tok = json_tokener_new();
247  for (ii = 0; incremental_steps[ii].string_to_parse != NULL; ii++)
248  {
249  int this_step_ok = 0;
250  struct incremental_step *step = &incremental_steps[ii];
251  int length = step->length;
252  int expected_char_offset = step->char_offset;
253 
254  if (step->reset_tokener & 2)
256  else
257  json_tokener_set_flags(tok, 0);
258 
259  if (length == -1)
260  length = strlen(step->string_to_parse);
261  if (expected_char_offset == -1)
262  expected_char_offset = length;
263 
264  printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ",
265  step->string_to_parse, length);
266  new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
267 
268  jerr = json_tokener_get_error(tok);
270  {
271  if (new_obj != NULL)
272  printf("ERROR: invalid object returned: %s\n",
273  json_object_to_json_string(new_obj));
274  else if (jerr != step->expected_error)
275  printf("ERROR: got wrong error: %s\n",
277  else if (tok->char_offset != expected_char_offset)
278  printf("ERROR: wrong char_offset %d != expected %d\n",
279  tok->char_offset,
280  expected_char_offset);
281  else
282  {
283  printf("OK: got correct error: %s\n", json_tokener_error_desc(jerr));
284  this_step_ok = 1;
285  }
286  }
287  else
288  {
289  if (new_obj == NULL)
290  printf("ERROR: expected valid object, instead: %s\n",
292  else if (tok->char_offset != expected_char_offset)
293  printf("ERROR: wrong char_offset %d != expected %d\n",
294  tok->char_offset,
295  expected_char_offset);
296  else
297  {
298  printf("OK: got object of type [%s]: %s\n",
300  json_object_to_json_string(new_obj));
301  this_step_ok = 1;
302  }
303  }
304 
305  if (new_obj)
306  json_object_put(new_obj);
307 
308  if (step->reset_tokener & 1)
309  json_tokener_reset(tok);
310 
311  if (this_step_ok)
312  num_ok++;
313  else
314  num_error++;
315  }
316 
317  json_tokener_free(tok);
318 
319  printf("End Incremental Tests OK=%d ERROR=%d\n", num_ok, num_error);
320 
321  return;
322 }
int main(int argc, char **argv)
Definition: test_parse.c:14
struct incremental_step incremental_steps[]
static void test_incremental_parse(void)
Definition: test_parse.c:224
struct json_tokener * json_tokener_new(void)
Definition: json_tokener.c:123
void json_tokener_reset(struct json_tokener *tok)
Definition: json_tokener.c:146
void json_tokener_free(struct json_tokener *tok)
Definition: json_tokener.c:128
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
Definition: json_tokener.c:95
enum json_type json_object_get_type(struct json_object *obj)
Definition: json_object.c:211
static void test_verbose_parse(void)
Definition: test_parse.c:139
const char * json_type_to_name(enum json_type o_type)
Definition: json_util.c:308
void json_tokener_set_flags(struct json_tokener *tok, int flags)
#define JSON_TOKENER_STRICT
Definition: json_tokener.h:110
#define MC_SET_DEBUG(x)
Definition: debug.h:60
const char * json_tokener_error_desc(enum json_tokener_error jerr)
Definition: json_tokener.c:87
struct json_object * json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
Definition: json_tokener.c:166
struct json_object * json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
Definition: json_tokener.c:273
static void test_basic_parse(void)
Definition: test_parse.c:26
enum json_tokener_error expected_error
Definition: test_parse.c:166
int json_object_put(struct json_object *obj)
Definition: json_object.c:155
const char * string_to_parse
Definition: test_parse.c:163
const char * json_object_to_json_string(struct json_object *obj)
Definition: json_object.c:295
struct json_object * json_tokener_parse(const char *str)
Definition: json_tokener.c:158
json_tokener_error
Definition: json_tokener.h:22