csonpath 0.3.0__tar.gz → 0.5.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.3.0
3
+ Version: 0.5.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.3.0
3
+ Version: 0.5.0
4
4
  Description-Content-Type: text/markdown
5
5
  License-File: LICENSE
6
6
  Provides-Extra: dev
@@ -34,6 +34,8 @@ enum csonpath_instuction_raw {
34
34
  CSONPATH_INST_GET_OBJ,
35
35
  CSONPATH_INST_GET_ARRAY_SMALL,
36
36
  CSONPATH_INST_GET_ARRAY_BIG,
37
+ CSONPATH_INST_FILTER_KEY_SUPERIOR,
38
+ CSONPATH_INST_FILTER_KEY_INFERIOR,
37
39
  CSONPATH_INST_FILTER_KEY_EQ,
38
40
  CSONPATH_INST_FILTER_KEY_NOT_EQ,
39
41
  CSONPATH_INST_FILTER_KEY_REG_EQ,
@@ -54,6 +56,8 @@ CSONPATH_UNUSED static const char *csonpath_instuction_str[] = {
54
56
  "GET_OBJ",
55
57
  "GET_ARRAY_SMALL",
56
58
  "GET_ARRAY_BIG",
59
+ "FILTER_KEY_SUPERIOR",
60
+ "FILTER_KEY_INFERIOR",
57
61
  "FILTER_KEY_EQ",
58
62
  "FILTER_KEY_NOT_EQ",
59
63
  "FILTER_KEY_REG_EQ",
@@ -265,6 +269,7 @@ again:
265
269
  int regex_idx = -1;
266
270
  int inst;
267
271
  int getter_end = 0;
272
+ int operand_instruction;
268
273
 
269
274
  inst = CSONPATH_INST_GET_OBJ;
270
275
  cjp->inst_lst[cjp->inst_idx - 1].next += 1;
@@ -367,11 +372,16 @@ again:
367
372
  } else if (to_check == '!' && next[0] == '=') {
368
373
  csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ);
369
374
  ++next;
375
+ } else if (to_check == '>') {
376
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR);
377
+ } else if (to_check == '<') {
378
+ csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR);
370
379
  } else {
371
380
  CSONPATH_COMPILE_ERR(tmp, next - orig,
372
381
  "'%c': unsuported operation", to_check);
373
382
  goto error;
374
383
  }
384
+ operand_instruction = cjp->inst_lst[cjp->inst_idx - 1].inst;
375
385
  for (;isblank(*next); ++next);
376
386
  cjp->inst_lst[cjp->inst_idx - 1].next = 0;
377
387
  cjp->inst_lst[cjp->inst_idx - 1].filter_next = cjp->inst_idx + nb_getter_inst;
@@ -381,6 +391,12 @@ again:
381
391
  cjp->inst_lst[cjp->inst_idx - 1].next += next - walker;
382
392
  walker = next;
383
393
  if (*walker == '"' || *walker == '\'' || *walker == '/') {
394
+ if (operand_instruction == CSONPATH_INST_FILTER_KEY_SUPERIOR ||
395
+ operand_instruction == CSONPATH_INST_FILTER_KEY_INFERIOR) {
396
+ CSONPATH_COMPILE_ERR(tmp, walker - orig, "string unsuported here");
397
+ goto error;
398
+ }
399
+
384
400
  char end = *walker;
385
401
  ++walker;
386
402
  cjp->inst_lst[cjp->inst_idx - 1].next++;
@@ -409,29 +425,39 @@ again:
409
425
  } else {
410
426
  int n;
411
427
 
428
+ if (operand_instruction == CSONPATH_INST_FILTER_KEY_REG_EQ) {
429
+ CSONPATH_COMPILE_ERR(tmp, walker - orig, "number unsuported for regex");
430
+ goto error;
431
+ }
432
+
412
433
  for (next = walker; isdigit(*next); ++next);
413
434
  if (next == walker) {
414
435
  CSONPATH_COMPILE_ERR(tmp, walker - orig,
415
436
  "'%c': broken filter with number",
416
437
  *walker);
417
438
  goto error;
439
+ } else if (!*next) {
440
+ CSONPATH_COMPILE_ERR(tmp, walker - orig,
441
+ "unclose filter");
442
+ goto error;
418
443
  }
444
+
419
445
  n = atoi(walker);
446
+ to_check = *next;
420
447
  if (n < 100) {
421
448
  *walker = n;
422
449
  csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE);
423
450
  } else {
424
- MAY_ALIAS int *walk_int = (void *)walker;
425
- *walk_int = n;
451
+ union {
452
+ int n;
453
+ char c[4];
454
+ } u = {.n=n};
455
+ walker[0] = u.c[0];
456
+ walker[1] = u.c[1];
457
+ walker[2] = u.c[2];
458
+ walker[3] = u.c[3];
426
459
  csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT);
