csonpath 0.5.0__tar.gz → 0.6.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.5.0
3
+ Version: 0.6.0
4
4
  Description-Content-Type: text/markdown
5
5
  License-File: LICENSE
6
6
  Provides-Extra: dev
@@ -35,6 +35,16 @@ Dynamic: license-file
35
35
 
36
36
  ## 🚀 Features
37
37
 
38
+ ### jsonpath
39
+ - support simple path like ex: `"$.a[3]["oui"]`
40
+ - support `..`: `"$..non`
41
+ - support `[*]`: `"$.array[*].obj[*].field"`
42
+ - support filters:
43
+ - with `>` or `<`: `"$.obj[?.field > 123]"`
44
+ - with `=` or '!=': `"$.obj[?.field != "123"]"`
45
+ - with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
46
+ - support `|`: `"$.obj | $.otherobj"`
47
+ ### Functions
38
48
  - **Find First**: Retrieve the first value matching a path.
39
49
  - **Find All**: Retrieve all values matching a path.
40
50
  - **Update or Create**: Update values or create new ones according to the path.
@@ -76,8 +86,53 @@ ret = csonpath_find_first(&p, jobj);
76
86
  // ret now points to "value"
77
87
  ```
78
88
 
89
+ #### Avaible functions:
90
+ ```C
91
+ int csonpath_init(struct csonpath cjp[static 1], const char path[static 1])
92
+ ```
93
+ init a csonpath struct
94
+
95
+ ```C
96
+ int csonpath_set_path(struct csonpath cjp[static 1], const char path[static 1])
97
+ ```
98
+ change the path of a struct
99
+
100
+ ```C
101
+ int csonpath_compile(struct csonpath cjp[static 1])
102
+ ```
103
+ compile the path, doesn't need to be called before using it, but can be useful to catch error earlyer.
104
+ ```C
105
+ void csonpath_print_instruction(struct csonpath cjp[static 1])
106
+ ```
107
+ print all instructions once compiled
108
+ ```C
109
+ struct json_object *csonpath_find_first(struct csonpath cjp[static 1], struct json_object *json);
110
+ ```
111
+ Retrieve the first value matching a path
112
+ ```C
113
+ struct json_object *csonpath_find_all(struct csonpath cjp[static 1], struct json_object *json);
114
+ ```
115
+ Retrieve all values matching a path, return need to be free using `json_object_put`
116
+ ```C
117
+ struct json_object *csonpath_remove(struct csonpath cjp[static 1], struct json_object *json);
118
+ ```
119
+ Remove all matching elements from json
120
+ ```C
121
+ struct json_object *csonpath_update_or_create(struct csonpath cjp[static 1], struct json_object *json, struct json_object *new_val)
122
+ ```
123
+ update and push new_val, in json.
124
+ ```C
125
+ struct json_object *csonpath_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
126
+ ```
127
+ call `callback` on each value matching path
128
+ ```C
129
+ struct json_object *csonpath_update_or_create_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
130
+ ```
131
+ like callback, but update json base on the path, along the way.
132
+
79
133
  ### Usage (Python)
80
134
 
135
+ #### Example
81
136
  ```python
82
137
  import csonpath
83
138
 
@@ -111,7 +166,7 @@ To use csonpath with a different data type or library, simply define the require
111
166
  - `csonpath_json-c.h` - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
112
167
  - `csonpath_python.c` - python implementation, use it like a python lib (so `pip install .`)
113
168
  - `tests/` - Contains tests
114
- - `bench//` - Some benchmarks
169
+ - `bench/` - Some benchmarks
115
170
 
116
171
  ## 🤝 Contributing
117
172
 
@@ -123,4 +178,3 @@ Feel free to open issues or pull requests!
123
178
 
124
179
  ## 📜 License
125
180
  BSD 3-Clause. See [LICENSE](LICENSE).
