2 * Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 #include <json-c/json.h>
28 #include <libubox/list.h>
36 struct json_object
*jsobj
;
37 struct list_head list
;
40 static struct json_object
*
41 parse_json(FILE *fd
, const char *source
, const char **error
)
45 struct json_object
*obj
= NULL
;
46 struct json_tokener
*tok
= json_tokener_new();
47 enum json_tokener_error err
= json_tokener_continue
;
54 obj
= json_tokener_parse_ex(tok
, source
, strlen(source
));
55 err
= json_tokener_get_error(tok
);
59 while ((len
= fread(buf
, 1, sizeof(buf
), fd
)) > 0)
61 obj
= json_tokener_parse_ex(tok
, buf
, len
);
62 err
= json_tokener_get_error(tok
);
64 if (!err
|| err
!= json_tokener_continue
)
69 json_tokener_free(tok
);
73 if (err
== json_tokener_continue
)
74 err
= json_tokener_error_parse_eof
;
76 *error
= json_tokener_error_desc(err
);
84 print_string(const char *s
)
102 export_value(struct list_head
*matches
, const char *prefix
)
106 struct match_item
*item
;
108 if (list_empty(matches
))
113 printf("export %s=", prefix
);
115 list_for_each_entry(item
, matches
, list
)
117 switch (json_object_get_type(item
->jsobj
))
119 case json_type_object
:
120 ; /* a label can only be part of a statement */
121 json_object_object_foreach(item
->jsobj
, key
, val
)
134 case json_type_array
:
135 for (n
= 0, len
= json_object_array_length(item
->jsobj
);
146 case json_type_boolean
:
149 printf("%d", json_object_get_boolean(item
->jsobj
));
155 printf("%d", json_object_get_int(item
->jsobj
));
158 case json_type_double
:
161 printf("%f", json_object_get_double(item
->jsobj
));
164 case json_type_string
:
167 print_string(json_object_get_string(item
->jsobj
));
181 list_for_each_entry(item
, matches
, list
)
183 switch (json_object_get_type(item
->jsobj
))
185 case json_type_object
:
186 case json_type_array
:
187 case json_type_boolean
:
189 case json_type_double
:
190 printf("%s\n", json_object_to_json_string(item
->jsobj
));
193 case json_type_string
:
194 printf("%s\n", json_object_get_string(item
->jsobj
));
205 export_type(struct list_head
*matches
, const char *prefix
)
208 struct match_item
*item
;
209 const char *types
[] = {
219 if (list_empty(matches
))
223 printf("export %s=", prefix
);
225 list_for_each_entry(item
, matches
, list
)
230 printf("%s", types
[json_object_get_type(item
->jsobj
)]);
241 match_cb(struct json_object
*res
, void *priv
)
243 struct list_head
*h
= priv
;
244 struct match_item
*i
= calloc(1, sizeof(*i
));
249 list_add_tail(&i
->list
, h
);
254 filter_json(int opt
, struct json_object
*jsobj
, char *expr
)
256 struct jp_state
*state
;
257 const char *prefix
= NULL
;
258 struct list_head matches
;
259 struct match_item
*item
, *tmp
;
260 struct json_object
*res
= NULL
;
262 state
= jp_parse(expr
);
264 if (!state
|| state
->error
)
266 fprintf(stderr
, "Syntax error near {%s}: %s\n",
267 state
? expr
+ state
->erroff
: expr
,
268 state
? state
->error
: "Out of memory");
273 INIT_LIST_HEAD(&matches
);
275 res
= jp_match(state
->path
, jsobj
, match_cb
, &matches
);
276 prefix
= (state
->path
->type
== T_LABEL
) ? state
->path
->str
: NULL
;
281 export_type(&matches
, prefix
);
285 export_value(&matches
, prefix
);
289 list_for_each_entry_safe(item
, tmp
, &matches
, list
)
299 int main(int argc
, char **argv
)
303 struct json_object
*jsobj
= NULL
;
304 const char *jserr
= NULL
, *source
= NULL
;
306 while ((opt
= getopt(argc
, argv
, "i:s:e:t:q")) != -1)
311 input
= fopen(optarg
, "r");
315 fprintf(stderr
, "Failed to open %s: %s\n",
316 optarg
, strerror(errno
));
332 jsobj
= parse_json(input
, source
, &jserr
);
336 fprintf(stderr
, "Failed to parse json data: %s\n",
344 if (!filter_json(opt
, jsobj
, optarg
))
357 json_object_put(jsobj
);