]> git.proxmox.com Git - ovs.git/blob - tests/test-json.c
f297dc205ea0c0f0d804ec6a61e094158a485fe6
[ovs.git] / tests / test-json.c
1 /*
2 * Copyright (c) 2009, 2010 Nicira Networks.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18
19 #include "json.h"
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <getopt.h>
24 #include <stdio.h>
25
26 #include "util.h"
27
28 /* --pretty: If set, the JSON output is pretty-printed, instead of printed as
29 * compactly as possible. */
30 static int pretty = 0;
31
32 /* --multiple: If set, the input is a sequence of JSON objects or arrays,
33 * instead of exactly one object or array. */
34 static int multiple = 0;
35
36 static bool
37 print_and_free_json(struct json *json)
38 {
39 bool ok;
40 if (json->type == JSON_STRING) {
41 printf("error: %s\n", json->u.string);
42 ok = false;
43 } else {
44 char *s = json_to_string(json, JSSF_SORT | (pretty ? JSSF_PRETTY : 0));
45 puts(s);
46 free(s);
47 ok = true;
48 }
49 json_destroy(json);
50 return ok;
51 }
52
53 static bool
54 refill(FILE *file, void *buffer, size_t buffer_size, size_t *n, size_t *used)
55 {
56 *used = 0;
57 if (feof(file)) {
58 *n = 0;
59 return false;
60 } else {
61 *n = fread(buffer, 1, buffer_size, file);
62 if (ferror(file)) {
63 ovs_fatal(errno, "Error reading input file");
64 }
65 return *n > 0;
66 }
67 }
68
69 static bool
70 parse_multiple(FILE *stream)
71 {
72 struct json_parser *parser;
73 char buffer[BUFSIZ];
74 size_t n, used;
75 bool ok;
76
77 parser = NULL;
78 n = used = 0;
79 ok = true;
80 while (used < n || refill(stream, buffer, sizeof buffer, &n, &used)) {
81 if (!parser && isspace((unsigned char) buffer[used])) {
82 /* Skip white space. */
83 used++;
84 } else {
85 if (!parser) {
86 parser = json_parser_create(0);
87 }
88
89 used += json_parser_feed(parser, &buffer[used], n - used);
90 if (used < n) {
91 if (!print_and_free_json(json_parser_finish(parser))) {
92 ok = false;
93 }
94 parser = NULL;
95 }
96 }
97 }
98 if (parser) {
99 if (!print_and_free_json(json_parser_finish(parser))) {
100 ok = false;
101 }
102 }
103 return ok;
104 }
105
106 int
107 main(int argc, char *argv[])
108 {
109 const char *input_file;
110 FILE *stream;
111 bool ok;
112
113 set_program_name(argv[0]);
114
115 for (;;) {
116 static const struct option options[] = {
117 {"pretty", no_argument, &pretty, 1},
118 {"multiple", no_argument, &multiple, 1},
119 };
120 int option_index = 0;
121 int c = getopt_long (argc, argv, "", options, &option_index);
122
123 if (c == -1) {
124 break;
125 }
126 switch (c) {
127 case 0:
128 break;
129
130 case '?':
131 exit(1);
132
133 default:
134 abort();
135 }
136 }
137
138 if (argc - optind != 1) {
139 ovs_fatal(0, "usage: %s [--pretty] [--multiple] INPUT.json",
140 program_name);
141 }
142
143 input_file = argv[optind];
144 stream = !strcmp(input_file, "-") ? stdin : fopen(input_file, "r");
145 if (!stream) {
146 ovs_fatal(errno, "Cannot open \"%s\"", input_file);
147 }
148
149 if (multiple) {
150 ok = parse_multiple(stream);
151 } else {
152 ok = print_and_free_json(json_from_stream(stream));
153 }
154
155 fclose(stream);
156
157 return !ok;
158 }