csonpath 0.8.0__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {csonpath-0.8.0/csonpath.egg-info → csonpath-0.9.0}/PKG-INFO +4 -3
- {csonpath-0.8.0 → csonpath-0.9.0}/README.md +3 -2
- {csonpath-0.8.0 → csonpath-0.9.0/csonpath.egg-info}/PKG-INFO +4 -3
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath.h +156 -10
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath_do.h +52 -72
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath_python.c +32 -3
- {csonpath-0.8.0 → csonpath-0.9.0}/pyproject.toml +2 -2
- {csonpath-0.8.0 → csonpath-0.9.0}/LICENSE +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/MANIFEST.in +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.9.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -40,9 +40,10 @@ Dynamic: license-file
|
|
|
40
40
|
- support `..`: `"$..non`
|
|
41
41
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
42
42
|
- support filters:
|
|
43
|
-
- with `>` or `<`: `"$.obj[
|
|
44
|
-
- with `=` or '!=': `"$.obj[
|
|
43
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
44
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
45
45
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
46
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
46
47
|
- support `|`: `"$.obj | $.otherobj"`
|
|
47
48
|
### Functions
|
|
48
49
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
- support `..`: `"$..non`
|
|
32
32
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
33
33
|
- support filters:
|
|
34
|
-
- with `>` or `<`: `"$.obj[
|
|
35
|
-
- with `=` or '!=': `"$.obj[
|
|
34
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
35
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
36
36
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
37
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
37
38
|
- support `|`: `"$.obj | $.otherobj"`
|
|
38
39
|
### Functions
|
|
39
40
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -40,9 +40,10 @@ Dynamic: license-file
|
|
|
40
40
|
- support `..`: `"$..non`
|
|
41
41
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
42
42
|
- support filters:
|
|
43
|
-
- with `>` or `<`: `"$.obj[
|
|
44
|
-
- with `=` or '!=': `"$.obj[
|
|
43
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
44
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
45
45
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
46
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
46
47
|
- support `|`: `"$.obj | $.otherobj"`
|
|
47
48
|
### Functions
|
|
48
49
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -33,6 +33,14 @@
|
|
|
33
33
|
#define CSONPATH_DECREF(obj)
|
|
34
34
|
#endif
|
|
35
35
|
|
|
36
|
+
#ifndef CSONPATH_FORMAT_EXCEPTION
|
|
37
|
+
#define CSONPATH_FORMAT_EXCEPTION(args...) fprintf(stderr, args)
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#ifndef CSONPATH_EXCEPTION
|
|
41
|
+
#define CSONPATH_EXCEPTION(args...) CSONPATH_GETTER_ERR(args)
|
|
42
|
+
#endif
|
|
43
|
+
|
|
36
44
|
enum csonpath_instuction_raw {
|
|
37
45
|
CSONPATH_INST_ROOT,
|
|
38
46
|
CSONPATH_INST_GET_OBJ,
|
|
@@ -46,6 +54,7 @@ enum csonpath_instuction_raw {
|
|
|
46
54
|
CSONPATH_INST_FILTER_OPERAND_STR,
|
|
47
55
|
CSONPATH_INST_FILTER_OPERAND_BYTE, /* store the same way it's in ARRAY_SMALL */
|
|
48
56
|
CSONPATH_INST_FILTER_OPERAND_INT, /* store the same way it's in ARRAY_BIG */
|
|
57
|
+
CSONPATH_INST_FILTER_AND,
|
|
49
58
|
CSONPATH_INST_GET_ALL,
|
|
50
59
|
CSONPATH_INST_FIND_ALL,
|
|
51
60
|
CSONPATH_INST_OR,
|
|
@@ -68,6 +77,7 @@ CSONPATH_UNUSED static const char *csonpath_instuction_str[] = {
|
|
|
68
77
|
"FILTER_OPERAND_STR",
|
|
69
78
|
"FILTER_OPERAND_BYTE",
|
|
70
79
|
"FILTER_OPERAND_INT",
|
|
80
|
+
"FILTER_AND",
|
|
71
81
|
"GET_ALL",
|
|
72
82
|
"FIND_ALL",
|
|
73
83
|
"OR",
|
|
@@ -244,13 +254,13 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
244
254
|
return 0;
|
|
245
255
|
|
|
246
256
|
tmp = strdup(cjp->path);
|
|
247
|
-
|
|
257
|
+
root_again:
|
|
248
258
|
CSONPATH_SKIP('$', walker);
|
|
249
259
|
csonpath_push_inst(cjp, CSONPATH_INST_ROOT, &inst_idx);
|
|
250
260
|
cjp->inst_lst[inst_idx - 1].next = 1;
|
|
251
261
|
to_check = *walker;
|
|
252
262
|
|
|
253
|
-
again:
|
|
263
|
+
again:
|
|
254
264
|
switch (to_check) {
|
|
255
265
|
case '[':
|
|
256
266
|
{
|
|
@@ -289,12 +299,18 @@ again:
|
|
|
289
299
|
*walker);
|
|
290
300
|
goto error;
|
|
291
301
|
}
|
|
302
|
+
filter_again_root:
|
|
292
303
|
inst = CSONPATH_INST_GET_OBJ;
|
|
293
304
|
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
294
305
|
++walker;
|
|
306
|
+
|
|
307
|
+
/* skipp blank */
|
|
308
|
+
for (; isblank(*walker); ++walker)
|
|
309
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
310
|
+
|
|
295
311
|
last_inst = &cjp->inst_lst[inst_idx - 1];
|
|
296
312
|
if (*walker == '(') {
|
|
297
|
-
have_parentesis
|
|
313
|
+
++have_parentesis;
|
|
298
314
|
++walker;
|
|
299
315
|
CSONPATH_SKIP('@', walker);
|
|
300
316
|
if (*walker == '[') {
|
|
@@ -356,7 +372,7 @@ again:
|
|
|
356
372
|
filter_getter[nb_getter_inst-1].next += 1;
|
|
357
373
|
++next;
|
|
358
374
|
to_check = *next;
|
|
359
|
-
have_parentesis
|
|
375
|
+
have_parentesis--;
|
|
360
376
|
}
|
|
361
377
|
|
|
362
378
|
walker = next;
|
|
@@ -478,19 +494,34 @@ again:
|
|
|
478
494
|
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT, &inst_idx);
|
|
479
495
|
}
|
|
480
496
|
}
|
|
497
|
+
|
|
498
|
+
/* skip space */
|
|
481
499
|
if (isblank(to_check)) {
|
|
482
500
|
for (next++; isblank(*next); ++next);
|
|
483
501
|
to_check = *next;
|
|
484
502
|
}
|
|
485
503
|
|
|
486
|
-
if (
|
|
504
|
+
if (to_check == '&') {
|
|
505
|
+
if (next[1] == '&') {
|
|
506
|
+
++next;
|
|
507
|
+
}
|
|
508
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
509
|
+
walker = next + 1;
|
|
510
|
+
to_check = *walker;
|
|
511
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_AND, &inst_idx);
|
|
512
|
+
nb_getter_inst = 0;
|
|
513
|
+
goto filter_again_root;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
while (have_parentesis) {
|
|
487
517
|
CSONPATH_SKIP(')', next);
|
|
488
518
|
to_check = *next;
|
|
519
|
+
--have_parentesis;
|
|
489
520
|
}
|
|
521
|
+
|
|
490
522
|
if (to_check != ']') {
|
|
491
523
|
CSONPATH_REQUIRE_ERR(']', next);
|
|
492
524
|
}
|
|
493
|
-
/* skip space */
|
|
494
525
|
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
495
526
|
walker = next + 1;
|
|
496
527
|
to_check = *walker;
|
|
@@ -656,6 +687,79 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
|
|
|
656
687
|
return 0;
|
|
657
688
|
}
|
|
658
689
|
|
|
690
|
+
static CSONPATH_JSON cosnpath_crawl_filter_el(struct csonpath cjp[static 1],
|
|
691
|
+
int *idx, char **owalker,
|
|
692
|
+
CSONPATH_JSON el2,
|
|
693
|
+
int filter_next)
|
|
694
|
+
{
|
|
695
|
+
|
|
696
|
+
for (; *idx < filter_next; ++(*idx)) {
|
|
697
|
+
switch (cjp->inst_lst[*idx].inst) {
|
|
698
|
+
case CSONPATH_INST_GET_OBJ:
|
|
699
|
+
el2 = CSONPATH_GET(el2, *owalker);
|
|
700
|
+
break;
|
|
701
|
+
default:
|
|
702
|
+
CSONPATH_FORMAT_EXCEPTION("unsuported %s inst",
|
|
703
|
+
csonpath_instuction_str[cjp->inst_lst[*idx].inst]);
|
|
704
|
+
return NULL;
|
|
705
|
+
}
|
|
706
|
+
(*owalker) += cjp->inst_lst[*idx].next;
|
|
707
|
+
}
|
|
708
|
+
return el2;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
static _Bool csonpath_make_match(struct csonpath cjp[static 1],
|
|
713
|
+
struct csonpath_instruction inst[static 1],
|
|
714
|
+
CSONPATH_JSON el2, char *owalker, int operation)
|
|
715
|
+
{
|
|
716
|
+
int operand_instruction = inst->inst;
|
|
717
|
+
|
|
718
|
+
if (el2 == CSONPATH_NULL)
|
|
719
|
+
return 0;
|
|
720
|
+
_Bool match = 0;
|
|
721
|
+
switch (operation) {
|
|
722
|
+
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
723
|
+
match = !csonpath_do_match(operand_instruction, el2, owalker);
|
|
724
|
+
break;
|
|
725
|
+
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
726
|
+
match = csonpath_do_match(operand_instruction, el2, owalker);
|
|
727
|
+
break;
|
|
728
|
+
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
729
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
730
|
+
break;
|
|
731
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) <
|
|
732
|
+
CSONPATH_GET_NUM(el2);
|
|
733
|
+
break;
|
|
734
|
+
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
735
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
736
|
+
break;
|
|
737
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) >
|
|
738
|
+
CSONPATH_GET_NUM(el2);
|
|
739
|
+
break;
|
|
740
|
+
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
741
|
+
#ifdef CSONPATH_NO_REGEX
|
|
742
|
+
CSONPATH_GETTER_ERR("regex deactivate\n");
|
|
743
|
+
return CSONPATH_NONE_FOUND_RET;
|
|
744
|
+
#else
|
|
745
|
+
if (CSONPATH_IS_STR(el2)) {
|
|
746
|
+
int regex_idx = inst->regex_idx;
|
|
747
|
+
regex_t *compiled = &cjp->regexs[regex_idx];
|
|
748
|
+
int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
|
|
749
|
+
0, NULL, 0);
|
|
750
|
+
match = match_len == 0;
|
|
751
|
+
}
|
|
752
|
+
break;
|
|
753
|
+
#endif
|
|
754
|
+
}
|
|
755
|
+
return match;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
static _Bool csonpath_is_endish_inst(int instruction)
|
|
759
|
+
{
|
|
760
|
+
return instruction == CSONPATH_INST_END || instruction == CSONPATH_INST_OR;
|
|
761
|
+
}
|
|
762
|
+
|
|
659
763
|
/* helper use multiple times */
|
|
660
764
|
#define CSONPATH_DO_GET_NOTFOUND_UPDATER(this_idx) \
|
|
661
765
|
do { \
|
|
@@ -674,7 +778,8 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
|
|
|
674
778
|
goto next_inst; \
|
|
675
779
|
} while (0)
|
|
676
780
|
|
|
677
|
-
|
|
781
|
+
|
|
782
|
+
#define CSONPATH_GOTO_ON_RELOOP(where) \
|
|
678
783
|
nb_res += tret; if (need_reloop_in) goto where;
|
|
679
784
|
|
|
680
785
|
#define CSONPATH_PREPARE_RELOOP(label) \
|
|
@@ -793,11 +898,11 @@ need_reloop_in = 0;
|
|
|
793
898
|
again:
|
|
794
899
|
|
|
795
900
|
#define CSONPATH_DO_FILTER_LOOP_PRE_SET \
|
|
796
|
-
|
|
901
|
+
csonpath_child_info_set(&child_info, tmp, foreach_idx);
|
|
797
902
|
|
|
798
903
|
#define CSONPATH_DO_FOREACH_PRE_SET \
|
|
799
|
-
|
|
800
|
-
|
|
904
|
+
need_reloop_in = 0; \
|
|
905
|
+
csonpath_child_info_set(&child_info, tmp, (intptr_t)key_idx);
|
|
801
906
|
|
|
802
907
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , child_info, &need_reloop_in
|
|
803
908
|
|
|
@@ -846,6 +951,41 @@ again:
|
|
|
846
951
|
|
|
847
952
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
848
953
|
|
|
954
|
+
static int csonpath_sync_root_array(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
955
|
+
{
|
|
956
|
+
CSONPATH_JSON child;
|
|
957
|
+
size_t idx;
|
|
958
|
+
(void) idx;
|
|
959
|
+
|
|
960
|
+
CSONPATH_ARRAY_CLEAR(parent);
|
|
961
|
+
CSONPATH_FOREACH_ARRAY(to_update, child, idx) {
|
|
962
|
+
CSONPATH_APPEND_AT(parent, idx, child);
|
|
963
|
+
}
|
|
964
|
+
return 1;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
968
|
+
{
|
|
969
|
+
CSONPATH_JSON child;
|
|
970
|
+
const char *key;
|
|
971
|
+
|
|
972
|
+
CSONPATH_OBJ_CLEAR(parent);
|
|
973
|
+
CSONPATH_FOREACH_OBJ(to_update, child, key) {
|
|
974
|
+
CSONPATH_APPEND_AT(parent, key, child);
|
|
975
|
+
}
|
|
976
|
+
return 1;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
#define CSONPATH_PRE_GET_ROOT \
|
|
980
|
+
int to_check = cjp->inst_lst[idx + 1].inst; \
|
|
981
|
+
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
982
|
+
if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) \
|
|
983
|
+
return csonpath_sync_root_obj(origin, to_update); \
|
|
984
|
+
else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) \
|
|
985
|
+
return csonpath_sync_root_array(origin, to_update); \
|
|
986
|
+
else \
|
|
987
|
+
CSONPATH_EXCEPTION("can't upate root ($)\n"); \
|
|
988
|
+
}
|
|
849
989
|
|
|
850
990
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
851
991
|
int check_at = idx + 1; \
|
|
@@ -927,6 +1067,12 @@ again:
|
|
|
927
1067
|
|
|
928
1068
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
929
1069
|
|
|
1070
|
+
#define CSONPATH_PRE_GET_ROOT \
|
|
1071
|
+
int to_check = cjp->inst_lst[idx + 1].inst; \
|
|
1072
|
+
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
1073
|
+
CSONPATH_GETTER_ERR("can't upate root ($)\n"); \
|
|
1074
|
+
return CSONPATH_NONE_FOUND_RET; \
|
|
1075
|
+
}
|
|
930
1076
|
|
|
931
1077
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
932
1078
|
int check_at = idx + 1; \
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
#define CSONPATH_PRE_GET(this_idx)
|
|
18
18
|
#endif
|
|
19
19
|
|
|
20
|
+
#ifndef CSONPATH_PRE_GET_ROOT
|
|
21
|
+
#define CSONPATH_PRE_GET_ROOT
|
|
22
|
+
#endif
|
|
23
|
+
|
|
20
24
|
#ifndef CSONPATH_DO_DECLARATION
|
|
21
25
|
#define CSONPATH_DO_DECLARATION
|
|
22
26
|
#endif
|
|
@@ -104,6 +108,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
104
108
|
int idx,
|
|
105
109
|
char *walker CSONPATH_DO_EXTRA_DECLATION);
|
|
106
110
|
|
|
111
|
+
|
|
107
112
|
#define csonpath_do_dotdot__(name) CATCAT(csonpath_, name, _dotdot)
|
|
108
113
|
#define csonpath_do_dotdot csonpath_do_dotdot__(CSONPATH_DO_FUNC_NAME)
|
|
109
114
|
|
|
@@ -155,11 +160,14 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
155
160
|
cjp->inst_lst[idx].inst != CSONPATH_INST_OR) {
|
|
156
161
|
switch (cjp->inst_lst[idx].inst) {
|
|
157
162
|
case CSONPATH_INST_ROOT:
|
|
163
|
+
{
|
|
164
|
+
CSONPATH_PRE_GET_ROOT
|
|
158
165
|
value = origin;
|
|
159
166
|
tmp = value;
|
|
160
167
|
ctx = CSONPATH_NULL;
|
|
161
168
|
walker += cjp->inst_lst[idx].next;
|
|
162
|
-
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
163
171
|
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
164
172
|
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
165
173
|
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
@@ -167,83 +175,54 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
167
175
|
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
168
176
|
{
|
|
169
177
|
CSONPATH_JSON el;
|
|
170
|
-
int operation = cjp->inst_lst[idx].inst;
|
|
178
|
+
int operation_in = cjp->inst_lst[idx].inst, operation = cjp->inst_lst[idx].inst;
|
|
171
179
|
walker += cjp->inst_lst[idx].next;
|
|
172
180
|
char *owalker;
|
|
173
|
-
int filter_next = cjp->inst_lst[idx].filter_next;
|
|
174
|
-
int
|
|
175
|
-
int
|
|
181
|
+
int filter_next_in = cjp->inst_lst[idx].filter_next, filter_next = cjp->inst_lst[idx].filter_next;
|
|
182
|
+
int walker_idx = idx + 1, in_idx = idx + 1;
|
|
183
|
+
int foreach_idx;
|
|
176
184
|
|
|
185
|
+
(void) foreach_idx;
|
|
177
186
|
CSONPATH_DO_FILTER_PRE_LOOP;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
204
|
-
match = !csonpath_do_match(operand_instruction, el2, owalker);
|
|
205
|
-
break;
|
|
206
|
-
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
207
|
-
match = csonpath_do_match(operand_instruction, el2, owalker);
|
|
208
|
-
break;
|
|
209
|
-
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
210
|
-
if (!CSONPATH_IS_NUM(el2))
|
|
211
|
-
break;
|
|
212
|
-
match = csonpath_int_from_walker(operand_instruction, owalker) <
|
|
213
|
-
CSONPATH_GET_NUM(el2);
|
|
214
|
-
break;
|
|
215
|
-
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
216
|
-
if (!CSONPATH_IS_NUM(el2))
|
|
217
|
-
break;
|
|
218
|
-
match = csonpath_int_from_walker(operand_instruction, owalker) >
|
|
219
|
-
CSONPATH_GET_NUM(el2);
|
|
220
|
-
break;
|
|
221
|
-
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
222
|
-
#ifdef CSONPATH_NO_REGEX
|
|
223
|
-
CSONPATH_GETTER_ERR("regex deactivate\n");
|
|
224
|
-
return CSONPATH_NONE_FOUND_RET;
|
|
225
|
-
#else
|
|
226
|
-
if (CSONPATH_IS_STR(el2)) {
|
|
227
|
-
int regex_idx = cjp->inst_lst[idx].regex_idx;
|
|
228
|
-
regex_t *compiled = &cjp->regexs[regex_idx];
|
|
229
|
-
int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
|
|
230
|
-
0, NULL, 0);
|
|
231
|
-
match = match_len == 0;
|
|
232
|
-
}
|
|
233
|
-
break;
|
|
234
|
-
#endif
|
|
235
|
-
}
|
|
236
|
-
if (match) {
|
|
237
|
-
CSONPATH_DO_RET_TYPE tret =
|
|
238
|
-
csonpath_do_internal(cjp, origin, el, tmp, idx + 1,
|
|
239
|
-
owalker + cjp->inst_lst[idx].next
|
|
240
|
-
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
241
|
-
|
|
242
|
-
CSONPATH_DO_FILTER_FIND;
|
|
243
|
-
}
|
|
187
|
+
CSONPATH_FOREACH_ARRAY(tmp, el, foreach_idx)
|
|
188
|
+
{
|
|
189
|
+
intptr_t key_idx = foreach_idx;
|
|
190
|
+
(void)key_idx;
|
|
191
|
+
owalker = walker;
|
|
192
|
+
match_and_or_or:
|
|
193
|
+
if (CSONPATH_IS_OBJ(el)) {
|
|
194
|
+
CSONPATH_JSON el2 = el;
|
|
195
|
+
|
|
196
|
+
idx = walker_idx;
|
|
197
|
+
CSONPATH_DO_FILTER_LOOP_PRE_SET;
|
|
198
|
+
el2 = cosnpath_crawl_filter_el(cjp, &idx, &owalker, el2, filter_next);
|
|
199
|
+
|
|
200
|
+
if (csonpath_make_match(cjp, &cjp->inst_lst[idx], el2, owalker,
|
|
201
|
+
operation)) {
|
|
202
|
+
if (cjp->inst_lst[idx + 1].inst == CSONPATH_INST_FILTER_AND) {
|
|
203
|
+
++idx; /* skip next */
|
|
204
|
+
if (csonpath_is_endish_inst(cjp->inst_lst[idx + 1].inst) ||
|
|
205
|
+
csonpath_is_endish_inst(cjp->inst_lst[idx + 2].inst))
|
|
206
|
+
goto fail_match;
|
|
207
|
+
operation = cjp->inst_lst[idx +1].inst;
|
|
208
|
+
filter_next = cjp->inst_lst[idx +1].filter_next;
|
|
209
|
+
owalker += cjp->inst_lst[idx].next + cjp->inst_lst[idx-1].next;
|
|
210
|
+
walker_idx = idx + 2;
|
|
211
|
+
goto match_and_or_or;
|
|
244
212
|
}
|
|
213
|
+
CSONPATH_DO_RET_TYPE tret =
|
|
214
|
+
csonpath_do_internal(cjp, origin, el, tmp, idx + 1,
|
|
215
|
+
owalker + cjp->inst_lst[idx].next
|
|
216
|
+
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
217
|
+
CSONPATH_DO_FILTER_FIND;
|
|
218
|
+
} else {
|
|
219
|
+
fail_match:
|
|
220
|
+
operation = operation_in;
|
|
221
|
+
walker_idx = in_idx;
|
|
222
|
+
filter_next = filter_next_in;
|
|
245
223
|
}
|
|
246
|
-
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
247
226
|
CSONPATH_DO_FILTER_OUT;
|
|
248
227
|
break;
|
|
249
228
|
}
|
|
@@ -356,6 +335,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
356
335
|
|
|
357
336
|
#ifndef CSONPATH_NO_UNDEF
|
|
358
337
|
|
|
338
|
+
#undef CSONPATH_PRE_GET_ROOT
|
|
359
339
|
#undef CSONPATH_PRE_GET
|
|
360
340
|
#undef CSONPATH_DO_PRE_OPERATION
|
|
361
341
|
#undef CSONPATH_DO_POST_OPERATION
|
|
@@ -50,6 +50,13 @@
|
|
|
50
50
|
r; \
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
+
#define CSONPATH_FORMAT_EXCEPTION(ARGS...) \
|
|
54
|
+
PyErr_Format(PyExc_ValueError, ARGS)
|
|
55
|
+
|
|
56
|
+
#define CSONPATH_EXCEPTION(ARGS...) \
|
|
57
|
+
PyErr_Format(PyExc_ValueError, ARGS); \
|
|
58
|
+
return -1;
|
|
59
|
+
|
|
53
60
|
#define CSONPATH_CALLBACK PyObject *
|
|
54
61
|
|
|
55
62
|
#define CSONPATH_CALLBACK_DATA PyObject *
|
|
@@ -84,7 +91,7 @@
|
|
|
84
91
|
static int pydict_try_setitemstring(PyObject *obj, const char * const at, PyObject *el)
|
|
85
92
|
{
|
|
86
93
|
if (!PyDict_Check(obj)) {
|
|
87
|
-
PyErr_Format(PyExc_ValueError, "Unable to follow path: Dict expected");
|
|
94
|
+
PyErr_Format(PyExc_ValueError, "Unable to follow path (%s): Dict expected", at);
|
|
88
95
|
return -1;
|
|
89
96
|
}
|
|
90
97
|
PyDict_SetItemString(obj, at, el);
|
|
@@ -97,7 +104,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
97
104
|
PyErr_Format(PyExc_ValueError, "Unable to follow path: List expected");
|
|
98
105
|
return -1;
|
|
99
106
|
}
|
|
100
|
-
Py_ssize_t s = PyList_Size(array);
|
|
107
|
+
Py_ssize_t s = PyList_Size(array);
|
|
101
108
|
if (at >= s) {
|
|
102
109
|
for (;s < at; ++s)
|
|
103
110
|
PyList_Insert(array, s, Py_None);
|
|
@@ -124,6 +131,22 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
124
131
|
) (array, at, el)
|
|
125
132
|
|
|
126
133
|
|
|
134
|
+
#define CSONPATH_ARRAY_CLEAR(o) PyList_Clear(o)
|
|
135
|
+
|
|
136
|
+
#define CSONPATH_OBJ_CLEAR(o) PyDict_Clear(o)
|
|
137
|
+
|
|
138
|
+
#define CSONPATH_FOREACH_ARRAY(obj, child, idx) \
|
|
139
|
+
for (intptr_t array_len = PyList_Size(obj), idx = 0; \
|
|
140
|
+
({int r = idx < array_len; if (r) child = PyList_GetItem(obj, idx); r;}); ++idx)
|
|
141
|
+
|
|
142
|
+
#define CSONPATH_FOREACH_OBJ(obj, child, key) \
|
|
143
|
+
for (Py_ssize_t pos_ = 0; ({ \
|
|
144
|
+
PyObject *key_; \
|
|
145
|
+
_Bool r = PyDict_Next(obj, &pos_, &key_, &child); \
|
|
146
|
+
if (r) key = PyUnicode_AsUTF8AndSize(key_, NULL); \
|
|
147
|
+
r; \
|
|
148
|
+
});)
|
|
149
|
+
|
|
127
150
|
#define CSONPATH_FOREACH_EXT(obj, el, code, key_idx) \
|
|
128
151
|
if (PyDict_Check(obj)) { \
|
|
129
152
|
PyObject *key_; \
|
|
@@ -223,6 +246,12 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
223
246
|
return ret;
|
|
224
247
|
}
|
|
225
248
|
|
|
249
|
+
static PyObject *print_instructions(PyCsonPathObject *self, PyObject *args, PyObject *kwds)
|
|
250
|
+
{
|
|
251
|
+
csonpath_print_instruction(self->cp);
|
|
252
|
+
return Py_None;
|
|
253
|
+
}
|
|
254
|
+
|
|
226
255
|
static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
227
256
|
{
|
|
228
257
|
PyObject *json, *callback, *udata = Py_None;
|
|
@@ -266,7 +295,6 @@ static PyObject *update_or_create_callback(PyCsonPathObject *self, PyObject* arg
|
|
|
266
295
|
return PyLong_FromLong(ret);
|
|
267
296
|
}
|
|
268
297
|
|
|
269
|
-
|
|
270
298
|
static void PyCsonPath_dealloc(PyCsonPathObject *self) {
|
|
271
299
|
if (self->cp) {
|
|
272
300
|
csonpath_destroy(self->cp);
|
|
@@ -289,6 +317,7 @@ static PyObject *PyCsonPath_set_path(PyCsonPathObject *self, PyObject* args) {
|
|
|
289
317
|
static PyMethodDef csonpath_py_method[] = {
|
|
290
318
|
{"set_path", (PyCFunction)PyCsonPath_set_path, METH_VARARGS, "set_path"},
|
|
291
319
|
{"callback", (PyCFunction)callback, METH_VARARGS, "callback"},
|
|
320
|
+
{"print_instructions", (PyCFunction)print_instructions, METH_NOARGS, "print_instructions"},
|
|
292
321
|
{"update_or_create_callback", (PyCFunction)update_or_create_callback, METH_VARARGS, "update_or_create_callback"},
|
|
293
322
|
{"find_first", (PyCFunction)find_first, METH_VARARGS, "find first elems"},
|
|
294
323
|
{"find_all", (PyCFunction)find_all, METH_VARARGS, "find all elems, if one found, pout it in an array"},
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.9.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
[tool.setuptools]
|
|
@@ -22,7 +22,7 @@ dev = [
|
|
|
22
22
|
testpaths = ["tests/python"]
|
|
23
23
|
|
|
24
24
|
[tool.bumpversion]
|
|
25
|
-
current_version = "0.
|
|
25
|
+
current_version = "0.9.0"
|
|
26
26
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
27
27
|
serialize = ["{major}.{minor}.{patch}"]
|
|
28
28
|
search = "{current_version}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|