2 * Copyright (C) 2013 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.
19 static struct json_object *
20 jp_match_next(struct jp_opcode *ptr,
21 struct json_object *root, struct json_object *cur);
24 jp_json_to_op(struct json_object *obj, struct jp_opcode *op)
26 switch (json_object_get_type(obj))
28 case json_type_boolean:
30 op->num = json_object_get_boolean(obj);
35 op->num = json_object_get_int(obj);
38 case json_type_string:
40 op->str = (char *)json_object_get_string(obj);
49 jp_resolve(struct json_object *root, struct json_object *cur,
50 struct jp_opcode *op, struct jp_opcode *res)
52 struct json_object *val;
57 val = jp_match(op, cur);
60 return jp_json_to_op(val, res);
65 val = jp_match(op, root);
68 return jp_json_to_op(val, res);
79 jp_cmp(struct jp_opcode *op, struct json_object *root, struct json_object *cur)
82 struct jp_opcode left, right;
84 if (!jp_resolve(root, cur, op->down, &left) ||
85 !jp_resolve(root, cur, op->down->sibling, &right))
88 if (left.type != right.type)
95 delta = left.num - right.num;
99 delta = strcmp(left.str, right.str);
132 jp_expr(struct jp_opcode *op, struct json_object *root, struct json_object *cur)
134 struct jp_opcode *sop;
147 return jp_cmp(op, root, cur);
150 return !!jp_match(op, root);
153 return !!jp_match(op, cur);
156 return !jp_expr(op->down, root, cur);
159 for (sop = op->down; sop; sop = sop->sibling)
160 if (!jp_expr(sop, root, cur))
165 for (sop = op->down; sop; sop = sop->sibling)
166 if (jp_expr(sop, root, cur))
175 static struct json_object *
176 jp_match_expr(struct jp_opcode *ptr,
177 struct json_object *root, struct json_object *cur)
180 struct json_object *tmp, *res = NULL;
182 switch (json_object_get_type(cur))
184 case json_type_object:
185 ; /* a label can only be part of a statement and a declaration is not a statement */
186 json_object_object_foreach(cur, key, val)
191 if (jp_expr(ptr, root, val))
193 tmp = jp_match_next(ptr->sibling, root, val);
202 case json_type_array:
203 len = json_object_array_length(cur);
205 for (idx = 0; idx < len; idx++)
207 tmp = json_object_array_get_idx(cur, idx);
209 if (jp_expr(ptr, root, tmp))
211 tmp = jp_match_next(ptr->sibling, root, tmp);
227 static struct json_object *
228 jp_match_next(struct jp_opcode *ptr,
229 struct json_object *root, struct json_object *cur)
231 struct json_object *next;
240 if (json_object_object_get_ex(cur, ptr->str, &next))
241 return jp_match_next(ptr->sibling, root, next);
246 next = json_object_array_get_idx(cur, ptr->num);
249 return jp_match_next(ptr->sibling, root, next);
254 return jp_match_expr(ptr, root, cur);
261 jp_match(struct jp_opcode *path, json_object *jsobj)
263 if (path->type == T_LABEL)
266 return jp_match_next(path->down, jsobj, jsobj);