126
- remimu.h is under the CC0 1.0 Universal, original source is [here](https://github.com/wareya/Remimu)
@@ -26,6 +26,16 @@
26
26
 
27
27
  ## 🚀 Features
28
28
 
29
+ ### jsonpath
30
+ - support simple path like ex: `"$.a[3]["oui"]`
31
+ - support `..`: `"$..non`
32
+ - support `[*]`: `"$.array[*].obj[*].field"`
33
+ - support filters:
34
+ - with `>` or `<`: `"$.obj[?.field > 123]"`
35
+ - with `=` or '!=': `"$.obj[?.field != "123"]"`
36
+ - with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
37
+ - support `|`: `"$.obj | $.otherobj"`
38
+ ### Functions
29
39
  - **Find First**: Retrieve the first value matching a path.
30
40
  - **Find All**: Retrieve all values matching a path.
31
41
  - **Update or Create**: Update values or create new ones according to the path.
@@ -67,8 +77,53 @@ ret = csonpath_find_first(&p, jobj);
67
77
  // ret now points to "value"
68
78
  ```
69
79
 
80
+ #### Avaible functions:
81
+ ```C
82
+ int csonpath_init(struct csonpath cjp[static 1], const char path[static 1])
83
+ ```
84
+ init a csonpath struct
85
+
86
+ ```C
87
+ int csonpath_set_path(struct csonpath cjp[static 1], const char path[static 1])
88
+ ```
89
+ change the path of a struct
90
+
91
+ ```C
92
+ int csonpath_compile(struct csonpath cjp[static 1])
93
+ ```
94
+ compile the path, doesn't need to be called before using it, but can be useful to catch error earlyer.
95
+ ```C
96
+ void csonpath_print_instruction(struct csonpath cjp[static 1])
97
+ ```
98
+ print all instructions once compiled
99
+ ```C
100
+ struct json_object *csonpath_find_first(struct csonpath cjp[static 1], struct json_object *json);
101
+ ```
102
+ Retrieve the first value matching a path
103
+ ```C
104
+ struct json_object *csonpath_find_all(struct csonpath cjp[static 1], struct json_object *json);
105
+ ```
106
+ Retrieve all values matching a path, return need to be free using `json_object_put`
107
+ ```C
108
+ struct json_object *csonpath_remove(struct csonpath cjp[static 1], struct json_object *json);
109
+ ```
110
+ Remove all matching elements from json
111
+ ```C
112
+ struct json_object *csonpath_update_or_create(struct csonpath cjp[static 1], struct json_object *json, struct json_object *new_val)
113
+ ```
114
+ update and push new_val, in json.
115
+ ```C
116
+ struct json_object *csonpath_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
117
+ ```
118
+ call `callback` on each value matching path
119
+ ```C
120
+ struct json_object *csonpath_update_or_create_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
121
+ ```
122
+ like callback, but update json base on the path, along the way.
123
+
70
124
  ### Usage (Python)
71
125
 
126
+ #### Example
72
127
  ```python
73
128
  import csonpath
74
129
 
@@ -102,7 +157,7 @@ To use csonpath with a different data type or library, simply define the require
102
157
  - `csonpath_json-c.h` - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
103
158
  - `csonpath_python.c` - python implementation, use it like a python lib (so `pip install .`)
104
159
  - `tests/` - Contains tests
105
- - `bench//` - Some benchmarks
160
+ - `bench/` - Some benchmarks
106
161
 
107
162
  ## 🤝 Contributing
108
163
 
@@ -114,4 +169,3 @@ Feel free to open issues or pull requests!
114
169
 
115
170
  ## 📜 License
116
171
  BSD 3-Clause. See [LICENSE](LICENSE).
117
- remimu.h is under the CC0 1.0 Universal, original source is [here](https://github.com/wareya/Remimu)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csonpath
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Description-Content-Type: text/markdown
5
5
  License-File: LICENSE
6
6
  Provides-Extra: dev
@@ -35,6 +35,16 @@ Dynamic: license-file
35
35
 
36
36
  ## 🚀 Features
37
37
 
38
+ ### jsonpath
39
+ - support simple path like ex: `"$.a[3]["oui"]`
40
+ - support `..`: `"$..non`
41
+ - support `[*]`: `"$.array[*].obj[*].field"`
42
+ - support filters:
43
+ - with `>` or `<`: `"$.obj[?.field > 123]"`
44
+ - with `=` or '!=': `"$.obj[?.field != "123"]"`
45
+ - with regex, using POSIX regcom: `"$.obj[?.field ~= "123"]"`
46
+ - support `|`: `"$.obj | $.otherobj"`
47
+ ### Functions
38
48
  - **Find First**: Retrieve the first value matching a path.
39
49
  - **Find All**: Retrieve all values matching a path.
40
50
  - **Update or Create**: Update values or create new ones according to the path.
@@ -76,8 +86,53 @@ ret = csonpath_find_first(&p, jobj);
76
86
  // ret now points to "value"
77
87
  ```
78
88
 
89
+ #### Avaible functions:
90
+ ```C
91
+ int csonpath_init(struct csonpath cjp[static 1], const char path[static 1])
92
+ ```
93
+ init a csonpath struct
94
+
95
+ ```C
96
+ int csonpath_set_path(struct csonpath cjp[static 1], const char path[static 1])
97
+ ```
98
+ change the path of a struct
99
+
100
+ ```C
101
+ int csonpath_compile(struct csonpath cjp[static 1])
102
+ ```
103
+ compile the path, doesn't need to be called before using it, but can be useful to catch error earlyer.
104
+ ```C
105
+ void csonpath_print_instruction(struct csonpath cjp[static 1])
106
+ ```
107
+ print all instructions once compiled
108
+ ```C
109
+ struct json_object *csonpath_find_first(struct csonpath cjp[static 1], struct json_object *json);
110
+ ```
111
+ Retrieve the first value matching a path
112
+ ```C
113
+ struct json_object *csonpath_find_all(struct csonpath cjp[static 1], struct json_object *json);
114
+ ```
115
+ Retrieve all values matching a path, return need to be free using `json_object_put`
116
+ ```C
117
+ struct json_object *csonpath_remove(struct csonpath cjp[static 1], struct json_object *json);
118
+ ```
119
+ Remove all matching elements from json
120
+ ```C
121
+ struct json_object *csonpath_update_or_create(struct csonpath cjp[static 1], struct json_object *json, struct json_object *new_val)
122
+ ```
123
+ update and push new_val, in json.
124
+ ```C
125
+ struct json_object *csonpath_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
126
+ ```
127
+ call `callback` on each value matching path
128
+ ```C
129
+ struct json_object *csonpath_update_or_create_callback(struct csonpath cjp[static 1], struct json_object *json, json_c_callback callback, void *userdata)
130
+ ```
131
+ like callback, but update json base on the path, along the way.
132
+
79
133
  ### Usage (Python)
80
134
 
135
+ #### Example
81
136
  ```python
82
137
  import csonpath
83
138
 
@@ -111,7 +166,7 @@ To use csonpath with a different data type or library, simply define the require
111
166
  - `csonpath_json-c.h` - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
112
167
  - `csonpath_python.c` - python implementation, use it like a python lib (so `pip install .`)
113
168
  - `tests/` - Contains tests
114
- - `bench//` - Some benchmarks
169
+ - `bench/` - Some benchmarks
115
170
 
116
171
  ## 🤝 Contributing
117
172
 
@@ -123,4 +178,3 @@ Feel free to open issues or pull requests!
123
178
 
124
179
  ## 📜 License
125
180
  BSD 3-Clause. See [LICENSE](LICENSE).
126
- remimu.h is under the CC0 1.0 Universal, original source is [here](https://github.com/wareya/Remimu)
@@ -86,15 +86,11 @@ struct csonpath_instruction {
86
86
  short int next;
87
87
  };
88
88
 
89
- #define CSONPATH_INST_MIN_ALLOC (1 << 7)
90
-
91
89
  struct csonpath {
92
- char *path;
93
90
  char *compile_error;
91
+ char *path;
94
92
  struct csonpath_instruction *inst_lst;
95
93
  int compiled;
96
- int inst_idx;
97
- int inst_size;
98
94
  #ifndef CSONPATH_NO_REGEX
99
95
  int regex_cnt;
100
96
  regex_t *regexs;
@@ -169,11 +165,26 @@ static inline void csonpath_destroy(struct csonpath cjp[static 1])
169
165
  *cjp = (struct csonpath){};
170
166
  }
171
167
 
168
+ static _Bool csonpath_is_one_char_instruction(int c)
169
+ {
170
+ return c == '|' || c == '$';
171
+ }
172
+
172
173
  static inline int csonpath_init(struct csonpath cjp[static 1],
173
174
  const char path[static 1]) {
175
+ /*
176
+ * We overalloc, but this enable us to avoid checking size,
177
+ * as the only instruction that require 1 character is $, and $$ is not allow
178
+ * we can safely assume that we can't have more instructions than path len / 2 + 2
179
+ * we add plus 2, because "$", is a valid path, and contain 2 instruction: ROOT and END
180
+ */
181
+ int max_inst = strlen(path) / 2 + 1;
182
+ for (const char *cpy = path; *cpy; ++cpy) {
183
+ if (csonpath_is_one_char_instruction(*cpy))
184
+ ++max_inst;
185
+ }
174
186
  *cjp = (struct csonpath) {.path=strdup(path),
175
- .inst_size = CSONPATH_INST_MIN_ALLOC,
176
- .inst_lst = malloc(sizeof(*cjp->inst_lst) * CSONPATH_INST_MIN_ALLOC)};
187
+ .inst_lst = malloc(sizeof(*cjp->inst_lst) * max_inst)};
177
188
  if (!cjp->path || !cjp->inst_lst) {
178
189
  return -ENOMEM;
179
190
  }
@@ -187,27 +198,18 @@ static inline int csonpath_set_path(struct csonpath cjp[static 1],
187
198
  return csonpath_init(cjp, path);
188
199
  }
189
200
 
190
- static inline void csonpath_push_inst(struct csonpath cjp[static 1], int inst)
201
+ static inline void csonpath_push_inst(struct csonpath cjp[static 1], int inst, int *inst_idx)
191
202
  {
192
- if (cjp->inst_idx + 1 > cjp->inst_size) {
193
- cjp->inst_size = cjp->inst_size << 1;
194
- cjp->inst_lst = realloc(cjp->inst_lst, cjp->inst_size);
195
- assert(cjp->inst_lst);
196
- }
197
- cjp->inst_lst[cjp->inst_idx] = (struct csonpath_instruction){.inst=inst};
198
- ++cjp->inst_idx;
203
+ cjp->inst_lst[*inst_idx] = (struct csonpath_instruction){.inst=inst};
204
+ *inst_idx += 1;
199
205
  }
200
206
 
201
207
  static inline void csonpath_push_inst_cpy(struct csonpath cjp[static 1],
202
- struct csonpath_instruction inst)
208
+ const struct csonpath_instruction inst,
209
+ int *inst_idx)
203
210
  {
204
- if (cjp->inst_idx + 1 > cjp->inst_size) {
205
- cjp->inst_size = cjp->inst_size << 1;
206
- cjp->inst_lst = realloc(cjp->inst_lst, cjp->inst_size);
207
- assert(cjp->inst_lst);
208
- }
209
- cjp->inst_lst[cjp->inst_idx] = inst;
210
- ++cjp->inst_idx;
211
+ cjp->inst_lst[*inst_idx] = inst;
212
+ *inst_idx += 1;
211
213
  }
212
214
 
213
215
  static void csonpath_print_instruction(struct csonpath cjp[static 1])
@@ -230,7 +232,9 @@ static int csonpath_compile(struct csonpath cjp[static 1])
230
232
  char *orig = walker;
231
233
  char *next;
232
234
  char to_check;
235
+ int inst_idx = 0;
233
236
  char *tmp; /* tmp is only here for debug */
237
+ int inst;
234
238
 
235
239
  if (cjp->compiled)
236
240
  return 0;
@@ -238,8 +242,8 @@ static int csonpath_compile(struct csonpath cjp[static 1])
238
242
  tmp = strdup(cjp->path);
239
243
  root_again:
240
244
  CSONPATH_SKIP('$', walker);
241
- csonpath_push_inst(cjp, CSONPATH_INST_ROOT);
242
- cjp->inst_lst[cjp->inst_idx - 1].next = 1;
245
+ csonpath_push_inst(cjp, CSONPATH_INST_ROOT, &inst_idx);
246
+ cjp->inst_lst[inst_idx - 1].next = 1;
243
247
  to_check = *walker;
244
248
 
245
249
  again:
@@ -248,15 +252,21 @@ again:
248
252
  {
249
253
  int end;
250
254
 
255
+ inst = 0;
251
256
  do_array:
252
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
257
+ cjp->inst_lst[inst_idx - 1].next += 1;
253
258
  ++walker;
254
259
  if (*walker == '*') {
255
- csonpath_push_inst(cjp, CSONPATH_INST_GET_ALL);
260
+ if (inst == CSONPATH_INST_FIND_ALL) {
261
+ CSONPATH_COMPILE_ERR(tmp, walker - orig, "'%c' is invalide here\n",
262
+ *walker);
263
+ goto error;
264
+ }
265
+ csonpath_push_inst(cjp, CSONPATH_INST_GET_ALL, &inst_idx);
256
266
  if (walker[1] != ']') {
257
267
  CSONPATH_COMPILE_ERR(tmp, walker - orig, "%s", "unclose bracket\n");
258
268
  }
259
- cjp->inst_lst[cjp->inst_idx - 1].next = 2;
269
+ cjp->inst_lst[inst_idx - 1].next = 2;
260
270
  walker += 2;
261
271
  to_check = *walker;
262
272
  goto again;
@@ -267,14 +277,18 @@ again:
267
277
  struct csonpath_instruction filter_getter[CSONPATH_TMP_BUF_SIZE];
268
278
  struct csonpath_instruction *last_inst;
269
279
  int regex_idx = -1;
270
- int inst;
271
280
  int getter_end = 0;
272
281
  int operand_instruction;
273
282
 
283
+ if (inst == CSONPATH_INST_FIND_ALL) {
284
+ CSONPATH_COMPILE_ERR(tmp, walker - orig, "'%c' is invalide here\n",
285
+ *walker);
286
+ goto error;
287
+ }
274
288
  inst = CSONPATH_INST_GET_OBJ;
275
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
289
+ cjp->inst_lst[inst_idx - 1].next += 1;
276
290
  ++walker;
277
- last_inst = &cjp->inst_lst[cjp->inst_idx - 1];
291
+ last_inst = &cjp->inst_lst[inst_idx - 1];
278
292
  if (*walker == '(') {
279
293
  have_parentesis = 1;
280
294
  ++walker;
@@ -285,9 +299,9 @@ again:
285
299
  } else {
286
300
  CSONPATH_SKIP('.', walker);
287
301
  }
288
- cjp->inst_lst[cjp->inst_idx - 1].next += 3;
302
+ cjp->inst_lst[inst_idx - 1].next += 3;
289
303
  for (; isblank(*walker); ++walker)
290
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
304
+ cjp->inst_lst[inst_idx - 1].next += 1;
291
305
  } else if (*walker == '[') {
292
306
  ++walker;
293
307
  last_inst->next++;
@@ -298,6 +312,7 @@ again:
298
312
  if (getter_end != '\'' && getter_end != '"') {
299
313
  CSONPATH_COMPILE_ERR(tmp, walker - orig,
300
314
  "string require here, got '%c'", getter_end);
315
+ goto error;
301
316
  }
302
317
  last_inst->next += 1;
303
318
  ++walker;
@@ -361,34 +376,34 @@ again:
361
376
  }
362
377
  /* = and == are the same here */
363
378
  if (to_check == '=') {
364
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ);
379
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ, &inst_idx);
365
380
  if (next[0] == '=')
366
381
  ++next;
367
382
  else if (next[0] == '~') {
368
- cjp->inst_lst[cjp->inst_idx - 1].inst = CSONPATH_INST_FILTER_KEY_REG_EQ;
383
+ cjp->inst_lst[inst_idx - 1].inst = CSONPATH_INST_FILTER_KEY_REG_EQ;
369
384
  regex_idx = cjp->regex_cnt++;
370
385
  ++next;
371
386
  }
372
387
  } else if (to_check == '!' && next[0] == '=') {
373
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ);
388
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ, &inst_idx);
374
389
  ++next;
