csonpath 0.13.1__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.
Files changed (40) hide show
  1. {csonpath-0.13.1/csonpath.egg-info → csonpath-0.14.0}/PKG-INFO +1 -1
  2. {csonpath-0.13.1 → csonpath-0.14.0/csonpath.egg-info}/PKG-INFO +1 -1
  3. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath.h +241 -99
  4. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath_do.h +3 -0
  5. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath_json-c.h +6 -0
  6. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath_python.c +7 -0
  7. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath_yyjson.h +6 -0
  8. {csonpath-0.13.1 → csonpath-0.14.0}/pyproject.toml +2 -2
  9. {csonpath-0.13.1 → csonpath-0.14.0}/LICENSE +0 -0
  10. {csonpath-0.13.1 → csonpath-0.14.0}/MANIFEST.in +0 -0
  11. {csonpath-0.13.1 → csonpath-0.14.0}/Makefile +0 -0
  12. {csonpath-0.13.1 → csonpath-0.14.0}/README.md +0 -0
  13. {csonpath-0.13.1 → csonpath-0.14.0}/configure +0 -0
  14. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath.egg-info/SOURCES.txt +0 -0
  15. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath.egg-info/dependency_links.txt +0 -0
  16. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath.egg-info/requires.txt +0 -0
  17. {csonpath-0.13.1 → csonpath-0.14.0}/csonpath.egg-info/top_level.txt +0 -0
  18. {csonpath-0.13.1 → csonpath-0.14.0}/setup.cfg +0 -0
  19. {csonpath-0.13.1 → csonpath-0.14.0}/setup.py +0 -0
  20. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/.git +0 -0
  21. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/.github/workflows/c-cpp.yml +0 -0
  22. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/.gitignore +0 -0
  23. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/LICENSE +0 -0
  24. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/Makefile +0 -0
  25. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/README.md +0 -0
  26. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/clib.json +0 -0
  27. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/formal_verification.md +0 -0
  28. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/re.c +0 -0
  29. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/re.h +0 -0
  30. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/scripts/exrex.py +0 -0
  31. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/scripts/regex_test.py +0 -0
  32. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/scripts/regex_test_neg.py +0 -0
  33. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test1.c +0 -0
  34. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test2.c +0 -0
  35. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test3.c +0 -0
  36. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test_compile.c +0 -0
  37. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test_print.c +0 -0
  38. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test_rand.c +0 -0
  39. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test_rand_neg.c +0 -0
  40. {csonpath-0.13.1 → csonpath-0.14.0}/tiny-regex-c/tests/test_thread.c +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csonpath
3
- Version: 0.13.1
3
+ Version: 0.14.0
4
4
  Description-Content-Type: text/markdown
5
5
  License-File: LICENSE
6
6
  Provides-Extra: dev
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csonpath
3
- Version: 0.13.1
3
+ Version: 0.14.0
4
4
  Description-Content-Type: text/markdown
5
5
  License-File: LICENSE
6
6
  Provides-Extra: dev
@@ -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(&reg, str, 0, NULL, 0) == 0;
49
- }
50
- static inline void csonpath_reg_free(csonpath_reg_t reg) { regfree(&reg); }
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, /* 1 CSONPATH_INST_GET_SUBPATH */
119
- 2, /* 2 CSONPATH_INST_GET_ARRAY_SMALL */
120
- 5, /* 3 CSONPATH_INST_GET_ARRAY_BIG */
121
- 2, /* 4 CSONPATH_INST_FILTER_KEY_SUPERIOR */
122
- 2, /* 5 CSONPATH_INST_FILTER_KEY_INFERIOR */
123
- 2, /* 6 CSONPATH_INST_FILTER_KEY_EQ */
124
- 2, /* 7 CSONPATH_INST_FILTER_KEY_NOT_EQ */
125
- 2, /* 8 CSONPATH_INST_FILTER_KEY_REG_EQ */
126
- -1, /* 9 CSONPATH_INST_FILTER_OPERAND_STR */
127
- 1, /* 10 CSONPATH_INST_FILTER_AND */
128
- 1, /* 11 CSONPATH_INST_GET_ALL */
129
- -1, /* 12 CSONPATH_INST_FIND_ALL */
130
- 1, /* 13 CSONPATH_INST_RANGE */
131
- 1, /* 14 CSONPATH_INST_OR */
132
- 1, /* 15 CSONPATH_INST_END */
133
- 1, /* 16 CSONPATH_INST_BROKEN */
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(&reg, str, 0, NULL, 0) == 0;
188
+ }
189
+ static inline void csonpath_reg_free(csonpath_reg_t reg) { regfree(&reg); }
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
- csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR, inst_idx);
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
- csonpath_push_char(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR, inst_idx);
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
- char *filter_end = &cjp->data[(*inst_idx)++];
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, CSONPATH_INST_FILTER_OPERAND_STR, inst_idx);
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
- # if defined CSONPATH_PCRE2
601
- int errorcode;
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 CSONPATH_INST_FILTER_OPERAND_STR:
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
- el2 = CSONPATH_GET(el2, *owalker);
867
- if (!el2)
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
- if (!CSONPATH_IS_NUM(el2))
1290
- break;
1291
- match = csonpath_int_from_walker(operand_instruction, owalker) <
1292
- CSONPATH_GET_NUM(el2);
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 (!CSONPATH_IS_NUM(el2))
1296
- break;
1297
- match = csonpath_int_from_walker(operand_instruction, owalker) >
1298
- CSONPATH_GET_NUM(el2);
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;
@@ -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;
@@ -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
 
@@ -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.13.1"
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.13.1"
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