2 * Copyright (C) 2013-2014 Jo-Philipp Wich <jo@mein.io>
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.
20 static struct json_object *
21 jp_match_next(struct jp_opcode *ptr,
22 struct json_object *root, struct json_object *cur,
23 jp_match_cb_t cb, void *priv);
26 jp_json_to_op(struct json_object *obj, struct jp_opcode *op)
28 switch (json_object_get_type(obj))
30 case json_type_boolean:
32 op->num = json_object_get_boolean(obj);
37 op->num = json_object_get_int(obj);
40 case json_type_string:
42 op->str = (char *)json_object_get_string(obj);
51 jp_resolve(struct json_object *root, struct json_object *cur,
52 struct jp_opcode *op, struct jp_opcode *res)
54 struct json_object *val;
59 val = jp_match(op, cur, NULL, NULL);
62 return jp_json_to_op(val, res);
67 val = jp_match(op, root, NULL, NULL);
70 return jp_json_to_op(val, res);
81 jp_cmp(struct jp_opcode *op, struct json_object *root, struct json_object *cur)
84 struct jp_opcode left, right;
86 if (!jp_resolve(root, cur, op->down, &left) ||
87 !jp_resolve(root, cur, op->down->sibling, &right))
90 if (left.type != right.type)
97 delta = left.num - right.num;
101 delta = strcmp(left.str, right.str);
134 jp_expr(struct jp_opcode *op, struct json_object *root, struct json_object *cur,
135 int idx, const char *key, jp_match_cb_t cb, void *priv)
137 struct jp_opcode *sop;
150 return jp_cmp(op, root, cur);
153 return !!jp_match(op, root, NULL, NULL);
156 return !!jp_match(op, cur, NULL, NULL);
159 return !jp_expr(op->down, root, cur, idx, key, cb, priv);
162 for (sop = op->down; sop; sop = sop->sibling)
163 if (!jp_expr(sop, root, cur, idx, key, cb, priv))
169 for (sop = op->down; sop; sop = sop->sibling)
170 if (jp_expr(sop, root, cur, idx, key, cb, priv))
175 return (key && !strcmp(op->str, key));
178 return (idx == op->num);
185 static struct json_object *
186 jp_match_expr(struct jp_opcode *ptr,
187 struct json_object *root, struct json_object *cur,
188 jp_match_cb_t cb, void *priv)
191 struct json_object *tmp, *res = NULL;
193 switch (json_object_get_type(cur))
195 case json_type_object:
196 ; /* a label can only be part of a statement and a declaration is not a statement */
197 json_object_object_foreach(cur, key, val)
199 if (jp_expr(ptr, root, val, -1, key, cb, priv))
201 tmp = jp_match_next(ptr->sibling, root, val, cb, priv);
210 case json_type_array:
211 len = json_object_array_length(cur);
213 for (idx = 0; idx < len; idx++)
215 tmp = json_object_array_get_idx(cur, idx);
217 if (jp_expr(ptr, root, tmp, idx, NULL, cb, priv))
219 tmp = jp_match_next(ptr->sibling, root, tmp, cb, priv);
235 static struct json_object *
236 jp_match_next(struct jp_opcode *ptr,
237 struct json_object *root, struct json_object *cur,
238 jp_match_cb_t cb, void *priv)
241 struct json_object *next = NULL;
255 if (json_object_object_get_ex(cur, ptr->str, &next))
256 return jp_match_next(ptr->sibling, root, next, cb, priv);
261 if (json_object_get_type(cur) == json_type_array)
266 idx += json_object_array_length(cur);
269 next = json_object_array_get_idx(cur, idx);
272 return jp_match_next(ptr->sibling, root, next, cb, priv);
278 return jp_match_expr(ptr, root, cur, cb, priv);
285 jp_match(struct jp_opcode *path, json_object *jsobj,
286 jp_match_cb_t cb, void *priv)
288 if (path->type == T_LABEL)
291 return jp_match_next(path->down, jsobj, jsobj, cb, priv);