csonpath 0.7.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.7.0/csonpath.egg-info → csonpath-0.9.0}/PKG-INFO +4 -3
- {csonpath-0.7.0 → csonpath-0.9.0}/README.md +3 -2
- {csonpath-0.7.0 → csonpath-0.9.0/csonpath.egg-info}/PKG-INFO +4 -3
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath.h +160 -13
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath_do.h +52 -72
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath_python.c +33 -3
- {csonpath-0.7.0 → csonpath-0.9.0}/pyproject.toml +2 -2
- {csonpath-0.7.0 → csonpath-0.9.0}/LICENSE +0 -0
- {csonpath-0.7.0 → csonpath-0.9.0}/MANIFEST.in +0 -0
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.7.0 → csonpath-0.9.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.7.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) \
|
|
@@ -725,9 +830,10 @@ need_reloop_in = 0;
|
|
|
725
830
|
#define CSONPATH_DO_FILTER_FIND CSONPATH_DO_FIND_ALL
|
|
726
831
|
|
|
727
832
|
#define CSONPATH_DO_FIND_ALL_OUT \
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
833
|
+
if (!nb_res) { \
|
|
834
|
+
return CSONPATH_NONE_FOUND_RET; \
|
|
835
|
+
} \
|
|
836
|
+
return ret_ar;
|
|
731
837
|
|
|
732
838
|
#define CSONPATH_DO_EXTRA_ARGS_IN , ret_ar
|
|
733
839
|
#define CSONPATH_DO_EXTRA_DECLATION , CSONPATH_FIND_ALL_RET ret_ar
|
|
@@ -792,11 +898,11 @@ need_reloop_in = 0;
|
|
|
792
898
|
again:
|
|
793
899
|
|
|
794
900
|
#define CSONPATH_DO_FILTER_LOOP_PRE_SET \
|
|
795
|
-
|
|
901
|
+
csonpath_child_info_set(&child_info, tmp, foreach_idx);
|
|
796
902
|
|
|
797
903
|
#define CSONPATH_DO_FOREACH_PRE_SET \
|
|
798
|
-
|
|
799
|
-
|
|
904
|
+
need_reloop_in = 0; \
|
|
905
|
+
csonpath_child_info_set(&child_info, tmp, (intptr_t)key_idx);
|
|
800
906
|
|
|
801
907
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , child_info, &need_reloop_in
|
|
802
908
|
|
|
@@ -845,6 +951,41 @@ again:
|
|
|
845
951
|
|
|
846
952
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
847
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
|
+
}
|
|
848
989
|
|
|
849
990
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
850
991
|
int check_at = idx + 1; \
|
|
@@ -926,6 +1067,12 @@ again:
|
|
|
926
1067
|
|
|
927
1068
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
928
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
|
+
}
|
|
929
1076
|
|
|
930
1077
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
931
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 *
|
|
@@ -61,6 +68,7 @@
|
|
|
61
68
|
else \
|
|
62
69
|
arglist = Py_BuildValue("(OiOO)", ctx, child_info->idx, tmp, udata); \
|
|
63
70
|
PyObject_CallObject(callback, arglist); \
|
|
71
|
+
Py_DECREF(arglist); \
|
|
64
72
|
} while (0)
|
|
65
73
|
|
|
66
74
|
/* assuming each modification of the object need to go out of the loop */
|
|
@@ -83,7 +91,7 @@
|
|
|
83
91
|
static int pydict_try_setitemstring(PyObject *obj, const char * const at, PyObject *el)
|
|
84
92
|
{
|
|
85
93
|
if (!PyDict_Check(obj)) {
|
|
86
|
-
PyErr_Format(PyExc_ValueError, "Unable to follow path: Dict expected");
|
|
94
|
+
PyErr_Format(PyExc_ValueError, "Unable to follow path (%s): Dict expected", at);
|
|
87
95
|
return -1;
|
|
88
96
|
}
|
|
89
97
|
PyDict_SetItemString(obj, at, el);
|
|
@@ -96,7 +104,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
96
104
|
PyErr_Format(PyExc_ValueError, "Unable to follow path: List expected");
|
|
97
105
|
return -1;
|
|
98
106
|
}
|
|
99
|
-
Py_ssize_t s = PyList_Size(array);
|
|
107
|
+
Py_ssize_t s = PyList_Size(array);
|
|
100
108
|
if (at >= s) {
|
|
101
109
|
for (;s < at; ++s)
|
|
102
110
|
PyList_Insert(array, s, Py_None);
|
|
@@ -123,6 +131,22 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
123
131
|
) (array, at, el)
|
|
124
132
|
|
|
125
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
|
+
|
|
126
150
|
#define CSONPATH_FOREACH_EXT(obj, el, code, key_idx) \
|
|
127
151
|
if (PyDict_Check(obj)) { \
|
|
128
152
|
PyObject *key_; \
|
|
@@ -222,6 +246,12 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
222
246
|
return ret;
|
|
223
247
|
}
|
|
224
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
|
+
|
|
225
255
|
static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
226
256
|
{
|
|
227
257
|
PyObject *json, *callback, *udata = Py_None;
|
|
@@ -265,7 +295,6 @@ static PyObject *update_or_create_callback(PyCsonPathObject *self, PyObject* arg
|
|
|
265
295
|
return PyLong_FromLong(ret);
|
|
266
296
|
}
|
|
267
297
|
|
|
268
|
-
|
|
269
298
|
static void PyCsonPath_dealloc(PyCsonPathObject *self) {
|
|
270
299
|
if (self->cp) {
|
|
271
300
|
csonpath_destroy(self->cp);
|
|
@@ -288,6 +317,7 @@ static PyObject *PyCsonPath_set_path(PyCsonPathObject *self, PyObject* args) {
|
|
|
288
317
|
static PyMethodDef csonpath_py_method[] = {
|
|
289
318
|
{"set_path", (PyCFunction)PyCsonPath_set_path, METH_VARARGS, "set_path"},
|
|
290
319
|
{"callback", (PyCFunction)callback, METH_VARARGS, "callback"},
|
|
320
|
+
{"print_instructions", (PyCFunction)print_instructions, METH_NOARGS, "print_instructions"},
|
|
291
321
|
{"update_or_create_callback", (PyCFunction)update_or_create_callback, METH_VARARGS, "update_or_create_callback"},
|
|
292
322
|
{"find_first", (PyCFunction)find_first, METH_VARARGS, "find first elems"},
|
|
293
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
|