aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Winston2024-06-09 20:33:04 -0400
committerBen Winston2024-06-09 20:33:04 -0400
commit49dab2ed917700711fe7c80ff437c6f66cd07842 (patch)
tree81c07513409fc0a48fc8d4091be518f9fc7227ce
parentc6399d0c9716a8f1c4afc083ffabd19fc000aad4 (diff)
capture additional fields, even if we're not using them
-rw-r--r--booki.c54
1 files changed, 48 insertions, 6 deletions
diff --git a/booki.c b/booki.c
index 32602ca..7bed085 100644
--- a/booki.c
+++ b/booki.c
@@ -13,7 +13,7 @@
#define MAX_SEARCH_OPTS 5
-enum DataType { booki_string, booki_number };
+enum DataType { booki_string, booki_number, booki_raw };
typedef struct DataField DataField;
@@ -32,7 +32,8 @@ static const DataField BOOK_FIELDS[] = {
{ "language", booki_string, true },
{ "translator", booki_string, true },
{ "on", booki_string, true },
- { "id", booki_number, false }
+ { "id", booki_number, false },
+ { "_other", booki_raw, false }
};
#define BOOK_FIELDS_COUNT (sizeof(BOOK_FIELDS) / sizeof(BOOK_FIELDS[0]))
@@ -402,6 +403,9 @@ struct Book {
ES translator;
ES on;
int published;
+
+ // catch-all
+ ES _other;
};
void init_book(BOOK* book) {
@@ -415,6 +419,8 @@ void init_book(BOOK* book) {
book->translator = default_es;
book->on = default_es;
book->published = 0;
+
+ book->_other = default_es;
}
#define ATTR_MATCH(cand, attr) (strncmp(cand, attr, strlen(attr)) == 0)
@@ -432,6 +438,8 @@ ES get_string_field(BOOK book, char* name) {
return book.translator;
else if (ATTR_MATCH(name, "on"))
return book.on;
+ else if (ATTR_MATCH(name, "_other"))
+ return book._other;
else
return default_es;
}
@@ -506,6 +514,16 @@ void write_book(BOOK book, FILE *output) {
continue;
size = sprintf(str, "%s = %d\n", datafield.name, number_field);
fwrite(str, 1, size, output);
+ } else if (datafield.type == booki_raw) {
+ string_field = get_string_field(book, datafield.name);
+ size = sprintf(str, "%.*s\n", string_field.len, string_field.ptr);
+ fwrite(str, 1, size, output);
+ ES* next = string_field.next;
+ while (next != NULL) {
+ size = sprintf(str, "%.*s\n", next->len, next->ptr);
+ fwrite(str, 1, size, output);
+ next = next->next;
+ }
}
}
@@ -514,10 +532,16 @@ void write_book(BOOK book, FILE *output) {
void free_book(BOOK book) {
// any string can be a list of strings
- free_es(book.author.next);
- free_es(book.translator.next);
- free_es(book.language.next);
- free_es(book.on.next);
+ DataField datafield;
+ ES string_field;
+ for (int i = 0; i < BOOK_FIELDS_COUNT; i++) {
+ datafield = BOOK_FIELDS[i];
+ if (datafield.type == booki_string || datafield.type == booki_raw) {
+ string_field = get_string_field(book, datafield.name);
+ free_es(string_field.next);
+ }
+
+ }
}
/*** parse toml-ish ***/
@@ -672,6 +696,24 @@ void parse_book(char* current_pos, BOOK* book) {
ES on = parse_strings(current_pos, &new_pos);
book->on = on;
current_pos = new_pos;
+ } else {
+ // anything we didn't match should be captured as-is
+ SEEK_UNTIL(current_pos, '\n');
+ if (book->_other.len == 0) {
+ ES other;
+ other.len = current_pos - attr;
+ other.ptr = attr;
+ other.next = NULL;
+ book->_other = other;
+ } else {
+ ES* last = &(book->_other);
+ while (last->next != NULL)
+ last = last->next;
+ last->next = (ES*)malloc(sizeof(ES));
+ last->next->len = current_pos - attr;
+ last->next->ptr = attr;
+ last->next->next = NULL;
+ }
}
// go to (and then past) the newline