375
390
  } else if (to_check == '>') {
376
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR);
391
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR, &inst_idx);
377
392
  } else if (to_check == '<') {
378
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR);
393
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR, &inst_idx);
379
394
  } else {
380
395
  CSONPATH_COMPILE_ERR(tmp, next - orig,
381
396
  "'%c': unsuported operation", to_check);
382
397
  goto error;
383
398
  }
384
- operand_instruction = cjp->inst_lst[cjp->inst_idx - 1].inst;
399
+ operand_instruction = cjp->inst_lst[inst_idx - 1].inst;
385
400
  for (;isblank(*next); ++next);
386
- cjp->inst_lst[cjp->inst_idx - 1].next = 0;
387
- cjp->inst_lst[cjp->inst_idx - 1].filter_next = cjp->inst_idx + nb_getter_inst;
401
+ cjp->inst_lst[inst_idx - 1].next = 0;
402
+ cjp->inst_lst[inst_idx - 1].filter_next = inst_idx + nb_getter_inst;
388
403
  for (int i = 0; i < nb_getter_inst; ++i) {
389
- csonpath_push_inst_cpy(cjp, filter_getter[i]);
404
+ csonpath_push_inst_cpy(cjp, filter_getter[i], &inst_idx);
390
405
  }
391
- cjp->inst_lst[cjp->inst_idx - 1].next += next - walker;
406
+ cjp->inst_lst[inst_idx - 1].next += next - walker;
392
407
  walker = next;
