csonpath 0.9.0__tar.gz → 0.11.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.9.0/csonpath.egg-info → csonpath-0.11.0}/PKG-INFO +2 -1
- {csonpath-0.9.0 → csonpath-0.11.0}/README.md +1 -0
- {csonpath-0.9.0 → csonpath-0.11.0/csonpath.egg-info}/PKG-INFO +2 -1
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath.egg-info/SOURCES.txt +1 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath.h +182 -87
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath_do.h +85 -12
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath_python.c +73 -29
- {csonpath-0.9.0 → csonpath-0.11.0}/pyproject.toml +3 -5
- csonpath-0.11.0/setup.py +33 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/LICENSE +0 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/MANIFEST.in +0 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.9.0 → csonpath-0.11.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.9.0 → csonpath-0.11.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.11.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -144,6 +144,7 @@ print(o.find_first(d)) # Output: "value"
|
|
|
144
144
|
|
|
145
145
|
#### Avaible methodes:
|
|
146
146
|
- `CsonPath(path)`: create a new csonpath object.
|
|
147
|
+
- `CsonPath(path, return_empty_array)`: Create a new csonpath object and return an empty list instead of None (like jsonpath-ng).
|
|
147
148
|
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
148
149
|
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
149
150
|
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
@@ -135,6 +135,7 @@ print(o.find_first(d)) # Output: "value"
|
|
|
135
135
|
|
|
136
136
|
#### Avaible methodes:
|
|
137
137
|
- `CsonPath(path)`: create a new csonpath object.
|
|
138
|
+
- `CsonPath(path, return_empty_array)`: Create a new csonpath object and return an empty list instead of None (like jsonpath-ng).
|
|
138
139
|
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
139
140
|
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
140
141
|
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -144,6 +144,7 @@ print(o.find_first(d)) # Output: "value"
|
|
|
144
144
|
|
|
145
145
|
#### Avaible methodes:
|
|
146
146
|
- `CsonPath(path)`: create a new csonpath object.
|
|
147
|
+
- `CsonPath(path, return_empty_array)`: Create a new csonpath object and return an empty list instead of None (like jsonpath-ng).
|
|
147
148
|
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
148
149
|
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
149
150
|
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
@@ -10,7 +10,20 @@
|
|
|
10
10
|
#endif
|
|
11
11
|
|
|
12
12
|
#ifndef CSONPATH_NO_REGEX
|
|
13
|
-
#
|
|
13
|
+
# if defined CSONPATH_TINY_REGEX
|
|
14
|
+
# include <tiny-regex-c/re.h>
|
|
15
|
+
typedef char * csonpath_reg_t;
|
|
16
|
+
# elif defined CSONPATH_PCRE2
|
|
17
|
+
# define PCRE2_CODE_UNIT_WIDTH 8
|
|
18
|
+
# include <pcre2.h>
|
|
19
|
+
typedef pcre2_code * csonpath_reg_t;
|
|
20
|
+
# elif defined CSONPATH_PCRE2_POSIX
|
|
21
|
+
# include <pcre2posix.h>
|
|
22
|
+
typedef regex_t csonpath_reg_t;
|
|
23
|
+
# else
|
|
24
|
+
# include <regex.h>
|
|
25
|
+
typedef regex_t csonpath_reg_t;
|
|
26
|
+
# endif
|
|
14
27
|
#endif
|
|
15
28
|
|
|
16
29
|
#define CSONPATH_UNUSED __attribute__((unused))
|
|
@@ -57,6 +70,7 @@ enum csonpath_instuction_raw {
|
|
|
57
70
|
CSONPATH_INST_FILTER_AND,
|
|
58
71
|
CSONPATH_INST_GET_ALL,
|
|
59
72
|
CSONPATH_INST_FIND_ALL,
|
|
73
|
+
CSONPATH_INST_RANGE,
|
|
60
74
|
CSONPATH_INST_OR,
|
|
61
75
|
CSONPATH_INST_END,
|
|
62
76
|
CSONPATH_INST_BROKEN
|
|
@@ -80,6 +94,7 @@ CSONPATH_UNUSED static const char *csonpath_instuction_str[] = {
|
|
|
80
94
|
"FILTER_AND",
|
|
81
95
|
"GET_ALL",
|
|
82
96
|
"FIND_ALL",
|
|
97
|
+
"RANGE",
|
|
83
98
|
"OR",
|
|
84
99
|
"END",
|
|
85
100
|
"BROKEN"
|
|
@@ -107,8 +122,12 @@ struct csonpath {
|
|
|
107
122
|
int compiled;
|
|
108
123
|
#ifndef CSONPATH_NO_REGEX
|
|
109
124
|
int regex_cnt;
|
|
110
|
-
|
|
125
|
+
csonpath_reg_t *regexs;
|
|
126
|
+
#ifdef CSONPATH_PCRE2
|
|
127
|
+
pcre2_match_data **match_datas;
|
|
111
128
|
#endif
|
|
129
|
+
#endif
|
|
130
|
+
int return_empty_array;
|
|
112
131
|
};
|
|
113
132
|
|
|
114
133
|
struct csonpath_child_info {
|
|
@@ -170,12 +189,25 @@ static inline void csonpath_destroy(struct csonpath cjp[static 1])
|
|
|
170
189
|
free(cjp->path);
|
|
171
190
|
free(cjp->inst_lst);
|
|
172
191
|
free(cjp->compile_error);
|
|
192
|
+
#ifndef CSONPATH_NO_REGEX
|
|
173
193
|
if (cjp->regex_cnt) {
|
|
194
|
+
#ifndef CSONPATH_TINY_REGEX
|
|
174
195
|
for (int i = 0; i < cjp->regex_cnt; ++i) {
|
|
196
|
+
#ifdef CSONPATH_PCRE2
|
|
197
|
+
pcre2_code_free(cjp->regexs[i]);
|
|
198
|
+
pcre2_match_data_free(cjp->match_datas[i]);
|
|
199
|
+
#else
|
|
175
200
|
regfree(&cjp->regexs[i]);
|
|
201
|
+
#endif
|
|
202
|
+
|
|
176
203
|
}
|
|
204
|
+
#endif
|
|
205
|
+
#ifdef CSONPATH_PCRE2
|
|
206
|
+
free(cjp->match_datas);
|
|
207
|
+
#endif
|
|
177
208
|
free(cjp->regexs);
|
|
178
209
|
}
|
|
210
|
+
#endif
|
|
179
211
|
*cjp = (struct csonpath){};
|
|
180
212
|
}
|
|
181
213
|
|
|
@@ -202,6 +234,9 @@ static inline int csonpath_init(struct csonpath cjp[static 1],
|
|
|
202
234
|
if (!cjp->path || !cjp->inst_lst) {
|
|
203
235
|
return -ENOMEM;
|
|
204
236
|
}
|
|
237
|
+
|
|
238
|
+
cjp->return_empty_array = 0;
|
|
239
|
+
|
|
205
240
|
return 0;
|
|
206
241
|
}
|
|
207
242
|
|
|
@@ -226,7 +261,7 @@ static inline void csonpath_push_inst_cpy(struct csonpath cjp[static 1],
|
|
|
226
261
|
*inst_idx += 1;
|
|
227
262
|
}
|
|
228
263
|
|
|
229
|
-
static void csonpath_print_instruction(struct csonpath cjp[static 1])
|
|
264
|
+
static void csonpath_print_instruction(const struct csonpath cjp[const static 1])
|
|
230
265
|
{
|
|
231
266
|
int idx = 0;
|
|
232
267
|
for (;cjp->inst_lst[idx].inst != CSONPATH_INST_END; ++idx) {
|
|
@@ -240,6 +275,43 @@ static inline _Bool csonpath_is_dot_operand(int c)
|
|
|
240
275
|
return isalnum(c) || c == '_' || c == '-';
|
|
241
276
|
}
|
|
242
277
|
|
|
278
|
+
|
|
279
|
+
static int csonpath_fill_walker_with_int(char *walker, int num, int first_ret)
|
|
280
|
+
{
|
|
281
|
+
if (num < 100) {
|
|
282
|
+
*walker = num;
|
|
283
|
+
return first_ret;
|
|
284
|
+
}
|
|
285
|
+
union {
|
|
286
|
+
int n;
|
|
287
|
+
char c[4];
|
|
288
|
+
} u = {.n=num};
|
|
289
|
+
walker[0] = u.c[0];
|
|
290
|
+
walker[1] = u.c[1];
|
|
291
|
+
walker[2] = u.c[2];
|
|
292
|
+
walker[3] = u.c[3];
|
|
293
|
+
return first_ret + 1;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
static int csonpath_int_from_walker(int operand_instruction, char *walker)
|
|
297
|
+
{
|
|
298
|
+
switch(operand_instruction) {
|
|
299
|
+
case CSONPATH_INST_FILTER_OPERAND_BYTE:
|
|
300
|
+
case CSONPATH_INST_GET_ARRAY_SMALL:
|
|
301
|
+
return *walker;
|
|
302
|
+
case CSONPATH_INST_GET_ARRAY_BIG:
|
|
303
|
+
case CSONPATH_INST_FILTER_OPERAND_INT:
|
|
304
|
+
{
|
|
305
|
+
union {int n; char c[4];} to_num =
|
|
306
|
+
{ .c= { walker[0], walker[1], walker[2], walker[3] } };
|
|
307
|
+
return to_num.n;
|
|
308
|
+
}
|
|
309
|
+
default:
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
return -1;
|
|
313
|
+
}
|
|
314
|
+
|
|
243
315
|
static int csonpath_compile(struct csonpath cjp[static 1])
|
|
244
316
|
{
|
|
245
317
|
char *walker = cjp->path;
|
|
@@ -397,13 +469,16 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
397
469
|
/* = and == are the same here */
|
|
398
470
|
if (to_check == '=') {
|
|
399
471
|
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ, &inst_idx);
|
|
400
|
-
if (next[0] == '=')
|
|
472
|
+
if (next[0] == '=') {
|
|
401
473
|
++next;
|
|
474
|
+
}
|
|
475
|
+
#ifndef CSONPATH_NO_REGEX
|
|
402
476
|
else if (next[0] == '~') {
|
|
403
477
|
cjp->inst_lst[inst_idx - 1].inst = CSONPATH_INST_FILTER_KEY_REG_EQ;
|
|
404
478
|
regex_idx = cjp->regex_cnt++;
|
|
405
479
|
++next;
|
|
406
480
|
}
|
|
481
|
+
#endif
|
|
407
482
|
} else if (to_check == '!' && next[0] == '=') {
|
|
408
483
|
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ, &inst_idx);
|
|
409
484
|
++next;
|
|
@@ -445,14 +520,38 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
445
520
|
*next = 0;
|
|
446
521
|
#ifndef CSONPATH_NO_REGEX
|
|
447
522
|
if (regex_idx >= 0) {
|
|
448
|
-
if (!regex_idx)
|
|
523
|
+
if (!regex_idx) {
|
|
449
524
|
cjp->regexs = malloc(sizeof *cjp->regexs * 255);
|
|
450
|
-
|
|
525
|
+
#ifdef CSONPATH_PCRE2
|
|
526
|
+
cjp->match_datas = malloc(sizeof *cjp->match_datas * 255);
|
|
527
|
+
#endif
|
|
528
|
+
}
|
|
451
529
|
cjp->inst_lst[inst_idx - 1].regex_idx = regex_idx;
|
|
530
|
+
# if defined CSONPATH_TINY_REGEX
|
|
531
|
+
cjp->regexs[regex_idx] = walker;
|
|
532
|
+
# elif defined CSONPATH_PCRE2
|
|
533
|
+
int errorcode;
|
|
534
|
+
PCRE2_SIZE erroroffset;
|
|
535
|
+
|
|
536
|
+
cjp->regexs[regex_idx] = pcre2_compile((unsigned char *)walker,
|
|
537
|
+
PCRE2_ZERO_TERMINATED, 0,
|
|
538
|
+
&errorcode, &erroroffset, NULL);
|
|
539
|
+
if (!cjp->regexs[regex_idx]) {
|
|
540
|
+
PCRE2_UCHAR buffer[256];
|
|
541
|
+
pcre2_get_error_message(errorcode, buffer, sizeof(buffer));
|
|
542
|
+
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error: \"%s\"\n", buffer);
|
|
543
|
+
goto error;
|
|
544
|
+
}
|
|
545
|
+
cjp->match_datas[regex_idx] = pcre2_match_data_create_from_pattern(cjp->regexs[regex_idx],
|
|
546
|
+
NULL);
|
|
547
|
+
pcre2_jit_compile(cjp->regexs[regex_idx], PCRE2_JIT_COMPLETE);
|
|
548
|
+
# else
|
|
549
|
+
int e = regcomp(&cjp->regexs[regex_idx], walker, 0);
|
|
452
550
|
if (e) {
|
|
453
551
|
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error\n");
|
|
454
552
|
goto error;
|
|
455
553
|
}
|
|
554
|
+
# endif
|
|
456
555
|
}
|
|
457
556
|
#endif
|
|
458
557
|
++next;
|
|
@@ -479,20 +578,8 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
479
578
|
|
|
480
579
|
n = atoi(walker);
|
|
481
580
|
to_check = *next;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE, &inst_idx);
|
|
485
|
-
} else {
|
|
486
|
-
union {
|
|
487
|
-
int n;
|
|
488
|
-
char c[4];
|
|
489
|
-
} u = {.n=n};
|
|
490
|
-
walker[0] = u.c[0];
|
|
491
|
-
walker[1] = u.c[1];
|
|
492
|
-
walker[2] = u.c[2];
|
|
493
|
-
walker[3] = u.c[3];
|
|
494
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT, &inst_idx);
|
|
495
|
-
}
|
|
581
|
+
csonpath_push_inst(cjp, csonpath_fill_walker_with_int(
|
|
582
|
+
walker, n, CSONPATH_INST_FILTER_OPERAND_BYTE), &inst_idx);
|
|
496
583
|
}
|
|
497
584
|
|
|
498
585
|
/* skip space */
|
|
@@ -537,11 +624,23 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
537
624
|
|
|
538
625
|
next = walker;
|
|
539
626
|
do {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
627
|
+
if (*next == ':') {
|
|
628
|
+
csonpath_push_inst(cjp, CSONPATH_INST_RANGE, &inst_idx);
|
|
629
|
+
num = atoi(walker);
|
|
630
|
+
csonpath_push_inst(
|
|
631
|
+
cjp, csonpath_fill_walker_with_int(
|
|
632
|
+
walker, num, CSONPATH_INST_GET_ARRAY_SMALL),
|
|
633
|
+
&inst_idx);
|
|
634
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
635
|
+
walker = next + 1;
|
|
636
|
+
++next;
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
if (*next < '0' || *next > '9') {
|
|
640
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
641
|
+
"unexpected '%c', sting, filter or number require\n", *next);
|
|
642
|
+
}
|
|
643
|
+
next++;
|
|
545
644
|
} while (*next && *next != ']');
|
|
546
645
|
if (!*next) {
|
|
547
646
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
@@ -549,20 +648,9 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
549
648
|
}
|
|
550
649
|
*next = 0;
|
|
551
650
|
num = atoi(walker);
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
} else {
|
|
556
|
-
union {
|
|
557
|
-
int n;
|
|
558
|
-
char c[4];
|
|
559
|
-
} u = {.n=num};
|
|
560
|
-
walker[0] = u.c[0];
|
|
561
|
-
walker[1] = u.c[1];
|
|
562
|
-
walker[2] = u.c[2];
|
|
563
|
-
walker[3] = u.c[3];
|
|
564
|
-
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG, &inst_idx);
|
|
565
|
-
}
|
|
651
|
+
csonpath_push_inst(cjp, csonpath_fill_walker_with_int(
|
|
652
|
+
walker, num, CSONPATH_INST_GET_ARRAY_SMALL),
|
|
653
|
+
&inst_idx);
|
|
566
654
|
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
567
655
|
walker = next + 1;
|
|
568
656
|
to_check = *walker;
|
|
@@ -615,7 +703,7 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
615
703
|
csonpath_push_inst(cjp, inst, &inst_idx);
|
|
616
704
|
to_check = *walker;
|
|
617
705
|
goto again;
|
|
618
|
-
}
|
|
706
|
+
}
|
|
619
707
|
for (next = walker; csonpath_is_dot_operand(*next); ++next);
|
|
620
708
|
if (next == walker) {
|
|
621
709
|
if (*next == '[')
|
|
@@ -656,19 +744,6 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
656
744
|
return -1;
|
|
657
745
|
}
|
|
658
746
|
|
|
659
|
-
static int csonpath_int_from_walker(int operand_instruction, char *walker)
|
|
660
|
-
{
|
|
661
|
-
if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_BYTE)
|
|
662
|
-
return *walker;
|
|
663
|
-
else if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_INT) {
|
|
664
|
-
union {int n; char c[4];} to_num =
|
|
665
|
-
{ .c= { walker[0], walker[1], walker[2], walker[3] } };
|
|
666
|
-
|
|
667
|
-
return to_num.n;
|
|
668
|
-
}
|
|
669
|
-
return -1;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
747
|
static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char *owalker)
|
|
673
748
|
{
|
|
674
749
|
switch (operand_instruction) {
|
|
@@ -687,12 +762,11 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
|
|
|
687
762
|
return 0;
|
|
688
763
|
}
|
|
689
764
|
|
|
690
|
-
static CSONPATH_JSON cosnpath_crawl_filter_el(struct csonpath cjp[static 1],
|
|
765
|
+
static CSONPATH_JSON cosnpath_crawl_filter_el(const struct csonpath cjp[const static 1],
|
|
691
766
|
int *idx, char **owalker,
|
|
692
767
|
CSONPATH_JSON el2,
|
|
693
768
|
int filter_next)
|
|
694
769
|
{
|
|
695
|
-
|
|
696
770
|
for (; *idx < filter_next; ++(*idx)) {
|
|
697
771
|
switch (cjp->inst_lst[*idx].inst) {
|
|
698
772
|
case CSONPATH_INST_GET_OBJ:
|
|
@@ -709,12 +783,12 @@ static CSONPATH_JSON cosnpath_crawl_filter_el(struct csonpath cjp[static 1],
|
|
|
709
783
|
}
|
|
710
784
|
|
|
711
785
|
|
|
712
|
-
static _Bool csonpath_make_match(struct csonpath cjp[static 1],
|
|
786
|
+
static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
|
|
713
787
|
struct csonpath_instruction inst[static 1],
|
|
714
788
|
CSONPATH_JSON el2, char *owalker, int operation)
|
|
715
789
|
{
|
|
716
790
|
int operand_instruction = inst->inst;
|
|
717
|
-
|
|
791
|
+
|
|
718
792
|
if (el2 == CSONPATH_NULL)
|
|
719
793
|
return 0;
|
|
720
794
|
_Bool match = 0;
|
|
@@ -738,16 +812,38 @@ static _Bool csonpath_make_match(struct csonpath cjp[static 1],
|
|
|
738
812
|
CSONPATH_GET_NUM(el2);
|
|
739
813
|
break;
|
|
740
814
|
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
741
|
-
#
|
|
742
|
-
|
|
743
|
-
|
|
815
|
+
#if defined CSONPATH_NO_REGEX
|
|
816
|
+
fprintf(stderr, "regex deactivate");
|
|
817
|
+
return 0;
|
|
744
818
|
#else
|
|
745
819
|
if (CSONPATH_IS_STR(el2)) {
|
|
746
820
|
int regex_idx = inst->regex_idx;
|
|
821
|
+
#if defined CSONPATH_TINY_REGEX
|
|
822
|
+
int match_len = 0;
|
|
823
|
+
const char *str = CSONPATH_GET_STR(el2);
|
|
824
|
+
re_match(cjp->regexs[regex_idx], str, &match_len);
|
|
825
|
+
match = !!match_len;
|
|
826
|
+
#elif defined CSONPATH_PCRE2
|
|
827
|
+
const unsigned char *str = (const unsigned char *)CSONPATH_GET_STR(el2);
|
|
828
|
+
int ret = pcre2_match(cjp->regexs[regex_idx], str, PCRE2_ZERO_TERMINATED, 0,
|
|
829
|
+
0, cjp->match_datas[regex_idx], NULL);
|
|
830
|
+
|
|
831
|
+
if (ret >= 0) {
|
|
832
|
+
// match found
|
|
833
|
+
return 1;
|
|
834
|
+
} else if (ret == PCRE2_ERROR_NOMATCH) {
|
|
835
|
+
// no match
|
|
836
|
+
return 0;
|
|
837
|
+
} else {
|
|
838
|
+
fprintf(stderr, "pcre2 match error: %d\n", ret);
|
|
839
|
+
return 0;
|
|
840
|
+
}
|
|
841
|
+
#else
|
|
747
842
|
regex_t *compiled = &cjp->regexs[regex_idx];
|
|
748
843
|
int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
|
|
749
844
|
0, NULL, 0);
|
|
750
845
|
match = match_len == 0;
|
|
846
|
+
#endif
|
|
751
847
|
}
|
|
752
848
|
break;
|
|
753
849
|
#endif
|
|
@@ -801,7 +897,7 @@ need_reloop_in = 0;
|
|
|
801
897
|
#define CSONPATH_DO_FUNC_NAME find_first
|
|
802
898
|
#define CSONPATH_DO_RETURN return tmp
|
|
803
899
|
|
|
804
|
-
#define CSONPATH_DO_FIND_ALL return tret
|
|
900
|
+
#define CSONPATH_DO_FIND_ALL if (tret) return tret
|
|
805
901
|
|
|
806
902
|
#define CSONPATH_DO_FILTER_FIND return tret
|
|
807
903
|
|
|
@@ -830,7 +926,7 @@ need_reloop_in = 0;
|
|
|
830
926
|
#define CSONPATH_DO_FILTER_FIND CSONPATH_DO_FIND_ALL
|
|
831
927
|
|
|
832
928
|
#define CSONPATH_DO_FIND_ALL_OUT \
|
|
833
|
-
|
|
929
|
+
if (!cjp->return_empty_array && !nb_res) { \
|
|
834
930
|
return CSONPATH_NONE_FOUND_RET; \
|
|
835
931
|
} \
|
|
836
932
|
return ret_ar;
|
|
@@ -838,7 +934,6 @@ need_reloop_in = 0;
|
|
|
838
934
|
#define CSONPATH_DO_EXTRA_ARGS_IN , ret_ar
|
|
839
935
|
#define CSONPATH_DO_EXTRA_DECLATION , CSONPATH_FIND_ALL_RET ret_ar
|
|
840
936
|
|
|
841
|
-
|
|
842
937
|
#include "csonpath_do.h"
|
|
843
938
|
|
|
844
939
|
/* Delete */
|
|
@@ -881,15 +976,26 @@ need_reloop_in = 0;
|
|
|
881
976
|
#define CSONPATH_DO_FILTER_FIND nb_res += tret;
|
|
882
977
|
|
|
883
978
|
#define CSONPATH_DO_FIND_ALL ({ \
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
979
|
+
if (tret < 0) return -1; \
|
|
980
|
+
nb_res += tret; \
|
|
981
|
+
if (need_reloop_in){ goto again; }; \
|
|
982
|
+
})
|
|
983
|
+
|
|
984
|
+
#define CSONPATH_DO_RANGE ({ \
|
|
985
|
+
if (tret < 0) return -1; \
|
|
986
|
+
nb_res += tret; \
|
|
987
|
+
--end; \
|
|
988
|
+
if (need_reloop_in){ goto range_again; }; \
|
|
989
|
+
})
|
|
888
990
|
|
|
889
991
|
#define CSONPATH_DO_EXTRA_DECLATION , struct csonpath_child_info child_info, int *need_reloop
|
|
890
992
|
|
|
891
993
|
#define CSONPATH_DO_EXTRA_ARGS_IN , (struct csonpath_child_info) {.type = CSONPATH_NONE}, NULL
|
|
892
994
|
|
|
995
|
+
#define CSONPATH_DO_RANGE_PRE_LOOP \
|
|
996
|
+
int need_reloop_in; \
|
|
997
|
+
range_again:
|
|
998
|
+
|
|
893
999
|
#define CSONPATH_DO_FILTER_PRE_LOOP \
|
|
894
1000
|
int need_reloop_in;
|
|
895
1001
|
|
|
@@ -979,12 +1085,13 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
979
1085
|
#define CSONPATH_PRE_GET_ROOT \
|
|
980
1086
|
int to_check = cjp->inst_lst[idx + 1].inst; \
|
|
981
1087
|
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
982
|
-
if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) \
|
|
1088
|
+
if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) { \
|
|
983
1089
|
return csonpath_sync_root_obj(origin, to_update); \
|
|
984
|
-
else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) \
|
|
1090
|
+
} else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) { \
|
|
985
1091
|
return csonpath_sync_root_array(origin, to_update); \
|
|
986
|
-
else
|
|
1092
|
+
} else { \
|
|
987
1093
|
CSONPATH_EXCEPTION("can't upate root ($)\n"); \
|
|
1094
|
+
} \
|
|
988
1095
|
}
|
|
989
1096
|
|
|
990
1097
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
@@ -1046,17 +1153,16 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1046
1153
|
#define CSONPATH_DO_RETURN \
|
|
1047
1154
|
if (tmp == value) { \
|
|
1048
1155
|
*need_reloop = 1; \
|
|
1049
|
-
CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata); \
|
|
1050
|
-
return 1; \
|
|
1051
1156
|
} \
|
|
1052
|
-
|
|
1157
|
+
CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata); \
|
|
1158
|
+
return 1;
|
|
1053
1159
|
|
|
1054
1160
|
#define CSONPATH_DO_EXTRA_ARGS_FIND_ALL , callback, udata, NULL, need_reloop
|
|
1055
1161
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , callback, udata, \
|
|
1056
1162
|
csonpath_child_info_set(&(struct csonpath_child_info ){}, tmp, (intptr_t)key_idx), \
|
|
1057
1163
|
&need_reloop_in
|
|
1058
1164
|
#define CSONPATH_DO_EXTRA_ARGS , CSONPATH_CALLBACK callback, CSONPATH_CALLBACK_DATA udata
|
|
1059
|
-
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata,
|
|
1165
|
+
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata, &(struct csonpath_child_info ){}, NULL
|
|
1060
1166
|
#define CSONPATH_DO_EXTRA_DECLATION CSONPATH_DO_EXTRA_ARGS, struct csonpath_child_info *child_info, int *need_reloop
|
|
1061
1167
|
#define CSONPATH_DO_FIND_ALL nb_res += tret;
|
|
1062
1168
|
#define CSONPATH_DO_FILTER_FIND CSONPATH_GOTO_ON_RELOOP(filter_again)
|
|
@@ -1075,19 +1181,8 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
|
1075
1181
|
}
|
|
1076
1182
|
|
|
1077
1183
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
do { \
|
|
1081
|
-
to_check = cjp->inst_lst[check_at].inst; \
|
|
1082
|
-
++check_at; \
|
|
1083
|
-
} while (to_check == CSONPATH_INST_GET_ALL || to_check == CSONPATH_INST_FIND_ALL); \
|
|
1084
|
-
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
1085
|
-
CSONPATH_CALL_CALLBACK( \
|
|
1086
|
-
callback, ctx, \
|
|
1087
|
-
csonpath_child_info_set(&(struct csonpath_child_info ){}, \
|
|
1088
|
-
ctx, (intptr_t)this_idx), tmp, udata); \
|
|
1089
|
-
return 1; \
|
|
1090
|
-
}
|
|
1184
|
+
int to_check = cjp->inst_lst[idx].inst; \
|
|
1185
|
+
csonpath_child_info_set(child_info, ctx, (intptr_t)this_idx)
|
|
1091
1186
|
|
|
1092
1187
|
|
|
1093
1188
|
#define CSONPATH_DO_GET_NOTFOUND(this_idx) \
|
|
@@ -93,6 +93,18 @@
|
|
|
93
93
|
#define CSONPATH_DO_FILTER_LOOP_PRE_SET
|
|
94
94
|
#endif
|
|
95
95
|
|
|
96
|
+
#ifndef CSONPATH_DO_RANGE
|
|
97
|
+
#define CSONPATH_DO_RANGE CSONPATH_DO_FIND_ALL
|
|
98
|
+
#endif
|
|
99
|
+
|
|
100
|
+
#ifndef CSONPATH_DO_RANGE
|
|
101
|
+
#define CSONPATH_DO_RANGE CSONPATH_DO_FIND_ALL
|
|
102
|
+
#endif
|
|
103
|
+
|
|
104
|
+
#ifndef CSONPATH_DO_RANGE_PRE_LOOP
|
|
105
|
+
#define CSONPATH_DO_RANGE_PRE_LOOP CSONPATH_DO_FIND_ALL_PRE_LOOP
|
|
106
|
+
#endif
|
|
107
|
+
|
|
96
108
|
#ifndef CAT
|
|
97
109
|
# define CATCAT(a, b, c) a ## b ## c
|
|
98
110
|
# define CAT(a, b) a ## b
|
|
@@ -101,7 +113,7 @@
|
|
|
101
113
|
#define csonpath_do_internal__(name) CATCAT(csonpath_, name, _internal)
|
|
102
114
|
#define csonpath_do_internal csonpath_do_internal__(CSONPATH_DO_FUNC_NAME)
|
|
103
115
|
|
|
104
|
-
static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
116
|
+
static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const static 1],
|
|
105
117
|
CSONPATH_JSON origin,
|
|
106
118
|
CSONPATH_JSON value,
|
|
107
119
|
CSONPATH_JSON ctx,
|
|
@@ -113,7 +125,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
113
125
|
#define csonpath_do_dotdot csonpath_do_dotdot__(CSONPATH_DO_FUNC_NAME)
|
|
114
126
|
|
|
115
127
|
|
|
116
|
-
static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
|
|
128
|
+
static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(const struct csonpath cjp[const static 1],
|
|
117
129
|
CSONPATH_JSON origin,
|
|
118
130
|
CSONPATH_JSON tmp,
|
|
119
131
|
CSONPATH_JSON ctx,
|
|
@@ -123,12 +135,17 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
|
|
|
123
135
|
CSONPATH_JSON el;
|
|
124
136
|
CSONPATH_DO_DECLARATION;
|
|
125
137
|
const int is_obj = CSONPATH_IS_OBJ(tmp);
|
|
138
|
+
intptr_t key_idx;
|
|
126
139
|
CSONPATH_DO_RET_TYPE tret = CSONPATH_NONE_FOUND_RET;
|
|
127
140
|
|
|
128
141
|
CSONPATH_DO_FIND_ALL_PRE_LOOP;
|
|
129
|
-
|
|
142
|
+
if (is_obj) {
|
|
143
|
+
const char *key;
|
|
144
|
+
CSONPATH_FOREACH_OBJ(tmp, el, key) {
|
|
145
|
+
key_idx = (intptr_t)key;
|
|
146
|
+
(void)key_idx;
|
|
130
147
|
CSONPATH_DO_FOREACH_PRE_SET;
|
|
131
|
-
if (
|
|
148
|
+
if (!strcmp(key, walker)) {
|
|
132
149
|
tret = csonpath_do_internal(cjp, origin, el, tmp, idx,
|
|
133
150
|
walker + cjp->inst_lst[idx].next
|
|
134
151
|
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
@@ -139,12 +156,22 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
|
|
|
139
156
|
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
140
157
|
CSONPATH_DO_FIND_ALL;
|
|
141
158
|
}
|
|
142
|
-
}
|
|
159
|
+
}
|
|
160
|
+
} else {
|
|
161
|
+
CSONPATH_FOREACH_ARRAY(tmp, el, key_idx) {
|
|
162
|
+
CSONPATH_DO_FOREACH_PRE_SET;
|
|
163
|
+
if (CSONPATH_IS_OBJ(el) || CSONPATH_IS_ARRAY(el)) {
|
|
164
|
+
tret = csonpath_do_dotdot(cjp, origin, el, tmp, idx, walker
|
|
165
|
+
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
166
|
+
CSONPATH_DO_FIND_ALL;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
143
170
|
CSONPATH_DO_FIND_ALL_OUT;
|
|
144
171
|
return tret;
|
|
145
172
|
}
|
|
146
173
|
|
|
147
|
-
static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
174
|
+
static CSONPATH_DO_RET_TYPE csonpath_do_internal(const struct csonpath cjp[const static 1],
|
|
148
175
|
CSONPATH_JSON origin,
|
|
149
176
|
CSONPATH_JSON value,
|
|
150
177
|
CSONPATH_JSON ctx,
|
|
@@ -228,11 +255,55 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
228
255
|
}
|
|
229
256
|
case CSONPATH_INST_FIND_ALL:
|
|
230
257
|
{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
258
|
+
if (CSONPATH_IS_OBJ(tmp) || CSONPATH_IS_ARRAY(tmp)) {
|
|
259
|
+
CSONPATH_DO_RET_TYPE tret =
|
|
260
|
+
csonpath_do_dotdot(cjp, origin, tmp, ctx, idx + 1,
|
|
261
|
+
walker CSONPATH_DO_EXTRA_ARGS_FIND_ALL);
|
|
262
|
+
CSONPATH_DO_FIND_ALL_CLEAUP;
|
|
263
|
+
return tret;
|
|
264
|
+
} else {
|
|
265
|
+
return CSONPATH_NONE_FOUND_RET;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
case CSONPATH_INST_RANGE:
|
|
269
|
+
{
|
|
270
|
+
if (!CSONPATH_IS_ARRAY(tmp)) {
|
|
271
|
+
return CSONPATH_NONE_FOUND_RET;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
CSONPATH_JSON el;
|
|
275
|
+
intptr_t key_idx;
|
|
276
|
+
|
|
277
|
+
(void)key_idx;
|
|
278
|
+
int next_0 = cjp->inst_lst[idx].next;
|
|
279
|
+
int next_1 = cjp->inst_lst[idx + 1].next;
|
|
280
|
+
int next_2 = cjp->inst_lst[idx + 2].next;
|
|
281
|
+
unsigned int beg = csonpath_int_from_walker(cjp->inst_lst[idx + 1].inst, walker + next_0);
|
|
282
|
+
unsigned int end = csonpath_int_from_walker(cjp->inst_lst[idx + 2].inst,
|
|
283
|
+
walker + next_0 + next_1);
|
|
284
|
+
|
|
285
|
+
if (!end)
|
|
286
|
+
end = -1;
|
|
287
|
+
|
|
288
|
+
CSONPATH_DO_RANGE_PRE_LOOP;
|
|
289
|
+
CSONPATH_FOREACH_ARRAY(tmp, el, key_idx) {
|
|
290
|
+
if (key_idx < beg) {
|
|
291
|
+
key_idx = beg - 1;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (key_idx >= end)
|
|
295
|
+
break;
|
|
296
|
+
CSONPATH_DO_FOREACH_PRE_SET
|
|
297
|
+
CSONPATH_DO_RET_TYPE tret =
|
|
298
|
+
csonpath_do_internal(cjp, origin, el, tmp, idx + 3,
|
|
299
|
+
walker + next_0 + next_1 + next_2
|
|
300
|
+
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
301
|
+
|
|
302
|
+
CSONPATH_DO_RANGE;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
CSONPATH_DO_GET_ALL_OUT;
|
|
306
|
+
break;
|
|
236
307
|
}
|
|
237
308
|
case CSONPATH_INST_GET_ALL:
|
|
238
309
|
{
|
|
@@ -330,7 +401,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
330
401
|
|
|
331
402
|
CSONPATH_DO_POST_OPERATION;
|
|
332
403
|
|
|
333
|
-
|
|
404
|
+
return ret;
|
|
334
405
|
}
|
|
335
406
|
|
|
336
407
|
#ifndef CSONPATH_NO_UNDEF
|
|
@@ -361,5 +432,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
361
432
|
#undef CSONPATH_DO_FILTER_PRE_LOOP
|
|
362
433
|
#undef CSONPATH_DO_FILTER_FIND
|
|
363
434
|
#undef CSONPATH_DO_FILTER_LOOP_PRE_SET
|
|
435
|
+
#undef CSONPATH_DO_RANGE
|
|
436
|
+
#undef CSONPATH_DO_RANGE_PRE_LOOP
|
|
364
437
|
|
|
365
438
|
#endif
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include <Python.h>
|
|
2
|
+
#include <stdio.h>
|
|
2
3
|
|
|
3
4
|
#define CSONPATH_JSON PyObject *
|
|
4
5
|
|
|
@@ -27,7 +28,6 @@
|
|
|
27
28
|
|
|
28
29
|
#define CSONPATH_DECREF(obj) \
|
|
29
30
|
Py_DECREF(obj);
|
|
30
|
-
|
|
31
31
|
|
|
32
32
|
#define CSONPATH_GET_NUM(obj) \
|
|
33
33
|
PyLong_AsLong(obj)
|
|
@@ -131,11 +131,30 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
131
131
|
) (array, at, el)
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
#ifdef __TINYC__
|
|
135
|
+
#define CSONPATH_PRAGMA(...)
|
|
136
|
+
#else
|
|
137
|
+
#define CSONPATH_PRAGMA(...) _Pragma(__VA_ARGS__)
|
|
138
|
+
#endif
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13)
|
|
142
|
+
/* PyList_Clear was introduced in Python 3.13 */
|
|
134
143
|
#define CSONPATH_ARRAY_CLEAR(o) PyList_Clear(o)
|
|
144
|
+
#else
|
|
145
|
+
/* For older versions, manually clear the list */
|
|
146
|
+
#define CSONPATH_ARRAY_CLEAR(o) \
|
|
147
|
+
do { \
|
|
148
|
+
while (PyList_Size(o) > 0) { \
|
|
149
|
+
PyList_SetSlice(o, 0, PyList_Size(o), NULL); \
|
|
150
|
+
} \
|
|
151
|
+
} while (0)
|
|
152
|
+
#endif
|
|
135
153
|
|
|
136
154
|
#define CSONPATH_OBJ_CLEAR(o) PyDict_Clear(o)
|
|
137
155
|
|
|
138
156
|
#define CSONPATH_FOREACH_ARRAY(obj, child, idx) \
|
|
157
|
+
CSONPATH_PRAGMA("GCC unroll 8") \
|
|
139
158
|
for (intptr_t array_len = PyList_Size(obj), idx = 0; \
|
|
140
159
|
({int r = idx < array_len; if (r) child = PyList_GetItem(obj, idx); r;}); ++idx)
|
|
141
160
|
|
|
@@ -158,6 +177,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
158
177
|
} \
|
|
159
178
|
} else if (PyList_Check(obj)) { \
|
|
160
179
|
int array_len_ = PyList_Size(obj); \
|
|
180
|
+
CSONPATH_PRAGMA("GCC unroll 8") \
|
|
161
181
|
for (intptr_t key_idx = 0; key_idx < array_len_; ++key_idx) { \
|
|
162
182
|
el = PyList_GetItem(obj, key_idx); \
|
|
163
183
|
code \
|
|
@@ -196,33 +216,53 @@ typedef struct {
|
|
|
196
216
|
|
|
197
217
|
|
|
198
218
|
static PyObject *PyCsonPath_new(PyTypeObject *subtype, PyObject* args,
|
|
199
|
-
PyObject*
|
|
219
|
+
PyObject* kwargs)
|
|
200
220
|
{
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
static char *kwlist[] = {"path", "return_empty_array", NULL};
|
|
222
|
+
PyCsonPathObject *self = (PyCsonPathObject *)subtype->tp_alloc(subtype, 0);
|
|
223
|
+
const char *s;
|
|
224
|
+
int return_empty_array = 0;
|
|
225
|
+
struct csonpath *ret = NULL;
|
|
226
|
+
PyObject *py_ret = NULL;
|
|
227
|
+
|
|
228
|
+
if (!self)
|
|
229
|
+
BAD_ARG();
|
|
230
|
+
|
|
231
|
+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|p", kwlist,
|
|
232
|
+
&s, &return_empty_array)) {
|
|
233
|
+
goto error;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
ret = malloc(sizeof *ret);
|
|
237
|
+
if (!ret) {
|
|
238
|
+
PyErr_NoMemory();
|
|
239
|
+
goto error;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (csonpath_init(ret, s) < 0) {
|
|
243
|
+
py_ret = PyErr_NoMemory();
|
|
244
|
+
goto error_free_ret;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
ret->return_empty_array = return_empty_array;
|
|
248
|
+
|
|
249
|
+
if (csonpath_compile(ret) < 0) {
|
|
250
|
+
char *err_str = ret->compile_error;
|
|
251
|
+
PyErr_Format(PyExc_ValueError, "compilation fail %s",
|
|
252
|
+
err_str ? err_str : "(unknow error)");
|
|
253
|
+
goto error_destroy_ret;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
self->cp = ret;
|
|
257
|
+
return (PyObject *)self;
|
|
258
|
+
|
|
259
|
+
error_destroy_ret:
|
|
260
|
+
csonpath_destroy(ret);
|
|
261
|
+
error_free_ret:
|
|
262
|
+
free(ret);
|
|
263
|
+
error:
|
|
264
|
+
Py_DECREF(self);
|
|
265
|
+
return py_ret;
|
|
226
266
|
}
|
|
227
267
|
|
|
228
268
|
static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
|
|
@@ -230,8 +270,10 @@ static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
|
|
|
230
270
|
PyObject *json;
|
|
231
271
|
|
|
232
272
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
233
|
-
|
|
273
|
+
BAD_ARG();
|
|
274
|
+
|
|
234
275
|
PyObject *ret = csonpath_find_all(self->cp, json);
|
|
276
|
+
|
|
235
277
|
return ret;
|
|
236
278
|
}
|
|
237
279
|
|
|
@@ -240,8 +282,10 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
240
282
|
PyObject *json;
|
|
241
283
|
|
|
242
284
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
243
|
-
|
|
285
|
+
BAD_ARG();
|
|
286
|
+
|
|
244
287
|
PyObject *ret = csonpath_find_first(self->cp, json);
|
|
288
|
+
|
|
245
289
|
Py_INCREF(ret);
|
|
246
290
|
return ret;
|
|
247
291
|
}
|
|
@@ -4,14 +4,12 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.11.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
[tool.setuptools]
|
|
11
11
|
packages = [] # no Python packages, just an extension
|
|
12
|
-
|
|
13
|
-
{name="csonpath", sources = ["csonpath_python.c"]}
|
|
14
|
-
]
|
|
12
|
+
# Extension module is defined in setup.py for platform-specific sources
|
|
15
13
|
|
|
16
14
|
[project.optional-dependencies]
|
|
17
15
|
dev = [
|
|
@@ -22,7 +20,7 @@ dev = [
|
|
|
22
20
|
testpaths = ["tests/python"]
|
|
23
21
|
|
|
24
22
|
[tool.bumpversion]
|
|
25
|
-
current_version = "0.
|
|
23
|
+
current_version = "0.11.0"
|
|
26
24
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
27
25
|
serialize = ["{major}.{minor}.{patch}"]
|
|
28
26
|
search = "{current_version}"
|
csonpath-0.11.0/setup.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import platform
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from setuptools import setup, Extension
|
|
5
|
+
|
|
6
|
+
# Force MinGW compiler on Windows
|
|
7
|
+
if platform.system() == "Windows":
|
|
8
|
+
# Set compiler before importing distutils
|
|
9
|
+
os.environ["CC"] = "gcc"
|
|
10
|
+
# Override distutils to use MinGW
|
|
11
|
+
from distutils.cygwinccompiler import Mingw32CCompiler
|
|
12
|
+
from distutils import sysconfig
|
|
13
|
+
sysconfig.get_config_vars()["CC"] = "gcc"
|
|
14
|
+
|
|
15
|
+
# Base sources
|
|
16
|
+
sources = ["csonpath_python.c"]
|
|
17
|
+
extra_compile_args=["-O3", "-I./"]
|
|
18
|
+
|
|
19
|
+
# On Windows, include tiny_regex.c for regex support
|
|
20
|
+
if platform.system() == "Windows":
|
|
21
|
+
sources.append("tiny-regex-c/re.c")
|
|
22
|
+
extra_compile_args.append("-DCSONPATH_TINY_REGEX")
|
|
23
|
+
extra_compile_args.append("-I./tiny-regex-c/")
|
|
24
|
+
|
|
25
|
+
extension = Extension(
|
|
26
|
+
"csonpath",
|
|
27
|
+
sources=sources,
|
|
28
|
+
extra_compile_args=extra_compile_args,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
setup(
|
|
32
|
+
ext_modules=[extension],
|
|
33
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|