csonpath 0.10.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csonpath
3
- Version: 0.10.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.10.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.
@@ -5,6 +5,7 @@ csonpath.h
5
5
  csonpath_do.h
6
6
  csonpath_python.c
7
7
  pyproject.toml
8
+ setup.py
8
9
  csonpath.egg-info/PKG-INFO
9
10
  csonpath.egg-info/SOURCES.txt
10
11
  csonpath.egg-info/dependency_links.txt
@@ -10,7 +10,20 @@
10
10
  #endif
11
11
 
12
12
  #ifndef CSONPATH_NO_REGEX
13
- #include <regex.h>
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))
@@ -109,8 +122,12 @@ struct csonpath {
109
122
  int compiled;
110
123
  #ifndef CSONPATH_NO_REGEX
111
124
  int regex_cnt;
112
- regex_t *regexs;
125
+ csonpath_reg_t *regexs;
126
+ #ifdef CSONPATH_PCRE2
127
+ pcre2_match_data **match_datas;
113
128
  #endif
129
+ #endif
130
+ int return_empty_array;
114
131
  };
115
132
 
116
133
  struct csonpath_child_info {
@@ -172,12 +189,25 @@ static inline void csonpath_destroy(struct csonpath cjp[static 1])
172
189
  free(cjp->path);
173
190
  free(cjp->inst_lst);
174
191
  free(cjp->compile_error);
192
+ #ifndef CSONPATH_NO_REGEX
175
193
  if (cjp->regex_cnt) {
194
+ #ifndef CSONPATH_TINY_REGEX
176
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
177
200
  regfree(&cjp->regexs[i]);
201
+ #endif
202
+
178
203
  }
204
+ #endif
205
+ #ifdef CSONPATH_PCRE2
206
+ free(cjp->match_datas);
207
+ #endif
179
208
  free(cjp->regexs);
180
209
  }
210
+ #endif
181
211
  *cjp = (struct csonpath){};
182
212
  }
183
213
 
@@ -204,6 +234,9 @@ static inline int csonpath_init(struct csonpath cjp[static 1],
204
234
  if (!cjp->path || !cjp->inst_lst) {
205
235
  return -ENOMEM;
206
236
  }
237
+
238
+ cjp->return_empty_array = 0;
239
+
207
240
  return 0;
208
241
  }
209
242
 
@@ -228,7 +261,7 @@ static inline void csonpath_push_inst_cpy(struct csonpath cjp[static 1],
228
261
  *inst_idx += 1;
229
262
  }
230
263
 
231
- static void csonpath_print_instruction(struct csonpath cjp[static 1])
264
+ static void csonpath_print_instruction(const struct csonpath cjp[const static 1])
232
265
  {
233
266
  int idx = 0;
234
267
  for (;cjp->inst_lst[idx].inst != CSONPATH_INST_END; ++idx) {
@@ -436,13 +469,16 @@ static int csonpath_compile(struct csonpath cjp[static 1])
436
469
  /* = and == are the same here */
437
470
  if (to_check == '=') {
438
471
  csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ, &inst_idx);
439
- if (next[0] == '=')
472
+ if (next[0] == '=') {
440
473
  ++next;
474
+ }
475
+ #ifndef CSONPATH_NO_REGEX
441
476
  else if (next[0] == '~') {
442
477
  cjp->inst_lst[inst_idx - 1].inst = CSONPATH_INST_FILTER_KEY_REG_EQ;
443
478
  regex_idx = cjp->regex_cnt++;
444
479
  ++next;
445
480
  }
481
+ #endif
446
482
  } else if (to_check == '!' && next[0] == '=') {
447
483
  csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ, &inst_idx);
448
484
  ++next;
@@ -484,14 +520,38 @@ static int csonpath_compile(struct csonpath cjp[static 1])
484
520
  *next = 0;
485
521
  #ifndef CSONPATH_NO_REGEX
486
522
  if (regex_idx >= 0) {
487
- if (!regex_idx)
523
+ if (!regex_idx) {
488
524
  cjp->regexs = malloc(sizeof *cjp->regexs * 255);
489
- int e = regcomp(&cjp->regexs[regex_idx], walker, 0);
525
+ #ifdef CSONPATH_PCRE2
526
+ cjp->match_datas = malloc(sizeof *cjp->match_datas * 255);
527
+ #endif
528
+ }
490
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);
491
550
  if (e) {
492
551
  CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error\n");
493
552
  goto error;
494
553
  }
554
+ # endif
495
555
  }
