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