427
460
  }
428
- if (!*next) {
429
- CSONPATH_COMPILE_ERR(tmp, walker - orig,
430
- "compilation error");
431
- goto error;
432
- }
433
- to_check = *next;
434
- *next = 0;
435
461
  }
436
462
  if (isblank(to_check)) {
437
463
  for (next++; isblank(*next); ++next);
@@ -570,6 +596,37 @@ again:
570
596
  return -1;
571
597
  }
572
598
 
599
+ static int csonpath_int_from_walker(int operand_instruction, char *walker)
600
+ {
601
+ if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_BYTE)
602
+ return *walker;
603
+ else if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_INT) {
604
+ union {int n; char c[4];} to_num =
605
+ { .c= { walker[0], walker[1], walker[2], walker[3] } };
606
+
607
+ return to_num.n;
608
+ }
609
+ return -1;
610
+ }
611
+
612
+ static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char *owalker)
613
+ {
614
+ switch (operand_instruction) {
615
+ case CSONPATH_INST_FILTER_OPERAND_STR:
616
+ return CSONPATH_EQUAL_STR(el2, owalker);
617
+ case CSONPATH_INST_FILTER_OPERAND_BYTE:
618
+ return CSONPATH_EQUAL_NUM(el2, *owalker);
619
+ case CSONPATH_INST_FILTER_OPERAND_INT:
620
+ {
621
+ union {int n; char c[4];} to_num =
622
+ { .c= { owalker[0], owalker[1], owalker[2], owalker[3] } };
623
+
624
+ return CSONPATH_EQUAL_NUM(el2, to_num.n);
625
+ }
626
+ }
627
+ return 0;
628
+ }
629
+
573
630
  /* helper use multiple times */
574
631
  #define CSONPATH_DO_GET_NOTFOUND_UPDATER(this_idx) \