496
556
  #endif
497
557
  ++next;
@@ -643,7 +703,7 @@ static int csonpath_compile(struct csonpath cjp[static 1])
643
703
  csonpath_push_inst(cjp, inst, &inst_idx);
644
704
  to_check = *walker;
645
705
  goto again;
646
- }
706
+ }
647
707
  for (next = walker; csonpath_is_dot_operand(*next); ++next);
648
708
  if (next == walker) {
649
709
  if (*next == '[')
@@ -702,12 +762,11 @@ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char
702
762
  return 0;
703
763
  }
704
764
 
705
- 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],
706
766
  int *idx, char **owalker,
707
767
  CSONPATH_JSON el2,
708
768
  int filter_next)
709
769
  {
710
-
711
770
  for (; *idx < filter_next; ++(*idx)) {
712
771
  switch (cjp->inst_lst[*idx].inst) {
713
772
  case CSONPATH_INST_GET_OBJ:
@@ -724,12 +783,12 @@ static CSONPATH_JSON cosnpath_crawl_filter_el(struct csonpath cjp[static 1],
724
783
  }
725
784
 
726
785
 
727
- static _Bool csonpath_make_match(struct csonpath cjp[static 1],
786
+ static _Bool csonpath_make_match(const struct csonpath cjp[const static 1],
728
787
  struct csonpath_instruction inst[static 1],
729
788
  CSONPATH_JSON el2, char *owalker, int operation)
730
789
  {
731
790
  int operand_instruction = inst->inst;
732
-
791
+
733
792
  if (el2 == CSONPATH_NULL)
734
793
  return 0;
735
794
  _Bool match = 0;
@@ -753,16 +812,38 @@ static _Bool csonpath_make_match(struct csonpath cjp[static 1],
753
812
  CSONPATH_GET_NUM(el2);
754
813
  break;
755
814
  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;
815
+ #if defined CSONPATH_NO_REGEX
816
+ fprintf(stderr, "regex deactivate");
817
+ return 0;
759
818
  #else
760
819
  if (CSONPATH_IS_STR(el2)) {
761
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
762
842
  regex_t *compiled = &cjp->regexs[regex_idx];
763
843
  int match_len = regexec(compiled, CSONPATH_GET_STR(el2),
764
844
  0, NULL, 0);
765
845
  match = match_len == 0;
846
+ #endif
766
847
  }
767
848
  break;
768
849
  #endif
@@ -816,7 +897,7 @@ need_reloop_in = 0;
816
897
  #define CSONPATH_DO_FUNC_NAME find_first
817
898
  #define CSONPATH_DO_RETURN return tmp
818
899
 
819
- #define CSONPATH_DO_FIND_ALL return tret
900
+ #define CSONPATH_DO_FIND_ALL if (tret) return tret
820
901
 
821
902
  #define CSONPATH_DO_FILTER_FIND return tret
822
903
 
@@ -845,7 +926,7 @@ need_reloop_in = 0;
845
926
  #define CSONPATH_DO_FILTER_FIND CSONPATH_DO_FIND_ALL
846
927
 
847
928
  #define CSONPATH_DO_FIND_ALL_OUT \
848
- if (!nb_res) { \
929
+ if (!cjp->return_empty_array && !nb_res) { \
849
930
  return CSONPATH_NONE_FOUND_RET; \
850
931
  } \
851
932
  return ret_ar;
@@ -853,7 +934,6 @@ need_reloop_in = 0;
853
934
  #define CSONPATH_DO_EXTRA_ARGS_IN , ret_ar
854
935
  #define CSONPATH_DO_EXTRA_DECLATION , CSONPATH_FIND_ALL_RET ret_ar
855
936
 
856
-
857
937
  #include "csonpath_do.h"
858
938
 
859
939
  /* Delete */
@@ -1005,12 +1085,13 @@ static int csonpath_sync_root_obj(CSONPATH_JSON parent, CSONPATH_JSON to_update)
1005
1085
  #define CSONPATH_PRE_GET_ROOT \
1006
1086
  int to_check = cjp->inst_lst[idx + 1].inst; \
1007
1087
  if (to_check == CSONPATH_INST_END || to_check == CSONPATH_INST_OR) { \
1008
- if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) \
1088
+ if (CSONPATH_IS_OBJ(origin) && CSONPATH_IS_OBJ(to_update)) { \
1009
1089
  return csonpath_sync_root_obj(origin, to_update); \
1010
- else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) \
1090
+ } else if (CSONPATH_IS_ARRAY(origin) && CSONPATH_IS_ARRAY(to_update)) { \
1011
1091
  return csonpath_sync_root_array(origin, to_update); \
1012
- else \
1092
+ } else { \
1013
1093
  CSONPATH_EXCEPTION("can't upate root ($)\n"); \
1094
+ } \
1014
1095
  }
1015
1096
 
1016
1097
  #define CSONPATH_PRE_GET(this_idx) \
@@ -113,7 +113,7 @@
113
113
  #define csonpath_do_internal__(name) CATCAT(csonpath_, name, _internal)
114
114
  #define csonpath_do_internal csonpath_do_internal__(CSONPATH_DO_FUNC_NAME)
115
115
 
116
- 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],
117
117
  CSONPATH_JSON origin,
118
118
  CSONPATH_JSON value,
119
119
  CSONPATH_JSON ctx,
@@ -125,7 +125,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
125
125
  #define csonpath_do_dotdot csonpath_do_dotdot__(CSONPATH_DO_FUNC_NAME)
126
126
 
127
127
 
128
- 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],
129
129
  CSONPATH_JSON origin,
130
130
  CSONPATH_JSON tmp,
131
131
  CSONPATH_JSON ctx,
@@ -135,12 +135,17 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
135
135
  CSONPATH_JSON el;
136
136
  CSONPATH_DO_DECLARATION;
137
137
  const int is_obj = CSONPATH_IS_OBJ(tmp);
138
+ intptr_t key_idx;
138
139
  CSONPATH_DO_RET_TYPE tret = CSONPATH_NONE_FOUND_RET;
139
140
 
140
141
  CSONPATH_DO_FIND_ALL_PRE_LOOP;
141
- CSONPATH_FOREACH(tmp, el, {
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;
142
147
  CSONPATH_DO_FOREACH_PRE_SET;
143
- if (is_obj && !strcmp((char *)key_idx, walker)) {
148
+ if (!strcmp(key, walker)) {
144
149
  tret = csonpath_do_internal(cjp, origin, el, tmp, idx,
145
150
  walker + cjp->inst_lst[idx].next
146
151
  CSONPATH_DO_EXTRA_ARGS_NEESTED);
@@ -151,12 +156,22 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
151
156
  CSONPATH_DO_EXTRA_ARGS_NEESTED);
152
157
  CSONPATH_DO_FIND_ALL;
153
158
  }
154
- })
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
+ }
155
170
  CSONPATH_DO_FIND_ALL_OUT;
156
171
  return tret;
157
172
  }
158
173
 
159
- 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],
160
175
  CSONPATH_JSON origin,
