csonpath 0.4.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.
- {csonpath-0.4.0/csonpath.egg-info → csonpath-0.6.0}/PKG-INFO +57 -3
- {csonpath-0.4.0 → csonpath-0.6.0}/README.md +56 -2
- {csonpath-0.4.0 → csonpath-0.6.0/csonpath.egg-info}/PKG-INFO +57 -3
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath.h +155 -73
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath_do.h +25 -6
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath_python.c +17 -11
- {csonpath-0.4.0 → csonpath-0.6.0}/pyproject.toml +2 -2
- {csonpath-0.4.0 → csonpath-0.6.0}/LICENSE +0 -0
- {csonpath-0.4.0 → csonpath-0.6.0}/MANIFEST.in +0 -0
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.4.0 → csonpath-0.6.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.4.0 → csonpath-0.6.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.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
|
|
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
|
|
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.
|
|
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
|
|
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)
|
|
@@ -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",
|
|
@@ -82,15 +86,11 @@ struct csonpath_instruction {
|
|
|
82
86
|
short int next;
|
|
83
87
|
};
|
|
84
88
|
|
|
85
|
-
#define CSONPATH_INST_MIN_ALLOC (1 << 7)
|
|
86
|
-
|
|
87
89
|
struct csonpath {
|
|
88
|
-
char *path;
|
|
89
90
|
char *compile_error;
|
|
91
|
+
char *path;
|
|
90
92
|
struct csonpath_instruction *inst_lst;
|
|
91
93
|
int compiled;
|
|
92
|
-
int inst_idx;
|
|
93
|
-
int inst_size;
|
|
94
94
|
#ifndef CSONPATH_NO_REGEX
|
|
95
95
|
int regex_cnt;
|
|
96
96
|
regex_t *regexs;
|
|
@@ -165,11 +165,26 @@ static inline void csonpath_destroy(struct csonpath cjp[static 1])
|
|
|
165
165
|
*cjp = (struct csonpath){};
|
|
166
166
|
}
|
|
167
167
|
|
|
168
|
+
static _Bool csonpath_is_one_char_instruction(int c)
|
|
169
|
+
{
|
|
170
|
+
return c == '|' || c == '$';
|
|
171
|
+
}
|
|
172
|
+
|
|
168
173
|
static inline int csonpath_init(struct csonpath cjp[static 1],
|
|
169
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
|
+
}
|
|
170
186
|
*cjp = (struct csonpath) {.path=strdup(path),
|
|
171
|
-
.
|
|
172
|
-
.inst_lst = malloc(sizeof(*cjp->inst_lst) * CSONPATH_INST_MIN_ALLOC)};
|
|
187
|
+
.inst_lst = malloc(sizeof(*cjp->inst_lst) * max_inst)};
|
|
173
188
|
if (!cjp->path || !cjp->inst_lst) {
|
|
174
189
|
return -ENOMEM;
|
|
175
190
|
}
|
|
@@ -183,27 +198,18 @@ static inline int csonpath_set_path(struct csonpath cjp[static 1],
|
|
|
183
198
|
return csonpath_init(cjp, path);
|
|
184
199
|
}
|
|
185
200
|
|
|
186
|
-
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)
|
|
187
202
|
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
cjp->inst_lst = realloc(cjp->inst_lst, cjp->inst_size);
|
|
191
|
-
assert(cjp->inst_lst);
|
|
192
|
-
}
|
|
193
|
-
cjp->inst_lst[cjp->inst_idx] = (struct csonpath_instruction){.inst=inst};
|
|
194
|
-
++cjp->inst_idx;
|
|
203
|
+
cjp->inst_lst[*inst_idx] = (struct csonpath_instruction){.inst=inst};
|
|
204
|
+
*inst_idx += 1;
|
|
195
205
|
}
|
|
196
206
|
|
|
197
207
|
static inline void csonpath_push_inst_cpy(struct csonpath cjp[static 1],
|
|
198
|
-
struct csonpath_instruction inst
|
|
208
|
+
const struct csonpath_instruction inst,
|
|
209
|
+
int *inst_idx)
|
|
199
210
|
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
cjp->inst_lst = realloc(cjp->inst_lst, cjp->inst_size);
|
|
203
|
-
assert(cjp->inst_lst);
|
|
204
|
-
}
|
|
205
|
-
cjp->inst_lst[cjp->inst_idx] = inst;
|
|
206
|
-
++cjp->inst_idx;
|
|
211
|
+
cjp->inst_lst[*inst_idx] = inst;
|
|
212
|
+
*inst_idx += 1;
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
static void csonpath_print_instruction(struct csonpath cjp[static 1])
|
|
@@ -226,7 +232,9 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
226
232
|
char *orig = walker;
|
|
227
233
|
char *next;
|
|
228
234
|
char to_check;
|
|
235
|
+
int inst_idx = 0;
|
|
229
236
|
char *tmp; /* tmp is only here for debug */
|
|
237
|
+
int inst;
|
|
230
238
|
|
|
231
239
|
if (cjp->compiled)
|
|
232
240
|
return 0;
|
|
@@ -234,8 +242,8 @@ static int csonpath_compile(struct csonpath cjp[static 1])
|
|
|
234
242
|
tmp = strdup(cjp->path);
|
|
235
243
|
root_again:
|
|
236
244
|
CSONPATH_SKIP('$', walker);
|
|
237
|
-
csonpath_push_inst(cjp, CSONPATH_INST_ROOT);
|
|
238
|
-
cjp->inst_lst[
|
|
245
|
+
csonpath_push_inst(cjp, CSONPATH_INST_ROOT, &inst_idx);
|
|
246
|
+
cjp->inst_lst[inst_idx - 1].next = 1;
|
|
239
247
|
to_check = *walker;
|
|
240
248
|
|
|
241
249
|
again:
|
|
@@ -244,15 +252,21 @@ again:
|
|
|
244
252
|
{
|
|
245
253
|
int end;
|
|
246
254
|
|
|
255
|
+
inst = 0;
|
|
247
256
|
do_array:
|
|
248
|
-
cjp->inst_lst[
|
|
257
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
249
258
|
++walker;
|
|
250
259
|
if (*walker == '*') {
|
|
251
|
-
|
|
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);
|
|
252
266
|
if (walker[1] != ']') {
|
|
253
267
|
CSONPATH_COMPILE_ERR(tmp, walker - orig, "%s", "unclose bracket\n");
|
|
254
268
|
}
|
|
255
|
-
cjp->inst_lst[
|
|
269
|
+
cjp->inst_lst[inst_idx - 1].next = 2;
|
|
256
270
|
walker += 2;
|
|
257
271
|
to_check = *walker;
|
|
258
272
|
goto again;
|
|
@@ -263,13 +277,18 @@ again:
|
|
|
263
277
|
struct csonpath_instruction filter_getter[CSONPATH_TMP_BUF_SIZE];
|
|
264
278
|
struct csonpath_instruction *last_inst;
|
|
265
279
|
int regex_idx = -1;
|
|
266
|
-
int inst;
|
|
267
280
|
int getter_end = 0;
|
|
281
|
+
int operand_instruction;
|
|
268
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
|
+
}
|
|
269
288
|
inst = CSONPATH_INST_GET_OBJ;
|
|
270
|
-
cjp->inst_lst[
|
|
289
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
271
290
|
++walker;
|
|
272
|
-
last_inst = &cjp->inst_lst[
|
|
291
|
+
last_inst = &cjp->inst_lst[inst_idx - 1];
|
|
273
292
|
if (*walker == '(') {
|
|
274
293
|
have_parentesis = 1;
|
|
275
294
|
++walker;
|
|
@@ -280,9 +299,9 @@ again:
|
|
|
280
299
|
} else {
|
|
281
300
|
CSONPATH_SKIP('.', walker);
|
|
282
301
|
}
|
|
283
|
-
cjp->inst_lst[
|
|
302
|
+
cjp->inst_lst[inst_idx - 1].next += 3;
|
|
284
303
|
for (; isblank(*walker); ++walker)
|
|
285
|
-
cjp->inst_lst[
|
|
304
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
286
305
|
} else if (*walker == '[') {
|
|
287
306
|
++walker;
|
|
288
307
|
last_inst->next++;
|
|
@@ -293,6 +312,7 @@ again:
|
|
|
293
312
|
if (getter_end != '\'' && getter_end != '"') {
|
|
294
313
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
295
314
|
"string require here, got '%c'", getter_end);
|
|
315
|
+
goto error;
|
|
296
316
|
}
|
|
297
317
|
last_inst->next += 1;
|
|
298
318
|
++walker;
|
|
@@ -356,35 +376,46 @@ again:
|
|
|
356
376
|
}
|
|
357
377
|
/* = and == are the same here */
|
|
358
378
|
if (to_check == '=') {
|
|
359
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ);
|
|
379
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_EQ, &inst_idx);
|
|
360
380
|
if (next[0] == '=')
|
|
361
381
|
++next;
|
|
362
382
|
else if (next[0] == '~') {
|
|
363
|
-
cjp->inst_lst[
|
|
383
|
+
cjp->inst_lst[inst_idx - 1].inst = CSONPATH_INST_FILTER_KEY_REG_EQ;
|
|
364
384
|
regex_idx = cjp->regex_cnt++;
|
|
365
385
|
++next;
|
|
366
386
|
}
|
|
367
387
|
} else if (to_check == '!' && next[0] == '=') {
|
|
368
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ);
|
|
388
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_NOT_EQ, &inst_idx);
|
|
369
389
|
++next;
|
|
390
|
+
} else if (to_check == '>') {
|
|
391
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_SUPERIOR, &inst_idx);
|
|
392
|
+
} else if (to_check == '<') {
|
|
393
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_KEY_INFERIOR, &inst_idx);
|
|
370
394
|
} else {
|
|
371
395
|
CSONPATH_COMPILE_ERR(tmp, next - orig,
|
|
372
396
|
"'%c': unsuported operation", to_check);
|
|
373
397
|
goto error;
|
|
374
398
|
}
|
|
399
|
+
operand_instruction = cjp->inst_lst[inst_idx - 1].inst;
|
|
375
400
|
for (;isblank(*next); ++next);
|
|
376
|
-
cjp->inst_lst[
|
|
377
|
-
cjp->inst_lst[
|
|
401
|
+
cjp->inst_lst[inst_idx - 1].next = 0;
|
|
402
|
+
cjp->inst_lst[inst_idx - 1].filter_next = inst_idx + nb_getter_inst;
|
|
378
403
|
for (int i = 0; i < nb_getter_inst; ++i) {
|
|
379
|
-
csonpath_push_inst_cpy(cjp, filter_getter[i]);
|
|
404
|
+
csonpath_push_inst_cpy(cjp, filter_getter[i], &inst_idx);
|
|
380
405
|
}
|
|
381
|
-
cjp->inst_lst[
|
|
406
|
+
cjp->inst_lst[inst_idx - 1].next += next - walker;
|
|
382
407
|
walker = next;
|
|
383
408
|
if (*walker == '"' || *walker == '\'' || *walker == '/') {
|
|
409
|
+
if (operand_instruction == CSONPATH_INST_FILTER_KEY_SUPERIOR ||
|
|
410
|
+
operand_instruction == CSONPATH_INST_FILTER_KEY_INFERIOR) {
|
|
411
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "string unsuported here");
|
|
412
|
+
goto error;
|
|
413
|
+
}
|
|
414
|
+
|
|
384
415
|
char end = *walker;
|
|
385
416
|
++walker;
|
|
386
|
-
cjp->inst_lst[
|
|
387
|
-
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);
|
|
388
419
|
for (next = walker; *next && *next != end; ++next);
|
|
389
420
|
if (!*next) {
|
|
390
421
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
@@ -397,7 +428,7 @@ again:
|
|
|
397
428
|
if (!regex_idx)
|
|
398
429
|
cjp->regexs = malloc(sizeof *cjp->regexs * 255);
|
|
399
430
|
int e = regcomp(&cjp->regexs[regex_idx], walker, 0);
|
|
400
|
-
cjp->inst_lst[
|
|
431
|
+
cjp->inst_lst[inst_idx - 1].regex_idx = regex_idx;
|
|
401
432
|
if (e) {
|
|
402
433
|
CSONPATH_COMPILE_ERR(tmp, next - orig, "regex has error\n");
|
|
403
434
|
goto error;
|
|
@@ -409,29 +440,39 @@ again:
|
|
|
409
440
|
} else {
|
|
410
441
|
int n;
|
|
411
442
|
|
|
443
|
+
if (operand_instruction == CSONPATH_INST_FILTER_KEY_REG_EQ) {
|
|
444
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "number unsuported for regex");
|
|
445
|
+
goto error;
|
|
446
|
+
}
|
|
447
|
+
|
|
412
448
|
for (next = walker; isdigit(*next); ++next);
|
|
413
449
|
if (next == walker) {
|
|
414
450
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
415
451
|
"'%c': broken filter with number",
|
|
416
452
|
*walker);
|
|
417
453
|
goto error;
|
|
454
|
+
} else if (!*next) {
|
|
455
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
456
|
+
"unclose filter");
|
|
457
|
+
goto error;
|
|
418
458
|
}
|
|
459
|
+
|
|
419
460
|
n = atoi(walker);
|
|
461
|
+
to_check = *next;
|
|
420
462
|
if (n < 100) {
|
|
421
463
|
*walker = n;
|
|
422
|
-
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE);
|
|
464
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_BYTE, &inst_idx);
|
|
423
465
|
} else {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
466
|
+
union {
|
|
467
|
+
int n;
|
|
468
|
+
char c[4];
|
|
469
|
+
} u = {.n=n};
|
|
470
|
+
walker[0] = u.c[0];
|
|
471
|
+
walker[1] = u.c[1];
|
|
472
|
+
walker[2] = u.c[2];
|
|
473
|
+
walker[3] = u.c[3];
|
|
474
|
+
csonpath_push_inst(cjp, CSONPATH_INST_FILTER_OPERAND_INT, &inst_idx);
|
|
432
475
|
}
|
|
433
|
-
to_check = *next;
|
|
434
|
-
*next = 0;
|
|
435
476
|
}
|
|
436
477
|
if (isblank(to_check)) {
|
|
437
478
|
for (next++; isblank(*next); ++next);
|
|
@@ -446,13 +487,19 @@ again:
|
|
|
446
487
|
CSONPATH_REQUIRE_ERR(']', next);
|
|
447
488
|
}
|
|
448
489
|
/* skip space */
|
|
449
|
-
cjp->inst_lst[
|
|
490
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
450
491
|
walker = next + 1;
|
|
451
492
|
to_check = *walker;
|
|
452
493
|
goto again;
|
|
494
|
+
/* Filter out */
|
|
453
495
|
} else if (*walker != '"' && *walker != '\'') {
|
|
454
496
|
int num;
|
|
455
497
|
|
|
498
|
+
if (inst == CSONPATH_INST_FIND_ALL) {
|
|
499
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, ".. require string\n");
|
|
500
|
+
goto error;
|
|
501
|
+
}
|
|
502
|
+
|
|
456
503
|
next = walker;
|
|
457
504
|
do {
|
|
458
505
|
if (*next < '0' || *next > '9') {
|
|
@@ -468,7 +515,7 @@ again:
|
|
|
468
515
|
*next = 0;
|
|
469
516
|
num = atoi(walker);
|
|
470
517
|
if (num < 100) {
|
|
471
|
-
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_SMALL);
|
|
518
|
+
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_SMALL, &inst_idx);
|
|
472
519
|
*walker = num;
|
|
473
520
|
} else {
|
|
474
521
|
union {
|
|
@@ -479,15 +526,17 @@ again:
|
|
|
479
526
|
walker[1] = u.c[1];
|
|
480
527
|
walker[2] = u.c[2];
|
|
481
528
|
walker[3] = u.c[3];
|
|
482
|
-
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG);
|
|
529
|
+
csonpath_push_inst(cjp, CSONPATH_INST_GET_ARRAY_BIG, &inst_idx);
|
|
483
530
|
}
|
|
484
|
-
cjp->inst_lst[
|
|
531
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
485
532
|
walker = next + 1;
|
|
486
533
|
to_check = *walker;
|
|
487
534
|
goto again;
|
|
488
535
|
} else {
|
|
489
536
|
end = *walker;
|
|
490
|
-
cjp->inst_lst[
|
|
537
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
538
|
+
if (inst != CSONPATH_INST_FIND_ALL)
|
|
539
|
+
inst = CSONPATH_INST_GET_OBJ;
|
|
491
540
|
|
|
492
541
|
++walker;
|
|
493
542
|
next = walker;
|
|
@@ -503,8 +552,8 @@ again:
|
|
|
503
552
|
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
504
553
|
"']' require instead of '%c'\n", *next);
|
|
505
554
|
|
|
506
|
-
csonpath_push_inst(cjp,
|
|
507
|
-
cjp->inst_lst[
|
|
555
|
+
csonpath_push_inst(cjp, inst, &inst_idx);
|
|
556
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker + 1;
|
|
508
557
|
|
|
509
558
|
walker = next + 1;
|
|
510
559
|
to_check = *walker;
|
|
@@ -513,20 +562,22 @@ again:
|
|
|
513
562
|
}
|
|
514
563
|
case '.':
|
|
515
564
|
{
|
|
516
|
-
|
|
565
|
+
inst = CSONPATH_INST_GET_OBJ;
|
|
517
566
|
|
|
518
|
-
cjp->inst_lst[
|
|
567
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
519
568
|
++walker;
|
|
520
569
|
if (*walker == '.') {
|
|
521
570
|
inst = CSONPATH_INST_FIND_ALL;
|
|
522
|
-
cjp->inst_lst[
|
|
571
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
523
572
|
++walker;
|
|
524
573
|
} else if (*walker == '*') {
|
|
525
574
|
inst = CSONPATH_INST_GET_ALL;
|
|
526
575
|
++walker;
|
|
527
|
-
if (*walker != '.' && *walker != '[' && *walker != '\0')
|
|
576
|
+
if (*walker != '.' && *walker != '[' && *walker != '\0') {
|
|
528
577
|
CSONPATH_COMPILE_ERR(tmp, walker - orig, "unsuported characters '%c' after '*'", *walker);
|
|
529
|
-
|
|
578
|
+
goto error;
|
|
579
|
+
}
|
|
580
|
+
csonpath_push_inst(cjp, inst, &inst_idx);
|
|
530
581
|
to_check = *walker;
|
|
531
582
|
goto again;
|
|
532
583
|
}
|
|
@@ -539,25 +590,25 @@ again:
|
|
|
539
590
|
to_check = *next;
|
|
540
591
|
*next = 0;
|
|
541
592
|
|
|
542
|
-
csonpath_push_inst(cjp, inst);
|
|
543
|
-
cjp->inst_lst[
|
|
593
|
+
csonpath_push_inst(cjp, inst, &inst_idx);
|
|
594
|
+
cjp->inst_lst[inst_idx - 1].next = next - walker;
|
|
544
595
|
walker = next;
|
|
545
596
|
goto again;
|
|
546
597
|
}
|
|
547
598
|
case '|':
|
|
548
|
-
/* cjp->inst_lst[
|
|
549
|
-
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);
|
|
550
601
|
++walker;
|
|
551
|
-
cjp->inst_lst[
|
|
602
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
552
603
|
goto root_again;
|
|
553
604
|
}
|
|
554
605
|
if (isblank(*walker)) {
|
|
555
|
-
cjp->inst_lst[
|
|
606
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
556
607
|
++walker;
|
|
557
608
|
goto again;
|
|
558
609
|
}
|
|
559
610
|
else if (*walker == 0) {
|
|
560
|
-
csonpath_push_inst(cjp, CSONPATH_INST_END);
|
|
611
|
+
csonpath_push_inst(cjp, CSONPATH_INST_END, &inst_idx);
|
|
561
612
|
cjp->compiled = 1;
|
|
562
613
|
free(tmp);
|
|
563
614
|
return 0;
|
|
@@ -570,6 +621,37 @@ again:
|
|
|
570
621
|
return -1;
|
|
571
622
|
}
|
|
572
623
|
|
|
624
|
+
static int csonpath_int_from_walker(int operand_instruction, char *walker)
|
|
625
|
+
{
|
|
626
|
+
if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_BYTE)
|
|
627
|
+
return *walker;
|
|
628
|
+
else if (operand_instruction == CSONPATH_INST_FILTER_OPERAND_INT) {
|
|
629
|
+
union {int n; char c[4];} to_num =
|
|
630
|
+
{ .c= { walker[0], walker[1], walker[2], walker[3] } };
|
|
631
|
+
|
|
632
|
+
return to_num.n;
|
|
633
|
+
}
|
|
634
|
+
return -1;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
static _Bool csonpath_do_match(int operand_instruction, CSONPATH_JSON el2, char *owalker)
|
|
638
|
+
{
|
|
639
|
+
switch (operand_instruction) {
|
|
640
|
+
case CSONPATH_INST_FILTER_OPERAND_STR:
|
|
641
|
+
return CSONPATH_EQUAL_STR(el2, owalker);
|
|
642
|
+
case CSONPATH_INST_FILTER_OPERAND_BYTE:
|
|
643
|
+
return CSONPATH_EQUAL_NUM(el2, *owalker);
|
|
644
|
+
case CSONPATH_INST_FILTER_OPERAND_INT:
|
|
645
|
+
{
|
|
646
|
+
union {int n; char c[4];} to_num =
|
|
647
|
+
{ .c= { owalker[0], owalker[1], owalker[2], owalker[3] } };
|
|
648
|
+
|
|
649
|
+
return CSONPATH_EQUAL_NUM(el2, to_num.n);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return 0;
|
|
653
|
+
}
|
|
654
|
+
|
|
573
655
|
/* helper use multiple times */
|
|
574
656
|
#define CSONPATH_DO_GET_NOTFOUND_UPDATER(this_idx) \
|
|
575
657
|
do { \
|
|
@@ -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 (
|
|
194
|
-
|
|
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 = !
|
|
204
|
+
match = !csonpath_do_match(operand_instruction, el2, owalker);
|
|
201
205
|
break;
|
|
202
206
|
case CSONPATH_INST_FILTER_KEY_EQ:
|
|
203
|
-
match =
|
|
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,
|
|
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,7 @@ 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
|
-
|
|
95
|
+
Py_ssize_t s = PyList_Size(array);
|
|
82
96
|
if (at >= s) {
|
|
83
97
|
for (;s < at; ++s)
|
|
84
98
|
PyList_Insert(array, s, Py_None);
|
|
@@ -86,7 +100,8 @@ static int python_set_or_insert_item(PyObject *array, Py_ssize_t at, PyObject *
|
|
|
86
100
|
PyList_Insert(array, at, el);
|
|
87
101
|
} else {
|
|
88
102
|
Py_INCREF(el);
|
|
89
|
-
PyList_SetItem(array, at, el)
|
|
103
|
+
if (PyList_SetItem(array, at, el) < 0)
|
|
104
|
+
Py_DECREF(el);
|
|
90
105
|
}
|
|
91
106
|
return 1;
|
|
92
107
|
}
|
|
@@ -189,14 +204,6 @@ static PyObject *find_all(PyCsonPathObject *self, PyObject* args)
|
|
|
189
204
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
190
205
|
BAD_ARG();
|
|
191
206
|
PyObject *ret = csonpath_find_all(self->cp, json);
|
|
192
|
-
if (ret != Py_None) {
|
|
193
|
-
PyObject *key_;
|
|
194
|
-
Py_ssize_t pos_ = 0;
|
|
195
|
-
PyObject *el;
|
|
196
|
-
while (PyDict_Next(ret, &pos_, &key_, &el)) {
|
|
197
|
-
Py_INCREF(el);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
207
|
return ret;
|
|
201
208
|
}
|
|
202
209
|
|
|
@@ -207,7 +214,6 @@ static PyObject *find_first(PyCsonPathObject *self, PyObject* args)
|
|
|
207
214
|
if (!PyArg_ParseTuple(args, "O", &json))
|
|
208
215
|
BAD_ARG();
|
|
209
216
|
PyObject *ret = csonpath_find_first(self->cp, json);
|
|
210
|
-
Py_INCREF(ret);
|
|
211
217
|
return ret;
|
|
212
218
|
}
|
|
213
219
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "csonpath"
|
|
7
|
-
version = "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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|