393
408
  if (*walker == '"' || *walker == '\'' || *walker == '/') {
394
409
  if (operand_instruction == CSONPATH_INST_FILTER_KEY_SUPERIOR ||
@@ -399,8 +414,8 @@ again:
399
414
 
400
415
  char end = *walker;
401
416
  ++walker;
402
- cjp->inst_lst[cjp->inst_idx - 1].next++;
403
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_STR);
417
+ cjp->inst_lst[inst_idx - 1].next++;
418
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_STR, &inst_idx);
404
419
  for (next = walker; *next && *next != end; ++next);
405
420
  if (!*next) {
406
421
  CSONPATH_COMPILE_ERR(tmp, walker - orig,
@@ -413,7 +428,7 @@ again:
413
428
  if (!regex_idx)
414
429
  cjp->regexs = malloc(sizeof *cjp->regexs * 255);
415
430
  int e = regcomp(&cjp->regexs[regex_idx], walker, 0);
416
- cjp->inst_lst[cjp->inst_idx - 1].regex_idx = regex_idx;
431
+ cjp->inst_lst[inst_idx - 1].regex_idx = regex_idx;
417
432
  if (e) {
418
433
  CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error\n");
419
434
  goto error;
@@ -446,7 +461,7 @@ again:
446
461
  to_check = *next;
447
462
  if (n < 100) {
448
463
  *walker = n;
449
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE);
464
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE, &inst_idx);
450
465
  } else {
451
466
  union {
452
467
  int n;
@@ -456,7 +471,7 @@ again:
456
471
  walker[1] = u.c[1];
457
472
  walker[2] = u.c[2];
458
473
  walker[3] = u.c[3];
459
- csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT);
474
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT, &inst_idx);
460
475
  }
