]> git.proxmox.com Git - mirror_ovs.git/blame - tests/test-json.c
ovs-dev.py: Build with both GCC and Clang.
[mirror_ovs.git] / tests / test-json.c
CommitLineData
f38b84ea 1/*
1600fa68 2 * Copyright (c) 2009, 2010, 2013 Nicira, Inc.
f38b84ea
BP
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. */
30static 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. */
34static int multiple = 0;
35
36static bool
37print_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));
1600fa68 45 ovs_assert(pretty || json_serialized_length(json) == strlen(s));
f38b84ea
BP
46 puts(s);
47 free(s);
48 ok = true;
49 }
50 json_destroy(json);
51 return ok;
52}
53
54static bool
55refill(FILE *file, void *buffer, size_t buffer_size, size_t *n, size_t *used)
56{
57 *used = 0;
58 if (feof(file)) {
59 *n = 0;
60 return false;
61 } else {
62 *n = fread(buffer, 1, buffer_size, file);
63 if (ferror(file)) {
64 ovs_fatal(errno, "Error reading input file");
65 }
66 return *n > 0;
67 }
68}
69
70static bool
5562d6f5 71parse_multiple(FILE *stream)
f38b84ea
BP
72{
73 struct json_parser *parser;
74 char buffer[BUFSIZ];
75 size_t n, used;
f38b84ea
BP
76 bool ok;
77
f38b84ea
BP
78 parser = NULL;
79 n = used = 0;
80 ok = true;
5562d6f5 81 while (used < n || refill(stream, buffer, sizeof buffer, &n, &used)) {
f38b84ea
BP
82 if (!parser && isspace((unsigned char) buffer[used])) {
83 /* Skip white space. */
84 used++;
85 } else {
86 if (!parser) {
87 parser = json_parser_create(0);
88 }
89
f2129093 90 used += json_parser_feed(parser, &buffer[used], n - used);
f38b84ea
BP
91 if (used < n) {
92 if (!print_and_free_json(json_parser_finish(parser))) {
93 ok = false;
94 }
95 parser = NULL;
96 }
97 }
98 }
99 if (parser) {
100 if (!print_and_free_json(json_parser_finish(parser))) {
101 ok = false;
102 }
103 }
104 return ok;
105}
106
107int
108main(int argc, char *argv[])
109{
110 const char *input_file;
5562d6f5 111 FILE *stream;
f38b84ea
BP
112 bool ok;
113
114 set_program_name(argv[0]);
115
116 for (;;) {
117 static const struct option options[] = {
118 {"pretty", no_argument, &pretty, 1},
119 {"multiple", no_argument, &multiple, 1},
120 };
121 int option_index = 0;
122 int c = getopt_long (argc, argv, "", options, &option_index);
123
124 if (c == -1) {
125 break;
126 }
127 switch (c) {
128 case 0:
129 break;
130
131 case '?':
132 exit(1);
133
134 default:
135 abort();
136 }
137 }
138
139 if (argc - optind != 1) {
140 ovs_fatal(0, "usage: %s [--pretty] [--multiple] INPUT.json",
141 program_name);
142 }
143
144 input_file = argv[optind];
5562d6f5
BP
145 stream = !strcmp(input_file, "-") ? stdin : fopen(input_file, "r");
146 if (!stream) {
147 ovs_fatal(errno, "Cannot open \"%s\"", input_file);
f38b84ea
BP
148 }
149
150 if (multiple) {
5562d6f5 151 ok = parse_multiple(stream);
f38b84ea 152 } else {
5562d6f5 153 ok = print_and_free_json(json_from_stream(stream));
f38b84ea
BP
154 }
155
93ff0290
BP
156 fclose(stream);
157
f38b84ea
BP
158 return !ok;
159}