mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-18 04:58:51 +02:00
Add higher level YAML functions.
These functions make parsing YAML simpler.
This commit is contained in:
parent
55bcb933ee
commit
fb9acc1c93
@ -16,6 +16,8 @@ Object type
|
||||
struct Yaml
|
||||
{
|
||||
yaml_parser_t parser; // Parse context
|
||||
bool eventNextSet; // Is the next event set?
|
||||
YamlEvent eventNext; // Next event, stored after a peek
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@ -116,6 +118,54 @@ yamlEventType(yaml_event_type_t type)
|
||||
}
|
||||
}
|
||||
|
||||
YamlEvent
|
||||
yamlEventPeek(Yaml *const this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(YAML, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (!this->eventNextSet)
|
||||
{
|
||||
yaml_event_t event;
|
||||
|
||||
if (!yaml_parser_parse(&this->parser, &event))
|
||||
{
|
||||
// These should always be set
|
||||
CHECK(ServiceError, this->parser.problem_mark.line && this->parser.problem_mark.column, "invalid yaml error info");
|
||||
|
||||
THROW_FMT(
|
||||
FormatError, "yaml parse error: %s at line: %lu column: %lu", this->parser.problem,
|
||||
(unsigned long)this->parser.problem_mark.line + 1, (unsigned long)this->parser.problem_mark.column + 1);
|
||||
}
|
||||
|
||||
this->eventNext = (YamlEvent)
|
||||
{
|
||||
.type = yamlEventType(event.type),
|
||||
.line = event.start_mark.line + 1,
|
||||
.column = event.start_mark.column + 1,
|
||||
};
|
||||
|
||||
if (this->eventNext.type == yamlEventTypeScalar)
|
||||
{
|
||||
MEM_CONTEXT_OBJ_BEGIN(this)
|
||||
{
|
||||
this->eventNext.value = strNewZ((const char *)event.data.scalar.value);
|
||||
}
|
||||
MEM_CONTEXT_OBJ_END();
|
||||
}
|
||||
|
||||
yaml_event_delete(&event);
|
||||
|
||||
this->eventNextSet = true;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_TYPE(YamlEvent, this->eventNext);
|
||||
}
|
||||
|
||||
|
||||
YamlEvent
|
||||
yamlEventNext(Yaml *this)
|
||||
{
|
||||
@ -125,31 +175,12 @@ yamlEventNext(Yaml *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
yaml_event_t event;
|
||||
if (!this->eventNextSet)
|
||||
yamlEventPeek(this);
|
||||
|
||||
if (!yaml_parser_parse(&this->parser, &event))
|
||||
{
|
||||
// These should always be set
|
||||
CHECK(ServiceError, this->parser.problem_mark.line && this->parser.problem_mark.column, "invalid yaml error info");
|
||||
this->eventNextSet = false;
|
||||
|
||||
THROW_FMT(
|
||||
FormatError, "yaml parse error: %s at line: %lu column: %lu", this->parser.problem,
|
||||
(unsigned long)this->parser.problem_mark.line + 1, (unsigned long)this->parser.problem_mark.column + 1);
|
||||
}
|
||||
|
||||
YamlEvent result =
|
||||
{
|
||||
.type = yamlEventType(event.type),
|
||||
.line = event.start_mark.line + 1,
|
||||
.column = event.start_mark.column + 1,
|
||||
};
|
||||
|
||||
if (result.type == yamlEventTypeScalar)
|
||||
result.value = strNewZ((const char *)event.data.scalar.value);
|
||||
|
||||
yaml_event_delete(&event);
|
||||
|
||||
FUNCTION_TEST_RETURN_TYPE(YamlEvent, result);
|
||||
FUNCTION_TEST_RETURN_TYPE(YamlEvent, this->eventNext);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -168,7 +199,7 @@ yamlEventNextCheck(Yaml *this, YamlEventType type)
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
YamlEvent
|
||||
yamlEventCheck(YamlEvent event, YamlEventType type)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
@ -177,12 +208,60 @@ yamlEventCheck(YamlEvent event, YamlEventType type)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (event.type != type)
|
||||
{
|
||||
if (event.type == yamlEventTypeScalar)
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "expected event type '%s' but got scalar '%s' at line %zu, column %zu", strZ(strIdToStr(type)),
|
||||
strZ(event.value), event.line, event.column);
|
||||
}
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "expected event type '%s' but got '%s' at line %zu, column %zu", strZ(strIdToStr(type)),
|
||||
strZ(strIdToStr(event.type)), event.line, event.column);
|
||||
}
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_TYPE(YamlEvent, event);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
void
|
||||
yamlScalarCheck(const YamlEvent event, const String *const value)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(YAML_EVENT, event);
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (event.type != yamlEventTypeScalar)
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "expected event type '%s' but got '%s' at line %zu, column %zu", strZ(strIdToStr(type)),
|
||||
FormatError, "expected scalar '%s' but got event type '%s' at line %zu, column %zu", strZ(value),
|
||||
strZ(strIdToStr(event.type)), event.line, event.column);
|
||||
}
|
||||
|
||||
if (!strEq(event.value, value))
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "expected scalar '%s' but got '%s' at line %zu, column %zu", strZ(value), strZ(event.value), event.line,
|
||||
event.column);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
void
|
||||
yamlScalarNextCheck(Yaml *const this, const String *const value)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(YAML, this);
|
||||
FUNCTION_TEST_PARAM(STRING, value);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
yamlScalarCheck(yamlEventNext(this), value);
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,34 @@ YamlEvent yamlEventNext(Yaml *this);
|
||||
YamlEvent yamlEventNextCheck(Yaml *this, YamlEventType type);
|
||||
|
||||
// Check the event type
|
||||
void yamlEventCheck(YamlEvent event, YamlEventType type);
|
||||
YamlEvent yamlEventCheck(YamlEvent event, YamlEventType type);
|
||||
|
||||
// Peek at the next event
|
||||
YamlEvent yamlEventPeek(Yaml *this);
|
||||
|
||||
// Get next scalar
|
||||
__attribute__((always_inline)) static inline YamlEvent
|
||||
yamlScalarNext(Yaml *const this)
|
||||
{
|
||||
return yamlEventNextCheck(this, yamlEventTypeScalar);
|
||||
}
|
||||
|
||||
// Check scalar
|
||||
void yamlScalarCheck(YamlEvent event, const String *value);
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
yamlScalarCheckZ(const YamlEvent event, const char *const value)
|
||||
{
|
||||
yamlScalarCheck(event, STR(value));
|
||||
}
|
||||
|
||||
void yamlScalarNextCheck(Yaml *this, const String *value);
|
||||
|
||||
__attribute__((always_inline)) static inline void
|
||||
yamlScalarNextCheckZ(Yaml *const this, const char *const value)
|
||||
{
|
||||
yamlScalarNextCheck(this, STR(value));
|
||||
}
|
||||
|
||||
// Convert an event to a boolean (or error)
|
||||
bool yamlBoolParse(YamlEvent event);
|
||||
|
@ -40,7 +40,16 @@ testRun(void)
|
||||
Yaml *yaml = NULL;
|
||||
TEST_ASSIGN(yaml, yamlNew(buffer), "new yaml")
|
||||
TEST_RESULT_VOID(yamlEventNextCheck(yaml, yamlEventTypeMapBegin), "map begin event");
|
||||
TEST_RESULT_VOID(yamlEventNextCheck(yaml, yamlEventTypeScalar), "scalar event");
|
||||
TEST_ERROR(
|
||||
yamlScalarCheck(yamlEventPeek(yaml), STRDEF("xxx")), FormatError,
|
||||
"expected scalar 'xxx' but got 'test' at line 1, column 1");
|
||||
TEST_ERROR(
|
||||
yamlEventCheck(yamlEventPeek(yaml), yamlEventTypeMapBegin), FormatError,
|
||||
"expected event type 'map-begin' but got scalar 'test' at line 1, column 1");
|
||||
TEST_RESULT_VOID(yamlScalarNextCheck(yaml, STRDEF("test")), "scalar event");
|
||||
TEST_ERROR(
|
||||
yamlScalarCheck(yamlEventPeek(yaml), STRDEF("test")), FormatError,
|
||||
"expected scalar 'test' but got event type 'map-begin' at line 2, column 4");
|
||||
TEST_RESULT_VOID(yamlEventNextCheck(yaml, yamlEventTypeMapBegin), "map begin event");
|
||||
TEST_RESULT_VOID(yamlEventNextCheck(yaml, yamlEventTypeScalar), "scalar event");
|
||||
TEST_RESULT_VOID(yamlEventNextCheck(yaml, yamlEventTypeSeqBegin), "seq begin event");
|
||||
|
Loading…
x
Reference in New Issue
Block a user