Coverage Report

Created: 2026-07-30 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmllpkgc/llpkgc_file.c
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.
2
   See accompanying file LICENSE.rst for details.  */
3
4
#include <stdint.h>
5
#include <stdlib.h>
6
#include <string.h>
7
8
#include "llpkgc_file.h"
9
10
#define CALLBACK_MAYBE(PARSER, NAME)                                           \
11
3.56k
  do {                                                                         \
12
3.56k
    const llpkgc_file_settings_t* settings;                                    \
13
3.56k
    settings =                                                                 \
14
3.56k
        (const llpkgc_file_settings_t*) (PARSER)->llpkgc_file__settings;       \
15
3.56k
    if(settings == NULL || settings->NAME == NULL) {                           \
16
0
      err = 0;                                                                 \
17
0
      break;                                                                   \
18
0
    }                                                                          \
19
3.56k
    err = settings->NAME((PARSER));                                            \
20
3.56k
  } while(0)
21
22
#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN)                          \
23
1.78k
  do {                                                                         \
24
1.78k
    const llpkgc_file_settings_t* settings;                                    \
25
1.78k
    settings =                                                                 \
26
1.78k
        (const llpkgc_file_settings_t*) (PARSER)->llpkgc_file__settings;       \
27
1.78k
    if(settings == NULL || settings->NAME == NULL) {                           \
28
0
      err = 0;                                                                 \
29
0
      break;                                                                   \
30
0
    }                                                                          \
31
1.78k
    err = settings->NAME((PARSER), (START), (LEN));                            \
32
1.78k
    if(err == -1) {                                                            \
33
0
      err = PFCE_USER;                                                         \
34
0
      llpkgc_file_set_error_reason((PARSER), "Span callback error in " #NAME); \
35
0
    }                                                                          \
36
1.78k
  } while(0)
37
38
enum llpkgc_file_unfinished_state {
39
  PFUS_NONE = 0,
40
  PFUS_IDENT = 1,
41
  PFUS_BAREWORDS = 2,
42
  PFUS_EXPECT_VALUE = 3,
43
  PFUS_VALUE = 4,
44
  PFUS_VALUE_LITERAL = 5,
45
  PFUS_VALUE_SUBSTITUTION = 6,
46
};
47
48
void llpkgc_file_init(llpkgc_file_t* parser,
49
1
    const llpkgc_file_settings_t* settings) {
50
1
  llpkgc_file__internal_init(parser);
51
52
1
  parser->llpkgc_file__settings = (void*) settings;
53
1
}
54
55
0
void llpkgc_file_reset(llpkgc_file_t* parser) {
56
0
  llpkgc_file_settings_t* settings = parser->llpkgc_file__settings;
57
0
  void* data = parser->data;
58
59
0
  llpkgc_file__internal_init(parser);
60
61
0
  parser->llpkgc_file__settings = settings;
62
0
  parser->data = data;
63
0
}
64
65
0
void llpkgc_file_settings_init(llpkgc_file_settings_t* settings) {
66
0
  memset(settings, 0, sizeof(*settings));
67
0
}
68
69
llpkgc_file_errno_t llpkgc_file_execute(llpkgc_file_t* parser, const char* data,
70
1
    size_t len) {
71
1
  return llpkgc_file__internal_execute(parser, data, data + len);
72
1
}
73
74
int llpkgc_file__line_begin(llpkgc_file_t* s, const char* p, const char* endp);
75
int llpkgc_file__ident_span(llpkgc_file_t* s, const char* p, const char* endp);
76
77
1
llpkgc_file_errno_t llpkgc_file_finish(llpkgc_file_t* parser) {
78
1
  int err = PFCE_OK;
79
80
1
  if(parser->error == PFCE_LOOKAHEAD) {
81
0
    if(parser->error_pos == NULL) {
82
0
      parser->error = PFCE_INTERNAL;
83
0
      parser->reason = "Missing lookahead error position";
84
0
      return parser->error;
85
0
    }
86
87
0
    parser->llpkgc_file__eof = 1;
88
0
    llpkgc_file_resume(parser);
89
0
    err = llpkgc_file_execute(parser, parser->error_pos, 1);
90
0
    parser->llpkgc_file__eof = 0;
91
92
0
    if(err != PFCE_OK) {
93
0
      return err;
94
0
    }
95
96
0
    parser->llpkgc_file__lookahead = 0;
97
1
  } else if(parser->error != 0) {
98
1
    return parser->error;
99
1
  }
100
101
0
  switch(parser->llpkgc_file__unfinished) {
102
0
    case PFUS_IDENT:
103
0
    case PFUS_BAREWORDS:
104
0
      CALLBACK_MAYBE(parser, on_barewords_complete);
105
0
      if(err != PFCE_OK) {
106
0
        parser->error = err;
107
0
        return err;
108
0
      }
109
110
0
      CALLBACK_MAYBE(parser, on_value_complete);
111
0
      if(err != PFCE_OK) {
112
0
        parser->error = err;
113
0
        return err;
114
0
      }
115
0
      break;
116
117
0
    case PFUS_EXPECT_VALUE:
118
0
    case PFUS_VALUE:
119
0
      CALLBACK_MAYBE(parser, on_value_complete);
120
0
      if(err != PFCE_OK) {
121
0
        parser->error = err;
122
0
        return err;
123
0
      }
124
0
      break;
125
126
0
    case PFUS_VALUE_LITERAL:
127
0
      CALLBACK_MAYBE(parser, on_value_literal_complete);
128
0
      if(err != PFCE_OK) {
129
0
        parser->error = err;
130
0
        return err;
131
0
      }
132
133
0
      CALLBACK_MAYBE(parser, on_value_complete);
134
0
      if(err != PFCE_OK) {
135
0
        parser->error = err;
136
0
        return err;
137
0
      }
138
0
      break;
139
140
0
    case PFUS_VALUE_SUBSTITUTION:
141
0
      parser->reason = "Invalid EOF state";
142
0
      parser->error = PFCE_UNFINISHED;
143
0
      return PFCE_UNFINISHED;
144
145
0
    case PFUS_NONE:
146
0
      break;
147
0
  }
148
149
0
  CALLBACK_MAYBE(parser, on_pkgc_complete);
150
0
  return err;
151
0
}
152
153
0
void llpkgc_file_pause(llpkgc_file_t* parser) {
154
0
  if(parser->error != PFCE_OK) {
155
0
    return;
156
0
  }
157
158
0
  parser->error = PFCE_PAUSED;
159
0
  parser->reason = "Paused";
160
0
}
161
162
0
void llpkgc_file_resume(llpkgc_file_t* parser) {
163
0
  if(parser->error != PFCE_PAUSED && parser->error != PFCE_LOOKAHEAD) {
164
0
    return;
165
0
  }
166
167
0
  parser->error = 0;
168
0
}
169
170
0
llpkgc_file_errno_t llpkgc_file_get_errno(const llpkgc_file_t* parser) {
171
0
  return parser->error;
172
0
}
173
174
0
const char* llpkgc_file_get_error_reason(const llpkgc_file_t* parser) {
175
0
  return parser->reason;
176
0
}
177
178
0
void llpkgc_file_set_error_reason(llpkgc_file_t* parser, const char* reason) {
179
0
  parser->reason = reason;
180
0
}
181
182
0
const char* llpkgc_file_get_error_pos(const llpkgc_file_t* parser) {
183
0
  return parser->error_pos;
184
0
}
185
186
0
const char* llpkgc_file_errno_name(llpkgc_file_errno_t err) {
187
0
  switch(err) {
188
0
    case PFCE_OK:
189
0
      return "PFCE_OK";
190
0
    case PFCE_INTERNAL:
191
0
      return "PFCE_INTERNAL";
192
0
    case PFCE_PAUSED:
193
0
      return "PFCE_PAUSED";
194
0
    case PFCE_USER:
195
0
      return "PFCE_USER";
196
0
    case PFCE_UNFINISHED:
197
0
      return "PFCE_UNFINISHED";
198
0
    case PFCE_LOOKAHEAD:
199
0
      return "PFCE_LOOKAHEAD";
200
0
  }
201
0
  return "INVALID_ERRNO";
202
0
}
203
204
0
int llpkgc_file__lookahead(llpkgc_file_t* s, const char* p, const char* endp) {
205
0
  if(p == endp) {
206
0
    llpkgc_file_set_error_reason(s, "Invalid lookahead state");
207
0
    return PFCE_INTERNAL;
208
0
  }
209
210
0
  if(p + 1 == endp) {
211
0
    if(s->llpkgc_file__eof != 0) {
212
0
      s->llpkgc_file__lookahead = 0;
213
0
      return 3;
214
0
    }
215
216
0
    s->llpkgc_file__lookahead = (uint8_t) *p;
217
0
    return PFCE_LOOKAHEAD;
218
0
  }
219
220
0
  s->llpkgc_file__lookahead = 0;
221
222
0
  if(*p != '$') {
223
0
    llpkgc_file_set_error_reason(s, "Invalid lookahead state");
224
0
    return PFCE_INTERNAL;
225
0
  }
226
227
0
  switch(p[1]) {
228
0
    case '{':
229
0
      return 1;
230
0
    case '$':
231
0
      return 2;
232
0
    default:
233
0
      return 0;
234
0
  }
235
0
}
236
237
int llpkgc_file__lookahead_backslash(llpkgc_file_t* s, const char* p,
238
6
    const char* endp) {
239
6
  if(p == endp) {
240
0
    llpkgc_file_set_error_reason(s, "Invalid lookahead state");
241
0
    return PFCE_INTERNAL;
242
0
  }
243
244
6
  if(p + 1 == endp) {
245
0
    if(s->llpkgc_file__eof != 0) {
246
0
      s->llpkgc_file__lookahead = 0;
247
0
      return 4;
248
0
    }
249
250
0
    s->llpkgc_file__lookahead = (uint8_t) *p;
251
0
    return 5;
252
0
  }
253
254
6
  s->llpkgc_file__lookahead = 0;
255
256
6
  if(*p != '\\') {
257
0
    llpkgc_file_set_error_reason(s, "Invalid lookahead state");
258
0
    return PFCE_INTERNAL;
259
0
  }
260
261
6
  switch(p[1]) {
262
0
    case '\r':
263
0
    case '\n':
264
0
      return 1;
265
3
    case '#':
266
3
      return 2;
267
1
    case '\\':
268
1
      return 3;
269
2
    default:
270
2
      return 0;
271
6
  }
272
6
}
273
274
0
int llpkgc_file__line_begin(llpkgc_file_t* s, const char* p, const char* endp) {
275
0
  int err;
276
0
  CALLBACK_MAYBE(s, on_line_begin);
277
0
  return err;
278
0
}
279
280
1.77k
int llpkgc_file__ident_span(llpkgc_file_t* s, const char* p, const char* endp) {
281
1.77k
  int err;
282
1.77k
  SPAN_CALLBACK_MAYBE(s, on_ident, p, endp - p);
283
1.77k
  return err;
284
1.77k
}
285
286
int llpkgc_file__prop_decl_complete(llpkgc_file_t* s, const char* p,
287
4
    const char* endp) {
288
4
  int err;
289
4
  CALLBACK_MAYBE(s, on_property_complete);
290
4
  return err;
291
4
}
292
293
int llpkgc_file__var_decl_complete(llpkgc_file_t* s, const char* p,
294
0
    const char* endp) {
295
0
  int err;
296
0
  CALLBACK_MAYBE(s, on_variable_complete);
297
0
  return err;
298
0
}
299
300
int llpkgc_file__barewords_decl_complete(llpkgc_file_t* s, const char* p,
301
1.77k
    const char* endp) {
302
1.77k
  int err;
303
1.77k
  CALLBACK_MAYBE(s, on_barewords_complete);
304
1.77k
  return err;
305
1.77k
}
306
307
6
int llpkgc_file__lit_span(llpkgc_file_t* s, const char* p, const char* endp) {
308
6
  int err;
309
6
  SPAN_CALLBACK_MAYBE(s, on_value_literal, p, endp - p);
310
6
  return err;
311
6
}
312
313
int llpkgc_file__lit_complete(llpkgc_file_t* s, const char* p,
314
6
    const char* endp) {
315
6
  int err;
316
6
  CALLBACK_MAYBE(s, on_value_literal_complete);
317
6
  return err;
318
6
}
319
320
0
int llpkgc_file__sub_span(llpkgc_file_t* s, const char* p, const char* endp) {
321
0
  int err;
322
0
  SPAN_CALLBACK_MAYBE(s, on_value_substitution, p, endp - p);
323
0
  return err;
324
0
}
325
326
int llpkgc_file__sub_complete(llpkgc_file_t* s, const char* p,
327
0
    const char* endp) {
328
0
  int err;
329
0
  CALLBACK_MAYBE(s, on_value_substitution_complete);
330
0
  return err;
331
0
}
332
333
int llpkgc_file__val_complete(llpkgc_file_t* s, const char* p,
334
1.77k
    const char* endp) {
335
1.77k
  int err;
336
  CALLBACK_MAYBE(s, on_value_complete);
337
1.77k
  return err;
338
1.77k
}