about summary refs log tree commit diff stats
path: root/src/LYHistory.c
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2011-06-11 12:12:46 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2011-06-11 12:12:46 -0400
commit279010bc0791556e63b4951d83a2c45252142b80 (patch)
tree2f0ca07764a555764bb1f5a628a3468e88bf0c59 /src/LYHistory.c
parent0b30d0d375231ff07227872f2d1d25f005e43e98 (diff)
downloadlynx-snapshots-279010bc0791556e63b4951d83a2c45252142b80.tar.gz
snapshot of project "lynx", label v2_8_8dev_9a
Diffstat (limited to 'src/LYHistory.c')
-rw-r--r--src/LYHistory.c1173
1 files changed, 0 insertions, 1173 deletions
diff --git a/src/LYHistory.c b/src/LYHistory.c
deleted file mode 100644
index 5ac35038..00000000
--- a/src/LYHistory.c
+++ /dev/null
@@ -1,1173 +0,0 @@
-/*
- * $LynxId: LYHistory.c,v 1.81 2011/05/28 13:05:14 tom Exp $
- */
-#include <HTUtils.h>
-#include <HTTP.h>
-#include <GridText.h>
-#include <HTAlert.h>
-#include <HText.h>
-#include <LYGlobalDefs.h>
-#include <LYUtils.h>
-#include <LYHistory.h>
-#include <LYPrint.h>
-#include <LYDownload.h>
-#include <LYOptions.h>
-#include <LYKeymap.h>
-#include <LYList.h>
-#include <LYShowInfo.h>
-#include <LYStrings.h>
-#include <LYCharUtils.h>
-#include <LYCharSets.h>
-#include <LYrcFile.h>
-#ifdef DISP_PARTIAL
-#include <LYMainLoop.h>
-#endif
-
-#ifdef DIRED_SUPPORT
-#include <LYUpload.h>
-#include <LYLocal.h>
-#endif /* DIRED_SUPPORT */
-
-#include <LYexit.h>
-#include <LYLeaks.h>
-#include <HTCJK.h>
-
-HTList *Visited_Links = NULL;	/* List of safe popped docs. */
-int Visited_Links_As = VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE;
-
-static VisitedLink *PrevVisitedLink = NULL;	/* NULL on auxillary */
-static VisitedLink *PrevActiveVisitedLink = NULL;	/* Last non-auxillary */
-static VisitedLink Latest_first;
-static VisitedLink Latest_last;
-static VisitedLink *Latest_tree;
-static VisitedLink *First_tree;
-static VisitedLink *Last_by_first;
-
-int nhist_extra;
-
-#ifdef LY_FIND_LEAKS
-static int already_registered_free_messages_stack = 0;
-static int already_registered_clean_all_history = 0;
-#endif
-
-#ifdef LY_FIND_LEAKS
-/*
- * Utility for freeing the list of visited links.  - FM
- */
-static void Visited_Links_free(void)
-{
-    VisitedLink *vl;
-    HTList *cur = Visited_Links;
-
-    PrevVisitedLink = NULL;
-    PrevActiveVisitedLink = NULL;
-    if (!cur)
-	return;
-
-    while (NULL != (vl = (VisitedLink *) HTList_nextObject(cur))) {
-	FREE(vl->address);
-	FREE(vl->title);
-	FREE(vl);
-    }
-    HTList_delete(Visited_Links);
-    Visited_Links = NULL;
-    Latest_last.prev_latest = &Latest_first;
-    Latest_first.next_latest = &Latest_last;
-    Last_by_first = Latest_tree = First_tree = 0;
-    return;
-}
-#endif /* LY_FIND_LEAKS */
-
-#ifdef DEBUG
-static void trace_history(const char *tag)
-{
-    if (TRACE) {
-	CTRACE((tfp, "HISTORY %s %d/%d (%d extra)\n",
-		tag, nhist, size_history, nhist_extra));
-	CTRACE_FLUSH(tfp);
-    }
-}
-#else
-#define trace_history(tag)	/* nothing */
-#endif /* DEBUG */
-
-/*
- * Utility for listing visited links, making any repeated links the most
- * current in the list.  - FM
- */
-void LYAddVisitedLink(DocInfo *doc)
-{
-    VisitedLink *tmp;
-    HTList *cur;
-    const char *title = (doc->title ? doc->title : NO_TITLE);
-
-    if (isEmpty(doc->address)) {
-	PrevVisitedLink = NULL;
-	return;
-    }
-
-    /*
-     * Exclude POST or HEAD replies, and bookmark, menu or list files.  - FM
-     */
-    if (doc->post_data || doc->isHEAD || doc->bookmark ||
-	(			/* special url or a temp file */
-	    (!StrNCmp(doc->address, "LYNX", 4) ||
-	     !StrNCmp(doc->address, "file://localhost/", 17)))) {
-	int related = 1;	/* First approximation only */
-
-	if (LYIsUIPage(doc->address, UIP_HISTORY) ||
-	    LYIsUIPage(doc->address, UIP_VLINKS) ||
-	    LYIsUIPage(doc->address, UIP_SHOWINFO) ||
-	    isLYNXMESSAGES(doc->address) ||
-	    ((related = 0) != 0) ||
-#ifdef DIRED_SUPPORT
-	    LYIsUIPage(doc->address, UIP_DIRED_MENU) ||
-	    LYIsUIPage(doc->address, UIP_UPLOAD_OPTIONS) ||
-	    LYIsUIPage(doc->address, UIP_PERMIT_OPTIONS) ||
-#endif /* DIRED_SUPPORT */
-	    LYIsUIPage(doc->address, UIP_PRINT_OPTIONS) ||
-	    LYIsUIPage(doc->address, UIP_DOWNLOAD_OPTIONS) ||
-	    LYIsUIPage(doc->address, UIP_OPTIONS_MENU) ||
-	    isLYNXKEYMAP(doc->address) ||
-	    LYIsUIPage(doc->address, UIP_LIST_PAGE) ||
-#ifdef USE_ADDRLIST_PAGE
-	    LYIsUIPage(doc->address, UIP_ADDRLIST_PAGE) ||
-#endif
-	    LYIsUIPage(doc->address, UIP_CONFIG_DEF) ||
-	    LYIsUIPage(doc->address, UIP_LYNXCFG) ||
-	    isLYNXCOOKIE(doc->address) ||
-	    LYIsUIPage(doc->address, UIP_TRACELOG)) {
-	    if (!related)
-		PrevVisitedLink = NULL;
-	    return;
-	}
-    }
-
-    if (!Visited_Links) {
-	Visited_Links = HTList_new();
-#ifdef LY_FIND_LEAKS
-	atexit(Visited_Links_free);
-#endif
-	Latest_last.prev_latest = &Latest_first;
-	Latest_first.next_latest = &Latest_last;
-	Latest_last.next_latest = NULL;		/* Find bugs quick! */
-	Latest_first.prev_latest = NULL;
-	Last_by_first = Latest_tree = First_tree = NULL;
-    }
-
-    cur = Visited_Links;
-    while (NULL != (tmp = (VisitedLink *) HTList_nextObject(cur))) {
-	if (!strcmp(NonNull(tmp->address),
-		    NonNull(doc->address))) {
-	    PrevVisitedLink = PrevActiveVisitedLink = tmp;
-	    /* Already visited.  Update the last-visited info. */
-	    if (tmp->next_latest == &Latest_last)	/* optimization */
-		return;
-
-	    /* Remove from "latest" chain */
-	    tmp->prev_latest->next_latest = tmp->next_latest;
-	    tmp->next_latest->prev_latest = tmp->prev_latest;
-
-	    /* Insert at the end of the "latest" chain */
-	    Latest_last.prev_latest->next_latest = tmp;
-	    tmp->prev_latest = Latest_last.prev_latest;
-	    tmp->next_latest = &Latest_last;
-	    Latest_last.prev_latest = tmp;
-	    return;
-	}
-    }
-
-    if ((tmp = typecalloc(VisitedLink)) == NULL)
-	outofmem(__FILE__, "LYAddVisitedLink");
-
-    assert(tmp != NULL);
-
-    StrAllocCopy(tmp->address, doc->address);
-    LYformTitle(&(tmp->title), title);
-
-    /* First-visited chain */
-    HTList_appendObject(Visited_Links, tmp);	/* At end */
-    tmp->prev_first = Last_by_first;
-    Last_by_first = tmp;
-
-    /* Tree structure */
-    if (PrevVisitedLink) {
-	VisitedLink *a = PrevVisitedLink;
-	VisitedLink *b = a->next_tree;
-	int l = PrevVisitedLink->level;
-
-	/* Find last on the deeper levels */
-	while (b && b->level > l)
-	    a = b, b = b->next_tree;
-
-	if (!b)			/* a == Latest_tree */
-	    Latest_tree = tmp;
-	tmp->next_tree = a->next_tree;
-	a->next_tree = tmp;
-
-	tmp->level = PrevVisitedLink->level + 1;
-    } else {
-	if (Latest_tree)
-	    Latest_tree->next_tree = tmp;
-	tmp->level = 0;
-	tmp->next_tree = NULL;
-	Latest_tree = tmp;
-    }
-    PrevVisitedLink = PrevActiveVisitedLink = tmp;
-    if (!First_tree)
-	First_tree = tmp;
-
-    /* "latest" chain */
-    Latest_last.prev_latest->next_latest = tmp;
-    tmp->prev_latest = Latest_last.prev_latest;
-    tmp->next_latest = &Latest_last;
-    Latest_last.prev_latest = tmp;
-
-    return;
-}
-
-/*
- * Returns true if this is a page that we would push onto the stack if not
- * forced.  If docurl is NULL, only the title is considered; otherwise also
- * check the URL whether it is (likely to be) a generated special page.
- */
-BOOLEAN LYwouldPush(const char *title,
-		    const char *docurl)
-{
-    BOOLEAN rc = FALSE;
-
-    /*
-     * All non-pushable generated pages have URLs that begin with
-     * "file://localhost/" and end with HTML_SUFFIX.  - kw
-     */
-    if (docurl) {
-	size_t ulen;
-
-	if (StrNCmp(docurl, "file://localhost/", 17) != 0 ||
-	    (ulen = strlen(docurl)) <= strlen(HTML_SUFFIX) ||
-	    strcmp(docurl + ulen - strlen(HTML_SUFFIX), HTML_SUFFIX) != 0) {
-	    /*
-	     * If it is not a local HTML file, it may be a Web page that
-	     * accidentally has the same title.  So return TRUE now.  - kw
-	     */
-	    return TRUE;
-	}
-    }
-
-    if (docurl) {
-	rc = (BOOLEAN)
-	    !(LYIsUIPage(docurl, UIP_HISTORY)
-	      || LYIsUIPage(docurl, UIP_PRINT_OPTIONS)
-#ifdef DIRED_SUPPORT
-	      || LYIsUIPage(docurl, UIP_DIRED_MENU)
-	      || LYIsUIPage(docurl, UIP_UPLOAD_OPTIONS)
-	      || LYIsUIPage(docurl, UIP_PERMIT_OPTIONS)
-#endif /* DIRED_SUPPORT */
-	    );
-    } else {
-	rc = (BOOLEAN)
-	    !(!strcmp(title, HISTORY_PAGE_TITLE)
-	      || !strcmp(title, PRINT_OPTIONS_TITLE)
-#ifdef DIRED_SUPPORT
-	      || !strcmp(title, DIRED_MENU_TITLE)
-	      || !strcmp(title, UPLOAD_OPTIONS_TITLE)
-	      || !strcmp(title, PERMIT_OPTIONS_TITLE)
-#endif /* DIRED_SUPPORT */
-	    );
-    }
-    return rc;
-}
-
-/*
- * Free post-data for 'DocInfo'
- */
-void LYFreePostData(DocInfo *doc)
-{
-    BStrFree(doc->post_data);
-    FREE(doc->post_content_type);
-}
-
-/*
- * Free strings associated with a 'DocInfo' struct.
- */
-void LYFreeDocInfo(DocInfo *doc)
-{
-    FREE(doc->title);
-    FREE(doc->address);
-    FREE(doc->bookmark);
-    LYFreePostData(doc);
-}
-
-/*
- * Free the information in the last history entry.
- */
-static void clean_extra_history(void)
-{
-    trace_history("clean_extra_history");
-    nhist += nhist_extra;
-    while (nhist_extra > 0) {
-	nhist--;
-	LYFreeDocInfo(&HDOC(nhist));
-	nhist_extra--;
-    }
-    trace_history("...clean_extra_history");
-}
-
-/*
- * Free the entire history stack, for auditing memory leaks.
- */
-#ifdef LY_FIND_LEAKS
-static void clean_all_history(void)
-{
-    trace_history("clean_all_history");
-    clean_extra_history();
-    while (nhist > 0) {
-	nhist--;
-	LYFreeDocInfo(&HDOC(nhist));
-    }
-    trace_history("...clean_all_history");
-}
-#endif
-
-/* FIXME What is the relationship to are_different() from the mainloop?! */
-static int are_identical(HistInfo * doc, DocInfo *doc1)
-{
-    return (STREQ(doc1->address, doc->hdoc.address)
-	    && BINEQ(doc1->post_data, doc->hdoc.post_data)
-	    && !strcmp(NonNull(doc1->bookmark),
-		       NonNull(doc->hdoc.bookmark))
-	    && doc1->isHEAD == doc->hdoc.isHEAD);
-}
-
-void LYAllocHistory(int entries)
-{
-    CTRACE((tfp, "LYAllocHistory %d vs %d\n", entries, size_history));
-    if (entries + 1 >= size_history) {
-	unsigned want;
-	int save = size_history;
-
-	size_history = (entries + 2) * 2;
-	want = (unsigned) size_history *(unsigned) sizeof(*history);
-
-	if (history == 0) {
-	    history = typeMallocn(HistInfo, want);
-	} else {
-	    history = typeRealloc(HistInfo, history, want);
-	}
-	if (history == 0)
-	    outofmem(__FILE__, "LYAllocHistory");
-
-	assert(history != NULL);
-
-	while (save < size_history) {
-	    memset(&history[save++], 0, sizeof(history[0]));
-	}
-    }
-    CTRACE((tfp, "...LYAllocHistory %d vs %d\n", entries, size_history));
-}
-
-/*
- * Push the current filename, link and line number onto the history list.
- */
-int LYpush(DocInfo *doc, int force_push)
-{
-    /*
-     * Don't push NULL file names.
-     */
-    if (*doc->address == '\0')
-	return 0;
-
-    /*
-     * Check whether this is a document we don't push unless forced.  - FM
-     */
-    if (!force_push) {
-	/*
-	 * Don't push the history, printer, or download lists.
-	 */
-	if (!LYwouldPush(doc->title, doc->address)) {
-	    if (!LYforce_no_cache)
-		LYoverride_no_cache = TRUE;
-	    return 0;
-	}
-    }
-
-    /*
-     * If file is identical to one before it, don't push it.
-     * But do not duplicate it if there is only one on the stack,
-     * note that HDOC() starts from 0, so nhist should be > 0.
-     */
-    if (nhist >= 1 && are_identical(&(history[nhist - 1]), doc)) {
-	if (HDOC(nhist - 1).internal_link == doc->internal_link) {
-	    /* But it is nice to have the last position remembered!
-	       - kw */
-	    HDOC(nhist - 1).link = doc->link;
-	    HDOC(nhist - 1).line = doc->line;
-	    return 0;
-	}
-    }
-
-    /*
-     * If file is identical to the current document, just move the pointer.
-     */
-    if (nhist_extra >= 1 && are_identical(&(history[nhist]), doc)) {
-	HDOC(nhist).link = doc->link;
-	HDOC(nhist).line = doc->line;
-	nhist_extra--;
-	LYAllocHistory(nhist);
-	nhist++;
-	trace_history("LYpush: just move the cursor");
-	return 1;
-    }
-
-    clean_extra_history();
-#ifdef LY_FIND_LEAKS
-    if (!already_registered_clean_all_history) {
-	already_registered_clean_all_history = 1;
-	atexit(clean_all_history);
-    }
-#endif
-
-    /*
-     * OK, push it...
-     */
-    LYAllocHistory(nhist);
-    HDOC(nhist).link = doc->link;
-    HDOC(nhist).line = doc->line;
-
-    HDOC(nhist).title = NULL;
-    LYformTitle(&(HDOC(nhist).title), doc->title);
-
-    HDOC(nhist).address = NULL;
-    StrAllocCopy(HDOC(nhist).address, doc->address);
-
-    HDOC(nhist).post_data = NULL;
-    BStrCopy(HDOC(nhist).post_data, doc->post_data);
-
-    HDOC(nhist).post_content_type = NULL;
-    StrAllocCopy(HDOC(nhist).post_content_type, doc->post_content_type);
-
-    HDOC(nhist).bookmark = NULL;
-    StrAllocCopy(HDOC(nhist).bookmark, doc->bookmark);
-
-    HDOC(nhist).isHEAD = doc->isHEAD;
-    HDOC(nhist).safe = doc->safe;
-
-    HDOC(nhist).internal_link = FALSE;	/* by default */
-    history[nhist].intern_seq_start = -1;	/* by default */
-    if (doc->internal_link) {
-	/* Now some tricky stuff: if the caller thinks that the doc
-	   to push was the result of following an internal
-	   (fragment) link, we check whether we believe it.
-	   It is only accepted as valid if the immediately preceding
-	   item on the history stack is actually the same document
-	   except for fragment and location info.  I.e. the Parent
-	   Anchors are the same.
-	   Also of course this requires that this is not the first
-	   history item. - kw */
-	if (nhist > 0) {
-	    DocAddress WWWDoc;
-	    HTParentAnchor *thisparent, *thatparent = NULL;
-
-	    WWWDoc.address = doc->address;
-	    WWWDoc.post_data = doc->post_data;
-	    WWWDoc.post_content_type = doc->post_content_type;
-	    WWWDoc.bookmark = doc->bookmark;
-	    WWWDoc.isHEAD = doc->isHEAD;
-	    WWWDoc.safe = doc->safe;
-	    thisparent =
-		HTAnchor_findAddress(&WWWDoc);
-	    /* Now find the ParentAnchor for the previous history
-	     * item - kw
-	     */
-	    if (thisparent) {
-		/* If the last-pushed item is a LYNXIMGMAP but THIS one
-		 * isn't, compare the physical URLs instead. - kw
-		 */
-		if (isLYNXIMGMAP(HDOC(nhist - 1).address) &&
-		    !isLYNXIMGMAP(doc->address)) {
-		    WWWDoc.address = HDOC(nhist - 1).address + LEN_LYNXIMGMAP;
-		    /*
-		     * If THIS item is a LYNXIMGMAP but the last-pushed one
-		     * isn't, fake it by using THIS item's address for
-		     * thatparent... - kw
-		     */
-		} else if (isLYNXIMGMAP(doc->address) &&
-			   !isLYNXIMGMAP(HDOC(nhist - 1).address)) {
-		    char *temp = NULL;
-
-		    StrAllocCopy(temp, STR_LYNXIMGMAP);
-		    StrAllocCat(temp, doc->address + LEN_LYNXIMGMAP);
-		    WWWDoc.address = temp;
-		    WWWDoc.post_content_type = HDOC(nhist - 1).post_content_type;
-		    WWWDoc.bookmark = HDOC(nhist - 1).bookmark;
-		    WWWDoc.isHEAD = HDOC(nhist - 1).isHEAD;
-		    WWWDoc.safe = HDOC(nhist - 1).safe;
-		    thatparent =
-			HTAnchor_findAddress(&WWWDoc);
-		    FREE(temp);
-		} else {
-		    WWWDoc.address = HDOC(nhist - 1).address;
-		}
-		if (!thatparent) {	/* if not yet done */
-		    WWWDoc.post_data = HDOC(nhist - 1).post_data;
-		    WWWDoc.post_content_type = HDOC(nhist - 1).post_content_type;
-		    WWWDoc.bookmark = HDOC(nhist - 1).bookmark;
-		    WWWDoc.isHEAD = HDOC(nhist - 1).isHEAD;
-		    WWWDoc.safe = HDOC(nhist - 1).safe;
-		    thatparent =
-			HTAnchor_findAddress(&WWWDoc);
-		}
-		/* In addition to equality of the ParentAnchors, require
-		 * that IF we have a HTMainText (i.e., it wasn't just
-		 * HTuncache'd by mainloop), THEN it has to be consistent
-		 * with what we are trying to push.
-		 *
-		 * This may be overkill...  - kw
-		 */
-		if (thatparent == thisparent &&
-		    (!HTMainText || HTMainAnchor == thisparent)
-		    ) {
-		    HDOC(nhist).internal_link = TRUE;
-		    history[nhist].intern_seq_start =
-			history[nhist - 1].intern_seq_start >= 0 ?
-			history[nhist - 1].intern_seq_start : nhist - 1;
-		    CTRACE((tfp, "\nLYpush: pushed as internal link, OK\n"));
-		}
-	    }
-	}
-	if (!HDOC(nhist).internal_link) {
-	    CTRACE((tfp, "\nLYpush: push as internal link requested, %s\n",
-		    "but didn't check out!"));
-	}
-    }
-    CTRACE((tfp, "\nLYpush[%d]: address:%s\n        title:%s\n",
-	    nhist, doc->address, doc->title));
-    nhist++;
-    return 1;
-}
-
-/*
- * Pop the previous filename, link and line number from the history list.
- */
-void LYpop(DocInfo *doc)
-{
-    if (nhist > 0) {
-	clean_extra_history();
-	nhist--;
-
-	LYFreeDocInfo(doc);
-
-	*doc = HDOC(nhist);
-
-#ifdef DISP_PARTIAL
-	/* assume we pop the 'doc' to show it soon... */
-	LYSetNewline(doc->line);	/* reinitialize */
-#endif /* DISP_PARTIAL */
-	CTRACE((tfp, "LYpop[%d]: address:%s\n     title:%s\n",
-		nhist, doc->address, doc->title));
-    }
-}
-
-/*
- * Move to the previous filename, link and line number from the history list.
- */
-void LYhist_prev(DocInfo *doc)
-{
-    trace_history("LYhist_prev");
-    if (nhist > 0 && (nhist_extra || nhist < size_history)) {
-	nhist--;
-	nhist_extra++;
-	LYpop_num(nhist, doc);
-	trace_history("...LYhist_prev");
-    }
-}
-
-/*
- * Called before calling LYhist_prev().
- */
-void LYhist_prev_register(DocInfo *doc)
-{
-    trace_history("LYhist_prev_register");
-    if (nhist > 1) {
-	if (nhist_extra) {	/* Make something to return back */
-	    /* Store the new position */
-	    HDOC(nhist).link = doc->link;
-	    HDOC(nhist).line = doc->line;
-	} else if (LYpush(doc, 0)) {
-	    nhist--;
-	    nhist_extra++;
-	}
-	trace_history("...LYhist_prev_register");
-    }
-}
-
-/*
- * Move to the next filename, link and line number from the history.
- */
-int LYhist_next(DocInfo *doc, DocInfo *newdoc)
-{
-    if (nhist_extra <= 1)	/* == 1 when we are the last one */
-	return 0;
-    /* Store the new position */
-    HDOC(nhist).link = doc->link;
-    HDOC(nhist).line = doc->line;
-    LYAllocHistory(nhist);
-    nhist++;
-    nhist_extra--;
-    LYpop_num(nhist, newdoc);
-    return 1;
-}
-
-/*
- * Pop the specified hist entry, link and line number from the history list but
- * don't actually remove the entry, just return it.
- * (This procedure is badly named :)
- */
-void LYpop_num(int number,
-	       DocInfo *doc)
-{
-    if (number >= 0 && nhist + nhist_extra > number) {
-	doc->link = HDOC(number).link;
-	doc->line = HDOC(number).line;
-	StrAllocCopy(doc->title, HDOC(number).title);
-	StrAllocCopy(doc->address, HDOC(number).address);
-	BStrCopy(doc->post_data, HDOC(number).post_data);
-	StrAllocCopy(doc->post_content_type, HDOC(number).post_content_type);
-	StrAllocCopy(doc->bookmark, HDOC(number).bookmark);
-	doc->isHEAD = HDOC(number).isHEAD;
-	doc->safe = HDOC(number).safe;
-	doc->internal_link = HDOC(number).internal_link;	/* ?? */
-#ifdef DISP_PARTIAL
-	/* assume we pop the 'doc' to show it soon... */
-	LYSetNewline(doc->line);	/* reinitialize */
-#endif /* DISP_PARTIAL */
-	if (TRACE) {
-	    CTRACE((tfp, "LYpop_num(%d)\n", number));
-	    CTRACE((tfp, "  link    %d\n", doc->link));
-	    CTRACE((tfp, "  line    %d\n", doc->line));
-	    CTRACE((tfp, "  title   %s\n", NonNull(doc->title)));
-	    CTRACE((tfp, "  address %s\n", NonNull(doc->address)));
-	}
-    }
-}
-
-/*
- * This procedure outputs the history buffer into a temporary file.
- */
-int showhistory(char **newfile)
-{
-    static char tempfile[LY_MAXPATH] = "\0";
-    char *Title = NULL;
-    int x = 0;
-    FILE *fp0;
-
-    if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
-	return (-1);
-
-    LYLocalFileToURL(newfile, tempfile);
-
-    LYforce_HTML_mode = TRUE;	/* force this file to be HTML */
-    LYforce_no_cache = TRUE;	/* force this file to be new */
-
-    BeginInternalPage(fp0, HISTORY_PAGE_TITLE, HISTORY_PAGE_HELP);
-
-    fprintf(fp0, "<p align=right> <a href=\"%s\">[%s]</a>\n",
-	    STR_LYNXMESSAGES, STATUSLINES_TITLE);
-
-    fprintf(fp0, "<pre>\n");
-
-    fprintf(fp0, "<em>%s</em>\n", gettext("You selected:"));
-    for (x = nhist + nhist_extra - 1; x >= 0; x--) {
-	/*
-	 * The number of the document in the hist stack, its title in a link,
-	 * and its address.  - FM
-	 */
-	if (HDOC(x).title != NULL) {
-	    StrAllocCopy(Title, HDOC(x).title);
-	    LYEntify(&Title, TRUE);
-	    LYTrimLeading(Title);
-	    LYTrimTrailing(Title);
-	    if (*Title == '\0')
-		StrAllocCopy(Title, NO_TITLE);
-	} else {
-	    StrAllocCopy(Title, NO_TITLE);
-	}
-	fprintf(fp0,
-		"%s<em>%d</em>. <tab id=t%d><a href=\"%s%d\">%s</a>\n",
-		(x > 99 ? "" : x < 10 ? "  " : " "),
-		x, x, STR_LYNXHIST, x, Title);
-	if (HDOC(x).address != NULL) {
-	    StrAllocCopy(Title, HDOC(x).address);
-	    LYEntify(&Title, TRUE);
-	} else {
-	    StrAllocCopy(Title, gettext("(no address)"));
-	}
-	if (HDOC(x).internal_link) {
-	    if (history[x].intern_seq_start == history[nhist - 1].intern_seq_start)
-		StrAllocCat(Title, gettext(" (internal)"));
-	    else
-		StrAllocCat(Title, gettext(" (was internal)"));
-	}
-	fprintf(fp0, "<tab to=t%d>%s\n", x, Title);
-    }
-    fprintf(fp0, "</pre>\n");
-    EndInternalPage(fp0);
-
-    LYCloseTempFP(fp0);
-    FREE(Title);
-    return (0);
-}
-
-/*
- * This function makes the history page seem like any other type of file since
- * more info is needed than can be provided by the normal link structure.  We
- * saved out the history number to a special URL.
- *
- * The info looks like:  LYNXHIST:#
- */
-BOOLEAN historytarget(DocInfo *newdoc)
-{
-    int number;
-    DocAddress WWWDoc;
-    HTParentAnchor *tmpanchor;
-    HText *text;
-    BOOLEAN treat_as_intern = FALSE;
-
-    if ((!newdoc || !newdoc->address) ||
-	strlen(newdoc->address) < 10 || !isdigit(UCH(*(newdoc->address + 9))))
-	return (FALSE);
-
-    if ((number = atoi(newdoc->address + 9)) > nhist + nhist_extra || number < 0)
-	return (FALSE);
-
-    /*
-     * Optimization: assume we came from the History Page,
-     * so never return back - always a new version next time.
-     * But check first whether HTMainText is really the History
-     * Page document - in some obscure situations this may not be
-     * the case.  If HTMainText seems to be a History Page document,
-     * also check that it really hasn't been pushed. - LP, kw
-     */
-    if (HTMainText && nhist > 0 &&
-	!strcmp(HTLoadedDocumentTitle(), HISTORY_PAGE_TITLE) &&
-	LYIsUIPage3(HTLoadedDocumentURL(), UIP_HISTORY, 0) &&
-	strcmp(HTLoadedDocumentURL(), HDOC(nhist - 1).address)) {
-	HTuncache_current_document();	/* don't waste the cache */
-    }
-
-    LYpop_num(number, newdoc);
-    if (((newdoc->internal_link &&
-	  history[number].intern_seq_start == history[nhist - 1].intern_seq_start)
-	 || (number < nhist - 1 &&
-	     HDOC(nhist - 1).internal_link &&
-	     number == history[nhist - 1].intern_seq_start))
-	&& !(LYforce_no_cache == TRUE && LYoverride_no_cache == FALSE)) {
-#ifndef DONT_TRACK_INTERNAL_LINKS
-	LYforce_no_cache = FALSE;
-	LYinternal_flag = TRUE;
-	newdoc->internal_link = TRUE;
-	treat_as_intern = TRUE;
-#endif
-    } else {
-	newdoc->internal_link = FALSE;
-    }
-    /*
-     * If we have POST content, and have LYresubmit_posts set or have no_cache
-     * set or do not still have the text cached, ask the user whether to
-     * resubmit the form.  - FM
-     */
-    if (newdoc->post_data != NULL) {
-	WWWDoc.address = newdoc->address;
-	WWWDoc.post_data = newdoc->post_data;
-	WWWDoc.post_content_type = newdoc->post_content_type;
-	WWWDoc.bookmark = newdoc->bookmark;
-	WWWDoc.isHEAD = newdoc->isHEAD;
-	WWWDoc.safe = newdoc->safe;
-	tmpanchor = HTAnchor_findAddress(&WWWDoc);
-	text = (HText *) HTAnchor_document(tmpanchor);
-	if (((((LYresubmit_posts == TRUE) ||
-	       (LYforce_no_cache == TRUE &&
-		LYoverride_no_cache == FALSE)) &&
-	      !(treat_as_intern && !reloading)) ||
-	     text == NULL) &&
-	    (isLYNXIMGMAP(newdoc->address) ||
-	     HTConfirm(CONFIRM_POST_RESUBMISSION) == TRUE)) {
-	    LYforce_no_cache = TRUE;
-	    LYoverride_no_cache = FALSE;
-	} else if (text != NULL) {
-	    LYforce_no_cache = FALSE;
-	    LYoverride_no_cache = TRUE;
-	} else {
-	    HTInfoMsg(CANCELLED);
-	    return (FALSE);
-	}
-    }
-
-    if (number != 0)
-	StrAllocCat(newdoc->title, gettext(" (From History)"));
-    return (TRUE);
-}
-
-/*
- * This procedure outputs the Visited Links list into a temporary file.  - FM
- * Returns links's number to make active (1-based), or 0 if not required.
- */
-int LYShowVisitedLinks(char **newfile)
-{
-    static char tempfile[LY_MAXPATH] = "\0";
-    char *Title = NULL;
-    char *Address = NULL;
-    int x, tot;
-    FILE *fp0;
-    VisitedLink *vl;
-    HTList *cur = Visited_Links;
-    int offset;
-    int ret = 0;
-    const char *arrow, *post_arrow;
-
-    if (!cur)
-	return (-1);
-
-    if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
-	return (-1);
-
-    LYLocalFileToURL(newfile, tempfile);
-    LYRegisterUIPage(*newfile, UIP_VLINKS);
-
-    LYforce_HTML_mode = TRUE;	/* force this file to be HTML */
-    LYforce_no_cache = TRUE;	/* force this file to be new */
-
-    BeginInternalPage(fp0, VISITED_LINKS_TITLE, VISITED_LINKS_HELP);
-
-#ifndef NO_OPTION_FORMS
-    fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS);
-    LYMenuVisitedLinks(fp0, FALSE);
-    fprintf(fp0, "<input type=\"submit\" value=\"Accept Changes\">\n");
-    fprintf(fp0, "</form>\n");
-    fprintf(fp0, "<P>\n");
-#endif
-
-    fprintf(fp0, "<pre>\n");
-    fprintf(fp0, "<em>%s</em>\n",
-	    gettext("You visited (POSTs, bookmark, menu and list files excluded):"));
-    if (Visited_Links_As & VISITED_LINKS_REVERSE)
-	tot = x = HTList_count(Visited_Links);
-    else
-	tot = x = -1;
-
-    if (Visited_Links_As & VISITED_LINKS_AS_TREE) {
-	vl = First_tree;
-    } else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) {
-	if (Visited_Links_As & VISITED_LINKS_REVERSE)
-	    vl = Latest_last.prev_latest;
-	else
-	    vl = Latest_first.next_latest;
-	if (vl == &Latest_last || vl == &Latest_first)
-	    vl = NULL;
-    } else {
-	if (Visited_Links_As & VISITED_LINKS_REVERSE)
-	    vl = Last_by_first;
-	else
-	    vl = (VisitedLink *) HTList_nextObject(cur);
-    }
-    while (NULL != vl) {
-	/*
-	 * The number of the document (most recent highest), its title in a
-	 * link, and its address.  - FM
-	 */
-	post_arrow = arrow = "";
-	if (Visited_Links_As & VISITED_LINKS_REVERSE)
-	    x--;
-	else
-	    x++;
-	if (vl == PrevActiveVisitedLink) {
-	    if (Visited_Links_As & VISITED_LINKS_REVERSE)
-		ret = tot - x + 2;
-	    else
-		ret = x + 3;
-	}
-	if (vl == PrevActiveVisitedLink) {
-	    post_arrow = "<A NAME=current></A>";
-	    /* Otherwise levels 0 and 1 look the same when with arrow: */
-	    arrow = (vl->level && (Visited_Links_As & VISITED_LINKS_AS_TREE))
-		? "==>" : "=>";
-	    StrAllocCat(*newfile, "#current");
-	}
-	if (Visited_Links_As & VISITED_LINKS_AS_TREE) {
-	    offset = 2 * vl->level;
-	    if (offset > 24)
-		offset = (offset + 24) / 2;
-	    if (offset > LYcols * 3 / 4)
-		offset = LYcols * 3 / 4;
-	} else
-	    offset = (x > 99 ? 0 : x < 10 ? 2 : 1);
-	if (non_empty(vl->title)) {
-	    StrAllocCopy(Title, vl->title);
-	    LYEntify(&Title, TRUE);
-	    LYTrimLeading(Title);
-	    LYTrimTrailing(Title);
-	    if (*Title == '\0')
-		StrAllocCopy(Title, NO_TITLE);
-	} else {
-	    StrAllocCopy(Title, NO_TITLE);
-	}
-	if (non_empty(vl->address)) {
-	    StrAllocCopy(Address, vl->address);
-	    LYEntify(&Address, FALSE);
-	    fprintf(fp0,
-		    "%-*s%s<em>%d</em>. <tab id=t%d><a href=\"%s\">%s</a>\n",
-		    offset, arrow, post_arrow,
-		    x, x, Address, Title);
-	} else {
-	    fprintf(fp0,
-		    "%-*s%s<em>%d</em>. <tab id=t%d><em>%s</em>\n",
-		    offset, arrow, post_arrow,
-		    x, x, Title);
-	}
-	if (Address != NULL) {
-	    StrAllocCopy(Address, vl->address);
-	    LYEntify(&Address, TRUE);
-	}
-	fprintf(fp0, "<tab to=t%d>%s\n", x,
-		((Address != NULL) ? Address : gettext("(no address)")));
-	if (Visited_Links_As & VISITED_LINKS_AS_TREE)
-	    vl = vl->next_tree;
-	else if (Visited_Links_As & VISITED_LINKS_AS_LATEST) {
-	    if (Visited_Links_As & VISITED_LINKS_REVERSE)
-		vl = vl->prev_latest;
-	    else
-		vl = vl->next_latest;
-	    if (vl == &Latest_last || vl == &Latest_first)
-		vl = NULL;
-	} else {
-	    if (Visited_Links_As & VISITED_LINKS_REVERSE)
-		vl = vl->prev_first;
-	    else
-		vl = (VisitedLink *) HTList_nextObject(cur);
-	}
-    }
-    fprintf(fp0, "</pre>\n");
-    EndInternalPage(fp0);
-
-    LYCloseTempFP(fp0);
-    FREE(Title);
-    FREE(Address);
-    return (ret);
-}
-
-/*
- * Keep cycled buffer for statusline messages.
- * But allow user to change how big it will be from userdefs.h
- */
-#ifndef STATUSBUFSIZE
-#define STATUSBUFSIZE   40
-#endif
-
-int status_buf_size = STATUSBUFSIZE;
-
-static char **buffstack;
-static int topOfStack = 0;
-
-#ifdef LY_FIND_LEAKS
-static void free_messages_stack(void)
-{
-    if (buffstack != 0) {
-	topOfStack = status_buf_size;
-
-	while (--topOfStack >= 0) {
-	    FREE(buffstack[topOfStack]);
-	}
-	FREE(buffstack);
-    }
-}
-#endif
-
-static void to_stack(char *str)
-{
-    /*
-     * Cycle buffer:
-     */
-    if (topOfStack >= status_buf_size) {
-	topOfStack = 0;
-    }
-
-    /*
-     * Register string.
-     */
-    if (buffstack == 0)
-	buffstack = typecallocn(char *, (size_t) status_buf_size);
-
-    FREE(buffstack[topOfStack]);
-    buffstack[topOfStack] = str;
-    topOfStack++;
-#ifdef LY_FIND_LEAKS
-    if (!already_registered_free_messages_stack) {
-	already_registered_free_messages_stack = 1;
-	atexit(free_messages_stack);
-    }
-#endif
-    if (topOfStack >= status_buf_size) {
-	topOfStack = 0;
-    }
-}
-
-/*
- * Dump statusline messages into the buffer.
- * Called from mainloop() when exit immediately with an error:
- * can not access startfile (first_file) so a couple of alert messages
- * will be very useful on exit.
- * (Don't expect everyone will look a trace log in case of difficulties:))
- */
-void LYstatusline_messages_on_exit(char **buf)
-{
-    int i;
-
-    if (buffstack != 0) {
-	StrAllocCat(*buf, "\n");
-	/* print messages in chronological order:
-	 * probably a single message but let's do it.
-	 */
-	i = topOfStack - 1;
-	while (++i < status_buf_size) {
-	    if (buffstack[i] != NULL) {
-		StrAllocCat(*buf, buffstack[i]);
-		StrAllocCat(*buf, "\n");
-	    }
-	}
-	i = -1;
-	while (++i < topOfStack) {
-	    if (buffstack[i] != NULL) {
-		StrAllocCat(*buf, buffstack[i]);
-		StrAllocCat(*buf, "\n");
-	    }
-	}
-    }
-}
-
-void LYstore_message2(const char *message,
-		      const char *argument)
-{
-
-    if (message != NULL) {
-	char *temp = NULL;
-
-	HTSprintf0(&temp, message, NonNull(argument));
-	to_stack(temp);
-    }
-}
-
-void LYstore_message(const char *message)
-{
-    if (message != NULL) {
-	char *temp = NULL;
-
-	StrAllocCopy(temp, message);
-	to_stack(temp);
-    }
-}
-
-/*     LYLoadMESSAGES
- *     --------------
- *     Create a text/html stream with a list of recent statusline messages.
- *     LYNXMESSAGES:/ internal page.
- *     [implementation based on LYLoadKeymap()].
- */
-
-struct _HTStream {
-    HTStreamClass *isa;
-};
-
-static int LYLoadMESSAGES(const char *arg GCC_UNUSED,
-			  HTParentAnchor *anAnchor,
-			  HTFormat format_out,
-			  HTStream *sink)
-{
-    HTFormat format_in = WWW_HTML;
-    HTStream *target = NULL;
-    char *buf = NULL;
-    int nummsg = 0;
-
-    int i;
-    char *temp = NULL;
-
-    if (buffstack != 0) {
-	i = status_buf_size;
-	while (--i >= 0) {
-	    if (buffstack[i] != NULL)
-		nummsg++;
-	}
-    }
-
-    /*
-     * Set up the stream.  - FM
-     */
-    target = HTStreamStack(format_in, format_out, sink, anAnchor);
-
-    if (!target || target == NULL) {
-	HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O,
-		   HTAtom_name(format_in), HTAtom_name(format_out));
-	HTAlert(buf);
-	FREE(buf);
-	return (HT_NOT_LOADED);
-    }
-    anAnchor->no_cache = TRUE;
-
-#define PUTS(buf)    (*target->isa->put_block)(target, buf, (int) strlen(buf))
-
-    HTSprintf0(&buf, "<html>\n<head>\n");
-    PUTS(buf);
-    /*
-     * This page is a list of messages in display character set.
-     */
-    HTSprintf0(&buf, "<META %s content=\"text/html;charset=%s\">\n",
-	       "http-equiv=\"content-type\"",
-	       LYCharSet_UC[current_char_set].MIMEname);
-    PUTS(buf);
-    HTSprintf0(&buf, "<title>%s</title>\n</head>\n<body>\n",
-	       STATUSLINES_TITLE);
-    PUTS(buf);
-
-    if (nummsg != 0) {
-	HTSprintf0(&buf, "<ol>\n");
-	PUTS(buf);
-	/* print messages in reverse order: */
-	i = topOfStack;
-	while (--i >= 0) {
-	    if (buffstack[i] != NULL) {
-		StrAllocCopy(temp, buffstack[i]);
-		LYEntify(&temp, TRUE);
-		HTSprintf0(&buf, "<li value=%d> <em>%s</em>\n", nummsg, temp);
-		nummsg--;
-		PUTS(buf);
-	    }
-	}
-	i = status_buf_size;
-	while (--i >= topOfStack) {
-	    if (buffstack[i] != NULL) {
-		StrAllocCopy(temp, buffstack[i]);
-		LYEntify(&temp, TRUE);
-		HTSprintf0(&buf, "<li value=%d> <em>%s</em>\n", nummsg, temp);
-		nummsg--;
-		PUTS(buf);
-	    }
-	}
-	FREE(temp);
-	HTSprintf0(&buf, "</ol>\n</body>\n</html>\n");
-    } else {
-	HTSprintf0(&buf, "<p>%s\n</body>\n</html>\n",
-		   gettext("(No messages yet)"));
-    }
-    PUTS(buf);
-
-    (*target->isa->_free) (target);
-    FREE(buf);
-    return (HT_LOADED);
-}
-
-#ifdef GLOBALDEF_IS_MACRO
-#define _LYMESSAGES_C_GLOBALDEF_1_INIT { "LYNXMESSAGES", LYLoadMESSAGES, 0}
-GLOBALDEF(HTProtocol, LYLynxStatusMessages, _LYMESSAGES_C_GLOBALDEF_1_INIT);
-#else
-GLOBALDEF HTProtocol LYLynxStatusMessages =
-{"LYNXMESSAGES", LYLoadMESSAGES, 0};
-#endif /* GLOBALDEF_IS_MACRO */