575
632
  do { \
@@ -723,7 +780,7 @@ again:
723
780
  int nb_res = 0;
724
781
 
725
782
  #define CSONPATH_DO_RET_TYPE int
726
- #define CSONPATH_DO_FUNC_NAME update_or_ceate
783
+ #define CSONPATH_DO_FUNC_NAME update_or_create
727
784
 
728
785
  /*
729
786
  * assuming tmp == value can only be true,
@@ -813,7 +870,7 @@ again:
813
870
  int nb_res = 0;
814
871
 
815
872
  #define CSONPATH_DO_RET_TYPE int
816
- #define CSONPATH_DO_FUNC_NAME update_or_ceate_callback
873
+ #define CSONPATH_DO_FUNC_NAME update_or_create_callback
817
874
  #define CSONPATH_DO_RETURN \
818
875
  if (tmp == value) { \
819
876
  *need_reloop = 1; \
@@ -163,12 +163,15 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
163
163
  case CSONPATH_INST_FILTER_KEY_EQ:
164
164
  case CSONPATH_INST_FILTER_KEY_REG_EQ:
165
165
  case CSONPATH_INST_FILTER_KEY_NOT_EQ:
166
+ case CSONPATH_INST_FILTER_KEY_SUPERIOR:
167
+ case CSONPATH_INST_FILTER_KEY_INFERIOR:
166
168
  {
167
169
  CSONPATH_JSON el;
168
170
  int operation = cjp->inst_lst[idx].inst;
169
171
  walker += cjp->inst_lst[idx].next;
170
172
  char *owalker;
171
173
  int filter_next = cjp->inst_lst[idx].filter_next;
174
+ int operand_instruction = -1;
172
175
  int in_idx = idx + 1;
173
176
 
174
177
  CSONPATH_DO_FILTER_PRE_LOOP;
@@ -189,18 +192,31 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
189
192
  }
190
193
  owalker += cjp->inst_lst[idx].next;
191
194
  }
192
-
193
- if (cjp->inst_lst[idx].inst != CSONPATH_INST_FILTER_OPERAND_STR)
194
- CSONPATH_GETTER_ERR("unsuported instruction '%s' only FILTER_OPERAND_STR is supported here", csonpath_instuction_str[(int)cjp->inst_lst[idx].inst]);
195
+
196
+ if (operand_instruction < 0) {
197
+ operand_instruction = cjp->inst_lst[idx].inst;
198
+ }
195
199
 
196
200
  if (el2 != CSONPATH_NULL) {
197
201
  _Bool match = 0;
198
202
  switch (operation) {
199
203
  case CSONPATH_INST_FILTER_KEY_NOT_EQ:
200
- match = !CSONPATH_EQUAL_STR(el2, owalker);
204
+ match = !csonpath_do_match(operand_instruction, el2, owalker);
201
205
  break;
202
206
  case CSONPATH_INST_FILTER_KEY_EQ:
203
- match = CSONPATH_EQUAL_STR(el2, owalker);
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);
204
220
  break;
205
221
  case CSONPATH_INST_FILTER_KEY_REG_EQ:
206
222
  #ifdef CSONPATH_NO_REGEX
@@ -299,7 +315,10 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
299
315
  break;
300
316
  }
301
317
  default:
302
- CSONPATH_GETTER_ERR("unimplemented %d at idx %d\n", cjp->inst_lst[idx].inst, idx);
318
+ CSONPATH_GETTER_ERR("unimplemented %d (%s) at idx %d\n", cjp->inst_lst[idx].inst,
319
+ cjp->inst_lst[idx].inst <= CSONPATH_INST_BROKEN ?
320
+ csonpath_instuction_str[cjp->inst_lst[idx].inst] : "(unknow)",
321
+ idx);
303
322
  }
304
323
  next_inst:
305
324
  ++idx;
@@ -20,9 +20,23 @@
20
20
 
21
21
  #define CSONPATH_IS_STR(o) PyUnicode_Check(o)
22
22
 
23
+ #define CSONPATH_IS_NUM(o) PyLong_Check(o)
24
+
23
25
  #define CSONPATH_GET_STR(obj) \
24
26
  PyUnicode_AsUTF8(obj)
25
27
 
28
+ #define CSONPATH_GET_NUM(obj) \
29
+ PyLong_AsLong(obj)
30
+
31
+ #define CSONPATH_EQUAL_NUM(obj, to_cmp) \
32
+ ({ \
33
+ _Bool r = 0; \
34
+ if (PyLong_Check(obj)) { \
35
+ r = PyLong_AsLong(obj) == to_cmp; \
36
+ } \
37
+ r; \
38
+ })
39
+
26
40
  #define CSONPATH_EQUAL_STR(obj, to_cmp) ({ \
27
41
  _Bool r = 0; \
28
42
  if (PyUnicode_Check(obj)) { \
@@ -78,7 +92,11 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
78
92
  PyErr_Format(PyExc_ValueError, "Unable to follow path: List expected");
79
93
  return -1;
80
94
  }
81
- if (at >= PyList_Size(array)) {
95
+ Py_ssize_t s = PyList_Size(array);
96
+ if (at >= s) {
97
+ for (;s < at; ++s)
98
+ PyList_Insert(array, s, Py_None);
99
+
82
100
  PyList_Insert(array, at, el);
83
101
  } else {
84
102
  Py_INCREF(el);
@@ -234,7 +252,7 @@ static PyObject *update_or_create(PyCsonPathObject *self, PyObject* args)
234
252
 
235
253
  if (!PyArg_ParseTuple(args, "OO", &json, &value))
236
254
  BAD_ARG();
237
- int ret = csonpath_update_or_ceate(self->cp, json, value);
255
+ int ret = csonpath_update_or_create(self->cp, json, value);
238
256
  if (ret < 0)
239
257
  return NULL;
240
258
  return PyLong_FromLong(ret);
@@ -246,7 +264,7 @@ static PyObject *update_or_create_callback(PyCsonPathObject *self, PyObject* arg
246
264
 
247
265
  if (!PyArg_ParseTuple(args, "OO|O", &json, &callback, &udata))
248
266
  BAD_ARG();
249
- int ret = csonpath_update_or_ceate_callback(self->cp, json, callback, udata);
267
+ int ret = csonpath_update_or_create_callback(self->cp, json, callback, udata);
250
268
  return PyLong_FromLong(ret);
251
269
  }
252
270
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "csonpath"
7
- version = "0.3.0"
7
+ version = "0.5.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.3.0"
25
+ current_version = "0.5.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