aboutsummaryrefslogtreecommitdiffstats
path: root/src/cnki_outline_tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cnki_outline_tree.c')
-rw-r--r--src/cnki_outline_tree.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/cnki_outline_tree.c b/src/cnki_outline_tree.c
new file mode 100644
index 0000000..7d16ddb
--- /dev/null
+++ b/src/cnki_outline_tree.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2020, yzrh <yzrh@tuta.io>
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <stdlib.h>
+
+#include "cnki.h"
+
+int
+cnki_outline_tree(object_outline_tree_t **outline_tree,
+ object_outline_t **outline, int *ids)
+{
+ if (*outline_tree != NULL || *outline == NULL)
+ return 1;
+
+ int pos = 0;
+
+ *outline_tree = malloc(sizeof(object_outline_tree_t));
+
+ if (*outline_tree == NULL)
+ return 1;
+
+ object_outline_tree_t *tree = *outline_tree;
+
+ tree->id = ids[pos++];
+ tree->item = NULL;
+ tree->up = NULL;
+ tree->left = NULL;
+ tree->right = NULL;
+
+ object_outline_t *ptr = *outline;
+ while (ptr != NULL) {
+ if (tree->item == NULL ||
+ ptr->depth == tree->item->depth) {
+ while (tree->left != NULL)
+ tree = tree->left;
+
+ tree->left = malloc(sizeof(object_outline_tree_t));
+
+ if (tree->left == NULL)
+ return 1;
+
+ tree->left->id = ids[pos++];
+ tree->left->item = ptr;
+ tree->left->up = tree;
+ tree->left->left = NULL;
+ tree->left->right = NULL;
+
+ tree = tree->left;
+ } else if (ptr->depth == tree->item->depth + 1) {
+ tree->right = malloc(sizeof(object_outline_tree_t));
+
+ if (tree->right == NULL)
+ return 1;
+
+ tree->right->id = ids[pos++];
+ tree->right->item = ptr;
+ tree->right->up = tree;
+ tree->right->left = NULL;
+ tree->right->right = NULL;
+
+ tree = tree->right;
+ } else {
+ tree = tree->up;
+ continue;
+ }
+ ptr = ptr->next;
+ }
+
+ return 0;
+}