461
476
  }
462
477
  if (isblank(to_check)) {
@@ -472,13 +487,19 @@ again:
472
487
  CSONPATH_REQUIRE_ERR(']', next);
473
488
  }
474
489
  /* skip space */
475
- cjp->inst_lst[cjp->inst_idx - 1].next = next - walker + 1;
490
+ cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
476
491
  walker = next + 1;
477
492
  to_check = *walker;
478
493
  goto again;
494
+ /* Filter out */
479
495
  } else if (*walker != '"' && *walker != '\'') {
480
496
  int num;
481
497
 
498
+ if (inst == CSONPATH_INST_FIND_ALL) {
499
+ CSONPATH_COMPILE_ERR(tmp, walker - orig, ".. require string\n");
500
+ goto error;
501
+ }
502
+
482
503
  next = walker;
483
504
  do {
484
505
  if (*next < '0' || *next > '9') {
@@ -494,7 +515,7 @@ again:
494
515
  *next = 0;
495
516
  num = atoi(walker);
496
517
  if (num < 100) {
497
- csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_SMALL);
518
+ csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_SMALL, &inst_idx);
498
519
  *walker = num;
499
520
  } else {
500
521
  union {
@@ -505,15 +526,17 @@ again:
505
526
  walker[1] = u.c[1];
506
527
  walker[2] = u.c[2];
507
528
  walker[3] = u.c[3];
508
- csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG);
529
+ csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG, &inst_idx);
509
530
  }
