aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-05-29 15:20:23 -0400
committerDavid Robillard <d@drobilla.net>2022-01-13 23:04:13 -0500
commit059b4764d6b6b3a9ef04600bda45815c69365d30 (patch)
tree29d06770022a1542c29ece88f1f9709205576247
parent2638ded01498b41a67574a2eae4181106226a933 (diff)
downloadserd-059b4764d6b6b3a9ef04600bda45815c69365d30.tar.gz
serd-059b4764d6b6b3a9ef04600bda45815c69365d30.tar.bz2
serd-059b4764d6b6b3a9ef04600bda45815c69365d30.zip
Use a manual type-safe stack in writer
This fixes alignment issues on ARM. Since this stack is just for WriteContext which has a fixed size, using SerdStack here just made things more confusing anyway.
-rw-r--r--meson.build2
-rw-r--r--src/writer.c66
2 files changed, 28 insertions, 40 deletions
diff --git a/meson.build b/meson.build
index dcca40b1..90f59e9b 100644
--- a/meson.build
+++ b/meson.build
@@ -29,7 +29,6 @@ if get_option('strict')
if cc.get_id() == 'clang'
c_suppressions += [
- '-Wno-cast-align',
'-Wno-format-nonliteral',
'-Wno-nullability-extension',
'-Wno-nullable-to-nonnull-conversion',
@@ -38,7 +37,6 @@ if get_option('strict')
]
elif cc.get_id() == 'gcc'
c_suppressions += [
- '-Wno-cast-align',
'-Wno-float-conversion', # MinGW
'-Wno-format-nonliteral',
'-Wno-inline',
diff --git a/src/writer.c b/src/writer.c
index 2b1bc39d..cd6ce613 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -18,7 +18,6 @@
#include "node.h"
#include "serd_internal.h"
#include "sink.h"
-#include "stack.h"
#include "string_utils.h"
#include "system.h"
#include "uri_utils.h"
@@ -65,6 +64,8 @@ typedef struct {
static const WriteContext WRITE_CONTEXT_NULL =
{CTX_NAMED, 0, NULL, NULL, NULL, false};
+static const size_t anon_stack_capacity = SERD_PAGE_SIZE / sizeof(WriteContext);
+
typedef enum {
SEP_NONE, ///< Placeholder for nodes or nothing
SEP_END_S, ///< End of a subject ('.')
@@ -127,7 +128,8 @@ struct SerdWriterImpl {
SerdEnv* env;
SerdNode* root_node;
SerdURIView root_uri;
- SerdStack anon_stack;
+ WriteContext* anon_stack;
+ size_t anon_stack_size;
SerdWriteFunc write_func;
void* stream;
WriteContext context;
@@ -180,15 +182,10 @@ push_context(SerdWriter* const writer,
const SerdNode* const s,
const SerdNode* const p)
{
- WriteContext* top =
- (WriteContext*)serd_stack_push(&writer->anon_stack, sizeof(WriteContext));
-
- if (!top) {
+ if (writer->anon_stack_size >= anon_stack_capacity) {
return SERD_ERR_OVERFLOW;
}
- *top = writer->context;
-
const WriteContext new_context = {type,
flags,
serd_node_copy(g),
@@ -196,21 +193,18 @@ push_context(SerdWriter* const writer,
serd_node_copy(p),
false};
- writer->context = new_context;
+ writer->anon_stack[writer->anon_stack_size++] = writer->context;
+ writer->context = new_context;
return SERD_SUCCESS;
}
static void
pop_context(SerdWriter* writer)
{
- assert(!serd_stack_is_empty(&writer->anon_stack));
+ assert(writer->anon_stack_size > 0);
free_context(writer);
- writer->context =
- *(WriteContext*)(writer->anon_stack.buf + writer->anon_stack.size -
- sizeof(WriteContext));
-
- serd_stack_pop(&writer->anon_stack, sizeof(WriteContext));
+ writer->context = writer->anon_stack[--writer->anon_stack_size];
}
static SerdNode*
@@ -635,7 +629,7 @@ static void
reset_context(SerdWriter* writer, bool graph)
{
// Free any lingering contexts in case there was an error
- while (!serd_stack_is_empty(&writer->anon_stack)) {
+ while (writer->anon_stack_size > 0) {
pop_context(writer);
}
@@ -651,10 +645,9 @@ reset_context(SerdWriter* writer, bool graph)
memset(writer->context.predicate, 0, sizeof(SerdNode));
}
+ writer->anon_stack_size = 0;
writer->context.indented_object = false;
writer->empty = false;
-
- serd_stack_clear(&writer->anon_stack);
}
static bool
@@ -1015,26 +1008,21 @@ serd_writer_write_statement(SerdWriter* const writer,
writer->context.indented_object = false;
}
- if (serd_stack_is_empty(&writer->anon_stack)) {
- if (ctx(writer, SERD_SUBJECT)) { // Terminate last subject
- TRY(st, write_sep(writer, writer->context.flags, SEP_END_S));
- }
- TRY(st, write_top_level_sep(writer));
- }
-
- if (serd_stack_is_empty(&writer->anon_stack)) {
- TRY(st, write_node(writer, subject, SERD_SUBJECT, flags));
- if (!(flags & (SERD_ANON_S | SERD_LIST_S))) {
- TRY(st, write_sep(writer, writer->context.flags, SEP_S_P));
- } else if (flags & SERD_ANON_S) {
- TRY(st, write_sep(writer, writer->context.flags, SEP_ANON_S_P));
- }
- } else {
- TRY(st, write_sep(writer, writer->context.flags, SEP_ANON_S_P));
+ if (ctx(writer, SERD_SUBJECT)) {
+ // Terminate last subject
+ TRY(st, write_sep(writer, writer->context.flags, SEP_END_S));
}
+ // Start new subject
+ TRY(st, write_top_level_sep(writer));
reset_context(writer, false);
serd_node_set(&writer->context.subject, subject);
+ TRY(st, write_node(writer, subject, SERD_SUBJECT, flags));
+ if (!(flags & (SERD_ANON_S | SERD_LIST_S))) {
+ TRY(st, write_sep(writer, writer->context.flags, SEP_S_P));
+ } else if (flags & SERD_ANON_S) {
+ TRY(st, write_sep(writer, writer->context.flags, SEP_ANON_S_P));
+ }
if (!(flags & SERD_LIST_S)) {
TRY(st, write_pred(writer, flags, predicate));
@@ -1080,7 +1068,7 @@ serd_writer_end_anon(SerdWriter* writer, const SerdNode* node)
return SERD_SUCCESS;
}
- if (serd_stack_is_empty(&writer->anon_stack)) {
+ if (writer->anon_stack_size == 0) {
return serd_world_errorf(writer->world,
SERD_ERR_UNKNOWN,
"unexpected end of anonymous node `%s'\n",
@@ -1131,7 +1119,7 @@ serd_writer_finish(SerdWriter* writer)
}
// Free any lingering contexts in case there was an error
- while (!serd_stack_is_empty(&writer->anon_stack)) {
+ while (writer->anon_stack_size > 0) {
pop_context(writer);
}
@@ -1159,12 +1147,14 @@ serd_writer_new(SerdWorld* world,
writer->env = env;
writer->root_node = NULL;
writer->root_uri = SERD_URI_NULL;
- writer->anon_stack = serd_stack_new(SERD_PAGE_SIZE);
writer->write_func = write_func;
writer->stream = stream;
writer->context = context;
writer->empty = true;
+ writer->anon_stack =
+ (WriteContext*)calloc(anon_stack_capacity, sizeof(WriteContext));
+
writer->iface.handle = writer;
writer->iface.on_event = (SerdEventFunc)serd_writer_on_event;
@@ -1269,7 +1259,7 @@ serd_writer_free(SerdWriter* writer)
}
serd_writer_finish(writer);
- serd_stack_free(&writer->anon_stack);
+ free(writer->anon_stack);
free(writer->bprefix);
serd_node_free(writer->root_node);
free(writer);