netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / tests / test-json.c
1 /*
2  * Copyright (c) 2009, 2010, 2014 Nicira, Inc.
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 #undef NDEBUG
19 #include "json.h"
20 #include <ctype.h>
21 #include <errno.h>
22 #include <getopt.h>
23 #include <stdio.h>
24 #include "ovstest.h"
25 #include "util.h"
26
27 /* --pretty: If set, the JSON output is pretty-printed, instead of printed as
28  * compactly as possible.  */
29 static int pretty = 0;
30
31 /* --multiple: If set, the input is a sequence of JSON objects or arrays,
32  * instead of exactly one object or array. */
33 static int multiple = 0;
34
35 static bool
36 print_and_free_json(struct json *json)
37 {
38     bool ok;
39     if (json->type == JSON_STRING) {
40         printf("error: %s\n", json->u.string);
41         ok = false;
42     } else {
43         char *s = json_to_string(json, JSSF_SORT | (pretty ? JSSF_PRETTY : 0));
44         puts(s);
45         free(s);
46         ok = true;
47     }
48     json_destroy(json);
49     return ok;
50 }
51
52 static bool
53 refill(FILE *file, void *buffer, size_t buffer_size, size_t *n, size_t *used)
54 {
55     *used = 0;
56     if (feof(file)) {
57         *n = 0;
58         return false;
59     } else {
60         *n = fread(buffer, 1, buffer_size, file);
61         if (ferror(file)) {
62             ovs_fatal(errno, "Error reading input file");
63         }
64         return *n > 0;
65     }
66 }
67
68 static bool
69 parse_multiple(FILE *stream)
70 {
71     struct json_parser *parser;
72     char buffer[BUFSIZ];
73     size_t n, used;
74     bool ok;
75
76     parser = NULL;
77     n = used = 0;
78     ok = true;
79     while (used < n || refill(stream, buffer, sizeof buffer, &n, &used)) {
80         if (!parser && isspace((unsigned char) buffer[used])) {
81             /* Skip white space. */
82             used++;
83         } else {
84             if (!parser) {
85                 parser = json_parser_create(0);
86             }
87
88             used += json_parser_feed(parser, &buffer[used], n - used);
89             if (used < n) {
90                 if (!print_and_free_json(json_parser_finish(parser))) {
91                     ok = false;
92                 }
93                 parser = NULL;
94             }
95         }
96     }
97     if (parser) {
98         if (!print_and_free_json(json_parser_finish(parser))) {
99             ok = false;
100         }
101     }
102     return ok;
103 }
104
105 static void
106 test_json_main(int argc, char *argv[])
107 {
108     const char *input_file;
109     FILE *stream;
110     bool ok;
111
112     set_program_name(argv[0]);
113
114     for (;;) {
115         static const struct option options[] = {
116             {"pretty", no_argument, &pretty, 1},
117             {"multiple", no_argument, &multiple, 1},
118         };
119         int option_index = 0;
120         int c = getopt_long (argc, argv, "", options, &option_index);
121
122         if (c == -1) {
123             break;
124         }
125         switch (c) {
126         case 0:
127             break;
128
129         case '?':
130             exit(1);
131
132         default:
133             abort();
134         }
135     }
136
137     if (argc - optind != 1) {
138         ovs_fatal(0, "usage: %s [--pretty] [--multiple] INPUT.json",
139                   program_name);
140     }
141
142     input_file = argv[optind];
143     stream = !strcmp(input_file, "-") ? stdin : fopen(input_file, "r");
144     if (!stream) {
145         ovs_fatal(errno, "Cannot open \"%s\"", input_file);
146     }
147
148     if (multiple) {
149         ok = parse_multiple(stream);
150     } else {
151         ok = print_and_free_json(json_from_stream(stream));
152     }
153
154     fclose(stream);
155
156     exit(!ok);
157 }
158
159 OVSTEST_REGISTER("test-json", test_json_main);