9d2aa89e878ea715732a66e3f7a94c3b375c60ff
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
,
22 jp_match_cb_t cb
, void *priv
);
25 jp_json_to_op(struct json_object
*obj
, struct jp_opcode
*op
)
27 switch (json_object_get_type(obj
))
29 case json_type_boolean
:
31 op
->num
= json_object_get_boolean(obj
);
36 op
->num
= json_object_get_int(obj
);
39 case json_type_string
:
41 op
->str
= (char *)json_object_get_string(obj
);
50 jp_resolve(struct json_object
*root
, struct json_object
*cur
,
51 struct jp_opcode
*op
, struct jp_opcode
*res
)
53 struct json_object
*val
;
58 val
= jp_match(op
, cur
, NULL
, NULL
);
61 return jp_json_to_op(val
, res
);
66 val
= jp_match(op
, root
, NULL
, NULL
);
69 return jp_json_to_op(val
, res
);
80 jp_cmp(struct jp_opcode
*op
, struct json_object
*root
, struct json_object
*cur
)
83 struct jp_opcode left
, right
;
85 if (!jp_resolve(root
, cur
, op
->down
, &left
) ||
86 !jp_resolve(root
, cur
, op
->down
->sibling
, &right
))
89 if (left
.type
!= right
.type
)
96 delta
= left
.num
- right
.num
;
100 delta
= strcmp(left
.str
, right
.str
);
133 jp_expr(struct jp_opcode
*op
, struct json_object
*root
, struct json_object
*cur
,
134 int idx
, const char *key
, jp_match_cb_t cb
, void *priv
)
136 struct jp_opcode
*sop
;
149 return jp_cmp(op
, root
, cur
);
152 return !!jp_match(op
, root
, NULL
, NULL
);
155 return !!jp_match(op
, cur
, NULL
, NULL
);
158 return !jp_expr(op
->down
, root
, cur
, idx
, key
, cb
, priv
);
161 for (sop
= op
->down
; sop
; sop
= sop
->sibling
)
162 if (!jp_expr(sop
, root
, cur
, idx
, key
, cb
, priv
))
167 for (sop
= op
->down
; sop
; sop
= sop
->sibling
)
168 if (jp_expr(sop
, root
, cur
, idx
, key
, cb
, priv
))
173 return (key
&& !strcmp(op
->str
, key
));
176 return (idx
== op
->num
);
183 static struct json_object
*
184 jp_match_expr(struct jp_opcode
*ptr
,
185 struct json_object
*root
, struct json_object
*cur
,
186 jp_match_cb_t cb
, void *priv
)
189 struct json_object
*tmp
, *res
= NULL
;
191 switch (json_object_get_type(cur
))
193 case json_type_object
:
194 ; /* a label can only be part of a statement and a declaration is not a statement */
195 json_object_object_foreach(cur
, key
, val
)
197 if (jp_expr(ptr
, root
, val
, -1, key
, cb
, priv
))
199 tmp
= jp_match_next(ptr
->sibling
, root
, val
, cb
, priv
);
208 case json_type_array
:
209 len
= json_object_array_length(cur
);
211 for (idx
= 0; idx
< len
; idx
++)
213 tmp
= json_object_array_get_idx(cur
, idx
);
215 if (jp_expr(ptr
, root
, tmp
, idx
, NULL
, cb
, priv
))
217 tmp
= jp_match_next(ptr
->sibling
, root
, tmp
, cb
, priv
);
233 static struct json_object
*
234 jp_match_next(struct jp_opcode
*ptr
,
235 struct json_object
*root
, struct json_object
*cur
,
236 jp_match_cb_t cb
, void *priv
)
238 struct json_object
*next
;
252 if (json_object_object_get_ex(cur
, ptr
->str
, &next
))
253 return jp_match_next(ptr
->sibling
, root
, next
, cb
, priv
);
258 next
= json_object_array_get_idx(cur
, ptr
->num
);
261 return jp_match_next(ptr
->sibling
, root
, next
, cb
, priv
);
266 return jp_match_expr(ptr
, root
, cur
, cb
, priv
);
273 jp_match(struct jp_opcode
*path
, json_object
*jsobj
,
274 jp_match_cb_t cb
, void *priv
)
276 if (path
->type
== T_LABEL
)
279 return jp_match_next(path
->down
, jsobj
, jsobj
, cb
, priv
);