161
176
  CSONPATH_JSON value,
162
177
  CSONPATH_JSON ctx,
@@ -240,11 +255,15 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
240
255
  }
241
256
  case CSONPATH_INST_FIND_ALL:
242
257
  {
243
- CSONPATH_DO_RET_TYPE tret =
244
- csonpath_do_dotdot(cjp, origin, tmp, ctx, idx + 1,
245
- walker CSONPATH_DO_EXTRA_ARGS_FIND_ALL);
246
- CSONPATH_DO_FIND_ALL_CLEAUP;
247
- return tret;
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
+ }
248
267
  }
249
268
  case CSONPATH_INST_RANGE:
250
269
  {
@@ -382,7 +401,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
382
401
 
383
402
  CSONPATH_DO_POST_OPERATION;
384
403
 
385
- return ret;
404
+ return ret;
386
405
  }
387
406
 
388
407
  #ifndef CSONPATH_NO_UNDEF
@@ -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,6 +131,13 @@ 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
+
134
141
  #if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13)
135
142
  /* PyList_Clear was introduced in Python 3.13 */
136
143
  #define CSONPATH_ARRAY_CLEAR(o) PyList_Clear(o)
@@ -147,6 +154,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
147
154
  #define CSONPATH_OBJ_CLEAR(o) PyDict_Clear(o)
