summaryrefslogtreecommitdiff
path: root/desktop/history_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/history_core.c')
-rw-r--r--desktop/history_core.c69
1 files changed, 31 insertions, 38 deletions
diff --git a/desktop/history_core.c b/desktop/history_core.c
index 749f54808..1150220bd 100644
--- a/desktop/history_core.c
+++ b/desktop/history_core.c
@@ -63,8 +63,8 @@ struct history {
int height;
};
-static bool history_clone_entry(struct history *history,
- struct history_entry **start);
+static struct history_entry *history_clone_entry(struct history *history,
+ struct history_entry *entry);
static void history_free_entry(struct history_entry *entry);
static void history_go(struct browser_window *bw, struct history *history,
struct history_entry *entry, bool new_window);
@@ -120,7 +120,9 @@ struct history *history_clone(struct history *history)
return 0;
memcpy(new_history, history, sizeof *history);
- if (!history_clone_entry(new_history, &new_history->start)) {
+ new_history->start = history_clone_entry(new_history,
+ new_history->start);
+ if (!history->start) {
warn_user("NoMemory", 0);
history_destroy(new_history);
return 0;
@@ -136,21 +138,22 @@ struct history *history_clone(struct history *history)
* \param history opaque history structure, as returned by history_create()
* \param start entry to clone
*
- * \return true on success, false otherwise.
+ * \return a cloned history entry, or 0 on error
*/
-bool history_clone_entry(struct history *history, struct history_entry **start)
+struct history_entry *history_clone_entry(struct history *history,
+ struct history_entry *entry)
{
struct history_entry *child;
- struct history_entry *sibling;
- struct history_entry *entry = *start;
+ struct history_entry *new_child;
+ struct history_entry *prev = NULL;
struct history_entry *new_entry;
/* clone the entry */
new_entry = malloc(sizeof *entry);
if (!new_entry) {
- *start = 0;
- return false;
+ history_destroy(history);
+ return 0;
}
memcpy(new_entry, entry, sizeof *entry);
new_entry->url = strdup(entry->url);
@@ -163,40 +166,30 @@ bool history_clone_entry(struct history *history, struct history_entry **start)
free(entry->url);
free(entry->title);
free(entry->frag_id);
- *start = 0;
- return false;
+ history_destroy(history);
+ return 0;
}
+
+ /* update references */
if (history->current == entry)
history->current = new_entry;
- *start = new_entry;
-
- if (entry->back) {
- /* update all entry->next refrences */
- for (sibling = entry->back->forward; sibling->next;
- sibling = sibling->next) {
- if (sibling->next == entry)
- sibling->next = new_entry;
- }
- /* update all entry->forward, entry->forward_pref, and
- * entry->forward_last references */
- if (entry->back->forward == entry)
- entry->back->forward = new_entry;
- if (entry->back->forward_pref == entry)
- entry->back->forward_pref = new_entry;
- if (entry->back->forward_last == entry)
- entry->back->forward_last = new_entry;
- }
- for (child = entry->forward; child; child = child->next) {
- child->back = new_entry;
- if (!history_clone_entry(history, &child)) {
- entry->next = 0;
- entry->forward = 0;
- return false;
- }
+ /* recurse for all children */
+ for (child = new_entry->forward; child; child = child->next) {
+ new_child = history_clone_entry(history, child);
+ assert(new_child);
+ new_child->back = entry;
+ if (prev)
+ prev->next = new_child;
+ if (new_entry->forward == child)
+ new_entry->forward = new_child;
+ if (new_entry->forward_pref == child)
+ new_entry->forward_pref = new_child;
+ if (new_entry->forward_last == child)
+ new_entry->forward_last = new_child;
+ prev = new_child;
}
-
- return true;
+ return new_entry;
}