csonpath 0.13.0__tar.gz → 0.14.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.13.0 → csonpath-0.14.0}/Makefile +11 -3
- {csonpath-0.13.0/csonpath.egg-info → csonpath-0.14.0}/PKG-INFO +1 -1
- {csonpath-0.13.0 → csonpath-0.14.0/csonpath.egg-info}/PKG-INFO +1 -1
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath.h +241 -99
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath_do.h +12 -6
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath_json-c.h +6 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath_python.c +20 -2
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath_yyjson.h +6 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/pyproject.toml +2 -2
- {csonpath-0.13.0 → csonpath-0.14.0}/LICENSE +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/MANIFEST.in +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/README.md +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/configure +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/setup.cfg +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/setup.py +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/.git +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/.github/workflows/c-cpp.yml +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/.gitignore +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/LICENSE +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/Makefile +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/README.md +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/clib.json +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/formal_verification.md +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/re.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/re.h +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/scripts/exrex.py +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/scripts/regex_test.py +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/scripts/regex_test_neg.py +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test1.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test2.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test3.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test_compile.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test_print.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test_rand.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test_rand_neg.c +0 -0
- {csonpath-0.13.0 → csonpath-0.14.0}/tiny-regex-c/tests/test_thread.c +0 -0
|
@@ -3,7 +3,7 @@ JSON_C_LDFLAGS=$(shell pkg-config --libs json-c)
|
|
|
3
3
|
|
|
4
4
|
include config.mk
|
|
5
5
|
|
|
6
|
-
all: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root
|
|
6
|
+
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
|
|
7
7
|
|
|
8
8
|
bench:
|
|
9
9
|
make -C bench
|
|
@@ -30,12 +30,20 @@ test-json-filter: tests/json-c/filter.c csonpath_json-c.h csonpath.h csonpath_do
|
|
|
30
30
|
test-json-subpath: tests/json-c/subpath.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
31
31
|
$(CC) tests/json-c/subpath.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-subpath $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
test-json-filter-and-missing-key: tests/json-c/filter-and-missing-key.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
34
|
+
$(CC) tests/json-c/filter-and-missing-key.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-filter-and-missing-key $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
35
|
+
|
|
36
|
+
test-json-get-array-big-index: tests/json-c/get-array-big-index.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
37
|
+
$(CC) tests/json-c/get-array-big-index.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-get-array-big-index $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
38
|
+
|
|
39
|
+
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
|
|
34
40
|
./test-json-c-get-a
|
|
35
41
|
./test-json-update
|
|
36
42
|
./test-json-filter
|
|
37
43
|
./test-json-subpath
|
|
38
44
|
./test-json-c-array-root
|
|
45
|
+
./test-json-filter-and-missing-key
|
|
46
|
+
./test-json-get-array-big-index
|
|
39
47
|
|
|
40
48
|
pip-dev:
|
|
41
49
|
pip install -e .[dev] --force-reinstall
|
|
@@ -46,5 +54,5 @@ tests-py: pip-dev
|
|
|
46
54
|
tests: tests-py tests-c
|
|
47
55
|
|
|
48
56
|
clean:
|
|
49
|
-
rm -rvf test-json-c-get-a test-json-update test-json-filter test-json-subpath
|
|
57
|
+
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
|
|
50
58
|
|
|
@@ -25,32 +25,6 @@ typedef regex_t csonpath_reg_t;
|
|
|
25
25
|
typedef regex_t csonpath_reg_t;
|
|
26
26
|
# endif
|
|
27
27
|
|
|
28
|
-
# if defined CSONPATH_TINY_REGEX
|
|
29
|
-
static inline int csonpath_reg_compile(csonpath_reg_t *out, const char *pat) {
|
|
30
|
-
*out = re_compile(pat);
|
|
31
|
-
return *out ? 0 : -1;
|
|
32
|
-
}
|
|
33
|
-
static inline _Bool csonpath_reg_exec(csonpath_reg_t reg, const char *str) {
|
|
34
|
-
int match_len = 0;
|
|
35
|
-
re_matchp(reg, str, &match_len);
|
|
36
|
-
return !!match_len;
|
|
37
|
-
}
|
|
38
|
-
static inline void csonpath_reg_free(csonpath_reg_t reg) {
|
|
39
|
-
free(reg);
|
|
40
|
-
}
|
|
41
|
-
# elif !defined CSONPATH_PCRE2
|
|
42
|
-
static inline int csonpath_reg_compile(csonpath_reg_t *out, const char *pat)
|
|
43
|
-
{
|
|
44
|
-
return regcomp(out, pat, 0);
|
|
45
|
-
}
|
|
46
|
-
static inline _Bool csonpath_reg_exec(csonpath_reg_t reg, const char *str)
|
|
47
|
-
{
|
|
48
|
-
return regexec(®, str, 0, NULL, 0) == 0;
|
|
49
|
-
}
|
|
50
|
-
static inline void csonpath_reg_free(csonpath_reg_t reg) { regfree(®); }
|
|
51
|
-
# endif
|
|
52
|
-
#endif
|
|
53
|
-
|
|
54
28
|
#if defined CSONPATH_TINY_REGEX
|
|
55
29
|
# define CSONPATH_HAVE_TINY_REGEX 1
|
|
56
30
|
#else
|
|
@@ -97,12 +71,16 @@ enum csonpath_instuction_raw {
|
|
|
97
71
|
CSONPATH_INST_GET_SUBPATH,
|
|
98
72
|
CSONPATH_INST_GET_ARRAY_SMALL,
|
|
99
73
|
CSONPATH_INST_GET_ARRAY_BIG,
|
|
74
|
+
CSONPATH_INST_FILTER_KEY_EXIST,
|
|
75
|
+
CSONPATH_INST_FILTER_KEY_TRUE,
|
|
76
|
+
CSONPATH_INST_FILTER_KEY_FALSE,
|
|
77
|
+
CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ,
|
|
78
|
+
CSONPATH_INST_FILTER_KEY_INFERIOR_EQ,
|
|
100
79
|
CSONPATH_INST_FILTER_KEY_SUPERIOR,
|
|
101
80
|
CSONPATH_INST_FILTER_KEY_INFERIOR,
|
|
102
81
|
CSONPATH_INST_FILTER_KEY_EQ,
|
|
103
82
|
CSONPATH_INST_FILTER_KEY_NOT_EQ,
|
|
104
83
|
CSONPATH_INST_FILTER_KEY_REG_EQ,
|
|
105
|
-
CSONPATH_INST_FILTER_OPERAND_STR,
|
|
106
84
|
CSONPATH_INST_FILTER_AND,
|
|
107
85
|
CSONPATH_INST_GET_ALL,
|
|
108
86
|
CSONPATH_INST_FIND_ALL,
|
|
@@ -115,22 +93,26 @@ enum csonpath_instuction_raw {
|
|
|
115
93
|
static int csonpath_instuction_len[] = {
|
|
116
94
|
1, /* 0 CSONPATH_INST_ROOT */
|
|
117
95
|
-1, /* 1 CSONPATH_INST_GET_OBJ */
|
|
118
|
-
1, /*
|
|
119
|
-
2, /*
|
|
120
|
-
5, /*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
2, /*
|
|
125
|
-
2, /*
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
1, /*
|
|
132
|
-
1, /*
|
|
133
|
-
1, /*
|
|
96
|
+
1, /* 2 CSONPATH_INST_GET_SUBPATH */
|
|
97
|
+
2, /* 3 CSONPATH_INST_GET_ARRAY_SMALL */
|
|
98
|
+
5, /* 4 CSONPATH_INST_GET_ARRAY_BIG */
|
|
99
|
+
1, /* 4.5 CSONPATH_INST_FILTER_KEY_EXIST */
|
|
100
|
+
1, /* 4.6 CSONPATH_INST_FILTER_KEY_TRUE */
|
|
101
|
+
1, /* 4.7 CSONPATH_INST_FILTER_KEY_FALSE */
|
|
102
|
+
2, /* 5 CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ */
|
|
103
|
+
2, /* 6 CSONPATH_INST_FILTER_KEY_INFERIOR_EQ */
|
|
104
|
+
2, /* 7 CSONPATH_INST_FILTER_KEY_SUPERIOR */
|
|
105
|
+
2, /* 8 CSONPATH_INST_FILTER_KEY_INFERIOR */
|
|
106
|
+
2, /* 9 CSONPATH_INST_FILTER_KEY_EQ */
|
|
107
|
+
2, /* A CSONPATH_INST_FILTER_KEY_NOT_EQ */
|
|
108
|
+
2, /* B CSONPATH_INST_FILTER_KEY_REG_EQ */
|
|
109
|
+
1, /* D CSONPATH_INST_FILTER_AND */
|
|
110
|
+
1, /* E CSONPATH_INST_GET_ALL */
|
|
111
|
+
-1, /* F CSONPATH_INST_FIND_ALL */
|
|
112
|
+
1, /* 10 CSONPATH_INST_RANGE */
|
|
113
|
+
1, /* 11 CSONPATH_INST_OR */
|
|
114
|
+
1, /* 12 CSONPATH_INST_END */
|
|
115
|
+
1, /* 13 CSONPATH_INST_BROKEN */
|
|
134
116
|
};
|
|
135
117
|
|
|
136
118
|
/* this should be in an include, but doing so, would break the
|
|
@@ -141,12 +123,16 @@ CSONPATH_UNUSED static const char *csonpath_instuction_str[] = {
|
|
|
141
123
|
"GET_SUBPATH",
|
|
142
124
|
"GET_ARRAY_SMALL",
|
|
143
125
|
"GET_ARRAY_BIG",
|
|
126
|
+
"FILTER_KEY_EXIST",
|
|
127
|
+
"FILTER_KEY_TRUE",
|
|
128
|
+
"FILTER_KEY_FALSE",
|
|
129
|
+
"FILTER_KEY_SUPERIOR_EQ",
|
|
130
|
+
"FILTER_KEY_INFERIOR_EQ",
|
|
144
131
|
"FILTER_KEY_SUPERIOR",
|
|
145
132
|
"FILTER_KEY_INFERIOR",
|
|
146
133
|
"FILTER_KEY_EQ",
|
|
147
134
|
"FILTER_KEY_NOT_EQ",
|
|
148
135
|
"FILTER_KEY_REG_EQ",
|
|
149
|
-
"FILTER_OPERAND_STR",
|
|
150
136
|
"FILTER_AND",
|
|
151
137
|
"GET_ALL",
|
|
152
138
|
"FIND_ALL",
|
|
@@ -175,6 +161,56 @@ struct csonpath {
|
|
|
175
161
|
char data[];
|
|
176
162
|
};
|
|
177
163
|
|
|
164
|
+
# if defined CSONPATH_TINY_REGEX
|
|
165
|
+
static inline int csonpath_reg_compile(struct csonpath *cjp, int idx, const char *pat, char **errbuff) {
|
|
166
|
+
(void)errbuff;
|
|
167
|
+
cjp->regexs[idx] = re_compile(pat);
|
|
168
|
+
return cjp->regexs[idx] ? 0 : -1;
|
|
169
|
+
}
|
|
170
|
+
static inline _Bool csonpath_reg_exec(csonpath_reg_t reg, const char *str) {
|
|
171
|
+
int match_len = 0;
|
|
172
|
+
re_matchp(reg, str, &match_len);
|
|
173
|
+
return !!match_len;
|
|
174
|
+
}
|
|
175
|
+
static inline void csonpath_reg_free(csonpath_reg_t reg) {
|
|
176
|
+
free(reg);
|
|
177
|
+
}
|
|
178
|
+
# elif !defined CSONPATH_PCRE2
|
|
179
|
+
static inline int csonpath_reg_compile(struct csonpath *cjp, int idx, const char *pat, char **errbuff)
|
|
180
|
+
{
|
|
181
|
+
(void)errbuff;
|
|
182
|
+
return regcomp(&cjp->regexs[idx], pat, 0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
static inline _Bool csonpath_reg_exec(csonpath_reg_t reg, const char *str)
|
|
186
|
+
{
|
|
187
|
+
return regexec(®, str, 0, NULL, 0) == 0;
|
|
188
|
+
}
|
|
189
|
+
static inline void csonpath_reg_free(csonpath_reg_t reg) { regfree(®); }
|
|
190
|
+
# else
|
|
191
|
+
static inline int csonpath_reg_compile(struct csonpath *cjp, int regex_idx,
|
|
192
|
+
const char *pat, char **errbuff)
|
|
193
|
+
{
|
|
194
|
+
int errorcode;
|
|
195
|
+
PCRE2_SIZE erroroffset;
|
|
196
|
+
|
|
197
|
+
cjp->regexs[regex_idx] = pcre2_compile((unsigned char *)pat,
|
|
198
|
+
PCRE2_ZERO_TERMINATED, 0,
|
|
199
|
+
&errorcode, &erroroffset, NULL);
|
|
200
|
+
if (!cjp->regexs[regex_idx]) {
|
|
201
|
+
static PCRE2_UCHAR buffer[256];
|
|
202
|
+
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
|
|
203
|
+
*errbuff = (char *)buffer;
|
|
204
|
+
return -1;
|
|
205
|
+
}
|
|
206
|
+
cjp->match_datas[regex_idx] = pcre2_match_data_create_from_pattern(cjp->regexs[regex_idx],
|
|
207
|
+
NULL);
|
|
208
|
+
pcre2_jit_compile(cjp->regexs[regex_idx], PCRE2_JIT_COMPLETE);
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
# endif
|
|
212
|
+
#endif
|
|
213
|
+
|
|
178
214
|
struct csonpath_child_info {
|
|
179
215
|
int type;
|
|
180
216
|
MAY_ALIAS union {
|
|
@@ -320,8 +356,13 @@ static void csonpath_print_instruction(const struct csonpath cjp[const static 1]
|
|
|
320
356
|
printf("0: BROKEN\n");
|
|
321
357
|
return;
|
|
322
358
|
}
|
|
359
|
+
int cnt = 0;
|
|
323
360
|
for (;*walker != CSONPATH_INST_END; walker = csonpath_walker_next_inst(walker)) {
|
|
324
361
|
printf("%d: %s\n", (int)(intptr_t)(walker - origin), csonpath_instuction_str[(int)*walker]);
|
|
362
|
+
if (cnt++ == 1000) {
|
|
363
|
+
printf("%d: TOO MUCH INSTRUCTION, BAIL OUT\n", (int)(intptr_t)(walker - origin));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
325
366
|
}
|
|
326
367
|
printf("%d: END\n", (int)(intptr_t)(walker - origin));
|
|
327
368
|
}
|
|
@@ -385,6 +426,17 @@ static int csonpath_compile_(struct csonpath *cjp, const char path[static 1], in
|
|
|
385
426
|
return ret;
|
|
386
427
|
}
|
|
387
428
|
|
|
429
|
+
static void push_filter_getter(struct csonpath *cjp, int *inst_idx, int nb_getter_inst,
|
|
430
|
+
char filter_getter[static nb_getter_inst])
|
|
431
|
+
{
|
|
432
|
+
char *filter_end = &cjp->data[(*inst_idx)++];
|
|
433
|
+
for (int i = 0; i < nb_getter_inst; ++i) {
|
|
434
|
+
csonpath_push_char(cjp, filter_getter[i], inst_idx);
|
|
435
|
+
}
|
|
436
|
+
*filter_end = (nb_getter_inst - 1);
|
|
437
|
+
|
|
438
|
+
}
|
|
439
|
+
|
|
388
440
|
static int csonpath_compile_do(struct csonpath *cjp, const char orig[static 1],
|
|
389
441
|
const char walker[static 1], char tmp[static 1],
|
|
390
442
|
int *inst_idx, int flag, int end_path,
|
|
@@ -459,6 +511,14 @@ root_again:
|
|
|
459
511
|
} else if (*walker == '[') {
|
|
460
512
|
++walker;
|
|
461
513
|
getter_end = *walker;
|
|
514
|
+
} else if (*walker == '@') {
|
|
515
|
+
++walker;
|
|
516
|
+
if (*walker == '[') {
|
|
517
|
+
++walker;
|
|
518
|
+
getter_end = *walker;
|
|
519
|
+
} else {
|
|
520
|
+
CSONPATH_SKIP('.', walker);
|
|
521
|
+
}
|
|
462
522
|
}
|
|
463
523
|
filter_again:
|
|
464
524
|
if (getter_end) {
|
|
@@ -519,17 +579,14 @@ root_again:
|
|
|
519
579
|
++next;
|
|
520
580
|
}
|
|
521
581
|
|
|
522
|
-
if (!*next) {
|
|
523
|
-
CSONPATH_COMPILE_ERR(tmp, next - orig,
|
|
524
|
-
"filter miss condition");
|
|
525
|
-
|
|
526
|
-
goto error;
|
|
527
|
-
}
|
|
528
582
|
/* = and == are the same here */
|
|
529
583
|
if (to_check == '=') {
|
|
530
584
|
if (next[0] == '=') {
|
|
531
|
-
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_EQ, inst_idx);
|
|
532
585
|
++next;
|
|
586
|
+
/* some implementation support === */
|
|
587
|
+
if (next[0] == '=')
|
|
588
|
+
++next;
|
|
589
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_EQ, inst_idx);
|
|
533
590
|
}
|
|
534
591
|
#ifndef CSONPATH_NO_REGEX
|
|
535
592
|
else if (next[0] == '~') {
|
|
@@ -545,33 +602,48 @@ root_again:
|
|
|
545
602
|
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ, inst_idx);
|
|
546
603
|
++next;
|
|
547
604
|
} else if (to_check == '>') {
|
|
548
|
-
|
|
605
|
+
if (next[0] == '=') {
|
|
606
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ, inst_idx);
|
|
607
|
+
++next;
|
|
608
|
+
} else {
|
|
609
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR, inst_idx);
|
|
610
|
+
}
|
|
549
611
|
} else if (to_check == '<') {
|
|
550
|
-
|
|
612
|
+
if (next[0] == '=') {
|
|
613
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR_EQ, inst_idx);
|
|
614
|
+
++next;
|
|
615
|
+
} else {
|
|
616
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR, inst_idx);
|
|
617
|
+
}
|
|
618
|
+
} else if (to_check == ']') {
|
|
619
|
+
if (have_parentesis > 0)
|
|
620
|
+
CSONPATH_COMPILE_ERR(tmp, next - orig, "too many open parentesis");
|
|
621
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_EXIST, inst_idx);
|
|
622
|
+
for (;isblank(*next); ++next);
|
|
623
|
+
push_filter_getter(cjp, inst_idx, nb_getter_inst, filter_getter);
|
|
624
|
+
walker = next;
|
|
625
|
+
to_check = *walker;
|
|
626
|
+
goto again;
|
|
551
627
|
} else {
|
|
552
628
|
CSONPATH_COMPILE_ERR(tmp, next - orig,
|
|
553
629
|
"'%c': unsuported operation", to_check);
|
|
554
630
|
goto error;
|
|
555
631
|
}
|
|
632
|
+
if (!*next) {
|
|
633
|
+
CSONPATH_COMPILE_ERR(tmp, next - orig,
|
|
634
|
+
"filter miss operand");
|
|
635
|
+
|
|
636
|
+
goto error;
|
|
637
|
+
}
|
|
556
638
|
operand_instruction = cjp->data[(*inst_idx) - 1];
|
|
557
639
|
for (;isblank(*next); ++next);
|
|
558
|
-
|
|
559
|
-
for (int i = 0; i < nb_getter_inst; ++i) {
|
|
560
|
-
csonpath_push_char(cjp, filter_getter[i], inst_idx);
|
|
561
|
-
}
|
|
562
|
-
*filter_end = (nb_getter_inst - 1);
|
|
640
|
+
push_filter_getter(cjp, inst_idx, nb_getter_inst, filter_getter);
|
|
563
641
|
walker = next;
|
|
564
642
|
if (*walker == '"' || *walker == '\'' || *walker == '/') {
|
|
565
|
-
if (operand_instruction == CSONPATH_INST_FILTER_KEY_SUPERIOR ||
|
|
566
|
-
operand_instruction == CSONPATH_INST_FILTER_KEY_INFERIOR) {
|
|
567
|
-
CSONPATH_COMPILE_ERR(tmp, walker - orig, "string unsuported here");
|
|
568
|
-
goto error;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
643
|
char end = *walker;
|
|
572
644
|
++walker;
|
|
573
645
|
if (regex_idx < 0) {
|
|
574
|
-
csonpath_push_char(cjp,
|
|
646
|
+
csonpath_push_char(cjp, CSONPATH_INST_GET_OBJ, inst_idx);
|
|
575
647
|
for (next = walker; *next && *next != end; ++next)
|
|
576
648
|
csonpath_push_char(cjp, *next, inst_idx);
|
|
577
649
|
csonpath_push_char(cjp, 0, inst_idx);
|
|
@@ -594,32 +666,17 @@ root_again:
|
|
|
594
666
|
for (next = walker; *next && *next != end; ++next);
|
|
595
667
|
char *reg_tmp = malloc(next - walker + 1);
|
|
596
668
|
char *crawler = reg_tmp;
|
|
669
|
+
char *errbuff = NULL;
|
|
597
670
|
for (next = walker; *next && *next != end; ++next, ++crawler)
|
|
598
671
|
*crawler = *next;
|
|
599
672
|
*crawler = 0;
|
|
600
|
-
|
|
601
|
-
int
|
|
602
|
-
PCRE2_SIZE erroroffset;
|
|
603
|
-
|
|
604
|
-
cjp->regexs[regex_idx] = pcre2_compile((unsigned char *)reg_tmp,
|
|
605
|
-
PCRE2_ZERO_TERMINATED, 0,
|
|
606
|
-
&errorcode, &erroroffset, NULL);
|
|
607
|
-
if (!cjp->regexs[regex_idx]) {
|
|
608
|
-
PCRE2_UCHAR buffer[256];
|
|
609
|
-
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
|
|
610
|
-
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error: \"%s\"\n", buffer);
|
|
611
|
-
goto error;
|
|
612
|
-
}
|
|
613
|
-
cjp->match_datas[regex_idx] = pcre2_match_data_create_from_pattern(cjp->regexs[regex_idx],
|
|
614
|
-
NULL);
|
|
615
|
-
pcre2_jit_compile(cjp->regexs[regex_idx], PCRE2_JIT_COMPLETE);
|
|
616
|
-
# else
|
|
617
|
-
int e = csonpath_reg_compile(&cjp->regexs[regex_idx], reg_tmp);
|
|
673
|
+
|
|
674
|
+
int e = csonpath_reg_compile(cjp, regex_idx, reg_tmp, &errbuff);
|
|
618
675
|
if (e) {
|
|
619
|
-
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error\n"
|
|
676
|
+
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error: %s\n",
|
|
677
|
+
errbuff ? errbuff : "(unknow)");
|
|
620
678
|
goto error;
|
|
621
679
|
}
|
|
622
|
-
# endif
|
|
623
680
|
free(reg_tmp);
|
|
624
681
|
}
|
|
625
682
|
#endif
|
|
@@ -627,6 +684,11 @@ root_again:
|
|
|
627
684
|
to_check = *next;
|
|
628
685
|
} else if (*walker == '$') { /* handle subpath here */
|
|
629
686
|
const char *end_sentinel;
|
|
687
|
+
|
|
688
|
+
if (operand_instruction == CSONPATH_INST_FILTER_KEY_REG_EQ) {
|
|
689
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "subpath unsuported for regex");
|
|
690
|
+
goto error;
|
|
691
|
+
}
|
|
630
692
|
csonpath_push_char(cjp, CSONPATH_INST_GET_SUBPATH, inst_idx);
|
|
631
693
|
int ret = csonpath_compile_do(cjp, orig, walker, tmp,
|
|
632
694
|
inst_idx, flag, ']', &end_sentinel);
|
|
@@ -635,6 +697,18 @@ root_again:
|
|
|
635
697
|
walker = end_sentinel;
|
|
636
698
|
next = walker;
|
|
637
699
|
to_check = *next;
|
|
700
|
+
} else if (!strncmp(walker, "null", 4) && !isalnum(walker[4])) {
|
|
701
|
+
next = walker + 4;
|
|
702
|
+
to_check = *next;
|
|
703
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_EXIST, inst_idx);
|
|
704
|
+
} else if (!strncmp(walker, "true", 4) && !isalnum(walker[4])) {
|
|
705
|
+
next = walker + 4;
|
|
706
|
+
to_check = *next;
|
|
707
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_TRUE, inst_idx);
|
|
708
|
+
} else if (!strncmp(walker, "false", 5) && !isalnum(walker[5])) {
|
|
709
|
+
next = walker + 5;
|
|
710
|
+
to_check = *next;
|
|
711
|
+
csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_FALSE, inst_idx);
|
|
638
712
|
} else {
|
|
639
713
|
int n;
|
|
640
714
|
|
|
@@ -827,7 +901,23 @@ static int csonpath_compile(struct csonpath *cjp, const char path[static 1])
|
|
|
827
901
|
static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, const char **owalker)
|
|
828
902
|
{
|
|
829
903
|
switch (operand_instruction) {
|
|
830
|
-
case
|
|
904
|
+
case CSONPATH_INST_FILTER_KEY_TRUE:
|
|
905
|
+
{
|
|
906
|
+
if (!CSONPATH_IS_BOOL(el2))
|
|
907
|
+
return 0;
|
|
908
|
+
return CSONPATH_GET_BOOL(el2) == 1;
|
|
909
|
+
}
|
|
910
|
+
case CSONPATH_INST_FILTER_KEY_FALSE:
|
|
911
|
+
{
|
|
912
|
+
if (!CSONPATH_IS_BOOL(el2))
|
|
913
|
+
return 0;
|
|
914
|
+
return CSONPATH_GET_BOOL(el2) == 0;
|
|
915
|
+
}
|
|
916
|
+
case CSONPATH_INST_FILTER_KEY_EXIST:
|
|
917
|
+
{
|
|
918
|
+
return CSONPATH_IS_NULL(el2);
|
|
919
|
+
}
|
|
920
|
+
case CSONPATH_INST_GET_OBJ:
|
|
831
921
|
{
|
|
832
922
|
_Bool ret = CSONPATH_EQUAL_STR(el2, *owalker);
|
|
833
923
|
*owalker += strlen(*owalker) + 1;
|
|
@@ -863,9 +953,8 @@ static CSONPATH_JSON cosnpath_crawl_filter_el(const struct csonpath cjp[const st
|
|
|
863
953
|
switch (**owalker) {
|
|
864
954
|
case CSONPATH_INST_GET_OBJ:
|
|
865
955
|
++*owalker;
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
return NULL;
|
|
956
|
+
if (el2)
|
|
957
|
+
el2 = CSONPATH_GET(el2, *owalker);
|
|
869
958
|
break;
|
|
870
959
|
default:
|
|
871
960
|
CSONPATH_FORMAT_EXCEPTION("unsuported %s inst",
|
|
@@ -1240,6 +1329,11 @@ static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
|
|
|
1240
1329
|
const char **owalker, int operation)
|
|
1241
1330
|
{
|
|
1242
1331
|
int operand_instruction = **owalker;
|
|
1332
|
+
|
|
1333
|
+
if (operation == CSONPATH_INST_FILTER_KEY_EXIST) {
|
|
1334
|
+
return el2 != CSONPATH_NULL;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1243
1337
|
if (operand_instruction == CSONPATH_INST_GET_SUBPATH) {
|
|
1244
1338
|
const char *end_sentinel;
|
|
1245
1339
|
*owalker = csonpath_walker_next_inst(*owalker);
|
|
@@ -1261,13 +1355,27 @@ static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
|
|
|
1261
1355
|
if (CSONPATH_IS_STR(el2) && CSONPATH_IS_STR(jret))
|
|
1262
1356
|
return (!strcmp(CSONPATH_GET_STR(el2), CSONPATH_GET_STR(jret)));
|
|
1263
1357
|
return 0;
|
|
1358
|
+
case CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ:
|
|
1264
1359
|
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
1265
1360
|
if (CSONPATH_IS_NUM(el2) && CSONPATH_IS_NUM(jret))
|
|
1361
|
+
if (operation == CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ)
|
|
1362
|
+
return CSONPATH_GET_NUM(el2) >= CSONPATH_GET_NUM(jret);
|
|
1266
1363
|
return CSONPATH_GET_NUM(el2) > CSONPATH_GET_NUM(jret);
|
|
1364
|
+
if (CSONPATH_IS_STR(el2) && CSONPATH_IS_STR(jret))
|
|
1365
|
+
if (operation == CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ)
|
|
1366
|
+
return strcmp(CSONPATH_GET_STR(el2), CSONPATH_GET_STR(jret)) >= 0;
|
|
1367
|
+
return strcmp(CSONPATH_GET_STR(el2), CSONPATH_GET_STR(jret)) > 0;
|
|
1267
1368
|
return 0;
|
|
1268
1369
|
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
1370
|
+
case CSONPATH_INST_FILTER_KEY_INFERIOR_EQ:
|
|
1269
1371
|
if (CSONPATH_IS_NUM(el2) && CSONPATH_IS_NUM(jret))
|
|
1372
|
+
if (operation == CSONPATH_INST_FILTER_KEY_INFERIOR_EQ)
|
|
1373
|
+
return CSONPATH_GET_NUM(el2) <= CSONPATH_GET_NUM(jret);
|
|
1270
1374
|
return CSONPATH_GET_NUM(el2) < CSONPATH_GET_NUM(jret);
|
|
1375
|
+
if (CSONPATH_IS_STR(el2) && CSONPATH_IS_STR(jret))
|
|
1376
|
+
if (operation == CSONPATH_INST_FILTER_KEY_INFERIOR_EQ)
|
|
1377
|
+
return strcmp(CSONPATH_GET_STR(el2), CSONPATH_GET_STR(jret)) <= 0;
|
|
1378
|
+
return strcmp(CSONPATH_GET_STR(el2), CSONPATH_GET_STR(jret)) < 0;
|
|
1271
1379
|
return 0;
|
|
1272
1380
|
default:
|
|
1273
1381
|
return 0;
|
|
@@ -1275,8 +1383,6 @@ static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
|
|
|
1275
1383
|
}
|
|
1276
1384
|
++*owalker;
|
|
1277
1385
|
|
|
1278
|
-
if (el2 == CSONPATH_NULL)
|
|
1279
|
-
return 0;
|
|
1280
1386
|
_Bool match = 0;
|
|
1281
1387
|
switch (operation) {
|
|
1282
1388
|
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
@@ -1286,22 +1392,58 @@ static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
|
|
|
1286
1392
|
match = csonpath_do_match(operand_instruction, el2, owalker);
|
|
1287
1393
|
break;
|
|
1288
1394
|
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1395
|
+
case CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ:
|
|
1396
|
+
if (el2 == CSONPATH_NULL)
|
|
1397
|
+
return 0;
|
|
1398
|
+
if (operand_instruction == CSONPATH_INST_GET_OBJ) {
|
|
1399
|
+
if (!CSONPATH_IS_STR(el2))
|
|
1400
|
+
break;
|
|
1401
|
+
if (operation == CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ)
|
|
1402
|
+
match = strcmp(CSONPATH_GET_STR(el2), *owalker) >= 0;
|
|
1403
|
+
else
|
|
1404
|
+
match = strcmp(CSONPATH_GET_STR(el2), *owalker) > 0;
|
|
1405
|
+
*owalker += strlen(*owalker) + 1;
|
|
1406
|
+
} else {
|
|
1407
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
1408
|
+
break;
|
|
1409
|
+
if (operation == CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ)
|
|
1410
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) <=
|
|
1411
|
+
CSONPATH_GET_NUM(el2);
|
|
1412
|
+
else
|
|
1413
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) <
|
|
1414
|
+
CSONPATH_GET_NUM(el2);
|
|
1415
|
+
}
|
|
1293
1416
|
break;
|
|
1417
|
+
case CSONPATH_INST_FILTER_KEY_INFERIOR_EQ:
|
|
1294
1418
|
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
1295
|
-
if (
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1419
|
+
if (el2 == CSONPATH_NULL)
|
|
1420
|
+
return 0;
|
|
1421
|
+
if (operand_instruction == CSONPATH_INST_GET_OBJ) {
|
|
1422
|
+
if (!CSONPATH_IS_STR(el2))
|
|
1423
|
+
break;
|
|
1424
|
+
if (operation == CSONPATH_INST_FILTER_KEY_INFERIOR_EQ)
|
|
1425
|
+
match = strcmp(CSONPATH_GET_STR(el2), *owalker) <= 0;
|
|
1426
|
+
else
|
|
1427
|
+
match = strcmp(CSONPATH_GET_STR(el2), *owalker) < 0;
|
|
1428
|
+
*owalker += strlen(*owalker) + 1;
|
|
1429
|
+
} else {
|
|
1430
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
1431
|
+
break;
|
|
1432
|
+
if (operation == CSONPATH_INST_FILTER_KEY_INFERIOR_EQ)
|
|
1433
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) >=
|
|
1434
|
+
CSONPATH_GET_NUM(el2);
|
|
1435
|
+
else
|
|
1436
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) >
|
|
1437
|
+
CSONPATH_GET_NUM(el2);
|
|
1438
|
+
}
|
|
1299
1439
|
break;
|
|
1300
1440
|
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
1301
1441
|
#if defined CSONPATH_NO_REGEX
|
|
1302
1442
|
fprintf(stderr, "regex deactivate");
|
|
1303
1443
|
return 0;
|
|
1304
1444
|
#else
|
|
1445
|
+
if (el2 == CSONPATH_NULL)
|
|
1446
|
+
return 0;
|
|
1305
1447
|
|
|
1306
1448
|
if (CSONPATH_IS_STR(el2)) {
|
|
1307
1449
|
int regex_idx = **owalker;
|
|
@@ -161,7 +161,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(const struct csonpath cjp[const s
|
|
|
161
161
|
CSONPATH_DO_FIND_ALL;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
} else {
|
|
164
|
+
} else if (CSONPATH_IS_ARRAY(tmp)) {
|
|
165
165
|
CSONPATH_FOREACH_ARRAY(tmp, el, key_idx) {
|
|
166
166
|
CSONPATH_DO_FOREACH_PRE_SET;
|
|
167
167
|
if (CSONPATH_IS_OBJ(el) || CSONPATH_IS_ARRAY(el)) {
|
|
@@ -197,11 +197,14 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
197
197
|
ctx = CSONPATH_NULL;
|
|
198
198
|
}
|
|
199
199
|
break;
|
|
200
|
+
case CSONPATH_INST_FILTER_KEY_EXIST:
|
|
200
201
|
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
201
202
|
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
202
203
|
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
203
204
|
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
204
205
|
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
206
|
+
case CSONPATH_INST_FILTER_KEY_SUPERIOR_EQ:
|
|
207
|
+
case CSONPATH_INST_FILTER_KEY_INFERIOR_EQ:
|
|
205
208
|
{
|
|
206
209
|
CSONPATH_JSON el;
|
|
207
210
|
int operation_in = *walker, operation = *walker;
|
|
@@ -212,9 +215,15 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
212
215
|
|
|
213
216
|
(void) foreach_idx;
|
|
214
217
|
CSONPATH_DO_FILTER_PRE_LOOP;
|
|
218
|
+
if (!CSONPATH_IS_ARRAY(tmp)) {
|
|
219
|
+
CSONPATH_DO_FILTER_OUT;
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
215
222
|
CSONPATH_FOREACH_ARRAY(tmp, el, foreach_idx)
|
|
216
223
|
{
|
|
217
224
|
intptr_t key_idx = foreach_idx;
|
|
225
|
+
filter_next = filter_next_in;
|
|
226
|
+
operation = operation_in;
|
|
218
227
|
(void)key_idx;
|
|
219
228
|
owalker = next;
|
|
220
229
|
match_and_or_or:
|
|
@@ -226,7 +235,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
226
235
|
|
|
227
236
|
if (csonpath_make_match(cjp, origin, el2, &owalker, operation)) {
|
|
228
237
|
if (*owalker == CSONPATH_INST_FILTER_AND) {
|
|
229
|
-
++owalker; /* skip
|
|
238
|
+
++owalker; /* skip and */
|
|
230
239
|
operation = *owalker;
|
|
231
240
|
++owalker;
|
|
232
241
|
filter_next = *owalker;
|
|
@@ -237,9 +246,6 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
237
246
|
csonpath_do_internal(cjp, origin, el, tmp, owalker
|
|
238
247
|
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
239
248
|
CSONPATH_DO_FILTER_FIND;
|
|
240
|
-
} else {
|
|
241
|
-
operation = operation_in;
|
|
242
|
-
filter_next = filter_next_in;
|
|
243
249
|
}
|
|
244
250
|
}
|
|
245
251
|
}
|
|
@@ -385,7 +391,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const
|
|
|
385
391
|
this_idx = to_num.n;
|
|
386
392
|
CSONPATH_PRE_GET(this_idx);
|
|
387
393
|
tmp = CSONPATH_AT(tmp, to_num.n);
|
|
388
|
-
walker +=
|
|
394
|
+
walker += 4;
|
|
389
395
|
if (tmp == CSONPATH_NULL) {
|
|
390
396
|
CSONPATH_DO_GET_NOTFOUND(this_idx);
|
|
391
397
|
}
|
|
@@ -31,6 +31,8 @@ typedef void (*json_c_callback)(json_object *, struct csonpath_child_info *, jso
|
|
|
31
31
|
|
|
32
32
|
#define CSONPATH_REMOVE(o) json_object_put(o)
|
|
33
33
|
|
|
34
|
+
#define CSONPATH_IS_NULL(o) (o == NULL || json_object_is_type(o, json_type_null))
|
|
35
|
+
|
|
34
36
|
#define CSONPATH_IS_OBJ(o) json_object_is_type(o, json_type_object)
|
|
35
37
|
|
|
36
38
|
#define CSONPATH_IS_ARRAY(o) json_object_is_type(o, json_type_array)
|
|
@@ -39,6 +41,10 @@ typedef void (*json_c_callback)(json_object *, struct csonpath_child_info *, jso
|
|
|
39
41
|
|
|
40
42
|
#define CSONPATH_IS_NUM(o) json_object_is_type(o, json_type_int)
|
|
41
43
|
|
|
44
|
+
#define CSONPATH_IS_BOOL(o) json_object_is_type(o, json_type_boolean)
|
|
45
|
+
|
|
46
|
+
#define CSONPATH_GET_BOOL(o) json_object_get_boolean(o)
|
|
47
|
+
|
|
42
48
|
#define CSONPATH_GET_STR(obj) \
|
|
43
49
|
json_object_get_string(obj)
|
|
44
50
|
|
|
@@ -23,6 +23,13 @@
|
|
|
23
23
|
|
|
24
24
|
#define CSONPATH_IS_NUM(o) PyLong_Check(o)
|
|
25
25
|
|
|
26
|
+
#define CSONPATH_IS_NULL(o) (o == Py_None)
|
|
27
|
+
|
|
28
|
+
#define CSONPATH_IS_BOOL(o) PyBool_Check(o)
|
|
29
|
+
|
|
30
|
+
/* that one assume CSONPATH_IS_BOOL have been called before calling CSONPATH_GET_BOOL */
|
|
31
|
+
#define CSONPATH_GET_BOOL(o) (o == Py_True)
|
|
32
|
+
|
|
26
33
|
#define CSONPATH_GET_STR(obj) \
|
|
27
34
|
PyUnicode_AsUTF8(obj)
|
|
28
35
|
|
|
@@ -264,6 +271,8 @@ static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
|
|
|
264
271
|
BAD_ARG();
|
|
265
272
|
|
|
266
273
|
PyObject *ret = csonpath_find_all(self->cp, json);
|
|
274
|
+
if (PyErr_Occurred())
|
|
275
|
+
return NULL;
|
|
267
276
|
|
|
268
277
|
return ret;
|
|
269
278
|
}
|
|
@@ -276,6 +285,8 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
276
285
|
BAD_ARG();
|
|
277
286
|
|
|
278
287
|
PyObject *ret = csonpath_find_first(self->cp, json);
|
|
288
|
+
if (PyErr_Occurred())
|
|
289
|
+
return NULL;
|
|
279
290
|
|
|
280
291
|
Py_INCREF(ret);
|
|
281
292
|
return ret;
|
|
@@ -284,7 +295,7 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
284
295
|
static PyObject *print_instructions(PyCsonPathObject *self, PyObject *args, PyObject *kwds)
|
|
285
296
|
{
|
|
286
297
|
csonpath_print_instruction(self->cp);
|
|
287
|
-
|
|
298
|
+
Py_RETURN_NONE;
|
|
288
299
|
}
|
|
289
300
|
|
|
290
301
|
static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
@@ -294,6 +305,8 @@ static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
|
294
305
|
if (!PyArg_ParseTuple(args, "OO|O", &json, &callback, &udata))
|
|
295
306
|
BAD_ARG();
|
|
296
307
|
int ret = csonpath_callback(self->cp, json, callback, udata);
|
|
308
|
+
if (PyErr_Occurred())
|
|
309
|
+
return NULL;
|
|
297
310
|
return PyLong_FromLong(ret);
|
|
298
311
|
}
|
|
299
312
|
|
|
@@ -304,6 +317,8 @@ static PyObject *do_remove(PyCsonPathObject *self, PyObject* args)
|
|
|
304
317
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
305
318
|
BAD_ARG();
|
|
306
319
|
int ret = csonpath_remove(self->cp, json);
|
|
320
|
+
if (PyErr_Occurred())
|
|
321
|
+
return NULL;
|
|
307
322
|
return PyLong_FromLong(ret);
|
|
308
323
|
}
|
|
309
324
|
|
|
@@ -315,7 +330,7 @@ static PyObject *update_or_create(PyCsonPathObject *self, PyObject* args)
|
|
|
315
330
|
if (!PyArg_ParseTuple(args, "OO", &json, &value))
|
|
316
331
|
BAD_ARG();
|
|
317
332
|
int ret = csonpath_update_or_create(self->cp, json, value);
|
|
318
|
-
if (ret < 0) {
|
|
333
|
+
if (PyErr_Occurred() || ret < 0) {
|
|
319
334
|
return NULL;
|
|
320
335
|
}
|
|
321
336
|
return PyLong_FromLong(ret);
|
|
@@ -328,6 +343,9 @@ static PyObject *update_or_create_callback(PyCsonPathObject *self, PyObject* arg
|
|
|
328
343
|
if (!PyArg_ParseTuple(args, "OO|O", &json, &callback, &udata))
|
|
329
344
|
BAD_ARG();
|
|
330
345
|
int ret = csonpath_update_or_create_callback(self->cp, json, callback, udata);
|
|
346
|
+
if (PyErr_Occurred() || ret < 0) {
|
|
347
|
+
return NULL;
|
|
348
|
+
}
|
|
331
349
|
return PyLong_FromLong(ret);
|
|
332
350
|
}
|
|
333
351
|
|
|
@@ -28,6 +28,12 @@
|
|
|
28
28
|
#define CSONPATH_IS_STR(obj) (yyjson_get_type(obj) == YYJSON_TYPE_STR)
|
|
29
29
|
#define CSONPATH_IS_NUM(o) (yyjson_get_type(o) == YYJSON_TYPE_NUM)
|
|
30
30
|
|
|
31
|
+
#define CSONPATH_IS_NULL(o) (o == NULL || yyjson_get_type(o) == YYJSON_TYPE_NULL)
|
|
32
|
+
|
|
33
|
+
#define CSONPATH_IS_BOOL(o) (yyjson_get_type(o) == YYJSON_TYPE_BOOL)
|
|
34
|
+
|
|
35
|
+
#define CSONPATH_GET_BOOL(o) yyjson_get_bool(o)
|
|
36
|
+
|
|
31
37
|
struct csonpath_child_info;
|
|
32
38
|
typedef void (*yyjson_val_callback)(yyjson_val *, struct csonpath_child_info *, yyjson_val *, void *);
|
|
33
39
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.14.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.14.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
|
|
File without changes
|
|
File without changes
|