148
155
 
149
156
  #define CSONPATH_FOREACH_ARRAY(obj, child, idx) \
157
+ CSONPATH_PRAGMA("GCC unroll 8") \
150
158
  for (intptr_t array_len = PyList_Size(obj), idx = 0; \
151
159
  ({int r = idx < array_len; if (r) child = PyList_GetItem(obj, idx); r;}); ++idx)
152
160
 
@@ -169,6 +177,7 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
169
177
  } \
170
178
  } else if (PyList_Check(obj)) { \
171
179
  int array_len_ = PyList_Size(obj); \
180
+ CSONPATH_PRAGMA("GCC unroll 8") \
172
181
  for (intptr_t key_idx = 0; key_idx < array_len_; ++key_idx) { \
173
182
  el = PyList_GetItem(obj, key_idx); \
174
183
  code \
@@ -207,33 +216,53 @@ typedef struct {
207
216
 
208
217
 
209
218
  static PyObject *PyCsonPath_new(PyTypeObject *subtype, PyObject* args,
210
- PyObject* dont_care)
219
+ PyObject* kwargs)
211
220
  {
212
- PyCsonPathObject *self = (PyCsonPathObject *)subtype->tp_alloc(subtype, 0);
213
- const char *s;
214
-
215
- if (!self)
216
- BAD_ARG();
217
-
218
- if (!PyArg_ParseTuple(args, "s", &s))
219
- BAD_ARG();
220
-
221
- struct csonpath *ret = malloc(sizeof *ret);
222
- if (!self)
223
- return PyErr_NoMemory();
224
-
225
- if (csonpath_init(ret, s) < 0)
226
- return PyErr_NoMemory();
227
-
228
- if (csonpath_compile(ret) < 0) {
229
- char *error = ret->compile_error;
230
- PyErr_Format(PyExc_ValueError, "compilation fail %s", error ? error : "(unknow error)");
231
- csonpath_destroy(ret);
232
- return NULL;
233
- }
234
- self->cp = ret;
235
-
236
- return (PyObject *)self;
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;
237
266
  }
238
267
 
239
268
  static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
@@ -241,8 +270,10 @@ static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
241
270
  PyObject *json;
242
271
 
243
272
  if (!PyArg_ParseTuple(args, "O", &json))
244
- BAD_ARG();
273
+ BAD_ARG();
274
+
245
275
  PyObject *ret = csonpath_find_all(self->cp, json);
276
+
246
277
  return ret;
247
278
  }
248
279
 
@@ -251,8 +282,10 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
251
282
  PyObject *json;
252
283
 
253
284
  if (!PyArg_ParseTuple(args, "O", &json))
254
- BAD_ARG();
285
+ BAD_ARG();
286
+
255
287
  PyObject *ret = csonpath_find_first(self->cp, json);
288
+
256
289
  Py_INCREF(ret);
257
290
  return ret;
258
291
  }
@@ -4,14 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "csonpath"
7
- version = "0.10.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
- ext-modules = [
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.10.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}"
@@ -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