510
- cjp->inst_lst[cjp->inst_idx - 1].next = next - walker + 1;
531
+ cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
511
532
  walker = next + 1;
512
533
  to_check = *walker;
513
534
  goto again;
514
535
  } else {
515
536
  end = *walker;
516
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
537
+ cjp->inst_lst[inst_idx - 1].next += 1;
538
+ if (inst != CSONPATH_INST_FIND_ALL)
539
+ inst = CSONPATH_INST_GET_OBJ;
517
540
 
518
541
  ++walker;
519
542
  next = walker;
@@ -529,8 +552,8 @@ again:
529
552
  CSONPATH_COMPILE_ERR(tmp, walker - orig,
530
553
  "']' require instead of '%c'\n", *next);
531
554
 
532
- csonpath_push_inst(cjp, CSONPATH_INST_GET_OBJ);
533
- cjp->inst_lst[cjp->inst_idx - 1].next = next - walker + 1;
555
+ csonpath_push_inst(cjp, inst, &inst_idx);
556
+ cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
534
557
 
535
558
  walker = next + 1;
536
559
  to_check = *walker;
@@ -539,20 +562,22 @@ again:
539
562
  }
540
563
  case '.':
541
564
  {
542
- int inst = CSONPATH_INST_GET_OBJ;
565
+ inst = CSONPATH_INST_GET_OBJ;
543
566
 
544
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
567
+ cjp->inst_lst[inst_idx - 1].next += 1;
545
568
  ++walker;
546
569
  if (*walker == '.') {
547
570
  inst = CSONPATH_INST_FIND_ALL;
548
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
571
+ cjp->inst_lst[inst_idx - 1].next += 1;
549
572
  ++walker;
550
573
  } else if (*walker == '*') {
551
574
  inst = CSONPATH_INST_GET_ALL;
552
575
  ++walker;
553
- if (*walker != '.' && *walker != '[' && *walker != '\0')
576
+ if (*walker != '.' && *walker != '[' && *walker != '\0') {
554
577
  CSONPATH_COMPILE_ERR(tmp, walker - orig, "unsuported characters '%c' after '*'", *walker);
555
- csonpath_push_inst(cjp, inst);
578
+ goto error;
579
+ }
580
+ csonpath_push_inst(cjp, inst, &inst_idx);
556
581
  to_check = *walker;
557
582
  goto again;
558
583
  }
@@ -565,25 +590,25 @@ again:
565
590
  to_check = *next;
566
591
  *next = 0;
567
592
 
568
- csonpath_push_inst(cjp, inst);
569
- cjp->inst_lst[cjp->inst_idx - 1].next = next - walker;
593
+ csonpath_push_inst(cjp, inst, &inst_idx);
594
+ cjp->inst_lst[inst_idx - 1].next = next - walker;
570
595
  walker = next;
571
596
  goto again;
572
597
  }
