csonpath 0.15.0__tar.gz → 0.16.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.15.0 → csonpath-0.16.0}/Makefile +11 -3
- {csonpath-0.15.0/csonpath.egg-info → csonpath-0.16.0}/PKG-INFO +3 -2
- {csonpath-0.15.0 → csonpath-0.16.0}/README.md +2 -1
- {csonpath-0.15.0 → csonpath-0.16.0}/configure +5 -0
- {csonpath-0.15.0 → csonpath-0.16.0/csonpath.egg-info}/PKG-INFO +3 -2
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath.h +92 -53
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath_do.h +7 -7
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath_json-c.h +11 -9
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath_python.c +62 -30
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath_yyjson.h +3 -3
- {csonpath-0.15.0 → csonpath-0.16.0}/pyproject.toml +2 -2
- {csonpath-0.15.0 → csonpath-0.16.0}/LICENSE +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/MANIFEST.in +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/setup.cfg +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/setup.py +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/.git +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/.github/workflows/c-cpp.yml +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/.gitignore +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/LICENSE +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/Makefile +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/README.md +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/clib.json +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/formal_verification.md +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/re.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/re.h +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/scripts/exrex.py +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/scripts/regex_test.py +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/scripts/regex_test_neg.py +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test1.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test2.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test3.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test_compile.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test_print.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test_rand.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test_rand_neg.c +0 -0
- {csonpath-0.15.0 → csonpath-0.16.0}/tiny-regex-c/tests/test_thread.c +0 -0
|
@@ -5,7 +5,7 @@ YYJSON_LDFLAGS=$(shell pkg-config --libs yyjson)
|
|
|
5
5
|
|
|
6
6
|
include config.mk
|
|
7
7
|
|
|
8
|
-
all: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union
|
|
8
|
+
all: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors
|
|
9
9
|
|
|
10
10
|
YYJSON_TESTS=test-yyjson
|
|
11
11
|
|
|
@@ -43,10 +43,16 @@ test-json-get-array-big-index: tests/json-c/get-array-big-index.c csonpath_json-
|
|
|
43
43
|
test-json-union: tests/json-c/union.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
44
44
|
$(CC) tests/json-c/union.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-union $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
45
45
|
|
|
46
|
+
test-json-audit-bugs: tests/json-c/audit-bugs.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
47
|
+
$(CC) tests/json-c/audit-bugs.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-audit-bugs $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
48
|
+
|
|
49
|
+
test-json-crash-vectors: tests/json-c/crash-vectors.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
50
|
+
$(CC) tests/json-c/crash-vectors.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-crash-vectors $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
51
|
+
|
|
46
52
|
test-yyjson: tests/yyjson/test-yyjson.c csonpath_yyjson.h csonpath.h csonpath_do.h
|
|
47
53
|
$(CC) tests/yyjson/test-yyjson.c $(EXTRA_FILES) $(YYJSON_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-yyjson $(YYJSON_LDFLAGS) $(LDFLAGS)
|
|
48
54
|
|
|
49
|
-
tests-c: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-yyjson
|
|
55
|
+
tests-c: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-yyjson
|
|
50
56
|
./test-json-c-get-a
|
|
51
57
|
./test-json-update
|
|
52
58
|
./test-json-filter
|
|
@@ -55,6 +61,8 @@ test-yyjson: tests/yyjson/test-yyjson.c csonpath_yyjson.h csonpath.h csonpath_do
|
|
|
55
61
|
./test-json-filter-and-missing-key
|
|
56
62
|
./test-json-get-array-big-index
|
|
57
63
|
./test-json-union
|
|
64
|
+
./test-json-audit-bugs
|
|
65
|
+
./test-json-crash-vectors
|
|
58
66
|
./test-yyjson
|
|
59
67
|
|
|
60
68
|
pip-dev:
|
|
@@ -66,5 +74,5 @@ tests-py: pip-dev
|
|
|
66
74
|
tests: tests-py tests-c
|
|
67
75
|
|
|
68
76
|
clean:
|
|
69
|
-
rm -rvf test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-yyjson
|
|
77
|
+
rm -rvf test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-yyjson
|
|
70
78
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -30,7 +30,8 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
30
30
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
31
31
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
32
32
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
33
|
-
| Union
|
|
33
|
+
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
34
|
+
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
34
35
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
35
36
|
| Regex filters | `$.items[?name =~ "foo"]` | POSIX regex-based filtering |
|
|
36
37
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
@@ -21,7 +21,8 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
21
21
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
22
22
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
23
23
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
24
|
-
| Union
|
|
24
|
+
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
25
|
+
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
25
26
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
26
27
|
| Regex filters | `$.items[?name =~ "foo"]` | POSIX regex-based filtering |
|
|
27
28
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
@@ -21,12 +21,17 @@ for arg in $@; do
|
|
|
21
21
|
CFLAGS="${CFLAGS} -DCSONPATH_PCRE2_POSIX $(pkg-config --cflags libpcre2-posix)"
|
|
22
22
|
LDFLAGS="${LDFLAGS} $(pkg-config --libs libpcre2-posix)"
|
|
23
23
|
fi
|
|
24
|
+
if [ "--asan" = $arg ]; then
|
|
25
|
+
CFLAGS="${CFLAGS} -fsanitize=address -fno-omit-frame-pointer"
|
|
26
|
+
LDFLAGS="${LDFLAGS} -fsanitize=address"
|
|
27
|
+
fi
|
|
24
28
|
if [ "--help" = $arg ]; then
|
|
25
29
|
echo "help"
|
|
26
30
|
echo " --tiny-regex"
|
|
27
31
|
echo " --pcre2-regex"
|
|
28
32
|
echo " --pcre2-posix"
|
|
29
33
|
echo " --no-regex"
|
|
34
|
+
echo " --asan"
|
|
30
35
|
fi
|
|
31
36
|
done
|
|
32
37
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -30,7 +30,8 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
30
30
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
31
31
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
32
32
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
33
|
-
| Union
|
|
33
|
+
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
34
|
+
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
34
35
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
35
36
|
| Regex filters | `$.items[?name =~ "foo"]` | POSIX regex-based filtering |
|
|
36
37
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
!defined(CSONPATH_EQUAL_STR) || !defined(CSONPATH_CALL_CALLBACK) || \
|
|
6
6
|
!defined(CSONPATH_FOREACH_EXT) || !defined(CSONPATH_APPEND_AT) || \
|
|
7
7
|
!defined(CSONPATH_REMOVE_CHILD) || !defined(CSONPATH_NEED_FOREACH_REDO) || \
|
|
8
|
-
!defined(
|
|
8
|
+
!defined(CSONPATH_ARRAY_APPEND) || !defined(CSONPATH_REMOVE)
|
|
9
9
|
# error "some definitions are missing"
|
|
10
10
|
#endif
|
|
11
11
|
|
|
@@ -48,10 +48,6 @@ typedef regex_t csonpath_reg_t;
|
|
|
48
48
|
#define CSONPATH_FIND_ALL_RET_INIT CSONPATH_NEW_ARRAY
|
|
49
49
|
#endif
|
|
50
50
|
|
|
51
|
-
#ifndef CSONPATH_DECREF
|
|
52
|
-
#define CSONPATH_DECREF(obj)
|
|
53
|
-
#endif
|
|
54
|
-
|
|
55
51
|
#ifndef CSONPATH_FORMAT_EXCEPTION
|
|
56
52
|
#define CSONPATH_FORMAT_EXCEPTION(args...) fprintf(stderr, args)
|
|
57
53
|
#endif
|
|
@@ -231,6 +227,14 @@ struct csonpath_child_info {
|
|
|
231
227
|
#define CSONPATH_ERROR_MAX_SIZE 1024
|
|
232
228
|
#define CSONPATH_TMP_BUF_SIZE 256
|
|
233
229
|
|
|
230
|
+
#define CSONPATH_FILTER_PUSH(dst, cnt, c, walk_ptr) do { \
|
|
231
|
+
if ((cnt + 1) >= CSONPATH_TMP_BUF_SIZE) { \
|
|
232
|
+
CSONPATH_COMPILE_ERR(tmp, walk_ptr - orig, "%s", "filter key too long"); \
|
|
233
|
+
goto error; \
|
|
234
|
+
} \
|
|
235
|
+
(dst)[(cnt)++] = (c); \
|
|
236
|
+
} while (0)
|
|
237
|
+
|
|
234
238
|
/* I'm assuming error message won't be longer than 125 */
|
|
235
239
|
#define CSONPATH_COMPILE_ERR(tmp, idx, args...) do { \
|
|
236
240
|
int ltmp = strlen(tmp), lidx, oidx = idx; \
|
|
@@ -455,7 +459,15 @@ static void push_filter_getter(struct csonpath *cjp, int *inst_idx, int nb_gette
|
|
|
455
459
|
csonpath_push_char(cjp, filter_getter[i], inst_idx);
|
|
456
460
|
}
|
|
457
461
|
*filter_end = (nb_getter_inst - 1);
|
|
462
|
+
}
|
|
458
463
|
|
|
464
|
+
static _Bool consonpath_check_tmp_walker(const char tmp_walk[static 1], int cnt_brackets)
|
|
465
|
+
{
|
|
466
|
+
if (!*tmp_walk)
|
|
467
|
+
return 0;
|
|
468
|
+
if (cnt_brackets)
|
|
469
|
+
return 1;
|
|
470
|
+
return (*tmp_walk != ']');
|
|
459
471
|
}
|
|
460
472
|
|
|
461
473
|
static int csonpath_compile_do(struct csonpath *cjp, const char orig[static 1],
|
|
@@ -492,8 +504,9 @@ root_again:
|
|
|
492
504
|
do_array:
|
|
493
505
|
if (!in_union) {
|
|
494
506
|
int cnt_brackets = 0;
|
|
495
|
-
|
|
496
|
-
|
|
507
|
+
const char *tmp_walk;
|
|
508
|
+
for (tmp_walk = walker + 1;
|
|
509
|
+
consonpath_check_tmp_walker(tmp_walk, cnt_brackets);
|
|
497
510
|
++tmp_walk) {
|
|
498
511
|
if (!cnt_brackets && *tmp_walk == ',') {
|
|
499
512
|
csonpath_push_char(cjp, CSONPATH_INST_GET_UNION, inst_idx);
|
|
@@ -504,10 +517,16 @@ root_again:
|
|
|
504
517
|
++cnt_brackets;
|
|
505
518
|
if (cnt_brackets && *tmp_walk == ']')
|
|
506
519
|
--cnt_brackets;
|
|
507
|
-
if (*tmp_walk == '"')
|
|
520
|
+
if (*tmp_walk == '"') {
|
|
508
521
|
for (++tmp_walk; *tmp_walk != '"' && *tmp_walk; ++tmp_walk);
|
|
509
|
-
|
|
510
|
-
|
|
522
|
+
}
|
|
523
|
+
else if (*tmp_walk == '\'') {
|
|
524
|
+
for (++tmp_walk; *tmp_walk != '\'' && *tmp_walk; ++tmp_walk);
|
|
525
|
+
}
|
|
526
|
+
if (!*tmp_walk) break;
|
|
527
|
+
}
|
|
528
|
+
if (!tmp_walk[0]) {
|
|
529
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "unclose union");
|
|
511
530
|
}
|
|
512
531
|
}
|
|
513
532
|
++walker;
|
|
@@ -547,7 +566,7 @@ root_again:
|
|
|
547
566
|
}
|
|
548
567
|
filter_again_root:
|
|
549
568
|
inst = CSONPATH_INST_GET_OBJ;
|
|
550
|
-
filter_getter
|
|
569
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, CSONPATH_INST_GET_OBJ, walker);
|
|
551
570
|
++walker;
|
|
552
571
|
|
|
553
572
|
/* skipp blank */
|
|
@@ -585,12 +604,12 @@ root_again:
|
|
|
585
604
|
}
|
|
586
605
|
++walker;
|
|
587
606
|
for (next = walker; *next != getter_end; ++next)
|
|
588
|
-
filter_getter
|
|
589
|
-
filter_getter
|
|
607
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, *next, next);
|
|
608
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, 0, next);
|
|
590
609
|
} else {
|
|
591
610
|
for (next = walker; csonpath_is_dot_operand(*next); ++next)
|
|
592
|
-
filter_getter
|
|
593
|
-
filter_getter
|
|
611
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, *next, next);
|
|
612
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, 0, next);
|
|
594
613
|
}
|
|
595
614
|
if (!*next) {
|
|
596
615
|
CSONPATH_COMPILE_ERR(tmp, next - orig,
|
|
@@ -606,11 +625,11 @@ root_again:
|
|
|
606
625
|
}
|
|
607
626
|
if (to_check == '.') {
|
|
608
627
|
walker = next + 1;
|
|
609
|
-
filter_getter
|
|
628
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, CSONPATH_INST_GET_OBJ, walker);
|
|
610
629
|
goto filter_again;
|
|
611
630
|
} else if (to_check == '[') {
|
|
612
631
|
walker = next + 1;
|
|
613
|
-
filter_getter
|
|
632
|
+
CSONPATH_FILTER_PUSH(filter_getter, nb_getter_inst, CSONPATH_INST_GET_OBJ, walker);
|
|
614
633
|
getter_end = *walker;
|
|
615
634
|
goto filter_again;
|
|
616
635
|
}
|
|
@@ -896,13 +915,17 @@ root_again:
|
|
|
896
915
|
++walker;
|
|
897
916
|
next = walker;
|
|
898
917
|
csonpath_push_char(cjp, inst, inst_idx);
|
|
899
|
-
while (*next != end) {
|
|
900
|
-
/* \" should be ignored */
|
|
918
|
+
while (*next && *next != end) {
|
|
919
|
+
/* TODO: \" should be ignored */
|
|
901
920
|
csonpath_push_char(cjp, *next, inst_idx);
|
|
902
921
|
++next;
|
|
903
922
|
while (*next == '\\')
|
|
904
923
|
++next;
|
|
905
924
|
}
|
|
925
|
+
if (!*next) {
|
|
926
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
927
|
+
"unclosed string in bracket");
|
|
928
|
+
}
|
|
906
929
|
++next; // skipp end
|
|
907
930
|
csonpath_push_char(cjp, 0, inst_idx);
|
|
908
931
|
if (in_union && *next == ',') {
|
|
@@ -1103,7 +1126,7 @@ need_reloop_in = 0;
|
|
|
1103
1126
|
|
|
1104
1127
|
#define CSONPATH_DO_FIND_ALL_OUT if (end_sentinel) *end_sentinel = walker; return CSONPATH_NULL
|
|
1105
1128
|
|
|
1106
|
-
#define
|
|
1129
|
+
#define CSONPATH_DO_EXTRA_DECLARATION , const char **end_sentinel
|
|
1107
1130
|
#define CSONPATH_DO_EXTRA_ARGS_IN , NULL
|
|
1108
1131
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , end_sentinel
|
|
1109
1132
|
|
|
@@ -1122,7 +1145,7 @@ need_reloop_in = 0;
|
|
|
1122
1145
|
|
|
1123
1146
|
#define CSONPATH_DO_FUNC_NAME find_all
|
|
1124
1147
|
#define CSONPATH_DO_RET_TYPE CSONPATH_FIND_ALL_RET
|
|
1125
|
-
#define CSONPATH_DO_RETURN ({
|
|
1148
|
+
#define CSONPATH_DO_RETURN ({CSONPATH_ARRAY_APPEND(ret_ar, tmp); return ret_ar;})
|
|
1126
1149
|
|
|
1127
1150
|
#define CSONPATH_DO_FIND_ALL \
|
|
1128
1151
|
if (tret) ++nb_res; \
|
|
@@ -1136,7 +1159,7 @@ need_reloop_in = 0;
|
|
|
1136
1159
|
return ret_ar;
|
|
1137
1160
|
|
|
1138
1161
|
#define CSONPATH_DO_EXTRA_ARGS_IN , ret_ar
|
|
1139
|
-
#define
|
|
1162
|
+
#define CSONPATH_DO_EXTRA_DECLARATION , CSONPATH_FIND_ALL_RET ret_ar
|
|
1140
1163
|
|
|
1141
1164
|
#include "csonpath_do.h"
|
|
1142
1165
|
|
|
@@ -1158,10 +1181,12 @@ need_reloop_in = 0;
|
|
|
1158
1181
|
|
|
1159
1182
|
#define CSONPATH_DO_RET_TYPE int
|
|
1160
1183
|
#define CSONPATH_DO_RETURN \
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1184
|
+
({if (ctx == in_ctx && need_reloop && \
|
|
1185
|
+
CSONPATH_NEED_FOREACH_REDO(ctx)) \
|
|
1186
|
+
*need_reloop = 1; \
|
|
1187
|
+
if (child_info.type == CSONPATH_NONE) \
|
|
1188
|
+
return 0; \
|
|
1189
|
+
CSONPATH_REMOVE_CHILD(ctx, child_info); return 1;})
|
|
1165
1190
|
|
|
1166
1191
|
#define CSONPATH_PRE_GET_OBJ(val) \
|
|
1167
1192
|
const char *to_del = val;
|
|
@@ -1200,7 +1225,7 @@ need_reloop_in = 0;
|
|
|
1200
1225
|
nb_res += tret; \
|
|
1201
1226
|
})
|
|
1202
1227
|
|
|
1203
|
-
#define
|
|
1228
|
+
#define CSONPATH_DO_EXTRA_DECLARATION , struct csonpath_child_info child_info, int *need_reloop
|
|
1204
1229
|
|
|
1205
1230
|
#define CSONPATH_DO_EXTRA_ARGS_IN , (struct csonpath_child_info) {.type = CSONPATH_NONE}, NULL
|
|
1206
1231
|
|
|
@@ -1260,9 +1285,9 @@ again:
|
|
|
1260
1285
|
if (child_info->type != CSONPATH_NONE) { \
|
|
1261
1286
|
if (need_reloop) *need_reloop = 1; \
|
|
1262
1287
|
if (child_info->type == CSONPATH_INTEGER) \
|
|
1263
|
-
return CSONPATH_APPEND_AT(ctx, child_info->idx, to_update); \
|
|
1288
|
+
return CSONPATH_APPEND_AT(ctx, child_info->idx, to_update, 1); \
|
|
1264
1289
|
else \
|
|
1265
|
-
return CSONPATH_APPEND_AT(ctx, child_info->key, to_update); \
|
|
1290
|
+
return CSONPATH_APPEND_AT(ctx, child_info->key, to_update, 1); \
|
|
1266
1291
|
return 1; \
|
|
1267
1292
|
} \
|
|
1268
1293
|
return 0;
|
|
@@ -1273,7 +1298,7 @@ again:
|
|
|
1273
1298
|
csonpath_child_info_set(&(struct csonpath_child_info ){}, tmp, (intptr_t)key_idx), &need_reloop_in
|
|
1274
1299
|
#define CSONPATH_DO_EXTRA_ARGS , CSONPATH_JSON to_update
|
|
1275
1300
|
#define CSONPATH_DO_EXTRA_ARGS_IN , to_update, &(struct csonpath_child_info ){}, NULL
|
|
1276
|
-
#define
|
|
1301
|
+
#define CSONPATH_DO_EXTRA_DECLARATION CSONPATH_DO_EXTRA_ARGS, struct csonpath_child_info *child_info, int *need_reloop
|
|
1277
1302
|
#define CSONPATH_DO_FIND_ALL nb_res += tret;
|
|
1278
1303
|
#define CSONPATH_DO_FILTER_FIND CSONPATH_GOTO_ON_RELOOP(filter_again)
|
|
1279
1304
|
|
|
@@ -1318,7 +1343,7 @@ static int csonpath_sync_root_array(CSONPATH_JSON parent, CSONPATH_JSON to_updat
|
|
|
1318
1343
|
(void) idx;
|
|
1319
1344
|
CSONPATH_ARRAY_CLEAR(parent);
|
|
1320
1345
|
CSONPATH_FOREACH_ARRAY(to_update, child, idx) {
|
|
1321
|
-
if (CSONPATH_APPEND_AT(parent, idx, child) < 0)
|
|
1346
|
+
if (CSONPATH_APPEND_AT(parent, idx, child, 1) < 0)
|
|
1322
1347
|
return -1;
|
|
1323
1348
|
}
|
|
1324
1349
|
return 1;
|
|
@@ -1332,7 +1357,7 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1332
1357
|
(void )key;
|
|
1333
1358
|
CSONPATH_OBJ_CLEAR(parent);
|
|
1334
1359
|
CSONPATH_FOREACH_OBJ(to_update, child, key) {
|
|
1335
|
-
if (CSONPATH_APPEND_AT(parent, key, child) < 0)
|
|
1360
|
+
if (CSONPATH_APPEND_AT(parent, key, child, 1) < 0)
|
|
1336
1361
|
return -1;
|
|
1337
1362
|
}
|
|
1338
1363
|
return 1;
|
|
@@ -1342,14 +1367,14 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1342
1367
|
#define CSONPATH_UPDATE_CHECK_EXIST(mk_cnt) \
|
|
1343
1368
|
if (tmp == CSONPATH_NULL) { \
|
|
1344
1369
|
int append_ret = 0; \
|
|
1370
|
+
if (child_info->type == CSONPATH_NONE) \
|
|
1371
|
+
CSONPATH_GETTER_ERR("CSONPATH_NONE is nope\n"); \
|
|
1345
1372
|
tmp = mk_cnt(); \
|
|
1346
1373
|
if (child_info->type == CSONPATH_INTEGER) \
|
|
1347
|
-
append_ret = CSONPATH_APPEND_AT(ctx, child_info->idx, tmp);
|
|
1374
|
+
append_ret = CSONPATH_APPEND_AT(ctx, child_info->idx, tmp, 1); \
|
|
1348
1375
|
else if (child_info->type == CSONPATH_STR) \
|
|
1349
|
-
append_ret = CSONPATH_APPEND_AT(ctx, child_info->key, tmp);
|
|
1350
|
-
|
|
1351
|
-
CSONPATH_GETTER_ERR("CSONPATH_NONE is nope\n"); \
|
|
1352
|
-
CSONPATH_DECREF(tmp); \
|
|
1376
|
+
append_ret = CSONPATH_APPEND_AT(ctx, child_info->key, tmp, 1); \
|
|
1377
|
+
CSONPATH_REMOVE(tmp); \
|
|
1353
1378
|
if (append_ret < 0) return append_ret; \
|
|
1354
1379
|
ctx = tmp; \
|
|
1355
1380
|
}
|
|
@@ -1370,7 +1395,6 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1370
1395
|
csonpath_child_info_set(child_info, tmp, this_idx);
|
|
1371
1396
|
|
|
1372
1397
|
|
|
1373
|
-
|
|
1374
1398
|
#include "csonpath_do.h"
|
|
1375
1399
|
|
|
1376
1400
|
/* callback */
|
|
@@ -1381,18 +1405,26 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1381
1405
|
#define CSONPATH_DO_RET_TYPE int
|
|
1382
1406
|
#define CSONPATH_DO_FUNC_NAME callback
|
|
1383
1407
|
#define CSONPATH_DO_RETURN do { \
|
|
1384
|
-
|
|
1385
|
-
|
|
1408
|
+
if (CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) < 0) \
|
|
1409
|
+
return -1; \
|
|
1410
|
+
return 1;} \
|
|
1411
|
+
while (0)
|
|
1412
|
+
|
|
1413
|
+
#define CSONPATH_DO_PRE_OPERATION \
|
|
1414
|
+
if (callback == NULL) { \
|
|
1415
|
+
CSONPATH_GETTER_ERR("callback is NULL\n"); \
|
|
1416
|
+
return -1; \
|
|
1417
|
+
}
|
|
1386
1418
|
|
|
1387
1419
|
#define CSONPATH_DO_EXTRA_ARGS_FIND_ALL , callback, udata, child_info
|
|
1388
1420
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , callback, udata, \
|
|
1389
1421
|
csonpath_child_info_set(child_info, tmp, (intptr_t)key_idx)
|
|
1390
1422
|
#define CSONPATH_DO_EXTRA_ARGS , CSONPATH_CALLBACK callback, CSONPATH_CALLBACK_DATA udata
|
|
1391
1423
|
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata, &(struct csonpath_child_info ){}
|
|
1392
|
-
#define
|
|
1424
|
+
#define CSONPATH_DO_EXTRA_DECLARATION CSONPATH_DO_EXTRA_ARGS, struct csonpath_child_info *child_info
|
|
1393
1425
|
|
|
1394
|
-
#define CSONPATH_DO_FIND_ALL nb_res += tret;
|
|
1395
|
-
#define CSONPATH_DO_FILTER_FIND nb_res += tret;
|
|
1426
|
+
#define CSONPATH_DO_FIND_ALL do { if (tret < 0) return tret; nb_res += tret; } while (0)
|
|
1427
|
+
#define CSONPATH_DO_FILTER_FIND do { if (tret < 0) return tret; nb_res += tret; } while (0)
|
|
1396
1428
|
|
|
1397
1429
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
1398
1430
|
|
|
@@ -1408,24 +1440,31 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1408
1440
|
#define CSONPATH_DO_DECLARATION \
|
|
1409
1441
|
int nb_res = 0;
|
|
1410
1442
|
|
|
1443
|
+
#define CSONPATH_DO_PRE_OPERATION \
|
|
1444
|
+
if (callback == NULL) { \
|
|
1445
|
+
CSONPATH_GETTER_ERR("callback is NULL\n"); \
|
|
1446
|
+
return -1; \
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1411
1449
|
#define CSONPATH_DO_RET_TYPE int
|
|
1412
1450
|
#define CSONPATH_DO_FUNC_NAME update_or_create_callback
|
|
1413
1451
|
#define CSONPATH_DO_RETURN \
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
return 1;
|
|
1452
|
+
if (need_reloop && tmp == value) { \
|
|
1453
|
+
*need_reloop = 1; \
|
|
1454
|
+
} \
|
|
1455
|
+
if (CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) < 0) \
|
|
1456
|
+
return -1; \
|
|
1457
|
+
return 1;
|
|
1419
1458
|
|
|
1420
1459
|
#define CSONPATH_DO_EXTRA_ARGS_FIND_ALL , callback, udata, NULL, need_reloop
|
|
1421
|
-
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , callback, udata,
|
|
1460
|
+
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , callback, udata, \
|
|
1422
1461
|
csonpath_child_info_set(&(struct csonpath_child_info ){}, tmp, (intptr_t)key_idx), \
|
|
1423
1462
|
&need_reloop_in
|
|
1424
1463
|
#define CSONPATH_DO_EXTRA_ARGS , CSONPATH_CALLBACK callback, CSONPATH_CALLBACK_DATA udata
|
|
1425
1464
|
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata, &(struct csonpath_child_info ){}, NULL
|
|
1426
|
-
#define
|
|
1427
|
-
#define CSONPATH_DO_FIND_ALL nb_res += tret;
|
|
1428
|
-
#define CSONPATH_DO_FILTER_FIND CSONPATH_GOTO_ON_RELOOP(filter_again)
|
|
1465
|
+
#define CSONPATH_DO_EXTRA_DECLARATION CSONPATH_DO_EXTRA_ARGS, struct csonpath_child_info *child_info, int *need_reloop
|
|
1466
|
+
#define CSONPATH_DO_FIND_ALL do { if (tret < 0) return tret; nb_res += tret; } while (0)
|
|
1467
|
+
#define CSONPATH_DO_FILTER_FIND do { if (tret < 0) return tret; CSONPATH_GOTO_ON_RELOOP(filter_again); } while (0)
|
|
1429
1468
|
|
|
1430
1469
|
#define CSONPATH_DO_FIND_ALL_PRE_LOOP int need_reloop_in = 0;
|
|
1431
1470
|
|
|
@@ -1434,7 +1473,7 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1434
1473
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
1435
1474
|
|
|
1436
1475
|
#define CSONPATH_PRE_GET_ROOT \
|
|
1437
|
-
int to_check =
|
|
1476
|
+
int to_check = walker[1]; \
|
|
1438
1477
|
if (csonpath_is_endish_inst(to_check)) { \
|
|
1439
1478
|
CSONPATH_GETTER_ERR("can't update root ($)\n"); \
|
|
1440
1479
|
return CSONPATH_NONE_FOUND_RET; \
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
#define CSONPATH_DO_POST_FIND_ARRAY
|
|
37
37
|
#endif
|
|
38
38
|
|
|
39
|
-
#ifndef
|
|
40
|
-
#define
|
|
39
|
+
#ifndef CSONPATH_DO_EXTRA_DECLARATION
|
|
40
|
+
#define CSONPATH_DO_EXTRA_DECLARATION
|
|
41
41
|
#endif
|
|
42
42
|
|
|
43
43
|
#ifndef CSONPATH_DO_FIND_ALL_CLEAUP
|
|
@@ -121,7 +121,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
121
121
|
CSONPATH_JSON origin,
|
|
122
122
|
CSONPATH_JSON value,
|
|
123
123
|
CSONPATH_JSON ctx,
|
|
124
|
-
const char *walker
|
|
124
|
+
const char *walker CSONPATH_DO_EXTRA_DECLARATION);
|
|
125
125
|
|
|
126
126
|
|
|
127
127
|
#define csonpath_do_dotdot__(name) CATCAT(csonpath_, name, _dotdot)
|
|
@@ -132,7 +132,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(const struct csonpath cjp[const s
|
|
|
132
132
|
CSONPATH_JSON origin,
|
|
133
133
|
CSONPATH_JSON tmp,
|
|
134
134
|
CSONPATH_JSON ctx,
|
|
135
|
-
const char *walker
|
|
135
|
+
const char *walker CSONPATH_DO_EXTRA_DECLARATION)
|
|
136
136
|
{
|
|
137
137
|
CSONPATH_JSON el;
|
|
138
138
|
CSONPATH_DO_DECLARATION;
|
|
@@ -181,7 +181,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
181
181
|
CSONPATH_JSON origin,
|
|
182
182
|
CSONPATH_JSON value,
|
|
183
183
|
CSONPATH_JSON ctx,
|
|
184
|
-
const char *walker
|
|
184
|
+
const char *walker CSONPATH_DO_EXTRA_DECLARATION)
|
|
185
185
|
{
|
|
186
186
|
CSONPATH_JSON tmp = value;
|
|
187
187
|
CSONPATH_DO_DECLARATION;
|
|
@@ -218,7 +218,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
218
218
|
CSONPATH_JSON el;
|
|
219
219
|
int operation_in = *walker, operation = *walker;
|
|
220
220
|
const char *owalker;
|
|
221
|
-
int filter_next_in = *(walker+1), filter_next = *(walker+1);
|
|
221
|
+
int filter_next_in = (unsigned char)*(walker+1), filter_next = (unsigned char)*(walker+1);
|
|
222
222
|
const char *next = walker + 2;
|
|
223
223
|
int foreach_idx;
|
|
224
224
|
|
|
@@ -504,7 +504,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
504
504
|
#undef CSONPATH_DO_EXTRA_ARGS_IN
|
|
505
505
|
#undef CSONPATH_DO_EXTRA_ARGS_FIND_ALL
|
|
506
506
|
#undef CSONPATH_DO_EXTRA_ARGS
|
|
507
|
-
#undef
|
|
507
|
+
#undef CSONPATH_DO_EXTRA_DECLARATION
|
|
508
508
|
#undef CSONPATH_DO_FIND_ALL_PRE_LOOP
|
|
509
509
|
#undef CSONPATH_DO_FOREACH_PRE_SET
|
|
510
510
|
#undef CSONPATH_DO_GET_ALL_OUT
|
|
@@ -23,7 +23,7 @@ typedef void (*json_c_callback)(json_object *, struct csonpath_child_info *, jso
|
|
|
23
23
|
#define CSONPATH_CALLBACK_DATA void *
|
|
24
24
|
|
|
25
25
|
#define CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) \
|
|
26
|
-
callback(ctx, child_info, tmp, udata)
|
|
26
|
+
(callback(ctx, child_info, tmp, udata), 0)
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
#define CSONPATH_NEED_FOREACH_REDO(o) \
|
|
@@ -122,27 +122,29 @@ typedef void (*json_c_callback)(json_object *, struct csonpath_child_info *, jso
|
|
|
122
122
|
#define CSONPATH_NEW_OBJECT() json_object_new_object()
|
|
123
123
|
|
|
124
124
|
static int json_object_try_object_add(struct json_object *obj, const char * const at,
|
|
125
|
-
struct json_object *el)
|
|
125
|
+
struct json_object *el, int do_incref)
|
|
126
126
|
{
|
|
127
127
|
if (!CSONPATH_IS_OBJ(obj)) {
|
|
128
128
|
return -1;
|
|
129
129
|
}
|
|
130
|
+
if (do_incref) json_object_get(el);
|
|
130
131
|
json_object_object_add(obj, at, el);
|
|
131
132
|
return 1;
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
static int json_array_try_put(struct json_object *obj, int at,
|
|
135
|
-
struct json_object *el)
|
|
136
|
+
struct json_object *el, int do_incref)
|
|
136
137
|
{
|
|
137
138
|
if (!CSONPATH_IS_ARRAY(obj)) {
|
|
138
139
|
return -1;
|
|
139
140
|
}
|
|
141
|
+
if (do_incref) json_object_get(el);
|
|
140
142
|
json_object_array_put_idx(obj, at, el);
|
|
141
143
|
return 1;
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
#define CSONPATH_APPEND_AT(array, at, el) \
|
|
145
|
-
_Generic((at),
|
|
146
|
+
#define CSONPATH_APPEND_AT(array, at, el, do_incref) \
|
|
147
|
+
_Generic((at), \
|
|
146
148
|
int: json_array_try_put, \
|
|
147
149
|
unsigned int: json_array_try_put, \
|
|
148
150
|
long: json_array_try_put, \
|
|
@@ -151,11 +153,11 @@ static int json_array_try_put(struct json_object *obj, int at,
|
|
|
151
153
|
unsigned long long: json_array_try_put, \
|
|
152
154
|
const char *: json_object_try_object_add, \
|
|
153
155
|
char *: json_object_try_object_add \
|
|
154
|
-
) (array, at, el)
|
|
156
|
+
) (array, at, el, do_incref)
|
|
155
157
|
|
|
156
|
-
#define
|
|
157
|
-
json_object_get(el);
|
|
158
|
-
json_object_array_add(array, el);
|
|
158
|
+
#define CSONPATH_ARRAY_APPEND(array, el) ({ \
|
|
159
|
+
json_object_get(el); \
|
|
160
|
+
json_object_array_add(array, el); \
|
|
159
161
|
})
|
|
160
162
|
|
|
161
163
|
static struct json_object *csonpath_json_c_get(struct json_object *obj,
|
|
@@ -33,9 +33,6 @@
|
|
|
33
33
|
#define CSONPATH_GET_STR(obj) \
|
|
34
34
|
PyUnicode_AsUTF8(obj)
|
|
35
35
|
|
|
36
|
-
#define CSONPATH_DECREF(obj) \
|
|
37
|
-
Py_DECREF(obj);
|
|
38
|
-
|
|
39
36
|
#define CSONPATH_GET_NUM(obj) \
|
|
40
37
|
PyLong_AsLong(obj)
|
|
41
38
|
|
|
@@ -68,15 +65,23 @@
|
|
|
68
65
|
|
|
69
66
|
#define CSONPATH_CALLBACK_DATA PyObject *
|
|
70
67
|
|
|
71
|
-
#define CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata)
|
|
68
|
+
#define CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) \
|
|
69
|
+
({ \
|
|
70
|
+
int _cb_ok = 0; \
|
|
72
71
|
PyObject *arglist; \
|
|
72
|
+
PyObject *_cb_ret; \
|
|
73
73
|
if (child_info->type == CSONPATH_STR) \
|
|
74
74
|
arglist = Py_BuildValue("(OsOO)", ctx, child_info->key, tmp, udata); \
|
|
75
75
|
else \
|
|
76
76
|
arglist = Py_BuildValue("(OiOO)", ctx, child_info->idx, tmp, udata); \
|
|
77
|
-
PyObject_CallObject(callback, arglist);
|
|
77
|
+
_cb_ret = PyObject_CallObject(callback, arglist); \
|
|
78
78
|
Py_DECREF(arglist); \
|
|
79
|
-
|
|
79
|
+
if (!_cb_ret) \
|
|
80
|
+
_cb_ok = -1; \
|
|
81
|
+
else \
|
|
82
|
+
Py_DECREF(_cb_ret); \
|
|
83
|
+
_cb_ok; \
|
|
84
|
+
})
|
|
80
85
|
|
|
81
86
|
/* assuming each modification of the object need to go out of the loop */
|
|
82
87
|
#define CSONPATH_NEED_FOREACH_REDO(o) 1
|
|
@@ -90,13 +95,10 @@
|
|
|
90
95
|
|
|
91
96
|
#define CSONPATH_ARRAY_APPEND(list, el) PyList_Append(list, el)
|
|
92
97
|
|
|
93
|
-
/* I don't think incrref is needed with python */
|
|
94
|
-
#define CSONPATH_ARRAY_APPEND_INCREF(array, el) ({ \
|
|
95
|
-
PyList_Append(array, el); \
|
|
96
|
-
})
|
|
97
98
|
|
|
98
|
-
static int pydict_try_setitemstring(PyObject *obj,
|
|
99
|
+
static int pydict_try_setitemstring(PyObject *obj, const char * const at, PyObject *el, int do_incref)
|
|
99
100
|
{
|
|
101
|
+
(void)do_incref;
|
|
100
102
|
if (!PyDict_Check(obj)) {
|
|
101
103
|
PyObject* repr = PyObject_Repr(obj);
|
|
102
104
|
PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
|
|
@@ -107,12 +109,18 @@ static int pydict_try_setitemstring(PyObject *obj, const char * const at, PyObj
|
|
|
107
109
|
Py_XDECREF(str);
|
|
108
110
|
return -1;
|
|
109
111
|
}
|
|
110
|
-
|
|
112
|
+
if (!at) {
|
|
113
|
+
PyErr_SetString(PyExc_TypeError, "dict keys must be strings");
|
|
114
|
+
return -1;
|
|
115
|
+
}
|
|
116
|
+
if (PyDict_SetItemString(obj, at, el) < 0)
|
|
117
|
+
return -1;
|
|
111
118
|
return 1;
|
|
112
119
|
}
|
|
113
120
|
|
|
114
|
-
static int python_set_or_insert_item(PyObject *array,
|
|
121
|
+
static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *el, int do_incref)
|
|
115
122
|
{
|
|
123
|
+
(void)do_incref;
|
|
116
124
|
if (!PyList_Check(array)) {
|
|
117
125
|
PyErr_Format(PyExc_ValueError, "Unable to follow path: List expected");
|
|
118
126
|
return -1;
|
|
@@ -125,23 +133,25 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
125
133
|
PyList_Insert(array, at, el);
|
|
126
134
|
} else {
|
|
127
135
|
Py_INCREF(el);
|
|
128
|
-
if (PyList_SetItem(array, at, el) < 0)
|
|
129
|
-
|
|
136
|
+
if (PyList_SetItem(array, at, el) < 0) {
|
|
137
|
+
Py_DECREF(el);
|
|
138
|
+
return -1;
|
|
139
|
+
}
|
|
130
140
|
}
|
|
131
141
|
return 1;
|
|
132
142
|
}
|
|
133
143
|
|
|
134
|
-
#define CSONPATH_APPEND_AT(array, at, el) \
|
|
135
|
-
_Generic((at),
|
|
136
|
-
int: python_set_or_insert_item,
|
|
137
|
-
unsigned int: python_set_or_insert_item,
|
|
138
|
-
long: python_set_or_insert_item,
|
|
139
|
-
unsigned long: python_set_or_insert_item,
|
|
140
|
-
long long: python_set_or_insert_item,
|
|
141
|
-
unsigned long long: python_set_or_insert_item,
|
|
142
|
-
const char *: pydict_try_setitemstring,
|
|
143
|
-
char *: pydict_try_setitemstring
|
|
144
|
-
) (array, at, el)
|
|
144
|
+
#define CSONPATH_APPEND_AT(array, at, el, do_incref) \
|
|
145
|
+
_Generic((at), \
|
|
146
|
+
int: python_set_or_insert_item, \
|
|
147
|
+
unsigned int: python_set_or_insert_item, \
|
|
148
|
+
long: python_set_or_insert_item, \
|
|
149
|
+
unsigned long: python_set_or_insert_item, \
|
|
150
|
+
long long: python_set_or_insert_item, \
|
|
151
|
+
unsigned long long: python_set_or_insert_item, \
|
|
152
|
+
const char *: pydict_try_setitemstring, \
|
|
153
|
+
char *: pydict_try_setitemstring \
|
|
154
|
+
) (array, at, el, do_incref)
|
|
145
155
|
|
|
146
156
|
|
|
147
157
|
#ifdef __TINYC__
|
|
@@ -193,6 +203,11 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
193
203
|
CSONPATH_PRAGMA("GCC unroll 8") \
|
|
194
204
|
for (intptr_t key_idx = 0; key_idx < array_len_; ++key_idx) { \
|
|
195
205
|
el = PyList_GetItem(obj, key_idx); \
|
|
206
|
+
if (!el) { \
|
|
207
|
+
PyErr_SetString(PyExc_RuntimeError, \
|
|
208
|
+
"list was modified during iteration"); \
|
|
209
|
+
break; \
|
|
210
|
+
} \
|
|
196
211
|
code \
|
|
197
212
|
} \
|
|
198
213
|
}
|
|
@@ -298,6 +313,10 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
298
313
|
|
|
299
314
|
static PyObject *print_instructions(PyCsonPathObject *self, PyObject *args, PyObject *kwds)
|
|
300
315
|
{
|
|
316
|
+
if (!self->cp) {
|
|
317
|
+
PyErr_SetString(PyExc_RuntimeError, "compiled path is NULL");
|
|
318
|
+
return NULL;
|
|
319
|
+
}
|
|
301
320
|
csonpath_print_instruction(self->cp);
|
|
302
321
|
Py_RETURN_NONE;
|
|
303
322
|
}
|
|
@@ -309,8 +328,9 @@ static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
|
309
328
|
if (!PyArg_ParseTuple(args, "OO|O", &json, &callback, &udata))
|
|
310
329
|
BAD_ARG();
|
|
311
330
|
int ret = csonpath_callback(self->cp, json, callback, udata);
|
|
312
|
-
if (PyErr_Occurred())
|
|
331
|
+
if (PyErr_Occurred() || ret < 0) {
|
|
313
332
|
return NULL;
|
|
333
|
+
}
|
|
314
334
|
return PyLong_FromLong(ret);
|
|
315
335
|
}
|
|
316
336
|
|
|
@@ -321,7 +341,7 @@ static PyObject *do_remove(PyCsonPathObject *self, PyObject* args)
|
|
|
321
341
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
322
342
|
BAD_ARG();
|
|
323
343
|
int ret = csonpath_remove(self->cp, json);
|
|
324
|
-
if (PyErr_Occurred())
|
|
344
|
+
if (PyErr_Occurred() || ret < 0)
|
|
325
345
|
return NULL;
|
|
326
346
|
return PyLong_FromLong(ret);
|
|
327
347
|
}
|
|
@@ -365,10 +385,22 @@ static void PyCsonPath_dealloc(PyCsonPathObject *self) {
|
|
|
365
385
|
static PyObject *PyCsonPath_set_path(PyCsonPathObject *self, PyObject* args) {
|
|
366
386
|
const char *new_path;
|
|
367
387
|
if (!PyArg_ParseTuple(args, "s", &new_path))
|
|
368
|
-
return
|
|
388
|
+
return NULL;
|
|
369
389
|
if (!new_path) return Py_False;
|
|
370
390
|
|
|
371
|
-
|
|
391
|
+
struct csonpath *new_cjp = csonpath_new_ex(new_path, CSONPATH_NO_DETROY);
|
|
392
|
+
if (!new_cjp) {
|
|
393
|
+
PyErr_NoMemory();
|
|
394
|
+
return NULL;
|
|
395
|
+
}
|
|
396
|
+
if (new_cjp->compile_error) {
|
|
397
|
+
PyErr_Format(PyExc_ValueError, "compilation fail %s",
|
|
398
|
+
new_cjp->compile_error);
|
|
399
|
+
csonpath_destroy(new_cjp);
|
|
400
|
+
return NULL;
|
|
401
|
+
}
|
|
402
|
+
csonpath_destroy(self->cp);
|
|
403
|
+
self->cp = new_cjp;
|
|
372
404
|
return Py_True;
|
|
373
405
|
}
|
|
374
406
|
|
|
@@ -63,7 +63,7 @@ typedef void (*yyjson_val_callback)(yyjson_val *, struct csonpath_child_info *,
|
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
#define CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata) \
|
|
66
|
-
callback(ctx, child_info, tmp, udata)
|
|
66
|
+
(callback(ctx, child_info, tmp, udata), 0)
|
|
67
67
|
|
|
68
68
|
|
|
69
69
|
#define CSONPATH_FOREACH(obj, el, code) \
|
|
@@ -111,7 +111,7 @@ typedef void (*yyjson_val_callback)(yyjson_val *, struct csonpath_child_info *,
|
|
|
111
111
|
#define CSONPATH_OBJ_CLEAR(o) \
|
|
112
112
|
fail_on_non_mut(NULL)
|
|
113
113
|
|
|
114
|
-
#define CSONPATH_APPEND_AT(array, at, el) \
|
|
114
|
+
#define CSONPATH_APPEND_AT(array, at, el, do_incref) \
|
|
115
115
|
fail_on_non_mut(NULL) \
|
|
116
116
|
|
|
117
117
|
|
|
@@ -134,7 +134,7 @@ struct find_all_ret {
|
|
|
134
134
|
|
|
135
135
|
#define CSONPATH_FIND_ALL_RET struct find_all_ret *
|
|
136
136
|
|
|
137
|
-
#define
|
|
137
|
+
#define CSONPATH_ARRAY_APPEND(ar, o) \
|
|
138
138
|
_Generic(ar, \
|
|
139
139
|
struct find_all_ret *: find_all_append, \
|
|
140
140
|
yyjson_val *: fail_on_non_mut)(ar, o)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.16.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
[tool.setuptools]
|
|
@@ -27,7 +27,7 @@ test-command = "pytest {project}/tests/python"
|
|
|
27
27
|
before-build = "choco install mingw -y"
|
|
28
28
|
|
|
29
29
|
[tool.bumpversion]
|
|
30
|
-
current_version = "0.
|
|
30
|
+
current_version = "0.16.0"
|
|
31
31
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
32
32
|
serialize = ["{major}.{minor}.{patch}"]
|
|
33
33
|
search = "{current_version}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|