csonpath 0.8.0__tar.gz → 0.10.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {csonpath-0.8.0/csonpath.egg-info → csonpath-0.10.0}/PKG-INFO +4 -3
- {csonpath-0.8.0 → csonpath-0.10.0}/README.md +3 -2
- {csonpath-0.8.0 → csonpath-0.10.0/csonpath.egg-info}/PKG-INFO +4 -3
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath.h +237 -77
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath_do.h +106 -72
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath_python.c +43 -3
- {csonpath-0.8.0 → csonpath-0.10.0}/pyproject.toml +2 -2
- {csonpath-0.8.0 → csonpath-0.10.0}/LICENSE +0 -0
- {csonpath-0.8.0 → csonpath-0.10.0}/MANIFEST.in +0 -0
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.10.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.8.0 → csonpath-0.10.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.10.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -40,9 +40,10 @@ Dynamic: license-file
|
|
|
40
40
|
- support `..`: `"$..non`
|
|
41
41
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
42
42
|
- support filters:
|
|
43
|
-
- with `>` or `<`: `"$.obj[
|
|
44
|
-
- with `=` or '!=': `"$.obj[
|
|
43
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
44
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
45
45
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
46
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
46
47
|
- support `|`: `"$.obj | $.otherobj"`
|
|
47
48
|
### Functions
|
|
48
49
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -31,9 +31,10 @@
|
|
|
31
31
|
- support `..`: `"$..non`
|
|
32
32
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
33
33
|
- support filters:
|
|
34
|
-
- with `>` or `<`: `"$.obj[
|
|
35
|
-
- with `=` or '!=': `"$.obj[
|
|
34
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
35
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
36
36
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
37
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
37
38
|
- support `|`: `"$.obj | $.otherobj"`
|
|
38
39
|
### Functions
|
|
39
40
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -40,9 +40,10 @@ Dynamic: license-file
|
|
|
40
40
|
- support `..`: `"$..non`
|
|
41
41
|
- support `[*]`: `"$.array[*].obj[*].field"`
|
|
42
42
|
- support filters:
|
|
43
|
-
- with `>` or `<`: `"$.obj[
|
|
44
|
-
- with `=` or '!=': `"$.obj[
|
|
43
|
+
- with `>` or `<`: `"$.obj[?field > 123]"`
|
|
44
|
+
- with `=` or '!=': `"$.obj[?field != "123"]"`
|
|
45
45
|
- with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
|
|
46
|
+
- with `&`: `"$.obj[?field != "123" & second = 1]"`
|
|
46
47
|
- support `|`: `"$.obj | $.otherobj"`
|
|
47
48
|
### Functions
|
|
48
49
|
- **Find First**: Retrieve the first value matching a path.
|
|
@@ -33,6 +33,14 @@
|
|
|
33
33
|
#define CSONPATH_DECREF(obj)
|
|
34
34
|
#endif
|
|
35
35
|
|
|
36
|
+
#ifndef CSONPATH_FORMAT_EXCEPTION
|
|
37
|
+
#define CSONPATH_FORMAT_EXCEPTION(args...) fprintf(stderr, args)
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
#ifndef CSONPATH_EXCEPTION
|
|
41
|
+
#define CSONPATH_EXCEPTION(args...) CSONPATH_GETTER_ERR(args)
|
|
42
|
+
#endif
|
|
43
|
+
|
|
36
44
|
enum csonpath_instuction_raw {
|
|
37
45
|
CSONPATH_INST_ROOT,
|
|
38
46
|
CSONPATH_INST_GET_OBJ,
|
|
@@ -46,8 +54,10 @@ enum csonpath_instuction_raw {
|
|
|
46
54
|
CSONPATH_INST_FILTER_OPERAND_STR,
|
|
47
55
|
CSONPATH_INST_FILTER_OPERAND_BYTE, /* store the same way it's in ARRAY_SMALL */
|
|
48
56
|
CSONPATH_INST_FILTER_OPERAND_INT, /* store the same way it's in ARRAY_BIG */
|
|
57
|
+
CSONPATH_INST_FILTER_AND,
|
|
49
58
|
CSONPATH_INST_GET_ALL,
|
|
50
59
|
CSONPATH_INST_FIND_ALL,
|
|
60
|
+
CSONPATH_INST_RANGE,
|
|
51
61
|
CSONPATH_INST_OR,
|
|
52
62
|
CSONPATH_INST_END,
|
|
53
63
|
CSONPATH_INST_BROKEN
|
|
@@ -68,8 +78,10 @@ CSONPATH_UNUSED static const char *csonpath_instuction_str[] = {
|
|
|
68
78
|
"FILTER_OPERAND_STR",
|
|
69
79
|
"FILTER_OPERAND_BYTE",
|
|
70
80
|
"FILTER_OPERAND_INT",
|
|
81
|
+
"FILTER_AND",
|
|
71
82
|
"GET_ALL",
|
|
72
83
|
"FIND_ALL",
|
|
84
|
+
"RANGE",
|
|
73
85
|
"OR",
|
|
74
86
|
"END",
|
|
75
87
|
"BROKEN"
|
|
@@ -230,6 +242,43 @@ static inline _Bool csonpath_is_dot_operand(int c)
|
|
|
230
242
|
return isalnum(c) || c == '_' || c == '-';
|
|
231
243
|
}
|
|
232
244
|
|
|
245
|
+
|
|
246
|
+
static int csonpath_fill_walker_with_int(char *walker, int num, int first_ret)
|
|
247
|
+
{
|
|
248
|
+
if (num < 100) {
|
|
249
|
+
*walker = num;
|
|
250
|
+
return first_ret;
|
|
251
|
+
}
|
|
252
|
+
union {
|
|
253
|
+
int n;
|
|
254
|
+
char c[4];
|
|
255
|
+
} u = {.n=num};
|
|
256
|
+
walker[0] = u.c[0];
|
|
257
|
+
walker[1] = u.c[1];
|
|
258
|
+
walker[2] = u.c[2];
|
|
259
|
+
walker[3] = u.c[3];
|
|
260
|
+
return first_ret + 1;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
static int csonpath_int_from_walker(int operand_instruction, char *walker)
|
|
264
|
+
{
|
|
265
|
+
switch(operand_instruction) {
|
|
266
|
+
case CSONPATH_INST_FILTER_OPERAND_BYTE:
|
|
267
|
+
case CSONPATH_INST_GET_ARRAY_SMALL:
|
|
268
|
+
return *walker;
|
|
269
|
+
case CSONPATH_INST_GET_ARRAY_BIG:
|
|
270
|
+
case CSONPATH_INST_FILTER_OPERAND_INT:
|
|
271
|
+
{
|
|
272
|
+
union {int n; char c[4];} to_num =
|
|
273
|
+
{ .c= { walker[0], walker[1], walker[2], walker[3] } };
|
|
274
|
+
return to_num.n;
|
|
275
|
+
}
|
|
276
|
+
default:
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
return -1;
|
|
280
|
+
}
|
|
281
|
+
|
|
233
282
|
static int csonpath_compile(struct csonpath cjp[static 1])
|
|
234
283
|
{
|
|
235
284
|
char *walker = cjp->path;
|
|
@@ -244,13 +293,13 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
244
293
|
return 0;
|
|
245
294
|
|
|
246
295
|
tmp = strdup(cjp->path);
|
|
247
|
-
|
|
296
|
+
root_again:
|
|
248
297
|
CSONPATH_SKIP('$', walker);
|
|
249
298
|
csonpath_push_inst(cjp, CSONPATH_INST_ROOT, &inst_idx);
|
|
250
299
|
cjp->inst_lst[inst_idx - 1].next = 1;
|
|
251
300
|
to_check = *walker;
|
|
252
301
|
|
|
253
|
-
again:
|
|
302
|
+
again:
|
|
254
303
|
switch (to_check) {
|
|
255
304
|
case '[':
|
|
256
305
|
{
|
|
@@ -289,12 +338,18 @@ again:
|
|
|
289
338
|
*walker);
|
|
290
339
|
goto error;
|
|
291
340
|
}
|
|
341
|
+
filter_again_root:
|
|
292
342
|
inst = CSONPATH_INST_GET_OBJ;
|
|
293
343
|
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
294
344
|
++walker;
|
|
345
|
+
|
|
346
|
+
/* skipp blank */
|
|
347
|
+
for (; isblank(*walker); ++walker)
|
|
348
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
349
|
+
|
|
295
350
|
last_inst = &cjp->inst_lst[inst_idx - 1];
|
|
296
351
|
if (*walker == '(') {
|
|
297
|
-
have_parentesis
|
|
352
|
+
++have_parentesis;
|
|
298
353
|
++walker;
|
|
299
354
|
CSONPATH_SKIP('@', walker);
|
|
300
355
|
if (*walker == '[') {
|
|
@@ -356,7 +411,7 @@ again:
|
|
|
356
411
|
filter_getter[nb_getter_inst-1].next += 1;
|
|
357
412
|
++next;
|
|
358
413
|
to_check = *next;
|
|
359
|
-
have_parentesis
|
|
414
|
+
have_parentesis--;
|
|
360
415
|
}
|
|
361
416
|
|
|
362
417
|
walker = next;
|
|
@@ -463,34 +518,37 @@ again:
|
|
|
463
518
|
|
|
464
519
|
n = atoi(walker);
|
|
465
520
|
to_check = *next;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE, &inst_idx);
|
|
469
|
-
} else {
|
|
470
|
-
union {
|
|
471
|
-
int n;
|
|
472
|
-
char c[4];
|
|
473
|
-
} u = {.n=n};
|
|
474
|
-
walker[0] = u.c[0];
|
|
475
|
-
walker[1] = u.c[1];
|
|
476
|
-
walker[2] = u.c[2];
|
|
477
|
-
walker[3] = u.c[3];
|
|
478
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT, &inst_idx);
|
|
479
|
-
}
|
|
521
|
+
csonpath_push_inst(cjp, csonpath_fill_walker_with_int(
|
|
522
|
+
walker, n, CSONPATH_INST_FILTER_OPERAND_BYTE), &inst_idx);
|
|
480
523
|
}
|
|
524
|
+
|
|
525
|
+
/* skip space */
|
|
481
526
|
if (isblank(to_check)) {
|
|
482
527
|
for (next++; isblank(*next); ++next);
|
|
483
528
|
to_check = *next;
|
|
484
529
|
}
|
|
485
530
|
|
|
486
|
-
if (
|
|
531
|
+
if (to_check == '&') {
|
|
532
|
+
if (next[1] == '&') {
|
|
533
|
+
++next;
|
|
534
|
+
}
|
|
535
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
536
|
+
walker = next + 1;
|
|
537
|
+
to_check = *walker;
|
|
538
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_AND, &inst_idx);
|
|
539
|
+
nb_getter_inst = 0;
|
|
540
|
+
goto filter_again_root;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
while (have_parentesis) {
|
|
487
544
|
CSONPATH_SKIP(')', next);
|
|
488
545
|
to_check = *next;
|
|
546
|
+
--have_parentesis;
|
|
489
547
|
}
|
|
548
|
+
|
|
490
549
|
if (to_check != ']') {
|
|
491
550
|
CSONPATH_REQUIRE_ERR(']', next);
|
|
492
551
|
}
|
|
493
|
-
/* skip space */
|
|
494
552
|
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
495
553
|
walker = next + 1;
|
|
496
554
|
to_check = *walker;
|
|
@@ -506,11 +564,23 @@ again:
|
|
|
506
564
|
|
|
507
565
|
next = walker;
|
|
508
566
|
do {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
567
|
+
if (*next == ':') {
|
|
568
|
+
csonpath_push_inst(cjp, CSONPATH_INST_RANGE, &inst_idx);
|
|
569
|
+
num = atoi(walker);
|
|
570
|
+
csonpath_push_inst(
|
|
571
|
+
cjp, csonpath_fill_walker_with_int(
|
|
572
|
+
walker, num, CSONPATH_INST_GET_ARRAY_SMALL),
|
|
573
|
+
&inst_idx);
|
|
574
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
575
|
+
walker = next + 1;
|
|
576
|
+
++next;
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
if (*next < '0' || *next > '9') {
|
|
580
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
581
|
+
"unexpected '%c', sting, filter or number require\n", *next);
|
|
582
|
+
}
|
|
583
|
+
next++;
|
|
514
584
|
} while (*next && *next != ']');
|
|
515
585
|
if (!*next) {
|
|
516
586
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
@@ -518,20 +588,9 @@ again:
|
|
|
518
588
|
}
|
|
519
589
|
*next = 0;
|
|
520
590
|
num = atoi(walker);
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
} else {
|
|
525
|
-
union {
|
|
526
|
-
int n;
|
|
527
|
-
char c[4];
|
|
528
|
-
} u = {.n=num};
|
|
529
|
-
walker[0] = u.c[0];
|
|
530
|
-
walker[1] = u.c[1];
|
|
531
|
-
walker[2] = u.c[2];
|
|
532
|
-
walker[3] = u.c[3];
|
|
533
|
-
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG, &inst_idx);
|
|
534
|
-
}
|
|
591
|
+
csonpath_push_inst(cjp, csonpath_fill_walker_with_int(
|
|
592
|
+
walker, num, CSONPATH_INST_GET_ARRAY_SMALL),
|
|
593
|
+
&inst_idx);
|
|
535
594
|
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
536
595
|
walker = next + 1;
|
|
537
596
|
to_check = *walker;
|
|
@@ -625,19 +684,6 @@ again:
|
|
|
625
684
|
return -1;
|
|
626
685
|
}
|
|
627
686
|
|
|
628
|
-
static int csonpath_int_from_walker(int operand_instruction, char *walker)
|
|
629
|
-
{
|
|
630
|
-
if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_BYTE)
|
|
631
|
-
return *walker;
|
|
632
|
-
else if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_INT) {
|
|
633
|
-
union {int n; char c[4];} to_num =
|
|
634
|
-
{ .c= { walker[0], walker[1], walker[2], walker[3] } };
|
|
635
|
-
|
|
636
|
-
return to_num.n;
|
|
637
|
-
}
|
|
638
|
-
return -1;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
687
|
static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char *owalker)
|
|
642
688
|
{
|
|
643
689
|
switch (operand_instruction) {
|
|
@@ -656,6 +702,79 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
|
|
|
656
702
|
return 0;
|
|
657
703
|
}
|
|
658
704
|
|
|
705
|
+
static CSONPATH_JSON cosnpath_crawl_filter_el(struct csonpath cjp[static 1],
|
|
706
|
+
int *idx, char **owalker,
|
|
707
|
+
CSONPATH_JSON el2,
|
|
708
|
+
int filter_next)
|
|
709
|
+
{
|
|
710
|
+
|
|
711
|
+
for (; *idx < filter_next; ++(*idx)) {
|
|
712
|
+
switch (cjp->inst_lst[*idx].inst) {
|
|
713
|
+
case CSONPATH_INST_GET_OBJ:
|
|
714
|
+
el2 = CSONPATH_GET(el2, *owalker);
|
|
715
|
+
break;
|
|
716
|
+
default:
|
|
717
|
+
CSONPATH_FORMAT_EXCEPTION("unsuported %s inst",
|
|
718
|
+
csonpath_instuction_str[cjp->inst_lst[*idx].inst]);
|
|
719
|
+
return NULL;
|
|
720
|
+
}
|
|
721
|
+
(*owalker) += cjp->inst_lst[*idx].next;
|
|
722
|
+
}
|
|
723
|
+
return el2;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
static _Bool csonpath_make_match(struct csonpath cjp[static 1],
|
|
728
|
+
struct csonpath_instruction inst[static 1],
|
|
729
|
+
CSONPATH_JSON el2, char *owalker, int operation)
|
|
730
|
+
{
|
|
731
|
+
int operand_instruction = inst->inst;
|
|
732
|
+
|
|
733
|
+
if (el2 == CSONPATH_NULL)
|
|
734
|
+
return 0;
|
|
735
|
+
_Bool match = 0;
|
|
736
|
+
switch (operation) {
|
|
737
|
+
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
738
|
+
match = !csonpath_do_match(operand_instruction, el2, owalker);
|
|
739
|
+
break;
|
|
740
|
+
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
741
|
+
match = csonpath_do_match(operand_instruction, el2, owalker);
|
|
742
|
+
break;
|
|
743
|
+
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
744
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
745
|
+
break;
|
|
746
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) <
|
|
747
|
+
CSONPATH_GET_NUM(el2);
|
|
748
|
+
break;
|
|
749
|
+
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
750
|
+
if (!CSONPATH_IS_NUM(el2))
|
|
751
|
+
break;
|
|
752
|
+
match = csonpath_int_from_walker(operand_instruction, owalker) >
|
|
753
|
+
CSONPATH_GET_NUM(el2);
|
|
754
|
+
break;
|
|
755
|
+
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
756
|
+
#ifdef CSONPATH_NO_REGEX
|
|
757
|
+
CSONPATH_GETTER_ERR("regex deactivate\n");
|
|
758
|
+
return CSONPATH_NONE_FOUND_RET;
|
|
759
|
+
#else
|
|
760
|
+
if (CSONPATH_IS_STR(el2)) {
|
|
761
|
+
int regex_idx = inst->regex_idx;
|
|
762
|
+
regex_t *compiled = &cjp->regexs[regex_idx];
|
|
763
|
+
int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
|
|
764
|
+
0, NULL, 0);
|
|
765
|
+
match = match_len == 0;
|
|
766
|
+
}
|
|
767
|
+
break;
|
|
768
|
+
#endif
|
|
769
|
+
}
|
|
770
|
+
return match;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
static _Bool csonpath_is_endish_inst(int instruction)
|
|
774
|
+
{
|
|
775
|
+
return instruction == CSONPATH_INST_END || instruction == CSONPATH_INST_OR;
|
|
776
|
+
}
|
|
777
|
+
|
|
659
778
|
/* helper use multiple times */
|
|
660
779
|
#define CSONPATH_DO_GET_NOTFOUND_UPDATER(this_idx) \
|
|
661
780
|
do { \
|
|
@@ -674,7 +793,8 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
|
|
|
674
793
|
goto next_inst; \
|
|
675
794
|
} while (0)
|
|
676
795
|
|
|
677
|
-
|
|
796
|
+
|
|
797
|
+
#define CSONPATH_GOTO_ON_RELOOP(where) \
|
|
678
798
|
nb_res += tret; if (need_reloop_in) goto where;
|
|
679
799
|
|
|
680
800
|
#define CSONPATH_PREPARE_RELOOP(label) \
|
|
@@ -776,15 +896,26 @@ need_reloop_in = 0;
|
|
|
776
896
|
#define CSONPATH_DO_FILTER_FIND nb_res += tret;
|
|
777
897
|
|
|
778
898
|
#define CSONPATH_DO_FIND_ALL ({ \
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
899
|
+
if (tret < 0) return -1; \
|
|
900
|
+
nb_res += tret; \
|
|
901
|
+
if (need_reloop_in){ goto again; }; \
|
|
902
|
+
})
|
|
903
|
+
|
|
904
|
+
#define CSONPATH_DO_RANGE ({ \
|
|
905
|
+
if (tret < 0) return -1; \
|
|
906
|
+
nb_res += tret; \
|
|
907
|
+
--end; \
|
|
908
|
+
if (need_reloop_in){ goto range_again; }; \
|
|
909
|
+
})
|
|
783
910
|
|
|
784
911
|
#define CSONPATH_DO_EXTRA_DECLATION , struct csonpath_child_info child_info, int *need_reloop
|
|
785
912
|
|
|
786
913
|
#define CSONPATH_DO_EXTRA_ARGS_IN , (struct csonpath_child_info) {.type = CSONPATH_NONE}, NULL
|
|
787
914
|
|
|
915
|
+
#define CSONPATH_DO_RANGE_PRE_LOOP \
|
|
916
|
+
int need_reloop_in; \
|
|
917
|
+
range_again:
|
|
918
|
+
|
|
788
919
|
#define CSONPATH_DO_FILTER_PRE_LOOP \
|
|
789
920
|
int need_reloop_in;
|
|
790
921
|
|
|
@@ -793,11 +924,11 @@ need_reloop_in = 0;
|
|
|
793
924
|
again:
|
|
794
925
|
|
|
795
926
|
#define CSONPATH_DO_FILTER_LOOP_PRE_SET \
|
|
796
|
-
|
|
927
|
+
csonpath_child_info_set(&child_info, tmp, foreach_idx);
|
|
797
928
|
|
|
798
929
|
#define CSONPATH_DO_FOREACH_PRE_SET \
|
|
799
|
-
|
|
800
|
-
|
|
930
|
+
need_reloop_in = 0; \
|
|
931
|
+
csonpath_child_info_set(&child_info, tmp, (intptr_t)key_idx);
|
|
801
932
|
|
|
802
933
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , child_info, &need_reloop_in
|
|
803
934
|
|
|
@@ -846,6 +977,41 @@ again:
|
|
|
846
977
|
|
|
847
978
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
848
979
|
|
|
980
|
+
static int csonpath_sync_root_array(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
981
|
+
{
|
|
982
|
+
CSONPATH_JSON child;
|
|
983
|
+
size_t idx;
|
|
984
|
+
(void) idx;
|
|
985
|
+
|
|
986
|
+
CSONPATH_ARRAY_CLEAR(parent);
|
|
987
|
+
CSONPATH_FOREACH_ARRAY(to_update, child, idx) {
|
|
988
|
+
CSONPATH_APPEND_AT(parent, idx, child);
|
|
989
|
+
}
|
|
990
|
+
return 1;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
|
|
994
|
+
{
|
|
995
|
+
CSONPATH_JSON child;
|
|
996
|
+
const char *key;
|
|
997
|
+
|
|
998
|
+
CSONPATH_OBJ_CLEAR(parent);
|
|
999
|
+
CSONPATH_FOREACH_OBJ(to_update, child, key) {
|
|
1000
|
+
CSONPATH_APPEND_AT(parent, key, child);
|
|
1001
|
+
}
|
|
1002
|
+
return 1;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
#define CSONPATH_PRE_GET_ROOT \
|
|
1006
|
+
int to_check = cjp->inst_lst[idx + 1].inst; \
|
|
1007
|
+
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
1008
|
+
if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) \
|
|
1009
|
+
return csonpath_sync_root_obj(origin, to_update); \
|
|
1010
|
+
else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) \
|
|
1011
|
+
return csonpath_sync_root_array(origin, to_update); \
|
|
1012
|
+
else \
|
|
1013
|
+
CSONPATH_EXCEPTION("can't upate root ($)\n"); \
|
|
1014
|
+
}
|
|
849
1015
|
|
|
850
1016
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
851
1017
|
int check_at = idx + 1; \
|
|
@@ -906,17 +1072,16 @@ again:
|
|
|
906
1072
|
#define CSONPATH_DO_RETURN \
|
|
907
1073
|
if (tmp == value) { \
|
|
908
1074
|
*need_reloop = 1; \
|
|
909
|
-
CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata); \
|
|
910
|
-
return 1; \
|
|
911
1075
|
} \
|
|
912
|
-
|
|
1076
|
+
CSONPATH_CALL_CALLBACK(callback, ctx, child_info, tmp, udata); \
|
|
1077
|
+
return 1;
|
|
913
1078
|
|
|
914
1079
|
#define CSONPATH_DO_EXTRA_ARGS_FIND_ALL , callback, udata, NULL, need_reloop
|
|
915
1080
|
#define CSONPATH_DO_EXTRA_ARGS_NEESTED , callback, udata, \
|
|
916
1081
|
csonpath_child_info_set(&(struct csonpath_child_info ){}, tmp, (intptr_t)key_idx), \
|
|
917
1082
|
&need_reloop_in
|
|
918
1083
|
#define CSONPATH_DO_EXTRA_ARGS , CSONPATH_CALLBACK callback, CSONPATH_CALLBACK_DATA udata
|
|
919
|
-
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata,
|
|
1084
|
+
#define CSONPATH_DO_EXTRA_ARGS_IN , callback, udata, &(struct csonpath_child_info ){}, NULL
|
|
920
1085
|
#define CSONPATH_DO_EXTRA_DECLATION CSONPATH_DO_EXTRA_ARGS, struct csonpath_child_info *child_info, int *need_reloop
|
|
921
1086
|
#define CSONPATH_DO_FIND_ALL nb_res += tret;
|
|
922
1087
|
#define CSONPATH_DO_FILTER_FIND CSONPATH_GOTO_ON_RELOOP(filter_again)
|
|
@@ -927,21 +1092,16 @@ again:
|
|
|
927
1092
|
|
|
928
1093
|
#define CSONPATH_DO_FIND_ALL_OUT return nb_res;
|
|
929
1094
|
|
|
1095
|
+
#define CSONPATH_PRE_GET_ROOT \
|
|
1096
|
+
int to_check = cjp->inst_lst[idx + 1].inst; \
|
|
1097
|
+
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
1098
|
+
CSONPATH_GETTER_ERR("can't upate root ($)\n"); \
|
|
1099
|
+
return CSONPATH_NONE_FOUND_RET; \
|
|
1100
|
+
}
|
|
930
1101
|
|
|
931
1102
|
#define CSONPATH_PRE_GET(this_idx) \
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
do { \
|
|
935
|
-
to_check = cjp->inst_lst[check_at].inst; \
|
|
936
|
-
++check_at; \
|
|
937
|
-
} while (to_check == CSONPATH_INST_GET_ALL || to_check == CSONPATH_INST_FIND_ALL); \
|
|
938
|
-
if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
|
|
939
|
-
CSONPATH_CALL_CALLBACK( \
|
|
940
|
-
callback, ctx, \
|
|
941
|
-
csonpath_child_info_set(&(struct csonpath_child_info ){}, \
|
|
942
|
-
ctx, (intptr_t)this_idx), tmp, udata); \
|
|
943
|
-
return 1; \
|
|
944
|
-
}
|
|
1103
|
+
int to_check = cjp->inst_lst[idx].inst; \
|
|
1104
|
+
csonpath_child_info_set(child_info, ctx, (intptr_t)this_idx)
|
|
945
1105
|
|
|
946
1106
|
|
|
947
1107
|
#define CSONPATH_DO_GET_NOTFOUND(this_idx) \
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
#define CSONPATH_PRE_GET(this_idx)
|
|
18
18
|
#endif
|
|
19
19
|
|
|
20
|
+
#ifndef CSONPATH_PRE_GET_ROOT
|
|
21
|
+
#define CSONPATH_PRE_GET_ROOT
|
|
22
|
+
#endif
|
|
23
|
+
|
|
20
24
|
#ifndef CSONPATH_DO_DECLARATION
|
|
21
25
|
#define CSONPATH_DO_DECLARATION
|
|
22
26
|
#endif
|
|
@@ -89,6 +93,18 @@
|
|
|
89
93
|
#define CSONPATH_DO_FILTER_LOOP_PRE_SET
|
|
90
94
|
#endif
|
|
91
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
|
+
|
|
92
108
|
#ifndef CAT
|
|
93
109
|
# define CATCAT(a, b, c) a ## b ## c
|
|
94
110
|
# define CAT(a, b) a ## b
|
|
@@ -104,6 +120,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
104
120
|
int idx,
|
|
105
121
|
char *walker CSONPATH_DO_EXTRA_DECLATION);
|
|
106
122
|
|
|
123
|
+
|
|
107
124
|
#define csonpath_do_dotdot__(name) CATCAT(csonpath_, name, _dotdot)
|
|
108
125
|
#define csonpath_do_dotdot csonpath_do_dotdot__(CSONPATH_DO_FUNC_NAME)
|
|
109
126
|
|
|
@@ -155,11 +172,14 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
155
172
|
cjp->inst_lst[idx].inst != CSONPATH_INST_OR) {
|
|
156
173
|
switch (cjp->inst_lst[idx].inst) {
|
|
157
174
|
case CSONPATH_INST_ROOT:
|
|
175
|
+
{
|
|
176
|
+
CSONPATH_PRE_GET_ROOT
|
|
158
177
|
value = origin;
|
|
159
178
|
tmp = value;
|
|
160
179
|
ctx = CSONPATH_NULL;
|
|
161
180
|
walker += cjp->inst_lst[idx].next;
|
|
162
|
-
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
163
183
|
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
164
184
|
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
165
185
|
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
@@ -167,83 +187,54 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
167
187
|
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
168
188
|
{
|
|
169
189
|
CSONPATH_JSON el;
|
|
170
|
-
int operation = cjp->inst_lst[idx].inst;
|
|
190
|
+
int operation_in = cjp->inst_lst[idx].inst, operation = cjp->inst_lst[idx].inst;
|
|
171
191
|
walker += cjp->inst_lst[idx].next;
|
|
172
192
|
char *owalker;
|
|
173
|
-
int filter_next = cjp->inst_lst[idx].filter_next;
|
|
174
|
-
int
|
|
175
|
-
int
|
|
193
|
+
int filter_next_in = cjp->inst_lst[idx].filter_next, filter_next = cjp->inst_lst[idx].filter_next;
|
|
194
|
+
int walker_idx = idx + 1, in_idx = idx + 1;
|
|
195
|
+
int foreach_idx;
|
|
176
196
|
|
|
197
|
+
(void) foreach_idx;
|
|
177
198
|
CSONPATH_DO_FILTER_PRE_LOOP;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
case CSONPATH_INST_FILTER_KEY_NOT_EQ:
|
|
204
|
-
match = !csonpath_do_match(operand_instruction, el2, owalker);
|
|
205
|
-
break;
|
|
206
|
-
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
207
|
-
match = csonpath_do_match(operand_instruction, el2, owalker);
|
|
208
|
-
break;
|
|
209
|
-
case CSONPATH_INST_FILTER_KEY_SUPERIOR:
|
|
210
|
-
if (!CSONPATH_IS_NUM(el2))
|
|
211
|
-
break;
|
|
212
|
-
match = csonpath_int_from_walker(operand_instruction, owalker) <
|
|
213
|
-
CSONPATH_GET_NUM(el2);
|
|
214
|
-
break;
|
|
215
|
-
case CSONPATH_INST_FILTER_KEY_INFERIOR:
|
|
216
|
-
if (!CSONPATH_IS_NUM(el2))
|
|
217
|
-
break;
|
|
218
|
-
match = csonpath_int_from_walker(operand_instruction, owalker) >
|
|
219
|
-
CSONPATH_GET_NUM(el2);
|
|
220
|
-
break;
|
|
221
|
-
case CSONPATH_INST_FILTER_KEY_REG_EQ:
|
|
222
|
-
#ifdef CSONPATH_NO_REGEX
|
|
223
|
-
CSONPATH_GETTER_ERR("regex deactivate\n");
|
|
224
|
-
return CSONPATH_NONE_FOUND_RET;
|
|
225
|
-
#else
|
|
226
|
-
if (CSONPATH_IS_STR(el2)) {
|
|
227
|
-
int regex_idx = cjp->inst_lst[idx].regex_idx;
|
|
228
|
-
regex_t *compiled = &cjp->regexs[regex_idx];
|
|
229
|
-
int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
|
|
230
|
-
0, NULL, 0);
|
|
231
|
-
match = match_len == 0;
|
|
232
|
-
}
|
|
233
|
-
break;
|
|
234
|
-
#endif
|
|
235
|
-
}
|
|
236
|
-
if (match) {
|
|
237
|
-
CSONPATH_DO_RET_TYPE tret =
|
|
238
|
-
csonpath_do_internal(cjp, origin, el, tmp, idx + 1,
|
|
239
|
-
owalker + cjp->inst_lst[idx].next
|
|
240
|
-
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
241
|
-
|
|
242
|
-
CSONPATH_DO_FILTER_FIND;
|
|
243
|
-
}
|
|
199
|
+
CSONPATH_FOREACH_ARRAY(tmp, el, foreach_idx)
|
|
200
|
+
{
|
|
201
|
+
intptr_t key_idx = foreach_idx;
|
|
202
|
+
(void)key_idx;
|
|
203
|
+
owalker = walker;
|
|
204
|
+
match_and_or_or:
|
|
205
|
+
if (CSONPATH_IS_OBJ(el)) {
|
|
206
|
+
CSONPATH_JSON el2 = el;
|
|
207
|
+
|
|
208
|
+
idx = walker_idx;
|
|
209
|
+
CSONPATH_DO_FILTER_LOOP_PRE_SET;
|
|
210
|
+
el2 = cosnpath_crawl_filter_el(cjp, &idx, &owalker, el2, filter_next);
|
|
211
|
+
|
|
212
|
+
if (csonpath_make_match(cjp, &cjp->inst_lst[idx], el2, owalker,
|
|
213
|
+
operation)) {
|
|
214
|
+
if (cjp->inst_lst[idx + 1].inst == CSONPATH_INST_FILTER_AND) {
|
|
215
|
+
++idx; /* skip next */
|
|
216
|
+
if (csonpath_is_endish_inst(cjp->inst_lst[idx + 1].inst) ||
|
|
217
|
+
csonpath_is_endish_inst(cjp->inst_lst[idx + 2].inst))
|
|
218
|
+
goto fail_match;
|
|
219
|
+
operation = cjp->inst_lst[idx +1].inst;
|
|
220
|
+
filter_next = cjp->inst_lst[idx +1].filter_next;
|
|
221
|
+
owalker += cjp->inst_lst[idx].next + cjp->inst_lst[idx-1].next;
|
|
222
|
+
walker_idx = idx + 2;
|
|
223
|
+
goto match_and_or_or;
|
|
244
224
|
}
|
|
225
|
+
CSONPATH_DO_RET_TYPE tret =
|
|
226
|
+
csonpath_do_internal(cjp, origin, el, tmp, idx + 1,
|
|
227
|
+
owalker + cjp->inst_lst[idx].next
|
|
228
|
+
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
229
|
+
CSONPATH_DO_FILTER_FIND;
|
|
230
|
+
} else {
|
|
231
|
+
fail_match:
|
|
232
|
+
operation = operation_in;
|
|
233
|
+
walker_idx = in_idx;
|
|
234
|
+
filter_next = filter_next_in;
|
|
245
235
|
}
|
|
246
|
-
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
247
238
|
CSONPATH_DO_FILTER_OUT;
|
|
248
239
|
break;
|
|
249
240
|
}
|
|
@@ -255,6 +246,46 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
255
246
|
CSONPATH_DO_FIND_ALL_CLEAUP;
|
|
256
247
|
return tret;
|
|
257
248
|
}
|
|
249
|
+
case CSONPATH_INST_RANGE:
|
|
250
|
+
{
|
|
251
|
+
if (!CSONPATH_IS_ARRAY(tmp)) {
|
|
252
|
+
return CSONPATH_NONE_FOUND_RET;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
CSONPATH_JSON el;
|
|
256
|
+
intptr_t key_idx;
|
|
257
|
+
|
|
258
|
+
(void)key_idx;
|
|
259
|
+
int next_0 = cjp->inst_lst[idx].next;
|
|
260
|
+
int next_1 = cjp->inst_lst[idx + 1].next;
|
|
261
|
+
int next_2 = cjp->inst_lst[idx + 2].next;
|
|
262
|
+
unsigned int beg = csonpath_int_from_walker(cjp->inst_lst[idx + 1].inst, walker + next_0);
|
|
263
|
+
unsigned int end = csonpath_int_from_walker(cjp->inst_lst[idx + 2].inst,
|
|
264
|
+
walker + next_0 + next_1);
|
|
265
|
+
|
|
266
|
+
if (!end)
|
|
267
|
+
end = -1;
|
|
268
|
+
|
|
269
|
+
CSONPATH_DO_RANGE_PRE_LOOP;
|
|
270
|
+
CSONPATH_FOREACH_ARRAY(tmp, el, key_idx) {
|
|
271
|
+
if (key_idx < beg) {
|
|
272
|
+
key_idx = beg - 1;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (key_idx >= end)
|
|
276
|
+
break;
|
|
277
|
+
CSONPATH_DO_FOREACH_PRE_SET
|
|
278
|
+
CSONPATH_DO_RET_TYPE tret =
|
|
279
|
+
csonpath_do_internal(cjp, origin, el, tmp, idx + 3,
|
|
280
|
+
walker + next_0 + next_1 + next_2
|
|
281
|
+
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
282
|
+
|
|
283
|
+
CSONPATH_DO_RANGE;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
CSONPATH_DO_GET_ALL_OUT;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
258
289
|
case CSONPATH_INST_GET_ALL:
|
|
259
290
|
{
|
|
260
291
|
CSONPATH_JSON el;
|
|
@@ -356,6 +387,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
356
387
|
|
|
357
388
|
#ifndef CSONPATH_NO_UNDEF
|
|
358
389
|
|
|
390
|
+
#undef CSONPATH_PRE_GET_ROOT
|
|
359
391
|
#undef CSONPATH_PRE_GET
|
|
360
392
|
#undef CSONPATH_DO_PRE_OPERATION
|
|
361
393
|
#undef CSONPATH_DO_POST_OPERATION
|
|
@@ -381,5 +413,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
381
413
|
#undef CSONPATH_DO_FILTER_PRE_LOOP
|
|
382
414
|
#undef CSONPATH_DO_FILTER_FIND
|
|
383
415
|
#undef CSONPATH_DO_FILTER_LOOP_PRE_SET
|
|
416
|
+
#undef CSONPATH_DO_RANGE
|
|
417
|
+
#undef CSONPATH_DO_RANGE_PRE_LOOP
|
|
384
418
|
|
|
385
419
|
#endif
|
|
@@ -50,6 +50,13 @@
|
|
|
50
50
|
r; \
|
|
51
51
|
})
|
|
52
52
|
|
|
53
|
+
#define CSONPATH_FORMAT_EXCEPTION(ARGS...) \
|
|
54
|
+
PyErr_Format(PyExc_ValueError, ARGS)
|
|
55
|
+
|
|
56
|
+
#define CSONPATH_EXCEPTION(ARGS...) \
|
|
57
|
+
PyErr_Format(PyExc_ValueError, ARGS); \
|
|
58
|
+
return -1;
|
|
59
|
+
|
|
53
60
|
#define CSONPATH_CALLBACK PyObject *
|
|
54
61
|
|
|
55
62
|
#define CSONPATH_CALLBACK_DATA PyObject *
|
|
@@ -84,7 +91,7 @@
|
|
|
84
91
|
static int pydict_try_setitemstring(PyObject *obj, const char * const at, PyObject *el)
|
|
85
92
|
{
|
|
86
93
|
if (!PyDict_Check(obj)) {
|
|
87
|
-
PyErr_Format(PyExc_ValueError, "Unable to follow path: Dict expected");
|
|
94
|
+
PyErr_Format(PyExc_ValueError, "Unable to follow path (%s): Dict expected", at);
|
|
88
95
|
return -1;
|
|
89
96
|
}
|
|
90
97
|
PyDict_SetItemString(obj, at, el);
|
|
@@ -97,7 +104,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
97
104
|
PyErr_Format(PyExc_ValueError, "Unable to follow path: List expected");
|
|
98
105
|
return -1;
|
|
99
106
|
}
|
|
100
|
-
Py_ssize_t s = PyList_Size(array);
|
|
107
|
+
Py_ssize_t s = PyList_Size(array);
|
|
101
108
|
if (at >= s) {
|
|
102
109
|
for (;s < at; ++s)
|
|
103
110
|
PyList_Insert(array, s, Py_None);
|
|
@@ -124,6 +131,33 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
124
131
|
) (array, at, el)
|
|
125
132
|
|
|
126
133
|
|
|
134
|
+
#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13)
|
|
135
|
+
/* PyList_Clear was introduced in Python 3.13 */
|
|
136
|
+
#define CSONPATH_ARRAY_CLEAR(o) PyList_Clear(o)
|
|
137
|
+
#else
|
|
138
|
+
/* For older versions, manually clear the list */
|
|
139
|
+
#define CSONPATH_ARRAY_CLEAR(o) \
|
|
140
|
+
do { \
|
|
141
|
+
while (PyList_Size(o) > 0) { \
|
|
142
|
+
PyList_SetSlice(o, 0, PyList_Size(o), NULL); \
|
|
143
|
+
} \
|
|
144
|
+
} while (0)
|
|
145
|
+
#endif
|
|
146
|
+
|
|
147
|
+
#define CSONPATH_OBJ_CLEAR(o) PyDict_Clear(o)
|
|
148
|
+
|
|
149
|
+
#define CSONPATH_FOREACH_ARRAY(obj, child, idx) \
|
|
150
|
+
for (intptr_t array_len = PyList_Size(obj), idx = 0; \
|
|
151
|
+
({int r = idx < array_len; if (r) child = PyList_GetItem(obj, idx); r;}); ++idx)
|
|
152
|
+
|
|
153
|
+
#define CSONPATH_FOREACH_OBJ(obj, child, key) \
|
|
154
|
+
for (Py_ssize_t pos_ = 0; ({ \
|
|
155
|
+
PyObject *key_; \
|
|
156
|
+
_Bool r = PyDict_Next(obj, &pos_, &key_, &child); \
|
|
157
|
+
if (r) key = PyUnicode_AsUTF8AndSize(key_, NULL); \
|
|
158
|
+
r; \
|
|
159
|
+
});)
|
|
160
|
+
|
|
127
161
|
#define CSONPATH_FOREACH_EXT(obj, el, code, key_idx) \
|
|
128
162
|
if (PyDict_Check(obj)) { \
|
|
129
163
|
PyObject *key_; \
|
|
@@ -223,6 +257,12 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
223
257
|
return ret;
|
|
224
258
|
}
|
|
225
259
|
|
|
260
|
+
static PyObject *print_instructions(PyCsonPathObject *self, PyObject *args, PyObject *kwds)
|
|
261
|
+
{
|
|
262
|
+
csonpath_print_instruction(self->cp);
|
|
263
|
+
return Py_None;
|
|
264
|
+
}
|
|
265
|
+
|
|
226
266
|
static PyObject *callback(PyCsonPathObject *self, PyObject* args)
|
|
227
267
|
{
|
|
228
268
|
PyObject *json, *callback, *udata = Py_None;
|
|
@@ -266,7 +306,6 @@ static PyObject *update_or_create_callback(PyCsonPathObject *self, PyObject* arg
|
|
|
266
306
|
return PyLong_FromLong(ret);
|
|
267
307
|
}
|
|
268
308
|
|
|
269
|
-
|
|
270
309
|
static void PyCsonPath_dealloc(PyCsonPathObject *self) {
|
|
271
310
|
if (self->cp) {
|
|
272
311
|
csonpath_destroy(self->cp);
|
|
@@ -289,6 +328,7 @@ static PyObject *PyCsonPath_set_path(PyCsonPathObject *self, PyObject* args) {
|
|
|
289
328
|
static PyMethodDef csonpath_py_method[] = {
|
|
290
329
|
{"set_path", (PyCFunction)PyCsonPath_set_path, METH_VARARGS, "set_path"},
|
|
291
330
|
{"callback", (PyCFunction)callback, METH_VARARGS, "callback"},
|
|
331
|
+
{"print_instructions", (PyCFunction)print_instructions, METH_NOARGS, "print_instructions"},
|
|
292
332
|
{"update_or_create_callback", (PyCFunction)update_or_create_callback, METH_VARARGS, "update_or_create_callback"},
|
|
293
333
|
{"find_first", (PyCFunction)find_first, METH_VARARGS, "find first elems"},
|
|
294
334
|
{"find_all", (PyCFunction)find_all, METH_VARARGS, "find all elems, if one found, pout it in an array"},
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.10.0"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
|
|
10
10
|
[tool.setuptools]
|
|
@@ -22,7 +22,7 @@ dev = [
|
|
|
22
22
|
testpaths = ["tests/python"]
|
|
23
23
|
|
|
24
24
|
[tool.bumpversion]
|
|
25
|
-
current_version = "0.
|
|
25
|
+
current_version = "0.10.0"
|
|
26
26
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
27
27
|
serialize = ["{major}.{minor}.{patch}"]
|
|
28
28
|
search = "{current_version}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|