573
598
  case '|':
574
- /* cjp->inst_lst[cjp->inst_idx - 1].next += 1; */
575
- csonpath_push_inst(cjp, CSONPATH_INST_OR);
599
+ /* cjp->inst_lst[inst_idx - 1].next += 1; */
600
+ csonpath_push_inst(cjp, CSONPATH_INST_OR, &inst_idx);
576
601
  ++walker;
577
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
602
+ cjp->inst_lst[inst_idx - 1].next += 1;
578
603
  goto root_again;
579
604
  }
580
605
  if (isblank(*walker)) {
581
- cjp->inst_lst[cjp->inst_idx - 1].next += 1;
606
+ cjp->inst_lst[inst_idx - 1].next += 1;
582
607
  ++walker;
583
608
  goto again;
584
609
  }
585
610
  else if (*walker == 0) {
586
- csonpath_push_inst(cjp, CSONPATH_INST_END);
611
+ csonpath_push_inst(cjp, CSONPATH_INST_END, &inst_idx);
587
612
  cjp->compiled = 1;
588
613
  free(tmp);
589
614
  return 0;
@@ -100,7 +100,8 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
100
100
  PyList_Insert(array, at, el);
101
101
  } else {
102
102
  Py_INCREF(el);
103
- PyList_SetItem(array, at, el);
103
+ if (PyList_SetItem(array, at, el) < 0)
104
+ Py_DECREF(el);
104
105
  }
105
106
  return 1;
106
107
  }
@@ -203,14 +204,6 @@ static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
203
204
  if (!PyArg_ParseTuple(args, "O", &json))
204
205
  BAD_ARG();
205
206
  PyObject *ret = csonpath_find_all(self->cp, json);
206
- if (ret != Py_None) {
207
- PyObject *key_;
208
- Py_ssize_t pos_ = 0;
209
- PyObject *el;
210
- while (PyDict_Next(ret, &pos_, &key_, &el)) {
211
- Py_INCREF(el);
212
- }
213
- }
214
207
  return ret;
215
208
  }
216
209
 
@@ -221,7 +214,6 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
221
214
  if (!PyArg_ParseTuple(args, "O", &json))
222
215
  BAD_ARG();
223
216
  PyObject *ret = csonpath_find_first(self->cp, json);
224
- Py_INCREF(ret);
225
217
  return ret;
226
218
  }
227
219
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "csonpath"
7
- version = "0.5.0"
7
+ version = "0.6.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.5.0"
25
+ current_version = "0.6.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