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.
- {csonpath-0.5.0/csonpath.egg-info → csonpath-0.6.0}/PKG-INFO +57 -3
- {csonpath-0.5.0 → csonpath-0.6.0}/README.md +56 -2
- {csonpath-0.5.0 → csonpath-0.6.0/csonpath.egg-info}/PKG-INFO +57 -3
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath.h +92 -67
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath_python.c +2 -10
- {csonpath-0.5.0 → csonpath-0.6.0}/pyproject.toml +2 -2
- {csonpath-0.5.0 → csonpath-0.6.0}/LICENSE +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/MANIFEST.in +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.5.0 → csonpath-0.6.0}/csonpath_do.h +0 -0
- {csonpath-0.5.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)
|
|
@@ -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
|
-
.
|
|
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
|
-
|
|
193
|
-
|
|
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
|
-
|
|
205
|
-
|
|
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[
|
|
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[
|
|
257
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
253
258
|
++walker;
|
|
254
259
|
if (*walker == '*') {
|
|
255
|
-
|
|
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[
|
|
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[
|
|
289
|
+
cjp->inst_lst[inst_idx - 1].next += 1;
|
|
276
290
|
++walker;
|
|
277
|
-
last_inst = &cjp->inst_lst[
|
|
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[
|
|
302
|
+
cjp->inst_lst[inst_idx - 1].next += 3;
|
|
289
303
|
for (; isblank(*walker); ++walker)
|
|
290
|
-
cjp->inst_lst[
|
|
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[
|
|
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[
|
|
399
|
+
operand_instruction = cjp->inst_lst[inst_idx - 1].inst;
|
|
385
400
|
for (;isblank(*next); ++next);
|
|
386
|
-
cjp->inst_lst[
|
|
387
|
-
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;
|
|
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[
|
|
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[
|
|
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[
|
|
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[
|
|
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[
|
|
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[
|
|
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,
|
|
533
|
-
cjp->inst_lst[
|
|
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
|
-
|
|
565
|
+
inst = CSONPATH_INST_GET_OBJ;
|
|
543
566
|
|
|
544
|
-
cjp->inst_lst[
|
|
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[
|
|
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
|
-
|
|
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[
|
|
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[
|
|
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[
|
|
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[
|
|
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.
|
|
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
|
|
File without changes
|