You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.8 KiB
206 lines
5.8 KiB
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "llpkgc.h"
|
|
|
|
#define CALLBACK_MAYBE(PARSER, NAME) \
|
|
do { \
|
|
const llpkgc_settings_t* settings; \
|
|
settings = (const llpkgc_settings_t*) (PARSER)->settings; \
|
|
if(settings == NULL || settings->NAME == NULL) { \
|
|
err = 0; \
|
|
break; \
|
|
} \
|
|
err = settings->NAME((PARSER)); \
|
|
} while(0)
|
|
|
|
#define SPAN_CALLBACK_MAYBE(PARSER, NAME, START, LEN) \
|
|
do { \
|
|
const llpkgc_settings_t* settings; \
|
|
settings = (const llpkgc_settings_t*) (PARSER)->settings; \
|
|
if(settings == NULL || settings->NAME == NULL) { \
|
|
err = 0; \
|
|
break; \
|
|
} \
|
|
err = settings->NAME((PARSER), (START), (LEN)); \
|
|
if(err == -1) { \
|
|
err = PCE_USER; \
|
|
llpkgc_set_error_reason((PARSER), "Span callback error in " #NAME); \
|
|
} \
|
|
} while(0)
|
|
|
|
void llpkgc_init(llpkgc_t* parser, const llpkgc_settings_t* settings) {
|
|
llpkgc__internal_init(parser);
|
|
|
|
parser->settings = (void*) settings;
|
|
}
|
|
|
|
void llpkgc_reset(llpkgc_t* parser) {
|
|
llpkgc_settings_t* settings = parser->settings;
|
|
void* data = parser->data;
|
|
|
|
llpkgc__internal_init(parser);
|
|
|
|
parser->settings = settings;
|
|
parser->data = data;
|
|
}
|
|
|
|
void llpkgc_settings_init(llpkgc_settings_t* settings) {
|
|
memset(settings, 0, sizeof(*settings));
|
|
}
|
|
|
|
llpkgc_errno_t llpkgc_execute(llpkgc_t* parser, const char* data, size_t len) {
|
|
return llpkgc__internal_execute(parser, data, data + len);
|
|
}
|
|
|
|
llpkgc_errno_t llpkgc_finish(llpkgc_t* parser) {
|
|
if(parser->error != 0)
|
|
return parser->error;
|
|
|
|
int err;
|
|
// ToDo: Better handling of user callback errors here
|
|
if(parser->unfinished_ == 1) {
|
|
parser->reason = "Invalid EOF state";
|
|
parser->error = PCE_UNFINISHED;
|
|
return PCE_UNFINISHED;
|
|
} else if(parser->unfinished_ == 2) {
|
|
CALLBACK_MAYBE(parser, on_value_literal_complete);
|
|
if(err != PCE_OK) {
|
|
parser->error = err;
|
|
return err;
|
|
}
|
|
CALLBACK_MAYBE(parser, on_value_complete);
|
|
if(err != PCE_OK) {
|
|
parser->error = err;
|
|
return err;
|
|
}
|
|
} else if(parser->unfinished_ == 3) {
|
|
CALLBACK_MAYBE(parser, on_value_complete);
|
|
if(err != PCE_OK) {
|
|
parser->error = err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
CALLBACK_MAYBE(parser, on_pkgc_complete);
|
|
return err;
|
|
}
|
|
|
|
void llpkgc_pause(llpkgc_t* parser) {
|
|
if(parser->error != PCE_OK) {
|
|
return;
|
|
}
|
|
|
|
parser->error = PCE_PAUSED;
|
|
parser->reason = "Paused";
|
|
}
|
|
|
|
void llpkgc_resume(llpkgc_t* parser) {
|
|
if(parser->error != PCE_PAUSED) {
|
|
return;
|
|
}
|
|
|
|
parser->error = 0;
|
|
}
|
|
|
|
llpkgc_errno_t llpkgc_get_errno(const llpkgc_t* parser) {
|
|
return parser->error;
|
|
}
|
|
|
|
const char* llpkgc_get_error_reason(const llpkgc_t* parser) {
|
|
return parser->reason;
|
|
}
|
|
|
|
void llpkgc_set_error_reason(llpkgc_t* parser, const char* reason) {
|
|
parser->reason = reason;
|
|
}
|
|
|
|
const char* llpkgc_get_error_pos(const llpkgc_t* parser) {
|
|
return parser->error_pos;
|
|
}
|
|
|
|
const char* llpkgc_errno_name(llpkgc_errno_t err) {
|
|
switch(err) {
|
|
case PCE_OK:
|
|
return "PCE_OK";
|
|
case PCE_INTERNAL:
|
|
return "PCE_INTERNAL";
|
|
case PCE_PAUSED:
|
|
return "PCE_PAUSED";
|
|
case PCE_USER:
|
|
return "PCE_USER";
|
|
case PCE_UNFINISHED:
|
|
return "PCE_UNFINISHED";
|
|
}
|
|
return "INVALID_ERRNO";
|
|
}
|
|
|
|
int llpkgc__line_begin(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 1;
|
|
CALLBACK_MAYBE(s, on_line_begin);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__key_span(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
SPAN_CALLBACK_MAYBE(s, on_key, p, endp - p);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__keyword_complete(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 3;
|
|
CALLBACK_MAYBE(s, on_keyword_complete);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__variable_complete(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 3;
|
|
CALLBACK_MAYBE(s, on_variable_complete);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__vallit_span(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
if(s->escaped_) {
|
|
--endp;
|
|
s->escaped_ = 0;
|
|
}
|
|
s->unfinished_ = 2;
|
|
SPAN_CALLBACK_MAYBE(s, on_value_literal, p, endp - p);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__vallit_complete(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 3;
|
|
CALLBACK_MAYBE(s, on_value_literal_complete);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__valvar_span(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 1;
|
|
SPAN_CALLBACK_MAYBE(s, on_value_variable, p, endp - p);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__valvar_complete(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 3;
|
|
CALLBACK_MAYBE(s, on_value_variable_complete);
|
|
return err;
|
|
}
|
|
|
|
int llpkgc__value_complete(llpkgc_t* s, const char* p, const char* endp) {
|
|
int err;
|
|
s->unfinished_ = 0;
|
|
CALLBACK_MAYBE(s, on_value_complete);
|
|
return err;
|
|
}
|