csonpath 0.0.1__tar.gz → 0.0.3__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.0.3/PKG-INFO +126 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/README.md +13 -2
- csonpath-0.0.3/csonpath.egg-info/PKG-INFO +126 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath.h +63 -22
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath_do.h +4 -4
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath_python.c +3 -1
- {csonpath-0.0.1 → csonpath-0.0.3}/pyproject.toml +2 -1
- csonpath-0.0.1/PKG-INFO +0 -7
- csonpath-0.0.1/csonpath.egg-info/PKG-INFO +0 -7
- {csonpath-0.0.1 → csonpath-0.0.3}/LICENSE +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/MANIFEST.in +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath.egg-info/SOURCES.txt +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.0.1 → csonpath-0.0.3}/setup.cfg +0 -0
csonpath-0.0.3/PKG-INFO
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: csonpath
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Description-Content-Type: text/markdown
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Provides-Extra: dev
|
|
7
|
+
Requires-Dist: pytest>=8.3.5; extra == "dev"
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+
# csonpath
|
|
11
|
+
|
|
12
|
+
> that's not my path, that's not your path, but csonpath
|
|
13
|
+
|
|
14
|
+
[](https://docs.outscale.com/en/userguide/Open-Source-Projects.html)
|
|
15
|
+
|
|
16
|
+
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C, with Python bindings. It allows you to query, update, and remove data from JSON objects using path expressions.
|
|
17
|
+
|
|
18
|
+
## 🌐 Links
|
|
19
|
+
|
|
20
|
+
- Project website: https://github.com/outscale/csonpath
|
|
21
|
+
- Join our community on [Discord](https://discord.gg/HUVtY5gT6s)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## 📄 Table of Contents
|
|
25
|
+
|
|
26
|
+
- [Overview](#-overview)
|
|
27
|
+
- [Requirements](#-requirements)
|
|
28
|
+
- [Installation](#-installation)
|
|
29
|
+
- [Configuration](#-configuration)
|
|
30
|
+
- [Usage](#-usage)
|
|
31
|
+
- [Examples](#-examples)
|
|
32
|
+
- [License](#-license)
|
|
33
|
+
- [Contributing](#-contributing)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## 🚀 Features
|
|
37
|
+
|
|
38
|
+
- **Find First**: Retrieve the first value matching a path.
|
|
39
|
+
- **Find All**: Retrieve all values matching a path.
|
|
40
|
+
- **Update or Create**: Update values or create new ones according to the path.
|
|
41
|
+
- **Remove**: Remove values matching a path.
|
|
42
|
+
- **Update or Create Callback**: Update values or create new ones according to the path, using a user-define callback.
|
|
43
|
+
- **Callback**: Call a callback according to the path.
|
|
44
|
+
- **Supports both C (using json-c) and Python objects.**
|
|
45
|
+
|
|
46
|
+
## ✅ Getting Started
|
|
47
|
+
|
|
48
|
+
### Prerequisites
|
|
49
|
+
|
|
50
|
+
- C compiler (gcc/clang)
|
|
51
|
+
- [json-c](https://github.com/json-c/json-c) library for C usage
|
|
52
|
+
- Python 3.x (for Python bindings)
|
|
53
|
+
|
|
54
|
+
### Build
|
|
55
|
+
|
|
56
|
+
To build the C tests and examples:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
make
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Usage (json-c)
|
|
63
|
+
|
|
64
|
+
See examples in [`tests/json-c/get-a.c`](tests/json-c/get-a.c):
|
|
65
|
+
|
|
66
|
+
```c
|
|
67
|
+
#include "csonpath_json-c.h"
|
|
68
|
+
|
|
69
|
+
const char *json_str = "{ \"a\": \"value\", \"array\": [1,2,3] }";
|
|
70
|
+
struct csonpath p;
|
|
71
|
+
struct json_object *jobj = json_tokener_parse(json_str);
|
|
72
|
+
struct json_object *ret;
|
|
73
|
+
|
|
74
|
+
csonpath_init(&p, "$.a");
|
|
75
|
+
ret = csonpath_find_first(&p, jobj);
|
|
76
|
+
// ret now points to "value"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Usage (Python)
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import csonpath
|
|
83
|
+
|
|
84
|
+
d = { "a": "value", "array": [1,2,3] }
|
|
85
|
+
o = csonpath.CsonPath("$.a")
|
|
86
|
+
print(o.find_first(d)) # Output: "value"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Avaible methodes:
|
|
90
|
+
- `CsonPath(path)`: create a new csonpath object.
|
|
91
|
+
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
92
|
+
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
93
|
+
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
94
|
+
- `OBJ.update_or_create(self, json, value)`: take a json, replace all found occurrence from it, by the value, if doesn't found something, create it.
|
|
95
|
+
- `OBJ.update_or_create_callback(self, json, callback, callback_data)`: take a json, if it doesn't find a parent object, create it, then it calls a callback.
|
|
96
|
+
- `OBJ.callback(self, json, callback, callback_data)`: take a json, call a callback, an all occurrence.
|
|
97
|
+
|
|
98
|
+
`callback` is a function that take 4 arguments: `parent`, `idx`, `cur_value` and `callback_data`
|
|
99
|
+
|
|
100
|
+
Check [`tests`](tests/python/) for more examples
|
|
101
|
+
|
|
102
|
+
### Backends and Direct Usage
|
|
103
|
+
|
|
104
|
+
csonpath is inspired by JSONPath, but is designed to be backend-agnostic: it can work with any C library or environment that manipulates array, object, and scalar types—not just JSON. Out of the box, backends for Python and json-c are provided, but you can create your own backend for other formats such as YAML, or any custom data structure.
|
|
105
|
+
|
|
106
|
+
To use csonpath with a different data type or library, simply define the required macros and types in a header file (similar to `csonpath_json-c.h` or `csonpath_python.c`), then include your backend header before `csonpath.h`. This approach allows you to adapt csonpath for manipulating data in any format that supports array/object semantics, giving you full flexibility beyond just JSON.
|
|
107
|
+
|
|
108
|
+
## Directory Structure
|
|
109
|
+
|
|
110
|
+
- `csonpath.h`, `csonpath_do.h` - Main implementation files
|
|
111
|
+
- `csonpath_json-c.h` - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
|
|
112
|
+
- `csonpath_python.c` - python implementation, use it like a python lib (so `pip install .`)
|
|
113
|
+
- `tests/` - Contains tests
|
|
114
|
+
- `bench//` - Some benchmarks
|
|
115
|
+
|
|
116
|
+
## 🤝 Contributing
|
|
117
|
+
|
|
118
|
+
We welcome contributions!
|
|
119
|
+
|
|
120
|
+
Please read our [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) before submitting a pull request.
|
|
121
|
+
|
|
122
|
+
Feel free to open issues or pull requests!
|
|
123
|
+
|
|
124
|
+
## 📜 License
|
|
125
|
+
BSD 3-Clause. See [LICENSE](LICENSE).
|
|
126
|
+
|
|
@@ -69,8 +69,6 @@ ret = csonpath_find_first(&p, jobj);
|
|
|
69
69
|
|
|
70
70
|
### Usage (Python)
|
|
71
71
|
|
|
72
|
-
Check [`dump-test.py`](dump-test.py) for examples:
|
|
73
|
-
|
|
74
72
|
```python
|
|
75
73
|
import csonpath
|
|
76
74
|
|
|
@@ -79,6 +77,19 @@ o = csonpath.CsonPath("$.a")
|
|
|
79
77
|
print(o.find_first(d)) # Output: "value"
|
|
80
78
|
```
|
|
81
79
|
|
|
80
|
+
#### Avaible methodes:
|
|
81
|
+
- `CsonPath(path)`: create a new csonpath object.
|
|
82
|
+
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
83
|
+
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
84
|
+
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
85
|
+
- `OBJ.update_or_create(self, json, value)`: take a json, replace all found occurrence from it, by the value, if doesn't found something, create it.
|
|
86
|
+
- `OBJ.update_or_create_callback(self, json, callback, callback_data)`: take a json, if it doesn't find a parent object, create it, then it calls a callback.
|
|
87
|
+
- `OBJ.callback(self, json, callback, callback_data)`: take a json, call a callback, an all occurrence.
|
|
88
|
+
|
|
89
|
+
`callback` is a function that take 4 arguments: `parent`, `idx`, `cur_value` and `callback_data`
|
|
90
|
+
|
|
91
|
+
Check [`tests`](tests/python/) for more examples
|
|
92
|
+
|
|
82
93
|
### Backends and Direct Usage
|
|
83
94
|
|
|
84
95
|
csonpath is inspired by JSONPath, but is designed to be backend-agnostic: it can work with any C library or environment that manipulates array, object, and scalar types—not just JSON. Out of the box, backends for Python and json-c are provided, but you can create your own backend for other formats such as YAML, or any custom data structure.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: csonpath
|
|
3
|
+
Version: 0.0.3
|
|
4
|
+
Description-Content-Type: text/markdown
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Provides-Extra: dev
|
|
7
|
+
Requires-Dist: pytest>=8.3.5; extra == "dev"
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+
# csonpath
|
|
11
|
+
|
|
12
|
+
> that's not my path, that's not your path, but csonpath
|
|
13
|
+
|
|
14
|
+
[](https://docs.outscale.com/en/userguide/Open-Source-Projects.html)
|
|
15
|
+
|
|
16
|
+
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C, with Python bindings. It allows you to query, update, and remove data from JSON objects using path expressions.
|
|
17
|
+
|
|
18
|
+
## 🌐 Links
|
|
19
|
+
|
|
20
|
+
- Project website: https://github.com/outscale/csonpath
|
|
21
|
+
- Join our community on [Discord](https://discord.gg/HUVtY5gT6s)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## 📄 Table of Contents
|
|
25
|
+
|
|
26
|
+
- [Overview](#-overview)
|
|
27
|
+
- [Requirements](#-requirements)
|
|
28
|
+
- [Installation](#-installation)
|
|
29
|
+
- [Configuration](#-configuration)
|
|
30
|
+
- [Usage](#-usage)
|
|
31
|
+
- [Examples](#-examples)
|
|
32
|
+
- [License](#-license)
|
|
33
|
+
- [Contributing](#-contributing)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## 🚀 Features
|
|
37
|
+
|
|
38
|
+
- **Find First**: Retrieve the first value matching a path.
|
|
39
|
+
- **Find All**: Retrieve all values matching a path.
|
|
40
|
+
- **Update or Create**: Update values or create new ones according to the path.
|
|
41
|
+
- **Remove**: Remove values matching a path.
|
|
42
|
+
- **Update or Create Callback**: Update values or create new ones according to the path, using a user-define callback.
|
|
43
|
+
- **Callback**: Call a callback according to the path.
|
|
44
|
+
- **Supports both C (using json-c) and Python objects.**
|
|
45
|
+
|
|
46
|
+
## ✅ Getting Started
|
|
47
|
+
|
|
48
|
+
### Prerequisites
|
|
49
|
+
|
|
50
|
+
- C compiler (gcc/clang)
|
|
51
|
+
- [json-c](https://github.com/json-c/json-c) library for C usage
|
|
52
|
+
- Python 3.x (for Python bindings)
|
|
53
|
+
|
|
54
|
+
### Build
|
|
55
|
+
|
|
56
|
+
To build the C tests and examples:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
make
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Usage (json-c)
|
|
63
|
+
|
|
64
|
+
See examples in [`tests/json-c/get-a.c`](tests/json-c/get-a.c):
|
|
65
|
+
|
|
66
|
+
```c
|
|
67
|
+
#include "csonpath_json-c.h"
|
|
68
|
+
|
|
69
|
+
const char *json_str = "{ \"a\": \"value\", \"array\": [1,2,3] }";
|
|
70
|
+
struct csonpath p;
|
|
71
|
+
struct json_object *jobj = json_tokener_parse(json_str);
|
|
72
|
+
struct json_object *ret;
|
|
73
|
+
|
|
74
|
+
csonpath_init(&p, "$.a");
|
|
75
|
+
ret = csonpath_find_first(&p, jobj);
|
|
76
|
+
// ret now points to "value"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Usage (Python)
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import csonpath
|
|
83
|
+
|
|
84
|
+
d = { "a": "value", "array": [1,2,3] }
|
|
85
|
+
o = csonpath.CsonPath("$.a")
|
|
86
|
+
print(o.find_first(d)) # Output: "value"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Avaible methodes:
|
|
90
|
+
- `CsonPath(path)`: create a new csonpath object.
|
|
91
|
+
- `OBJ.find_first(self, json)`: take a json, return first found occurrence.
|
|
92
|
+
- `OBJ.find_all(self, json)`: take a json, return all found occurrence in a list.
|
|
93
|
+
- `OBJ.remove(self, json)`: take a json, remove all found occurrence from it.
|
|
94
|
+
- `OBJ.update_or_create(self, json, value)`: take a json, replace all found occurrence from it, by the value, if doesn't found something, create it.
|
|
95
|
+
- `OBJ.update_or_create_callback(self, json, callback, callback_data)`: take a json, if it doesn't find a parent object, create it, then it calls a callback.
|
|
96
|
+
- `OBJ.callback(self, json, callback, callback_data)`: take a json, call a callback, an all occurrence.
|
|
97
|
+
|
|
98
|
+
`callback` is a function that take 4 arguments: `parent`, `idx`, `cur_value` and `callback_data`
|
|
99
|
+
|
|
100
|
+
Check [`tests`](tests/python/) for more examples
|
|
101
|
+
|
|
102
|
+
### Backends and Direct Usage
|
|
103
|
+
|
|
104
|
+
csonpath is inspired by JSONPath, but is designed to be backend-agnostic: it can work with any C library or environment that manipulates array, object, and scalar types—not just JSON. Out of the box, backends for Python and json-c are provided, but you can create your own backend for other formats such as YAML, or any custom data structure.
|
|
105
|
+
|
|
106
|
+
To use csonpath with a different data type or library, simply define the required macros and types in a header file (similar to `csonpath_json-c.h` or `csonpath_python.c`), then include your backend header before `csonpath.h`. This approach allows you to adapt csonpath for manipulating data in any format that supports array/object semantics, giving you full flexibility beyond just JSON.
|
|
107
|
+
|
|
108
|
+
## Directory Structure
|
|
109
|
+
|
|
110
|
+
- `csonpath.h`, `csonpath_do.h` - Main implementation files
|
|
111
|
+
- `csonpath_json-c.h` - Json-C implementation, use it by including "csonpath_json-c.h" directly in your source
|
|
112
|
+
- `csonpath_python.c` - python implementation, use it like a python lib (so `pip install .`)
|
|
113
|
+
- `tests/` - Contains tests
|
|
114
|
+
- `bench//` - Some benchmarks
|
|
115
|
+
|
|
116
|
+
## 🤝 Contributing
|
|
117
|
+
|
|
118
|
+
We welcome contributions!
|
|
119
|
+
|
|
120
|
+
Please read our [Contributing Guidelines](CONTRIBUTING.md) and [Code of Conduct](CODE_OF_CONDUCT.md) before submitting a pull request.
|
|
121
|
+
|
|
122
|
+
Feel free to open issues or pull requests!
|
|
123
|
+
|
|
124
|
+
## 📜 License
|
|
125
|
+
BSD 3-Clause. See [LICENSE](LICENSE).
|
|
126
|
+
|
|
@@ -1,9 +1,28 @@
|
|
|
1
|
+
#if !defined(CSONPATH_JSON) || !defined(CSONPATH_NULL) || !defined(CSONPATH_GET) || \
|
|
2
|
+
!defined(CSONPATH_AT) || !defined(CSONPATH_IS_OBJ) || !defined(CSONPATH_IS_ARRAY) || \
|
|
3
|
+
!defined(CSONPATH_CALLBACK) || !defined(CSONPATH_CALLBACK_DATA) || \
|
|
4
|
+
!defined(CSONPATH_EQUAL_STR) || !defined(CSONPATH_CALL_CALLBACK) || \
|
|
5
|
+
!defined(CSONPATH_FOREACH_EXT) || !defined(CSONPATH_APPEND_AT) || \
|
|
6
|
+
!defined(CSONPATH_REMOVE_CHILD) || !defined(CSONPATH_NEED_FOREACH_REDO) || \
|
|
7
|
+
!defined(CSONPATH_ARRAY_APPEND_INCREF) || !defined(CSONPATH_REMOVE)
|
|
8
|
+
# error "some defined are missing"
|
|
9
|
+
#endif
|
|
10
|
+
|
|
1
11
|
#define CSONPATH_UNUSED __attribute__((unused))
|
|
2
12
|
#define MAY_ALIAS __attribute__((__may_alias__))
|
|
3
13
|
|
|
4
|
-
#
|
|
5
|
-
|
|
14
|
+
#ifndef CSONPATH_FOREACH
|
|
15
|
+
# define CSONPATH_FOREACH(obj, el, code) \
|
|
16
|
+
CSONPATH_FOREACH_EXT(obj, el, code, key_idx)
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#ifndef CSONPATH_FIND_ALL_RET
|
|
20
|
+
#define CSONPATH_FIND_ALL_RET CSONPATH_JSON
|
|
21
|
+
#endif
|
|
6
22
|
|
|
23
|
+
#ifndef CSONPATH_FIND_ALL_RET_INIT
|
|
24
|
+
#define CSONPATH_FIND_ALL_RET_INIT CSONPATH_NEW_ARRAY
|
|
25
|
+
#endif
|
|
7
26
|
|
|
8
27
|
enum csonpath_instuction_raw {
|
|
9
28
|
CSONPATH_INST_ROOT,
|
|
@@ -54,11 +73,12 @@ struct csonpath_instruction {
|
|
|
54
73
|
#define CSONPATH_INST_MIN_ALLOC (1 << 7)
|
|
55
74
|
|
|
56
75
|
struct csonpath {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
char *path;
|
|
77
|
+
char *compile_error;
|
|
78
|
+
struct csonpath_instruction *inst_lst;
|
|
79
|
+
int compiled;
|
|
80
|
+
int inst_idx;
|
|
81
|
+
int inst_size;
|
|
62
82
|
};
|
|
63
83
|
|
|
64
84
|
struct csonpath_child_info {
|
|
@@ -69,13 +89,23 @@ struct csonpath_child_info {
|
|
|
69
89
|
};
|
|
70
90
|
};
|
|
71
91
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
92
|
+
/* I'm assuming error message won't be longer than 125 */
|
|
93
|
+
#define CSONPATH_COMPILE_ERR(tmp, idx, args...) do { \
|
|
94
|
+
int ltmp = strlen(tmp), lidx, oidx = idx; \
|
|
95
|
+
if (cjp->compile_error) \
|
|
96
|
+
free(cjp->compile_error); \
|
|
97
|
+
cjp->compile_error = malloc(ltmp * 2 + 1024); \
|
|
98
|
+
lidx = snprintf(cjp->compile_error, 1024, "colum %d:\n", oidx); \
|
|
99
|
+
strcpy(cjp->compile_error + lidx, tmp); \
|
|
100
|
+
ltmp += lidx; \
|
|
101
|
+
cjp->compile_error[ltmp++] = '\n'; \
|
|
102
|
+
for (; oidx; --oidx) {cjp->compile_error[ltmp++] = ' ';} \
|
|
103
|
+
snprintf(cjp->compile_error + ltmp, 1024 - lidx, "\\-- "args); \
|
|
104
|
+
goto error; \
|
|
105
|
+
} while (0)
|
|
76
106
|
|
|
77
107
|
static inline struct csonpath_child_info *csonpath_child_info_set(struct csonpath_child_info *child_info,
|
|
78
|
-
|
|
108
|
+
CSONPATH_JSON j, const intptr_t key)
|
|
79
109
|
{
|
|
80
110
|
if (CSONPATH_IS_OBJ(j)) {
|
|
81
111
|
*child_info = (struct csonpath_child_info){.key=(const char *)key, .type=CSONPATH_STR};
|
|
@@ -89,7 +119,8 @@ static inline void csonpath_destroy(struct csonpath cjp[static 1])
|
|
|
89
119
|
{
|
|
90
120
|
free(cjp->path);
|
|
91
121
|
free(cjp->inst_lst);
|
|
92
|
-
cjp->
|
|
122
|
+
free(cjp->compile_error);
|
|
123
|
+
*cjp = (struct csonpath){};
|
|
93
124
|
}
|
|
94
125
|
|
|
95
126
|
static inline int csonpath_init(struct csonpath cjp[static 1],
|
|
@@ -107,6 +138,7 @@ static inline int csonpath_set_path(struct csonpath cjp[static 1],
|
|
|
107
138
|
const char path[static 1])
|
|
108
139
|
{
|
|
109
140
|
free(cjp->path);
|
|
141
|
+
free(cjp->compile_error);
|
|
110
142
|
free(cjp->inst_lst);
|
|
111
143
|
return csonpath_init(cjp, path);
|
|
112
144
|
}
|
|
@@ -125,14 +157,18 @@ void csonpath_push_inst(struct csonpath cjp[static 1], int inst)
|
|
|
125
157
|
int csonpath_compile(struct csonpath cjp[static 1])
|
|
126
158
|
{
|
|
127
159
|
char *walker = cjp->path;
|
|
160
|
+
char *orig = walker;
|
|
128
161
|
char *next;
|
|
129
162
|
char to_check;
|
|
163
|
+
char *tmp;
|
|
130
164
|
|
|
131
165
|
if (cjp->compiled)
|
|
132
166
|
return 0;
|
|
133
|
-
|
|
167
|
+
|
|
168
|
+
tmp = strdup(cjp->path);
|
|
169
|
+
root_again:
|
|
134
170
|
if (*walker != '$') {
|
|
135
|
-
|
|
171
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "%s", "'$' needed");
|
|
136
172
|
}
|
|
137
173
|
++walker;
|
|
138
174
|
csonpath_push_inst(cjp, CSONPATH_INST_ROOT);
|
|
@@ -150,7 +186,7 @@ again:
|
|
|
150
186
|
if (*walker == '*') {
|
|
151
187
|
csonpath_push_inst(cjp, CSONPATH_INST_GET_ALL);
|
|
152
188
|
if (walker[1] != ']') {
|
|
153
|
-
|
|
189
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig, "%s", "unclose bracket\n");
|
|
154
190
|
}
|
|
155
191
|
cjp->inst_lst[cjp->inst_idx - 1].next = 2;
|
|
156
192
|
walker += 2;
|
|
@@ -227,12 +263,14 @@ again:
|
|
|
227
263
|
next = walker;
|
|
228
264
|
do {
|
|
229
265
|
if (*next < '0' || *next > '9') {
|
|
230
|
-
|
|
266
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
267
|
+
"unexpected '%c', sting, filter or number require\n", *next);
|
|
231
268
|
}
|
|
232
269
|
next++;
|
|
233
270
|
} while (*next && *next != ']');
|
|
234
271
|
if (!*next) {
|
|
235
|
-
|
|
272
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
273
|
+
"%s", "unclose bracket\n");
|
|
236
274
|
}
|
|
237
275
|
*next = 0;
|
|
238
276
|
num = atoi(walker);
|
|
@@ -269,7 +307,8 @@ again:
|
|
|
269
307
|
*next = 0;
|
|
270
308
|
++next;
|
|
271
309
|
if (*next != ']')
|
|
272
|
-
|
|
310
|
+
CSONPATH_COMPILE_ERR(tmp, walker - orig,
|
|
311
|
+
"']' require instead of '%c'\n", *next);
|
|
273
312
|
|
|
274
313
|
csonpath_push_inst(cjp, CSONPATH_INST_GET_OBJ);
|
|
275
314
|
cjp->inst_lst[cjp->inst_idx - 1].next = next - walker + 1;
|
|
@@ -310,10 +349,12 @@ again:
|
|
|
310
349
|
if (*walker == 0) {
|
|
311
350
|
csonpath_push_inst(cjp, CSONPATH_INST_END);
|
|
312
351
|
cjp->compiled = 1;
|
|
352
|
+
free(tmp);
|
|
313
353
|
return 0;
|
|
314
354
|
}
|
|
315
355
|
error:
|
|
316
356
|
cjp->inst_lst[0] = (struct csonpath_instruction){.inst=CSONPATH_INST_BROKEN};
|
|
357
|
+
free(tmp);
|
|
317
358
|
return -1;
|
|
318
359
|
}
|
|
319
360
|
|
|
@@ -362,7 +403,7 @@ need_reloop_in = 0;
|
|
|
362
403
|
/* Find All */
|
|
363
404
|
|
|
364
405
|
#define CSONPATH_DO_PRE_OPERATION \
|
|
365
|
-
|
|
406
|
+
CSONPATH_FIND_ALL_RET ret_ar = CSONPATH_FIND_ALL_RET_INIT();
|
|
366
407
|
|
|
367
408
|
#define CSONPATH_DO_POST_OPERATION \
|
|
368
409
|
if (ret == CSONPATH_NULL) CSONPATH_REMOVE(ret_ar)
|
|
@@ -371,7 +412,7 @@ need_reloop_in = 0;
|
|
|
371
412
|
int nb_res = 0;
|
|
372
413
|
|
|
373
414
|
#define CSONPATH_DO_FUNC_NAME find_all
|
|
374
|
-
#define CSONPATH_DO_RET_TYPE
|
|
415
|
+
#define CSONPATH_DO_RET_TYPE CSONPATH_FIND_ALL_RET
|
|
375
416
|
#define CSONPATH_DO_RETURN ({CSONPATH_ARRAY_APPEND_INCREF(ret_ar, tmp); return ret_ar;})
|
|
376
417
|
|
|
377
418
|
#define CSONPATH_DO_FIND_ALL \
|
|
@@ -385,7 +426,7 @@ need_reloop_in = 0;
|
|
|
385
426
|
return ret_ar;
|
|
386
427
|
|
|
387
428
|
#define CSONPATH_DO_EXTRA_ARGS_IN , ret_ar
|
|
388
|
-
#define CSONPATH_DO_EXTRA_DECLATION ,
|
|
429
|
+
#define CSONPATH_DO_EXTRA_DECLATION , CSONPATH_FIND_ALL_RET ret_ar
|
|
389
430
|
|
|
390
431
|
|
|
391
432
|
#include "csonpath_do.h"
|
|
@@ -134,7 +134,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_dotdot(struct csonpath cjp[static 1],
|
|
|
134
134
|
CSONPATH_DO_EXTRA_ARGS_NEESTED);
|
|
135
135
|
CSONPATH_DO_FIND_ALL;
|
|
136
136
|
}
|
|
137
|
-
})
|
|
137
|
+
})
|
|
138
138
|
CSONPATH_DO_FIND_ALL_OUT;
|
|
139
139
|
return tret;
|
|
140
140
|
}
|
|
@@ -173,8 +173,8 @@ static CSONPATH_DO_RET_TYPE csonpath_do_internal(struct csonpath cjp[static 1],
|
|
|
173
173
|
CSONPATH_JSON el2;
|
|
174
174
|
|
|
175
175
|
CSONPATH_DO_FILTER_LOOP_PRE_SET
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
if (cjp->inst_lst[idx].inst != CSONPATH_INST_FILTER_OPERAND_STR)
|
|
177
|
+
CSONPATH_GETTER_ERR("filter support only comparaison with STR");
|
|
178
178
|
|
|
179
179
|
CSONPATH_FOREACH_EXT(el, el2, {
|
|
180
180
|
if (!strcmp((char *)neested_key, filter_key)) {
|
|
@@ -281,7 +281,7 @@ static CSONPATH_DO_RET_TYPE csonpath_do_(struct csonpath cjp[static 1],
|
|
|
281
281
|
(void)ctx;
|
|
282
282
|
csonpath_compile(cjp);
|
|
283
283
|
if (cjp->inst_lst[0].inst == CSONPATH_INST_BROKEN) {
|
|
284
|
-
CSONPATH_GETTER_ERR("fail to compile\n");
|
|
284
|
+
CSONPATH_GETTER_ERR("fail to compile: %s\n", cjp->compile_error);
|
|
285
285
|
return CSONPATH_NONE_FOUND_RET;
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -148,7 +148,9 @@ static PyObject *PyCsonPath_new(PyTypeObject *subtype, PyObject* args,
|
|
|
148
148
|
return PyErr_NoMemory();
|
|
149
149
|
|
|
150
150
|
if (csonpath_compile(ret) < 0) {
|
|
151
|
-
|
|
151
|
+
char *error = ret->compile_error;
|
|
152
|
+
PyErr_Format(PyExc_ValueError, "compilation fail %s", error);
|
|
153
|
+
csonpath_destroy(ret);
|
|
152
154
|
return NULL;
|
|
153
155
|
}
|
|
154
156
|
self->cp = ret;
|
csonpath-0.0.1/PKG-INFO
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|