/src/CMake/Utilities/cmllpkgc/llpkgc.c
Line | Count | Source |
1 | | /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
2 | | file LICENSE.rst or https://cmake.org/licensing for details. */ |
3 | | |
4 | | #include <stdlib.h> |
5 | | #include <string.h> |
6 | | |
7 | | #include "llpkgc.h" |
8 | | |
9 | | #define CALLBACK_MAYBE(PARSER, NAME) \ |
10 | 222k | do { \ |
11 | 222k | const llpkgc_settings_t* settings; \ |
12 | 222k | settings = (const llpkgc_settings_t*) (PARSER)->settings; \ |
13 | 222k | if(settings == NULL || settings->NAME == NULL) { \ |
14 | 119k | err = 0; \ |
15 | 119k | break; \ |
16 | 119k | } \ |
17 | 222k | err = settings->NAME((PARSER)); \ |
18 | 102k | } while(0) |
19 | | |
20 | | #define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \ |
21 | 102k | do { \ |
22 | 102k | const llpkgc_settings_t* settings; \ |
23 | 102k | settings = (const llpkgc_settings_t*) (PARSER)->settings; \ |
24 | 102k | if(settings == NULL || settings->NAME == NULL) { \ |
25 | 0 | err = 0; \ |
26 | 0 | break; \ |
27 | 0 | } \ |
28 | 102k | err = settings->NAME((PARSER), (START), (LEN)); \ |
29 | 102k | if(err == -1) { \ |
30 | 0 | err = PCE_USER; \ |
31 | 0 | llpkgc_set_error_reason((PARSER), "Span callback error in " #NAME); \ |
32 | 0 | } \ |
33 | 102k | } while(0) |
34 | | |
35 | 495 | void llpkgc_init(llpkgc_t* parser, const llpkgc_settings_t* settings) { |
36 | 495 | llpkgc__internal_init(parser); |
37 | | |
38 | 495 | parser->settings = (void*) settings; |
39 | 495 | } |
40 | | |
41 | 0 | void llpkgc_reset(llpkgc_t* parser) { |
42 | 0 | llpkgc_settings_t* settings = parser->settings; |
43 | 0 | void* data = parser->data; |
44 | |
|
45 | 0 | llpkgc__internal_init(parser); |
46 | |
|
47 | 0 | parser->settings = settings; |
48 | 0 | parser->data = data; |
49 | 0 | } |
50 | | |
51 | 0 | void llpkgc_settings_init(llpkgc_settings_t* settings) { |
52 | 0 | memset(settings, 0, sizeof(*settings)); |
53 | 0 | } |
54 | | |
55 | 495 | llpkgc_errno_t llpkgc_execute(llpkgc_t* parser, const char* data, size_t len) { |
56 | 495 | return llpkgc__internal_execute(parser, data, data + len); |
57 | 495 | } |
58 | | |
59 | 495 | llpkgc_errno_t llpkgc_finish(llpkgc_t* parser) { |
60 | 495 | if(parser->error != 0) |
61 | 41 | return parser->error; |
62 | | |
63 | 454 | int err; |
64 | | // ToDo: Better handling of user callback errors here |
65 | 454 | if(parser->unfinished_ == 1) { |
66 | 35 | parser->reason = "Invalid EOF state"; |
67 | 35 | parser->error = PCE_UNFINISHED; |
68 | 35 | return PCE_UNFINISHED; |
69 | 419 | } else if(parser->unfinished_ == 2) { |
70 | 140 | CALLBACK_MAYBE(parser, on_value_literal_complete); |
71 | 140 | if(err != PCE_OK) { |
72 | 0 | parser->error = err; |
73 | 0 | return err; |
74 | 0 | } |
75 | 140 | CALLBACK_MAYBE(parser, on_value_complete); |
76 | 140 | if(err != PCE_OK) { |
77 | 0 | parser->error = err; |
78 | 0 | return err; |
79 | 0 | } |
80 | 279 | } else if(parser->unfinished_ == 3) { |
81 | 151 | CALLBACK_MAYBE(parser, on_value_complete); |
82 | 151 | if(err != PCE_OK) { |
83 | 0 | parser->error = err; |
84 | 0 | return err; |
85 | 0 | } |
86 | 151 | } |
87 | | |
88 | 419 | CALLBACK_MAYBE(parser, on_pkgc_complete); |
89 | 419 | return err; |
90 | 454 | } |
91 | | |
92 | 0 | void llpkgc_pause(llpkgc_t* parser) { |
93 | 0 | if(parser->error != PCE_OK) { |
94 | 0 | return; |
95 | 0 | } |
96 | | |
97 | 0 | parser->error = PCE_PAUSED; |
98 | 0 | parser->reason = "Paused"; |
99 | 0 | } |
100 | | |
101 | 0 | void llpkgc_resume(llpkgc_t* parser) { |
102 | 0 | if(parser->error != PCE_PAUSED) { |
103 | 0 | return; |
104 | 0 | } |
105 | | |
106 | 0 | parser->error = 0; |
107 | 0 | } |
108 | | |
109 | 0 | llpkgc_errno_t llpkgc_get_errno(const llpkgc_t* parser) { |
110 | 0 | return parser->error; |
111 | 0 | } |
112 | | |
113 | 0 | const char* llpkgc_get_error_reason(const llpkgc_t* parser) { |
114 | 0 | return parser->reason; |
115 | 0 | } |
116 | | |
117 | 0 | void llpkgc_set_error_reason(llpkgc_t* parser, const char* reason) { |
118 | 0 | parser->reason = reason; |
119 | 0 | } |
120 | | |
121 | 0 | const char* llpkgc_get_error_pos(const llpkgc_t* parser) { |
122 | 0 | return parser->error_pos; |
123 | 0 | } |
124 | | |
125 | 0 | const char* llpkgc_errno_name(llpkgc_errno_t err) { |
126 | 0 | switch(err) { |
127 | 0 | case PCE_OK: |
128 | 0 | return "PCE_OK"; |
129 | 0 | case PCE_INTERNAL: |
130 | 0 | return "PCE_INTERNAL"; |
131 | 0 | case PCE_PAUSED: |
132 | 0 | return "PCE_PAUSED"; |
133 | 0 | case PCE_USER: |
134 | 0 | return "PCE_USER"; |
135 | 0 | case PCE_UNFINISHED: |
136 | 0 | return "PCE_UNFINISHED"; |
137 | 0 | } |
138 | 0 | return "INVALID_ERRNO"; |
139 | 0 | } |
140 | | |
141 | 59.6k | int llpkgc__line_begin(llpkgc_t* s, const char* p, const char* endp) { |
142 | 59.6k | int err; |
143 | 59.6k | s->unfinished_ = 1; |
144 | 59.6k | CALLBACK_MAYBE(s, on_line_begin); |
145 | 59.6k | return err; |
146 | 59.6k | } |
147 | | |
148 | 59.6k | int llpkgc__key_span(llpkgc_t* s, const char* p, const char* endp) { |
149 | 59.6k | int err; |
150 | 59.6k | SPAN_CALLBACK_MAYBE(s, on_key, p, endp - p); |
151 | 59.6k | return err; |
152 | 59.6k | } |
153 | | |
154 | 38.6k | int llpkgc__keyword_complete(llpkgc_t* s, const char* p, const char* endp) { |
155 | 38.6k | int err; |
156 | 38.6k | s->unfinished_ = 3; |
157 | 38.6k | CALLBACK_MAYBE(s, on_keyword_complete); |
158 | 38.6k | return err; |
159 | 38.6k | } |
160 | | |
161 | 20.8k | int llpkgc__variable_complete(llpkgc_t* s, const char* p, const char* endp) { |
162 | 20.8k | int err; |
163 | 20.8k | s->unfinished_ = 3; |
164 | 20.8k | CALLBACK_MAYBE(s, on_variable_complete); |
165 | 20.8k | return err; |
166 | 20.8k | } |
167 | | |
168 | 40.1k | int llpkgc__vallit_span(llpkgc_t* s, const char* p, const char* endp) { |
169 | 40.1k | int err; |
170 | 40.1k | if(s->escaped_) { |
171 | 2.52k | --endp; |
172 | 2.52k | s->escaped_ = 0; |
173 | 2.52k | } |
174 | 40.1k | s->unfinished_ = 2; |
175 | 40.1k | SPAN_CALLBACK_MAYBE(s, on_value_literal, p, endp - p); |
176 | 40.1k | return err; |
177 | 40.1k | } |
178 | | |
179 | 39.9k | int llpkgc__vallit_complete(llpkgc_t* s, const char* p, const char* endp) { |
180 | 39.9k | int err; |
181 | 39.9k | s->unfinished_ = 3; |
182 | 39.9k | CALLBACK_MAYBE(s, on_value_literal_complete); |
183 | 39.9k | return err; |
184 | 39.9k | } |
185 | | |
186 | 3.05k | int llpkgc__valvar_span(llpkgc_t* s, const char* p, const char* endp) { |
187 | 3.05k | int err; |
188 | 3.05k | s->unfinished_ = 1; |
189 | 3.05k | SPAN_CALLBACK_MAYBE(s, on_value_variable, p, endp - p); |
190 | 3.05k | return err; |
191 | 3.05k | } |
192 | | |
193 | 3.04k | int llpkgc__valvar_complete(llpkgc_t* s, const char* p, const char* endp) { |
194 | 3.04k | int err; |
195 | 3.04k | s->unfinished_ = 3; |
196 | 3.04k | CALLBACK_MAYBE(s, on_value_variable_complete); |
197 | 3.04k | return err; |
198 | 3.04k | } |
199 | | |
200 | 59.2k | int llpkgc__value_complete(llpkgc_t* s, const char* p, const char* endp) { |
201 | 59.2k | int err; |
202 | 59.2k | s->unfinished_ = 0; |
203 | | CALLBACK_MAYBE(s, on_value_complete); |
204 | 59.2k | return err; |
205 | 59.2k | } |