about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GridText.c350
-rw-r--r--src/HTAlert.c42
-rw-r--r--src/HTFWriter.c2
-rw-r--r--src/HTFont.h6
-rw-r--r--src/HTML.c12
-rw-r--r--src/LYCgi.c16
-rw-r--r--src/LYCharUtils.c6
-rw-r--r--src/LYCurses.c123
-rw-r--r--src/LYCurses.h27
-rw-r--r--src/LYExtern.c4
-rw-r--r--src/LYForms.c4
-rw-r--r--src/LYGetFile.c632
-rw-r--r--src/LYGlobalDefs.h5
-rw-r--r--src/LYKeymap.c12
-rw-r--r--src/LYList.c25
-rw-r--r--src/LYLocal.c4
-rw-r--r--src/LYMain.c37
-rw-r--r--src/LYMainLoop.c73
-rw-r--r--src/LYOptions.c25
-rw-r--r--src/LYShowInfo.c299
-rw-r--r--src/LYStrings.c97
-rw-r--r--src/LYTraversal.c8
-rw-r--r--src/LYTraversal.h2
-rw-r--r--src/LYUtils.c64
-rw-r--r--src/LYUtils.h8
-rw-r--r--src/TRSTable.c4
26 files changed, 1097 insertions, 790 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 8ede1e6c..a10322a1 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -13,6 +13,7 @@
 #include <HTFile.h>
 #include <UCDefs.h>
 #include <UCAux.h>
+#include <HText.h>
 
 #include <assert.h>
 
@@ -54,14 +55,15 @@ unsigned int cached_styles[CACHEH][CACHEW];
 #include <LYJustify.h>
 
 #ifdef USE_CURSES_PADS
-#  define DISPLAY_COLS (LYwideLines ? MAX_COLS : LYcols)
+#  define DISPLAY_COLS    (LYwideLines ? MAX_COLS : LYcols)
 #  define WRAP_COLS(text) ((text)->stbl ?				\
 			   (LYtableCols <= 0				\
-			    ? DISPLAY_COLS : (LYtableCols * LYcols)/12)	\
-			   : LYcols)
+			    ? DISPLAY_COLS				\
+			    : (LYtableCols * LYcols)/12) - LYbarWidth	\
+			   : LYcolLimit)
 #else
-#  define DISPLAY_COLS LYcols
-#  define WRAP_COLS(text) LYcols
+#  define DISPLAY_COLS    LYcols
+#  define WRAP_COLS(text) LYcolLimit
 #endif
 
 #define FirstHTLine(text) ((text)->last_line->next)
@@ -103,6 +105,7 @@ struct _HTStream {		/* only know it as object */
 #ifdef KANJI_CODE_OVERRIDE
 HTkcode last_kcode = NOKANJI;	/* 1997/11/14 (Fri) 09:09:26 */
 #endif
+
 #ifdef CJK_EX
 #define CHAR_WIDTH 6
 #else
@@ -117,8 +120,8 @@ HTParentAnchor *HTMainAnchor = NULL;	/* Anchor for HTMainText */
 char *HTAppName = LYNX_NAME;	/* Application name */
 char *HTAppVersion = LYNX_VERSION;	/* Application version */
 
-int HTFormNumber = 0;
-int HTFormFields = 0;
+static int HTFormNumber = 0;
+static int HTFormFields = 0;
 char *HTCurSelectGroup = NULL;	/* Form select group name */
 static int HTCurSelectGroupCharset = -1;	/* ... and name's charset */
 int HTCurSelectGroupType = F_RADIO_TYPE;	/* Group type */
@@ -1315,8 +1318,8 @@ static int display_line(HTLine *line, HText *text, int scrline GCC_UNUSED,
      * go over the COLS limit on the display.
      */
     j = (int) line->offset;
-    if (j > (int) DISPLAY_COLS - 1)
-	j = (int) DISPLAY_COLS - 1;
+    if (j >= DISPLAY_COLS)
+	j = DISPLAY_COLS - 1;
 #ifdef USE_SLANG
     SLsmg_forward(j);
     i = j;
@@ -1364,7 +1367,7 @@ static int display_line(HTLine *line, HText *text, int scrline GCC_UNUSED,
 #endif /* SHOW_WHEREIS_TARGETS */
 #endif /* USE_COLOR_STYLE */
 
-    while ((i < DISPLAY_COLS) && ((buffer[0] = *data) != '\0')) {
+    while ((i <= DISPLAY_COLS) && ((buffer[0] = *data) != '\0')) {
 
 #ifndef USE_COLOR_STYLE
 #if defined(SHOW_WHEREIS_TARGETS)
@@ -1456,7 +1459,7 @@ static int display_line(HTLine *line, HText *text, int scrline GCC_UNUSED,
 		lynx_stop_bold();
 	    break;
 
-#endif
+#endif /* !USE_COLOR_STYLE */
 	case LY_SOFT_NEWLINE:
 	    if (!dump_output_immediately) {
 		LYaddch('+');
@@ -1525,27 +1528,24 @@ static int display_line(HTLine *line, HText *text, int scrline GCC_UNUSED,
 		/*
 		 * For CJK strings, by Masanobu Kimura.
 		 */
-		if (i >= DISPLAY_COLS)
-		    goto after_while;
-
-		buffer[1] = *data;
-		buffer[2] = '\0';
-		data++;
-		i++;
-		LYaddstr(buffer);
-		buffer[1] = '\0';
-		/*
-		 * For now, load 'M' into LastDisplayChar,
-		 * but we should check whether it's white
-		 * and if so, use ' '.  I don't know if
-		 * there actually are white CJK characters,
-		 * and we're loading ' ' for multibyte
-		 * spacing characters in this code set,
-		 * but this will become an issue when
-		 * the development code set's multibyte
-		 * character handling is used.  -FM
-		 */
-		LastDisplayChar = 'M';
+		if (i < DISPLAY_COLS) {
+		    buffer[1] = *data;
+		    buffer[2] = '\0';
+		    data++;
+		    i++;
+		    LYaddstr(buffer);
+		    buffer[1] = '\0';
+		    /*
+		     * For now, load 'M' into LastDisplayChar, but we should
+		     * check whether it's white and if so, use ' '.  I don't
+		     * know if there actually are white CJK characters, and
+		     * we're loading ' ' for multibyte spacing characters in
+		     * this code set, but this will become an issue when the
+		     * development code set's multibyte character handling is
+		     * used.  -FM
+		     */
+		    LastDisplayChar = 'M';
+		}
 	    } else {
 		LYaddstr(buffer);
 		LastDisplayChar = buffer[0];
@@ -1553,7 +1553,6 @@ static int display_line(HTLine *line, HText *text, int scrline GCC_UNUSED,
 	}			/* end of switch */
     }				/* end of while */
 
-  after_while:
 #if !(defined(NCURSES_VERSION) || defined(WIDEC_CURSES))
     if (text->has_utf8) {
 	LYtouchline(scrline);
@@ -1717,6 +1716,12 @@ static void display_title(HText *text)
 	LynxChangeStyle(s_forw_backw, STACK_OFF);
     }
 #endif /* USE_COLOR_STYLE */
+#ifdef WIDEC_CURSES
+    i = limit - LYbarWidth - strlen(percent) - LYstrCells(title);
+    if (i <= 0)
+	i = 0;
+    LYmove(0, i);
+#else
     i = (limit - 1) - strlen(percent) - strlen(title);
     if (i >= CHAR_WIDTH) {
 	LYmove(0, i);
@@ -1737,6 +1742,7 @@ static void display_title(HText *text)
 	}
 	LYmove(0, CHAR_WIDTH);
     }
+#endif
     LYaddstr(title);
     if (percent[0] != '\0')
 	LYaddstr(percent);
@@ -1745,7 +1751,7 @@ static void display_title(HText *text)
 
 #if defined(USE_COLOR_STYLE) && defined(CAN_CUT_AND_PASTE)
     if (s_hot_paste != NOSTYLE) {	/* Only if the user set the style */
-	LYmove(0, LYcols - 1);
+	LYmove(0, LYcolLimit);
 	LynxChangeStyle(s_hot_paste, STACK_ON);
 	LYaddch(ACS_RARROW);
 	LynxChangeStyle(s_hot_paste, STACK_OFF);
@@ -1823,7 +1829,7 @@ static void display_scrollbar(HText *text)
 	    LynxChangeStyle(s, ABS_ON);
 	}
 #endif /* USE_COLOR_STYLE */
-	LYmove(1, LYcols + LYshiftWin - 1);
+	LYmove(1, LYcolLimit + LYshiftWin);
 	addch_raw(ACS_UARROW);
 #ifdef USE_COLOR_STYLE
 	LynxChangeStyle(s, STACK_OFF);
@@ -1844,7 +1850,7 @@ static void display_scrollbar(HText *text)
 	if (i - 1 <= h - bot_skip && i > h - bot_skip)
 	    LynxChangeStyle(s_sb_bar, STACK_OFF);
 #endif /* USE_COLOR_STYLE */
-	LYmove(i + off, LYcols + LYshiftWin - 1);
+	LYmove(i + off, LYcolLimit + LYshiftWin);
 	if (i > top_skip && i <= h - bot_skip) {
 	    LYaddch(ACS_BLOCK);
 	} else {
@@ -1865,7 +1871,7 @@ static void display_scrollbar(HText *text)
 	    LynxChangeStyle(s, ABS_ON);
 	}
 #endif /* USE_COLOR_STYLE */
-	LYmove(h + 2, LYcols + LYshiftWin - 1);
+	LYmove(h + 2, LYcolLimit + LYshiftWin);
 	addch_raw(ACS_DARROW);
 #ifdef USE_COLOR_STYLE
 	LynxChangeStyle(s, STACK_OFF);
@@ -2100,7 +2106,7 @@ static void display_page(HText *text, int line_number,
 					     text->T.output_utf8, YES,
 					     NULL,
 					     &LenNeeded)) != NULL &&
-		   ((int) line->offset + LenNeeded) < DISPLAY_COLS) {
+		   ((int) line->offset + LenNeeded) <= DISPLAY_COLS) {
 		int itmp = 0;
 		int written = 0;
 		int x_pos = offset + (int) (cp - data);
@@ -2330,6 +2336,7 @@ static void display_page(HText *text, int line_number,
 				? checked_box
 				: unchecked_box);
 		} else if (FormInfo_ptr->type == F_PASSWORD_TYPE) {
+		    /* FIXME: use LYstrExtent, not strlen */
 		    LYSetHilite(nlinks,
 				STARS(strlen(FormInfo_ptr->value)));
 		} else {	/* TEXT type */
@@ -2432,6 +2439,7 @@ static void display_page(HText *text, int line_number,
 #endif /* WIDEC_CURSES */
 
     LYrefresh();
+    return;
 }
 
 /*			Object Building methods
@@ -2729,8 +2737,9 @@ static void split_line(HText *text, unsigned split)
 {
     HTStyle *style = text->style;
     int spare;
-    int indent = text->in_line_1 ?
-    text->style->indent1st : text->style->leftIndent;
+    int indent = (text->in_line_1
+		  ? text->style->indent1st
+		  : text->style->leftIndent);
     short alignment;
     TextAnchor *a;
     int CurLine = text->Lines;
@@ -2739,9 +2748,12 @@ static void split_line(HText *text, unsigned split)
     int TailTrim = 0;
     int s, s_post, s_pre, t_underline = underline_on, t_bold = bold_on;
     char *p;
+    char *cp;
     int ctrl_chars_on_previous_line = 0;
+
+#ifndef WIDEC_CURSES
     int utfxtra_on_previous_line = UTFXTRA_ON_THIS_LINE;
-    char *cp;
+#endif
 
     HTLine *previous = text->last_line;
     HTLine *line;
@@ -3084,7 +3096,9 @@ static void split_line(HText *text, unsigned split)
 		*cp == LY_UNDERLINE_END_CHAR ||
 		*cp == LY_BOLD_START_CHAR ||
 		*cp == LY_BOLD_END_CHAR ||
+#ifndef WIDEC_CURSES
 		IS_UTF_EXTRA(*cp) ||
+#endif
 		*cp == LY_SOFT_HYPHEN) {
 		ctrl_chars_on_previous_line++;
 	    }
@@ -3094,7 +3108,14 @@ static void split_line(HText *text, unsigned split)
 	    ctrl_chars_on_previous_line--;
 
 	/* @@ first line indent */
-	spare = (WRAP_COLS(text) - 1) -
+#ifdef WIDEC_CURSES
+	spare = WRAP_COLS(text) -
+	    (int) style->rightIndent - indent +
+	    ctrl_chars_on_previous_line - LYstrExtent2(previous->data, previous->size);
+	if (spare < 0 && LYwideLines)	/* Can be wider than screen */
+	    spare = 0;
+#else
+	spare = WRAP_COLS(text) -
 	    (int) style->rightIndent - indent +
 	    ctrl_chars_on_previous_line - previous->size;
 	if (spare < 0 && LYwideLines)	/* Can be wider than screen */
@@ -3104,9 +3125,9 @@ static void split_line(HText *text, unsigned split)
 	    text->T.output_utf8 && ctrl_chars_on_previous_line) {
 	    utfxtra_on_previous_line -= UTFXTRA_ON_THIS_LINE;
 	    if (utfxtra_on_previous_line) {
-		int spare_cu = (LYcols_cu(text) - 1) -
-		utfxtra_on_previous_line - indent +
-		ctrl_chars_on_previous_line - previous->size;
+		int spare_cu = (LYcols_cu(text) -
+				utfxtra_on_previous_line - indent +
+				ctrl_chars_on_previous_line - previous->size);
 
 		/*
 		 * Shift non-leftaligned UTF-8 lines that would be
@@ -3124,13 +3145,13 @@ static void split_line(HText *text, unsigned split)
 			    (int) (previous->offset + indent + spare / 2 +
 				   previous->size)
 			    - ctrl_chars_on_previous_line
-			    + utfxtra_on_previous_line <= (LYcols_cu(text) - 1))
+			    + utfxtra_on_previous_line <= LYcols_cu(text))
 			    /* do nothing - it still fits - kw */ ;
 			else {
 			    spare = spare_cu;
 			    if (alignment == HT_CENTER) {
 				/*
-				 * Can't move towars center all the way,
+				 * Can't move toward center all the way,
 				 * but at least make line contents appear
 				 * as far right as possible.  - kw
 				 */
@@ -3145,6 +3166,7 @@ static void split_line(HText *text, unsigned split)
 		}
 	    }
 	}
+#endif
     }
 
     switch (style->alignment) {
@@ -3269,7 +3291,7 @@ static void split_line(HText *text, unsigned split)
 	&& justify_max_void_percent > 0
 	&& justify_max_void_percent <= 100
 	&& justify_max_void_percent >= ((100 * spare)
-					/ ((WRAP_COLS(text) - 1)
+					/ (WRAP_COLS(text)
 					   - (int) style->rightIndent
 					   - indent
 					   + ctrl_chars_on_previous_line))) {
@@ -3966,7 +3988,7 @@ void HText_appendCharacter(HText *text, int ch)
 		    + ((line->size > 0) &&
 		       (int) (line->data[line->size - 1] ==
 			      LY_SOFT_HYPHEN ?
-			      1 : 0)) >= (LYcols_cu(text) - 1))
+			      1 : 0)) >= LYcols_cu(text))
 		) {
 		if (!text->permissible_split || text->source) {
 		    text->permissible_split = line->size;
@@ -4110,7 +4132,7 @@ void HText_appendCharacter(HText *text, int ch)
 	else
 	    target_cu = target + (here_cu - here);
 
-	if (target > (WRAP_COLS(text) - 1) - (int) style->rightIndent &&
+	if (target > WRAP_COLS(text) - (int) style->rightIndent &&
 	    HTOutputFormat != WWW_SOURCE) {
 	    new_line(text);
 	} else {
@@ -4118,8 +4140,8 @@ void HText_appendCharacter(HText *text, int ch)
 	     * Can split here.  -FM
 	     */
 	    text->permissible_split = line->size;
-	    if (target_cu > (WRAP_COLS(text) - 1))
-		target -= target_cu - (WRAP_COLS(text) - 1);
+	    if (target_cu > WRAP_COLS(text))
+		target -= target_cu - WRAP_COLS(text);
 	    if (line->size == 0) {
 		line->offset = line->offset + target - here;
 	    } else {
@@ -4142,10 +4164,10 @@ void HText_appendCharacter(HText *text, int ch)
 	int target = (int) (line->offset + line->size) - ctrl_chars_on_this_line;
 	int target_cu = target + UTFXTRA_ON_THIS_LINE;
 
-	if (target >= (WRAP_COLS(text) - 1) - style->rightIndent -
+	if (target >= WRAP_COLS(text) - style->rightIndent -
 	    (((HTCJK != NOCJK) && text->kanji_buf) ? 1 : 0) ||
 	    (text->T.output_utf8 &&
-	     target_cu + UTF_XLEN(ch) >= (LYcols_cu(text) - 1))) {
+	     target_cu + UTF_XLEN(ch) >= LYcols_cu(text))) {
 	    int saved_kanji_buf;
 	    int saved_state;
 
@@ -4182,7 +4204,7 @@ void HText_appendCharacter(HText *text, int ch)
 	int nominal = (indent + (int) (line->offset + line->size) - ctrl_chars_on_this_line);
 	int number;
 
-	limit = (WRAP_COLS(text) - 1);
+	limit = WRAP_COLS(text);
 	if (fields_are_numbered()
 	    && !number_fields_on_left
 	    && text->last_anchor != 0
@@ -4200,7 +4222,7 @@ void HText_appendCharacter(HText *text, int ch)
 				  : 1))))) + 2;
 	}
 	if ((nominal + (int) style->rightIndent) >= limit
-	    || (nominal + UTFXTRA_ON_THIS_LINE) >= (LYcols_cu(text) - 1)) {
+	    || (nominal + UTFXTRA_ON_THIS_LINE) >= LYcols_cu(text)) {
 	    return;
 	}
     }
@@ -4214,12 +4236,12 @@ void HText_appendCharacter(HText *text, int ch)
 
     if (text->T.output_utf8) {
 	actual += (UTFXTRA_ON_THIS_LINE - ctrl_chars_on_this_line + UTF_XLEN(ch));
-	limit = (LYcols_cu(text) - 1);
+	limit = LYcols_cu(text);
     } else {
 	actual +=
 	    (int) style->rightIndent - ctrl_chars_on_this_line +
 	    (((HTCJK != NOCJK) && text->kanji_buf) ? 1 : 0);
-	limit = (WRAP_COLS(text) - 1);
+	limit = WRAP_COLS(text);
     }
 
     if (actual >= limit) {
@@ -4661,7 +4683,7 @@ static int HText_insertBlanksInStblLines(HText *me, int ncols)
 	alignment = style->alignment;
     indent = style->leftIndent;
     /* Calculate spare character positions */
-    spare = (WRAP_COLS(me) - 1) -
+    spare = WRAP_COLS(me) -
 	(int) style->rightIndent - indent - max_width;
     if (spare < 0 && (int) style->rightIndent + spare >= 0) {
 	/*
@@ -5579,7 +5601,7 @@ void HText_endAppend(HText *text)
     if (!text)
 	return;
 
-    CTRACE((tfp, "Gridtext: Entering HText_endAppend\n"));
+    CTRACE((tfp, "GridText: Entering HText_endAppend\n"));
 
     /*
      * Create a blank line at the bottom.
@@ -5679,12 +5701,12 @@ static void HText_trimHightext(HText *text, BOOLEAN final,
 	return;
 
     if (final) {
-	CTRACE((tfp, "Gridtext: Entering HText_trimHightext (final)\n"));
+	CTRACE((tfp, "GridText: Entering HText_trimHightext (final)\n"));
     } else {
 	if (stop_before < 0 || stop_before > text->Lines)
 	    stop_before = text->Lines;
 	CTRACE((tfp,
-		"Gridtext: Entering HText_trimHightext (partial: 0..%d/%d)\n",
+		"GridText: Entering HText_trimHightext (partial: 0..%d/%d)\n",
 		stop_before, text->Lines));
     }
 
@@ -5701,7 +5723,7 @@ static void HText_trimHightext(HText *text, BOOLEAN final,
     for (anchor_ptr = text->first_anchor;
 	 anchor_ptr != NULL;
 	 prev_a = anchor_ptr, anchor_ptr = anchor_ptr->next) {
-	int have_soft_newline_in_1st_line = 0;
+	int anchor_col;
 
       re_parse:
 	/*
@@ -5750,7 +5772,7 @@ static void HText_trimHightext(HText *text, BOOLEAN final,
 	    anchor_ptr->line_num = cur_line;
 	}
 	CTRACE((tfp,
-		"Gridtext: Anchor found on line:%d col:%d [%d] ext:%d\n",
+		"GridText: Anchor found on line:%d col:%d [%d] ext:%d\n",
 		cur_line, anchor_ptr->line_pos,
 		anchor_ptr->number, anchor_ptr->extent));
 
@@ -5878,12 +5900,29 @@ static void HText_trimHightext(HText *text, BOOLEAN final,
 	}
 
 	/*
+	 * Save the offset (bytes) of the anchor in the line's data.
+	 */
+	anchor_col = anchor_ptr->line_pos;
+
+	/*
 	 * Subtract any formatting characters from the x position of the link.
 	 */
+#ifdef WIDEC_CURSES
+	if (anchor_ptr->line_pos > 0) {
+	    /*
+	     * LYstrExtent filters out the formatting characters, so we do not
+	     * have to count them here.
+	     *
+	     * FIXME: do we have to count soft-newlines?
+	     */
+	    anchor_ptr->line_pos = LYstrExtent2(line_ptr->data, anchor_col);
+	}
+#else /* 8-bit curses, etc.  */
 	if (anchor_ptr->line_pos > 0) {
 	    register int offset = 0, i = 0;
+	    int have_soft_newline_in_1st_line = 0;
 
-	    for (; i < anchor_ptr->line_pos; i++) {
+	    for (; i < anchor_col; i++) {
 		if (IS_UTF_EXTRA(line_ptr->data[i]) ||
 		    IsSpecialAttrChar(line_ptr->data[i])) {
 		    offset++;
@@ -5891,17 +5930,17 @@ static void HText_trimHightext(HText *text, BOOLEAN final,
 		}
 	    }
 	    anchor_ptr->line_pos -= offset;
+	    /*handle LY_SOFT_NEWLINEs -VH */
+	    anchor_ptr->line_pos += have_soft_newline_in_1st_line;
 	}
+#endif /* WIDEC_CURSES */
 
 	/*
-	 * Add the offset, and set the line number.
+	 * Set the line number.
 	 */
 	anchor_ptr->line_pos += line_ptr->offset;
 	anchor_ptr->line_num = cur_line;
 
-	/*handle LY_SOFT_NEWLINEs -VH */
-	anchor_ptr->line_pos += have_soft_newline_in_1st_line;
-
 	CTRACE((tfp, "GridText:     add link on line %d col %d [%d] %s\n",
 		cur_line, anchor_ptr->line_pos,
 		anchor_ptr->number, "in HText_trimHightext"));
@@ -6623,7 +6662,7 @@ BOOL HText_getFirstTargetInLine(HText *text, int line_num,
 				   utf_flag, YES,
 				   &HitOffset,
 				   &LenNeeded)) != NULL) &&
-	(LineOffset + LenNeeded) < DISPLAY_COLS) {
+	(LineOffset + LenNeeded) <= DISPLAY_COLS) {
 	/*
 	 * We had a hit so load the results,
 	 * remove IsSpecial characters from
@@ -7724,7 +7763,7 @@ void print_crawl_to_fd(FILE *fp, char *thelink,
     /*
      * Add the References list if appropriate
      */
-    if ((nolist == FALSE) &&
+    if ((no_list == FALSE) &&
 	links_are_numbered()) {
 	printlist(fp, FALSE);
     }
@@ -8172,18 +8211,40 @@ void HTuncache_current_document(void)
 static HTProtocol scm =
 {"source-cache-mem", 0, 0};	/* dummy - kw */
 
+static BOOLEAN useSourceCache(void)
+{
+    BOOLEAN result = FALSE;
+
+    if (LYCacheSource == SOURCE_CACHE_FILE) {
+	result = (HTMainAnchor->source_cache_file != 0);
+	CTRACE((tfp, "SourceCache: file-cache%s found\n",
+		result ? "" : " not"));
+    }
+    return result;
+}
+
+static BOOLEAN useMemoryCache(void)
+{
+    BOOLEAN result = FALSE;
+
+    if (LYCacheSource == SOURCE_CACHE_MEMORY) {
+	result = (HTMainAnchor->source_cache_chunk != 0);
+	CTRACE((tfp, "SourceCache: memory-cache%s found\n",
+		result ? "" : " not"));
+    }
+    return result;
+}
+
 BOOLEAN HTreparse_document(void)
 {
     BOOLEAN ok = FALSE;
 
-    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE ||
-	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainAnchor->source_cache_file) ||
-	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainAnchor->source_cache_chunk))
+    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE) {
+	CTRACE((tfp, "HTreparse_document returns FALSE\n"));
 	return FALSE;
+    }
 
-    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainAnchor->source_cache_file) {
+    if (useSourceCache()) {
 	FILE *fp;
 	HTFormat format;
 	int ret;
@@ -8243,10 +8304,11 @@ BOOLEAN HTreparse_document(void)
 		    HTLoadedDocumentURL()));
 	}
 	ok = (BOOL) (ret == HT_LOADED || ret == HT_PARTIAL_CONTENT);
+
+	CTRACE((tfp, "Reparse file %s\n", (ok ? "succeeded" : "failed")));
     }
 
-    if (LYCacheSource == SOURCE_CACHE_MEMORY &&
-	HTMainAnchor->source_cache_chunk) {
+    if (useMemoryCache()) {
 	HTFormat format = WWW_HTML;
 	int ret;
 
@@ -8292,32 +8354,27 @@ BOOLEAN HTreparse_document(void)
 	ret = HTParseMem(format, HTOutputFormat, HTMainAnchor,
 			 HTMainAnchor->source_cache_chunk, NULL);
 	ok = (BOOL) (ret == HT_LOADED);
-    }
 
-    CTRACE((tfp, "Reparse %s\n", (ok ? "succeeded" : "failed")));
+	CTRACE((tfp, "Reparse memory %s\n", (ok ? "succeeded" : "failed")));
+    }
 
     return ok;
 }
 
 BOOLEAN HTcan_reparse_document(void)
 {
-    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE ||
-	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainAnchor->source_cache_file) ||
-	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainAnchor->source_cache_chunk))
-	return FALSE;
+    BOOLEAN result = FALSE;
 
-    if (LYCacheSource == SOURCE_CACHE_FILE && HTMainAnchor->source_cache_file) {
-	return LYCanReadFile(HTMainAnchor->source_cache_file);
+    if (!HTMainAnchor || LYCacheSource == SOURCE_CACHE_NONE) {
+	result = FALSE;
+    } else if (useSourceCache()) {
+	result = LYCanReadFile(HTMainAnchor->source_cache_file);
+    } else if (useMemoryCache()) {
+	result = TRUE;
     }
 
-    if (LYCacheSource == SOURCE_CACHE_MEMORY &&
-	HTMainAnchor->source_cache_chunk) {
-	return TRUE;
-    }
-
-    return FALSE;		/* if came to here */
+    CTRACE((tfp, "HTcan_reparse_document -> %d\n", result));
+    return result;
 }
 
 static void trace_setting_change(const char *name,
@@ -8336,11 +8393,7 @@ BOOLEAN HTdocument_settings_changed(void)
      * Annoying Hack(TM):  If we don't have a source cache, we can't
      * reparse anyway, so pretend the settings haven't changed.
      */
-    if (!HTMainAnchor || !HTMainText || LYCacheSource == SOURCE_CACHE_NONE ||
-	(LYCacheSource == SOURCE_CACHE_FILE &&
-	 !HTMainAnchor->source_cache_file) ||
-	(LYCacheSource == SOURCE_CACHE_MEMORY &&
-	 !HTMainAnchor->source_cache_chunk))
+    if (!HTMainText || !HTcan_reparse_document())
 	return FALSE;
 
     if (TRACE) {
@@ -8660,11 +8713,10 @@ int HText_getCurrentColumn(HText *text)
 
 int HText_getMaximumColumn(HText *text)
 {
-    int column = (DISPLAY_COLS - 2);
+    int column = DISPLAY_COLS;
 
     if (text) {
-	column = ((int) text->style->rightIndent ? (DISPLAY_COLS - 2) :
-		  ((DISPLAY_COLS - 1) - (int) text->style->rightIndent));
+	column -= (int) text->style->rightIndent;
     }
     return column;
 }
@@ -9731,7 +9783,7 @@ int HText_beginInput(HText *text, BOOL underline,
     /*
      * Restrict SIZE to maximum allowable size.
      */
-    MaximumSize = WRAP_COLS(text) - adjust_marker;
+    MaximumSize = WRAP_COLS(text) + 1 - adjust_marker;
     switch (f->type) {
 
     case F_SUBMIT_TYPE:
@@ -13226,7 +13278,6 @@ static void move_to_glyph(int YP,
 			  int flags,
 			  BOOL utf_flag)
 {
-    register int i;
     char buffer[7];
     const char *end_of_data;
     size_t utf_extra = 0;
@@ -13236,12 +13287,22 @@ static void move_to_glyph(int YP,
     int i_start_tgt = 0, i_after_tgt;
     int HitOffset, LenNeeded;
 #endif /* SHOW_WHEREIS_TARGETS */
-    BOOL intarget = NO, inunderline = NO, inbold = NO;
-    BOOL drawing = NO, inU = NO, hadutf8 = NO;
-    BOOL incurlink = NO, drawingtarget = NO, flag = NO;
+    BOOL intarget = NO;
+    BOOL inunderline = NO;
+    BOOL inbold = NO;
+    BOOL drawing = NO;
+    BOOL inU = NO;
+    BOOL hadutf8 = NO;
+    BOOL incurlink = NO;
+    BOOL drawingtarget = NO;
+    BOOL flag = NO;
     char *sdata = data;
     char LastDisplayChar = ' ';
-    int XP_link = XP;
+
+    int i = (int) offset;	/* FIXME: should be columns, not offset? */
+    int last_i = DISPLAY_COLS;
+    int XP_link = XP;		/* column of link */
+    int XP_next = XP;		/* column to move to when done drawing */
     int linkvlen;
 
     int len;
@@ -13256,11 +13317,17 @@ static void move_to_glyph(int YP,
      * Add offset, making sure that we do not
      * go over the COLS limit on the display.
      */
-    i = (int) offset;
-    if (i > (int) DISPLAY_COLS - 1)
-	i = (int) DISPLAY_COLS - 1;
-
-    linkvlen = hightext ? LYmbcsstrlen(hightext, utf_flag, YES) : 0;
+    if (hightext != 0) {
+#ifdef WIDEC_CURSES
+	len = strlen(hightext);
+	last_i = i + LYstrExtent2(data, datasize);
+#endif
+	linkvlen = LYmbcsstrlen(hightext, utf_flag, YES);
+    } else {
+	linkvlen = 0;
+    }
+    if (i >= last_i)
+	i = last_i - 1;
 
     /*
      * Scan through the data, making sure that we do not
@@ -13282,7 +13349,7 @@ static void move_to_glyph(int YP,
 				     &HitOffset,
 				     &LenNeeded);
 	if (cp_tgt) {
-	    if ((int) offset + LenNeeded >= DISPLAY_COLS ||
+	    if ((int) offset + LenNeeded > last_i ||
 		((int) offset + HitOffset >= XP + linkvlen)) {
 		cp_tgt = NULL;
 	    } else {
@@ -13302,7 +13369,7 @@ static void move_to_glyph(int YP,
      * XP_draw_min) is found, or when we reach the link itself (if
      * highlight is non-NULL).  - kw
      */
-    while ((i < DISPLAY_COLS - 1) && data < end_of_data && (*data != '\0')) {
+    while ((i <= last_i) && data < end_of_data && (*data != '\0')) {
 
 	if (data && hightext && i >= XP && !incurlink) {
 
@@ -13313,12 +13380,12 @@ static void move_to_glyph(int YP,
 	     * routine is applied to normal hyperlink anchors) the text in
 	     * hightext will be identical to that part of the HTLine that
 	     * data was already pointing to, except that special attribute
-	     * chars LY_BOLD_START_CHAR etc.  have been stripped out (see
+	     * chars LY_BOLD_START_CHAR etc., have been stripped out (see
 	     * HText_trimHightext).  So the switching should not result in
 	     * any different display, but it ensures that it doesn't go
 	     * unnoticed if somehow hightext got messed up somewhere else.
 	     * This is also useful in preparation for using this function
-	     * for something else than normal hyperlink anchors, i.e. form
+	     * for something else than normal hyperlink anchors, i.e., form
 	     * fields.
 	     * Turn on drawing here or make sure it gets turned on before the
 	     * next actual normal character is handled.  - kw
@@ -13326,7 +13393,8 @@ static void move_to_glyph(int YP,
 	    data = hightext;
 	    len = strlen(hightext);
 	    end_of_data = hightext + len;
-	    XP += linkvlen;	/* from now on XP includes hightext chars */
+	    last_i = i + len;
+	    XP_next += linkvlen;
 	    incurlink = YES;
 #ifdef SHOW_WHEREIS_TARGETS
 	    if (cp_tgt) {
@@ -13335,7 +13403,7 @@ static void move_to_glyph(int YP,
 	    }
 #endif
 	    /*
-	     * The logic of where to set intarget drawingtarget etc.
+	     * The logic of where to set in-target drawing target etc.
 	     * and when to react to it should be cleaned up (here and
 	     * further below).  For now this seems to work but isn't
 	     * very clear.  The complications arise from reproducing
@@ -13385,11 +13453,10 @@ static void move_to_glyph(int YP,
 
 	    }
 	}
-	if (i >= XP || data >= end_of_data)
+	if (i >= last_i || data >= end_of_data)
 	    break;
 	if ((buffer[0] = *data) == '\0')
 	    break;
-
 #if defined(SHOW_WHEREIS_TARGETS)
 	/*
 	 * Look for a subsequent occurrence of the target string,
@@ -13398,7 +13465,7 @@ static void move_to_glyph(int YP,
 	if (cp_tgt && i >= i_after_tgt) {
 	    if (intarget) {
 
-		if (incurlink && flag && i == XP - 1)
+		if (incurlink && flag && i == last_i - 1)
 		    cp_tgt = NULL;
 		else
 		    cp_tgt = LYno_attr_mb_strstr(sdata,
@@ -13412,13 +13479,13 @@ static void move_to_glyph(int YP,
 		    if (incurlink) {
 			if (flag && i_start_tgt == XP_link)
 			    i_start_tgt++;
-			if (flag && i_start_tgt == XP - 1)
+			if (flag && i_start_tgt == last_i - 1)
 			    i_start_tgt++;
-			if (flag && i_after_tgt >= XP)
-			    i_after_tgt = XP - 1;
-			if (flag && i_start_tgt >= XP)
+			if (flag && i_after_tgt >= last_i)
+			    i_after_tgt = last_i - 1;
+			if (flag && i_start_tgt >= last_i)
 			    cp_tgt = NULL;
-		    } else if (i_start_tgt == XP) {
+		    } else if (i_start_tgt == last_i) {
 			if (flag)
 			    i_start_tgt++;
 		    }
@@ -13448,7 +13515,7 @@ static void move_to_glyph(int YP,
 	/*
 	 * Advance data to point to the next input char (for the
 	 * next round).  Advance sdata, used for searching for a
-	 * target string, so that they stays in synch.  As long
+	 * target string, so that they stay in synch.  As long
 	 * as we are not within the highlight text, data and sdata
 	 * have identical values.  After we have switched data to
 	 * point into hightext, sdata remains a pointer into the
@@ -13458,11 +13525,10 @@ static void move_to_glyph(int YP,
 	 * not present in highlight in order to stay in synch.  - kw
 	 */
 	data++;
-	if (*sdata) {
-	    do
-		sdata++;
-	    while (incurlink && *sdata && sdata != data &&
-		   IsSpecialAttrChar(*(sdata - 1)));
+	if (incurlink) {
+	    while (IsNormalChar(*sdata)) {
+		++sdata;
+	    }
 	}
 
 	switch (buffer[0]) {
@@ -13531,9 +13597,9 @@ static void move_to_glyph(int YP,
 	     */
 #if defined(SHOW_WHEREIS_TARGETS)
 	    if (incurlink && intarget && flag && i_after_tgt > i) {
-		if (i == XP - 1) {
+		if (i == last_i - 1) {
 		    i_after_tgt = i;
-		} else if (i == XP - 2 && HTCJK != NOCJK &&
+		} else if (i == last_i - 2 && HTCJK != NOCJK &&
 			   is8bits(buffer[0])) {
 		    i_after_tgt = i;
 		    cp_tgt = NULL;
@@ -13552,14 +13618,14 @@ static void move_to_glyph(int YP,
 
 		    if (incurlink && drawing &&
 			!(flag &&
-			  (i == XP_link || i == XP - 1))) {
+			  (i == XP_link || i == last_i - 1))) {
 			lynx_stop_link_color(flag, inU);
 		    }
 		    if (incurlink && !drawing) {
 			LYmove(YP, i);
 			if (inunderline)
 			    inU = YES;
-			if (flag && (i == XP_link || i == XP - 1)) {
+			if (flag && (i == XP_link || i == last_i - 1)) {
 			    lynx_start_link_color(flag, inU);
 			    drawingtarget = NO;
 			} else {
@@ -13576,7 +13642,7 @@ static void move_to_glyph(int YP,
 			lynx_start_link_color(flag, inU);
 		    } else if (drawing &&
 			       !(flag &&
-				 (i == XP_link || (incurlink && i == XP - 1)))) {
+				 (i == XP_link || (incurlink && i == last_i - 1)))) {
 			LYstartTargetEmphasis();
 			drawingtarget = YES;
 		    }
@@ -13595,11 +13661,13 @@ static void move_to_glyph(int YP,
 	    }
 
 	    i++;
+#ifndef WIDEC_CURSES
 	    if (utf_flag && is8bits(buffer[0])) {
 		hadutf8 = YES;
 		utf_extra = utf8_length(utf_flag, data - 1);
 		LastDisplayChar = 'M';
 	    }
+#endif
 	    if (utf_extra) {
 		strncpy(&buffer[1], data, utf_extra);
 		buffer[utf_extra + 1] = '\0';
@@ -13628,7 +13696,7 @@ static void move_to_glyph(int YP,
 		/*
 		 * For CJK strings, by Masanobu Kimura.
 		 */
-		if (drawing && (i < DISPLAY_COLS - 1)) {
+		if (drawing && (i <= last_i)) {
 		    buffer[1] = *data;
 		    LYaddstr(buffer);
 		    buffer[1] = '\0';
@@ -13656,7 +13724,7 @@ static void move_to_glyph(int YP,
     }				/* end of while */
 
     if (!drawing) {
-	LYmove(YP, i);
+	LYmove(YP, XP_next);
 	lynx_start_link_color(flag, inU);
     } else {
 #if defined(SHOW_WHEREIS_TARGETS)
diff --git a/src/HTAlert.c b/src/HTAlert.c
index b13d703e..6105cf26 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -481,7 +481,7 @@ BOOL confirm_post_resub(const char *address,
     char buf[240];
     char *temp = NULL;
     BOOL res;
-    size_t maxlen = LYcols - 6;
+    size_t maxlen = LYcolLimit - 5;
 
     if (!address) {
 	return (NO);
@@ -791,7 +791,7 @@ BOOL HTConfirmCookie(domain_entry * de, const char *server,
 	int namelen, valuelen, space_free, percentage;
 	char *message = 0;
 
-	space_free = ((LYcols - 1)
+	space_free = (LYcolLimit
 		      - (strlen(prompt)
 			 - 10)	/* %s and %.*s and %.*s chars */
 		      -strlen(server));
@@ -818,27 +818,27 @@ BOOL HTConfirmCookie(domain_entry * de, const char *server,
 	    ch = 'A';
 	} else {
 	    ch = LYgetch_single();
-#if defined(LOCALE) && defined(HAVE_GETTEXT) && !defined(gettext)
-	    /*
-	     * Special-purpose workaround for gettext support (we should do
-	     * this in a more general way -- after 2.8.3).
-	     *
-	     * NOTE TO TRANSLATORS:  If the prompt has been rendered into
-	     * another language, and if yes/no are distinct, assume the
-	     * translator can make an ordered list in parentheses with one
-	     * capital letter for each as we assumed in HTConfirmDefault().
-	     * The list has to be in the same order as in the original message,
-	     * and the four capital letters chosen to not match those in the
-	     * original unless they have the same position.
-	     *
-	     * Example:
-	     * (Y/N/Always/neVer)              - English (original)
-	     * (O/N/Toujours/Jamais)           - French
-	     */
+#if defined(LOCALE) && defined(HAVE_GETTEXT)
 	    {
 #define L_PAREN '('
 #define R_PAREN ')'
-		char *p;
+		/*
+		 * Special-purpose workaround for gettext support (we should do
+		 * this in a more general way) -TD
+		 *
+		 * NOTE TO TRANSLATORS:  If the prompt has been rendered into
+		 * another language, and if yes/no are distinct, assume the
+		 * translator can make an ordered list in parentheses with one
+		 * capital letter for each as we assumed in HTConfirmDefault().
+		 * The list has to be in the same order as in the original message,
+		 * and the four capital letters chosen to not match those in the
+		 * original unless they have the same position.
+		 *
+		 * Example:
+		 * (Y/N/Always/neVer)              - English (original)
+		 * (O/N/Toujours/Jamais)           - French
+		 */
+		char *p = gettext("Y/N/A/V");	/* placeholder for comment */
 		char *s = "YNAV\007\003";	/* see ADVANCED_COOKIE_CONFIRMATION */
 
 		if (strchr(s, ch) == 0
@@ -965,7 +965,7 @@ int HTConfirmPostRedirect(const char *Redirecting_url, int server_status)
 	LYclrtoeol();
 	LYmove(LYlines - 1, 0);
 	HTSprintf0(&url, "URL: %.*s",
-		   (LYcols < 250 ? LYcols - 6 : 250), Redirecting_url);
+		   (LYcols < 250 ? LYcolLimit - 5 : 250), Redirecting_url);
 	LYaddstr(url);
 	LYclrtoeol();
 	if (server_status == 301) {
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 893c2daa..f494b1e7 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -95,8 +95,6 @@ static void HTFWriter_put_character(HTStream *me, char c)
 
 /*	String handling
  *	---------------
- *
- *	Strings must be smaller than this buffer size.
  */
 static void HTFWriter_put_string(HTStream *me, const char *s)
 {
diff --git a/src/HTFont.h b/src/HTFont.h
index 192b0845..90c2b9ec 100644
--- a/src/HTFont.h
+++ b/src/HTFont.h
@@ -40,9 +40,11 @@ typedef long int HTMLFont;	/* For now */
 #define LY_SOFT_NEWLINE		((char)8)
 
 #ifdef EBCDIC
-#define IsSpecialAttrChar(a)  (((a) > '\002') && ((a) <= '\011') && ((a)!='\t'))
+#define IsSpecialAttrChar(a)	(((a) > '\002') && ((a) <= '\011') && ((a)!='\t'))
 #else
-#define IsSpecialAttrChar(a)  (((a) > '\002') && ((a) <= '\010'))
+#define IsSpecialAttrChar(a)	(((a) > '\002') && ((a) <= '\010'))
 #endif
 
+#define IsNormalChar(a)		((a) != '\0' && !IsSpecialAttrChar(a))
+
 #endif /* HTFONT_H */
diff --git a/src/HTML.c b/src/HTML.c
index c6b64864..1408f55d 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -1964,7 +1964,7 @@ static int HTML_start_element(HTStructured * me, int element_number,
 	    } else {
 		me->sp->style->alignment = HT_CENTER;
 	    }
-	    width = LYcols - 1 -
+	    width = LYcolLimit -
 		me->new_style->leftIndent - me->new_style->rightIndent;
 	    if (present && present[HTML_HR_WIDTH] && value[HTML_HR_WIDTH] &&
 		isdigit(UCH(*value[HTML_HR_WIDTH])) &&
@@ -4338,7 +4338,7 @@ static int HTML_start_element(HTStructured * me, int element_number,
 		me->sp->style->freeFormat) {
 		HTML_put_character(me, ' ');
 		me->in_word = NO;
-	    } else if (HText_LastLineSize(me->text, FALSE) > (LYcols - 7)) {
+	    } else if (HText_LastLineSize(me->text, FALSE) > (LYcolLimit - 6)) {
 		HTML_put_character(me, '\n');
 		me->in_word = NO;
 	    }
@@ -4503,7 +4503,7 @@ static int HTML_start_element(HTStructured * me, int element_number,
 		me->sp->style->freeFormat) {
 		HTML_put_character(me, ' ');
 		me->in_word = NO;
-	    } else if (HText_LastLineSize(me->text, FALSE) > (LYcols - 7)) {
+	    } else if (HText_LastLineSize(me->text, FALSE) > (LYcolLimit - 6)) {
 		HTML_put_character(me, '\n');
 		me->in_word = NO;
 	    }
@@ -5012,7 +5012,7 @@ static int HTML_start_element(HTStructured * me, int element_number,
 	else {
 	    int width;
 
-	    width = LYcols - 1 -
+	    width = LYcolLimit -
 		me->new_style->leftIndent - me->new_style->rightIndent;
 	    if (dump_output_immediately)	/* don't waste too much for this */
 		width = HTMIN(width, 60);
@@ -8076,6 +8076,7 @@ HTStream *HTMLToPlain(HTPresentation *pres,
 		      HTParentAnchor *anchor,
 		      HTStream *sink)
 {
+    CTRACE((tfp, "HTMLToPlain calling CacheThru_new\n"));
     return CacheThru_new(anchor,
 			 SGML_new(&HTML_dtd, anchor,
 				  HTML_new(anchor, pres->rep_out, sink)));
@@ -8138,6 +8139,7 @@ HTStream *HTMLParsedPresent(HTPresentation *pres,
     }
     if (!intermediate)
 	return NULL;
+    CTRACE((tfp, "HTMLParsedPresent calling CacheThru_new\n"));
     return CacheThru_new(anchor,
 			 SGML_new(&HTML_dtd, anchor,
 				  HTMLGenerator(intermediate)));
@@ -8166,6 +8168,7 @@ HTStream *HTMLToC(HTPresentation *pres GCC_UNUSED,
     html->comment_end = " */\n";	/* Must start in col 1 for cpp */
     if (!sink)
 	HTML_put_string(html, html->comment_start);
+    CTRACE((tfp, "HTMLToC calling CacheThru_new\n"));
     return CacheThru_new(anchor,
 			 SGML_new(&HTML_dtd, anchor, html));
 }
@@ -8183,6 +8186,7 @@ HTStream *HTMLPresent(HTPresentation *pres GCC_UNUSED,
 		      HTParentAnchor *anchor,
 		      HTStream *sink GCC_UNUSED)
 {
+    CTRACE((tfp, "HTMLPresent calling CacheThru_new\n"));
     return CacheThru_new(anchor,
 			 SGML_new(&HTML_dtd, anchor,
 				  HTML_new(anchor, WWW_PRESENT, NULL)));
diff --git a/src/LYCgi.c b/src/LYCgi.c
index 9cc051e1..77f708f3 100644
--- a/src/LYCgi.c
+++ b/src/LYCgi.c
@@ -67,6 +67,8 @@ static void add_environment_value(char *env_value);
 
 #define PERROR(msg) CTRACE((tfp, "LYNXCGI: %s: %s\n", msg, LYStrerror(errno)))
 
+#define PUTS(buf)    (*target->isa->put_block)(target, buf, strlen(buf))
+
 #ifdef LY_FIND_LEAKS
 static void free_alloced_lynxcgi(void)
 {
@@ -663,28 +665,28 @@ static int LYLoadCGI(const char *arg,
 
     HTSprintf0(&buf, "<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n",
 	       gettext("Good Advice"));
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf, "<h1>%s</h1>\n", gettext("Good Advice"));
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf, "%s <a\n",
 	       gettext("An excellent http server for VMS is available via"));
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf,
 	       "href=\"http://kcgl1.eng.ohio-state.edu/www/doc/serverinfo.html\"\n");
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf, ">%s</a>.\n", gettext("this link"));
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf, "<p>%s\n",
 	       gettext("It provides state of the art CGI script support.\n"));
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     HTSprintf0(&buf, "</body>\n</html>\n");
-    (*target->isa->put_block) (target, buf, strlen(buf));
+    PUTS(buf);
 
     (*target->isa->_free) (target);
     FREE(buf);
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index 4f2dba9b..13d81621 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -2599,9 +2599,9 @@ void LYHandleMETA(HTStructured * me, const BOOL *present,
 		cp++;
 	    if (*cp != '\0') {
 		StrAllocCopy(me->node_anchor->SugFname, cp);
-		if (*me->node_anchor->SugFname == '\"') {
+		if (*me->node_anchor->SugFname == '"') {
 		    if ((cp = strchr((me->node_anchor->SugFname + 1),
-				     '\"')) != NULL) {
+				     '"')) != NULL) {
 			*(cp + 1) = '\0';
 			HTMIME_TrimDoubleQuotes(me->node_anchor->SugFname);
 		    } else {
@@ -2852,7 +2852,7 @@ void LYHandleSELECT(HTStructured * me, const BOOL *present,
 	if ((multiple == NO && LYSelectPopups == TRUE) &&
 	    (me->sp[0].tag_number == HTML_PRE || me->inPRE == TRUE ||
 	     !me->sp->style->freeFormat) &&
-	    HText_LastLineSize(me->text, FALSE) > (LYcols - 8)) {
+	    HText_LastLineSize(me->text, FALSE) > (LYcolLimit - 7)) {
 	    /*
 	     * Force a newline when we're using a popup in a PRE block and are
 	     * within 7 columns from the right margin.  This will allow for the
diff --git a/src/LYCurses.c b/src/LYCurses.c
index 3d6646ac..9c3ca53b 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -17,6 +17,7 @@
 #include <LYStrings.h>
 #include <LYCharSets.h>
 #include <UCAux.h>
+#include <HTFont.h>
 
 #include <LYexit.h>
 #include <LYLeaks.h>
@@ -1331,8 +1332,9 @@ void lynx_nl2crlf(int normal GCC_UNUSED)
 
 void stop_curses(void)
 {
-    if (LYCursesON)
+    if (LYCursesON) {
 	echo();
+    }
 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
     resetty();
 #endif
@@ -1601,8 +1603,8 @@ void LYpaddstr(WINDOW * the_window, int width,
     int actual = strlen(the_string);
 
     getyx(the_window, y, x);
-    if (width + x >= LYcols)
-	width = LYcols - x - 1;
+    if (width + x > LYcolLimit)
+	width = LYcolLimit - x;
     if (actual > width)
 	actual = width;
     LYwaddnstr(the_window, the_string, actual);
@@ -1645,26 +1647,35 @@ WINDOW *LYtopwindow(void)
 }
 #endif
 
-WINDOW *LYstartPopup(
-			int top_y,
-			int left_x,
-			int height,
-			int width)
+WINDOW *LYstartPopup(int *top_y,
+		     int *left_x,
+		     int *height,
+		     int *width)
 {
     WINDOW *form_window = 0;
 
 #ifdef USE_SLANG
     static WINDOW fake_window;
 
-    SLsmg_fill_region(top_y, left_x - 1, height, width + 4, ' ');
+    if (*left_x < 1 || (*left_x + *width + 4) >= LYcolLimit) {
+	*left_x = 1;
+	*width = LYcolLimit - 5;
+    }
+
+    SLsmg_fill_region(*top_y, *left_x - 1, *height, *width + 4, ' ');
     form_window = &fake_window;
-    form_window->top_y = top_y;
-    form_window->left_x = left_x;
-    form_window->height = height;
-    form_window->width = width;
+    form_window->top_y = *top_y;
+    form_window->left_x = *left_x;
+    form_window->height = *height;
+    form_window->width = *width;
 #else
-    if (!(form_window = newwin(height, width + 4, top_y, left_x - 1)) &&
-	!(form_window = newwin(height, 0, top_y, 0))) {
+    if (*left_x > 0 && (*left_x + *width + 4) < LYcolLimit)
+	form_window = newwin(*height, *width + 4, *top_y, *left_x - 1);
+    if (form_window == 0) {
+	*width = LYcolLimit - 4;
+	form_window = newwin(*height, LYcolLimit, *top_y, 0);
+    }
+    if (form_window == 0) {
 	HTAlert(POPUP_FAILED);
     } else {
 	LYsubwindow(form_window);
@@ -1750,7 +1761,8 @@ void LYtouchline(int row)
 /*
  * Wrapper for waddnstr().
  */
-void LYwaddnstr(WINDOW * w, const char *src,
+void LYwaddnstr(WINDOW * w GCC_UNUSED,
+		const char *src,
 		size_t len)
 {
     /*
@@ -1892,6 +1904,81 @@ void LYwaddnstr(WINDOW * w, const char *src,
 #endif
 }
 
+/*
+ * Determine the number of cells the given string would take up on the screen,
+ * limited by the maxCells parameter.  This is used for constructing aligned
+ * text in the options and similar forms.
+ *
+ * FIXME: make this account for wrapping, too.
+ * FIXME: make this useful for "lynx -dump", which hasn't initialized curses.
+ */
+int LYstrExtent(const char *string, int len, int maxCells)
+{
+    int result = 0;
+    int used;
+
+    if (len < 0)
+	used = strlen(string);
+    else
+	used = len;
+
+    result = used;
+#ifdef WIDEC_CURSES
+    if (used > 0 && lynx_called_initscr) {
+	static WINDOW *fake_win;
+	static int fake_max;
+	int n;
+
+	if (fake_max < maxCells) {
+	    fake_max = (maxCells + 1) * 2;
+	    if (fake_win != 0) {
+		delwin(fake_win);
+		fake_win = 0;
+	    }
+	}
+	if (fake_win == 0) {
+	    fake_win = newwin(2, fake_max, 0, 0);
+	}
+	if (fake_win != 0) {
+	    int new_x = 0;
+	    int new_y = 0;
+
+	    result = 0;
+	    wmove(fake_win, 0, 0);
+	    for (n = 0; n < used; ++n) {
+		if (IsNormalChar(string[n])) {
+		    waddch(fake_win, UCH(string[n]));
+		    getyx(fake_win, new_y, new_x);
+		    if (new_y > 0 || new_x > maxCells)
+			break;
+		    result = new_x;
+		}
+	    }
+	}
+    }
+#endif
+    if (result > maxCells)
+	result = maxCells;
+    return result;
+}
+
+/*
+ * A simple call that relies upon the coincidence that multicell characters
+ * use at least as many bytes as cells.
+ */
+int LYstrExtent2(const char *string, int len)
+{
+    return LYstrExtent(string, len, len);
+}
+
+/*
+ * Returns the total number of cells that the string would use.
+ */
+int LYstrCells(const char *string)
+{
+    return LYstrExtent2(string, strlen(string));
+}
+
 #ifdef VMS
 /*
  *	Cut-down termio --
@@ -2448,8 +2535,8 @@ void LYrefresh(void)
 	int y, x;
 
 	getyx(LYwin, y, x);
-	if (x >= LYcols)
-	    x = LYcols - 1;
+	if (x > LYcolLimit)
+	    x = LYcolLimit;
 	wmove(stdscr, y, x);
 
 	wnoutrefresh(stdscr);
diff --git a/src/LYCurses.h b/src/LYCurses.h
index 11cc471f..1bb773be 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -295,7 +295,7 @@ extern WINDOW *LYtopwindow(void);
 #endif /* NCURSES */
 
 extern void LYbox(WINDOW * win, BOOLEAN formfield);
-extern WINDOW *LYstartPopup(int top_y, int left_x, int height, int width);
+extern WINDOW *LYstartPopup(int *top_y, int *left_x, int *height, int *width);
 
 /*
  * Useful macros not in PDCurses or very old ncurses headers.
@@ -367,6 +367,24 @@ extern long LYgetattrs(WINDOW * win);
 extern int LYlines;		/* replaces LINES */
 extern int LYcols;		/* replaces COLS */
 
+/*
+ * The scrollbar, if used, occupies the rightmost column.
+ */
+#ifdef USE_SCROLLBAR
+#define LYbarWidth (LYShowScrollbar ? 1 : 0)
+#else
+#define LYbarWidth 0
+#endif
+
+/*
+ * Usable limits for display:
+ */
+#if defined(FANCY_CURSES) || defined(USE_SLANG)
+#define LYcolLimit (LYcols - LYbarWidth)
+#else
+#define LYcolLimit (LYcols - 1)
+#endif
+
 #ifdef USE_CURSES_PADS
 extern WINDOW *LYwin;
 extern int LYshiftWin;
@@ -389,6 +407,9 @@ extern int Masked_Attr;
 extern BOOLEAN setup(char *terminal);
 extern int LYscreenHeight(void);
 extern int LYscreenWidth(void);
+extern int LYstrExtent(const char *string, int len, int maxCells);
+extern int LYstrExtent2(const char *string, int len);
+extern int LYstrCells(const char *string);
 extern void LYclear(void);
 extern void LYclrtoeol(void);
 extern void LYerase(void);
@@ -727,9 +748,9 @@ extern void lynx_stop_underline(void);
  * Adjust our "hidden" cursor position accordingly.
  */
 #if defined(FANCY_CURSES) || defined(USE_SLANG)
-#define LYHideCursor() LYmove((LYlines - 1), (LYcols - 1))
+#define LYHideCursor() LYmove((LYlines - 1), (LYcolLimit))
 #else
-#define LYHideCursor() LYmove((LYlines - 1), (LYcols - 2))
+#define LYHideCursor() LYmove((LYlines - 1), (LYcolLimit - 1))
 #endif
 
 extern void LYstowCursor(WINDOW * win, int row, int col);
diff --git a/src/LYExtern.c b/src/LYExtern.c
index 6d2084b2..77f53b49 100644
--- a/src/LYExtern.c
+++ b/src/LYExtern.c
@@ -103,7 +103,7 @@ static char *format_command(char *command,
     char *cmdbuf = NULL;
 
 #if defined(WIN_EX)
-    if (*param != '\"' && strchr(param, ' ') != NULL) {
+    if (*param != '"' && strchr(param, ' ') != NULL) {
 	char *cp = quote_pathname(param);
 
 	format(&cmdbuf, command, cp);
@@ -148,7 +148,7 @@ static char *format_command(char *command,
 		format(&cmdbuf,
 		       command, HTDOS_short_name(e_buff));
 	    } else {
-		if (*e_buff != '\"' && strchr(e_buff, ' ') != NULL) {
+		if (*e_buff != '"' && strchr(e_buff, ' ') != NULL) {
 		    p = quote_pathname(e_buff);
 		    LYstrncpy(e_buff, p, sizeof(e_buff) - 1);
 		    FREE(p);
diff --git a/src/LYForms.c b/src/LYForms.c
index f93638c3..f15754a8 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -387,8 +387,8 @@ static int form_getstr(int cur,
      * Get the initial position of the cursor.
      */
     LYGetYX(startline, startcol);
-    if ((startcol + form->size) > (LYcols - 1))
-	far_col = (LYcols - 1);
+    if ((startcol + form->size) > LYcolLimit)
+	far_col = LYcolLimit;
     else
 	far_col = (startcol + form->size);
 
diff --git a/src/LYGetFile.c b/src/LYGetFile.c
index af480573..48d63959 100644
--- a/src/LYGetFile.c
+++ b/src/LYGetFile.c
@@ -69,6 +69,7 @@ int HTNoDataOK = 0;
 int getfile(DocInfo *doc)
 {
     int url_type = 0;
+    char *pound;
     char *cp = NULL;
     char *temp = NULL;
     DocAddress WWWDoc;		/* a WWW absolute doc address struct */
@@ -153,13 +154,11 @@ int getfile(DocInfo *doc)
 		    HTAlert(PORT_NINETEEN_INVALID);
 		    FREE(temp);
 		    return (NULLFILE);
-		}
-		if (value == 25 || value == 65561) {
+		} else if (value == 25 || value == 65561) {
 		    HTAlert(PORT_TWENTYFIVE_INVALID);
 		    FREE(temp);
 		    return (NULLFILE);
-		}
-		if (value > 65535 || value < 0) {
+		} else if (value > 65535 || value < 0) {
 		    char *msg = 0;
 
 		    HTSprintf0(&msg, PORT_INVALID, (unsigned long) value);
@@ -701,274 +700,276 @@ int getfile(DocInfo *doc)
 #endif /* DIRED_SUPPORT */
 	    }
 	    return (status);
+	}
 
-	} {
-	    if (!ftp_ok
-		&& (url_type == FTP_URL_TYPE
-		    || url_type == NCFTP_URL_TYPE)) {
-		HTUserMsg(FTP_DISABLED);
-		return (NULLFILE);
-	    }
-
-	    if (url_type == HTML_GOPHER_URL_TYPE) {
-		char *tmp = NULL;
+	if (!ftp_ok
+	    && (url_type == FTP_URL_TYPE
+		|| url_type == NCFTP_URL_TYPE)) {
+	    HTUserMsg(FTP_DISABLED);
+	    return (NULLFILE);
+	} else if (url_type == HTML_GOPHER_URL_TYPE) {
+	    char *tmp = NULL;
 
+	    /*
+	     * If tuple's Path=GET%20/...  convert to an http URL.
+	     */
+	    if ((cp = strchr(doc->address + 9, '/')) != NULL &&
+		0 == strncmp(++cp, "hGET%20/", 8)) {
+		StrAllocCopy(tmp, "http://");
+		CTRACE((tfp, "getfile: URL '%s'\n",
+			doc->address));
+		*cp = '\0';
+		StrAllocCat(tmp, doc->address + 9);
 		/*
-		 * If tuple's Path=GET%20/...  convert to an http URL.
+		 * If the port is defaulted, it should stay 70.
 		 */
-		if ((cp = strchr(doc->address + 9, '/')) != NULL &&
-		    0 == strncmp(++cp, "hGET%20/", 8)) {
-		    StrAllocCopy(tmp, "http://");
-		    CTRACE((tfp, "getfile: URL '%s'\n",
-			    doc->address));
-		    *cp = '\0';
-		    StrAllocCat(tmp, doc->address + 9);
-		    /*
-		     * If the port is defaulted, it should stay 70.
-		     */
-		    if (strchr(tmp + 6, ':') == NULL) {
-			StrAllocCat(tmp, "70/");
-			tmp[strlen(tmp) - 4] = ':';
-		    }
-		    if (strlen(cp + 7) > 1)
-			StrAllocCat(tmp, cp + 8);
-		    StrAllocCopy(doc->address, tmp);
-		    CTRACE((tfp, "  changed to '%s'\n",
-			    doc->address));
-		    FREE(tmp);
-		    url_type = HTTP_URL_TYPE;
+		if (strchr(tmp + 6, ':') == NULL) {
+		    StrAllocCat(tmp, "70/");
+		    tmp[strlen(tmp) - 4] = ':';
 		}
+		if (strlen(cp + 7) > 1)
+		    StrAllocCat(tmp, cp + 8);
+		StrAllocCopy(doc->address, tmp);
+		CTRACE((tfp, "  changed to '%s'\n",
+			doc->address));
+		FREE(tmp);
+		url_type = HTTP_URL_TYPE;
 	    }
-	    if (url_type == HTTP_URL_TYPE ||
-		url_type == HTTPS_URL_TYPE ||
-		url_type == FTP_URL_TYPE ||
-		url_type == NCFTP_URL_TYPE ||
-		url_type == CSO_URL_TYPE)
-		fix_httplike_urls(doc, url_type);
-	    WWWDoc.address = doc->address;	/* possible reload */
+	}
+
+	if (url_type == HTTP_URL_TYPE ||
+	    url_type == HTTPS_URL_TYPE ||
+	    url_type == FTP_URL_TYPE ||
+	    url_type == NCFTP_URL_TYPE ||
+	    url_type == CSO_URL_TYPE) {
+	    fix_httplike_urls(doc, url_type);
+	}
+
+	WWWDoc.address = doc->address;	/* possible reload */
 #ifdef DIRED_SUPPORT
-	    lynx_edit_mode = FALSE;
+	lynx_edit_mode = FALSE;
 #endif /* DIRED_SUPPORT */
+
 #ifndef DISABLE_BIBP
-	    if (url_type == BIBP_URL_TYPE) {
-		char *bibpTmp = NULL;
-
-		if (!BibP_bibhost_checked)
-		    LYCheckBibHost();
-		if (BibP_bibhost_available) {
-		    StrAllocCopy(bibpTmp, BibP_bibhost);
-		} else if (HTMainAnchor && HTAnchor_citehost(HTMainAnchor)) {
-		    StrAllocCopy(bibpTmp, HTAnchor_citehost(HTMainAnchor));
-		} else {
-		    StrAllocCopy(bibpTmp, BibP_globalserver);
-		}
-		if (HTMainAnchor && HTAnchor_citehost(HTMainAnchor)) {
-		    StrAllocCat(bibpTmp, "bibp1.0/resolve?citehost=");
-		    StrAllocCat(bibpTmp, HTAnchor_citehost(HTMainAnchor));
-		    StrAllocCat(bibpTmp, "&usin=");
-		} else {
-		    StrAllocCat(bibpTmp, "bibp1.0/resolve?usin=");
-		}
-		StrAllocCat(bibpTmp, doc->address + 5);		/* USIN after bibp: */
-		StrAllocCopy(doc->address, bibpTmp);
-		WWWDoc.address = doc->address;
-		FREE(bibpTmp);
+	if (url_type == BIBP_URL_TYPE) {
+	    char *bibpTmp = NULL;
+
+	    if (!BibP_bibhost_checked)
+		LYCheckBibHost();
+	    if (BibP_bibhost_available) {
+		StrAllocCopy(bibpTmp, BibP_bibhost);
+	    } else if (HTMainAnchor && HTAnchor_citehost(HTMainAnchor)) {
+		StrAllocCopy(bibpTmp, HTAnchor_citehost(HTMainAnchor));
+	    } else {
+		StrAllocCopy(bibpTmp, BibP_globalserver);
 	    }
+	    if (HTMainAnchor && HTAnchor_citehost(HTMainAnchor)) {
+		StrAllocCat(bibpTmp, "bibp1.0/resolve?citehost=");
+		StrAllocCat(bibpTmp, HTAnchor_citehost(HTMainAnchor));
+		StrAllocCat(bibpTmp, "&usin=");
+	    } else {
+		StrAllocCat(bibpTmp, "bibp1.0/resolve?usin=");
+	    }
+	    StrAllocCat(bibpTmp, doc->address + 5);	/* USIN after bibp: */
+	    StrAllocCopy(doc->address, bibpTmp);
+	    WWWDoc.address = doc->address;
+	    FREE(bibpTmp);
+	}
 #endif /* !DISABLE_BIBP */
 
-	    if (url_type == FILE_URL_TYPE) {
-		/*
-		 * If a file URL has a '~' as the lead character of its first
-		 * symbolic element, convert the '~' to Home_Dir(), then append
-		 * the rest of of path, if present, skipping "user" if "~user"
-		 * was entered, simplifying, and eliminating any residual
-		 * relative elements.  - FM
-		 */
-		if (((cp = HTParse(doc->address, "",
-				   PARSE_PATH + PARSE_ANCHOR + PARSE_PUNCTUATION))
-		     != NULL) &&
-		    !strncmp(cp, "/~", 2)) {
-		    char *cp1 = strstr(doc->address, "/~");
-		    char *cp2;
-
-		    CTRACE((tfp, "getfile: URL '%s'\n",
-			    doc->address));
-		    *cp1 = '\0';
-		    cp1 += 2;
-		    StrAllocCopy(temp, doc->address);
-		    StrAllocCopy(cp, wwwName(Home_Dir()));
-		    if (!LYIsHtmlSep(*cp))
-			LYAddHtmlSep(&temp);
-		    StrAllocCat(temp, cp);
-		    if ((cp2 = strchr(cp1, '/')) != NULL) {
-			LYTrimRelFromAbsPath(cp2);
-			StrAllocCat(temp, cp2);
-		    }
-		    StrAllocCopy(doc->address, temp);
-		    FREE(temp);
-		    CTRACE((tfp, "  changed to '%s'\n",
-			    doc->address));
-		    WWWDoc.address = doc->address;
+	if (url_type == FILE_URL_TYPE) {
+	    /*
+	     * If a file URL has a '~' as the lead character of its first
+	     * symbolic element, convert the '~' to Home_Dir(), then append
+	     * the rest of of path, if present, skipping "user" if "~user"
+	     * was entered, simplifying, and eliminating any residual
+	     * relative elements.  - FM
+	     */
+	    if (((cp = HTParse(doc->address, "",
+			       PARSE_PATH + PARSE_ANCHOR + PARSE_PUNCTUATION))
+		 != NULL) &&
+		!strncmp(cp, "/~", 2)) {
+		char *cp1 = strstr(doc->address, "/~");
+		char *cp2;
+
+		CTRACE((tfp, "getfile: URL '%s'\n",
+			doc->address));
+		*cp1 = '\0';
+		cp1 += 2;
+		StrAllocCopy(temp, doc->address);
+		StrAllocCopy(cp, wwwName(Home_Dir()));
+		if (!LYIsHtmlSep(*cp))
+		    LYAddHtmlSep(&temp);
+		StrAllocCat(temp, cp);
+		if ((cp2 = strchr(cp1, '/')) != NULL) {
+		    LYTrimRelFromAbsPath(cp2);
+		    StrAllocCat(temp, cp2);
 		}
-		FREE(cp);
+		StrAllocCopy(doc->address, temp);
+		FREE(temp);
+		CTRACE((tfp, "  changed to '%s'\n",
+			doc->address));
+		WWWDoc.address = doc->address;
 	    }
-	    CTRACE_SLEEP(MessageSecs);
-	    user_message(WWW_WAIT_MESSAGE, doc->address);
+	    FREE(cp);
+	}
+	CTRACE_SLEEP(MessageSecs);
+	user_message(WWW_WAIT_MESSAGE, doc->address);
 
-	    if (TRACE) {
+	if (TRACE) {
 #ifdef USE_SLANG
-		if (LYCursesON) {
-		    LYaddstr("*\n");
-		    LYrefresh();
-		}
-#endif /* USE_SLANG */
-		CTRACE((tfp, "\n"));
+	    if (LYCursesON) {
+		LYaddstr("*\n");
+		LYrefresh();
 	    }
-	    if (!HTLoadAbsolute(&WWWDoc)) {
-		/*
-		 * Check for redirection.
-		 */
-		if (use_this_url_instead != NULL) {
-		    char *pound;
-
-		    if (!is_url(use_this_url_instead)) {
-			/*
-			 * The server did not return a complete URL in its
-			 * Location:  header, probably due to a FORM or other
-			 * CGI script written by someone who doesn't know that
-			 * the http protocol requires that it be a complete
-			 * URL, or using a server which does not treat such a
-			 * redirect string from the script as an instruction to
-			 * resolve it versus the initial request, check
-			 * authentication with that URL, and then act on it
-			 * without returning redirection to us.  We'll violate
-			 * the http protocol and resolve it ourselves using the
-			 * URL of the original request as the BASE, rather than
-			 * doing the RIGHT thing and returning an invalid
-			 * address message.  - FM
-			 */
-			HTUserMsg(LOCATION_NOT_ABSOLUTE);
-			temp = HTParse(use_this_url_instead,
-				       WWWDoc.address,
-				       PARSE_ALL);
-			if (temp && *temp) {
-			    StrAllocCopy(use_this_url_instead, temp);
-			}
-			FREE(temp);
+#endif /* USE_SLANG */
+	    CTRACE((tfp, "\n"));
+	}
+
+	if (!HTLoadAbsolute(&WWWDoc)) {
+	    /*
+	     * Check for redirection.
+	     */
+	    if (use_this_url_instead != NULL) {
+		if (!is_url(use_this_url_instead)) {
+		    /*
+		     * The server did not return a complete URL in its
+		     * Location:  header, probably due to a FORM or other
+		     * CGI script written by someone who doesn't know that
+		     * the http protocol requires that it be a complete
+		     * URL, or using a server which does not treat such a
+		     * redirect string from the script as an instruction to
+		     * resolve it versus the initial request, check
+		     * authentication with that URL, and then act on it
+		     * without returning redirection to us.  We'll violate
+		     * the http protocol and resolve it ourselves using the
+		     * URL of the original request as the BASE, rather than
+		     * doing the RIGHT thing and returning an invalid
+		     * address message.  - FM
+		     */
+		    HTUserMsg(LOCATION_NOT_ABSOLUTE);
+		    temp = HTParse(use_this_url_instead,
+				   WWWDoc.address,
+				   PARSE_ALL);
+		    if (temp && *temp) {
+			StrAllocCopy(use_this_url_instead, temp);
 		    }
-		    url_type = is_url(use_this_url_instead);
-		    if (!HTPermitRedir &&
-			(url_type == LYNXDOWNLOAD_URL_TYPE ||
-			 url_type == LYNXEXEC_URL_TYPE ||
-			 url_type == LYNXPROG_URL_TYPE ||
+		    FREE(temp);
+		}
+		url_type = is_url(use_this_url_instead);
+		if (!HTPermitRedir &&
+		    (url_type == LYNXDOWNLOAD_URL_TYPE ||
+		     url_type == LYNXEXEC_URL_TYPE ||
+		     url_type == LYNXPROG_URL_TYPE ||
 #ifdef DIRED_SUPPORT
-			 url_type == LYNXDIRED_URL_TYPE ||
+		     url_type == LYNXDIRED_URL_TYPE ||
 #endif /* DIRED_SUPPORT */
-			 url_type == LYNXPRINT_URL_TYPE ||
-			 url_type == LYNXOPTIONS_URL_TYPE ||
-			 url_type == LYNXCFG_URL_TYPE ||
-			 url_type == LYNXCOMPILE_OPTS_URL_TYPE ||
-			 url_type == LYNXHIST_URL_TYPE ||
-			 url_type == LYNXCOOKIE_URL_TYPE ||
-			 url_type == LYNXMESSAGES_URL_TYPE ||
-			 (LYValidate &&
-			  url_type != HTTP_URL_TYPE &&
-			  url_type != HTTPS_URL_TYPE) ||
-			 ((no_file_url || no_goto_file) &&
-			  url_type == FILE_URL_TYPE) ||
-			 (no_goto_lynxcgi &&
-			  url_type == LYNXCGI_URL_TYPE) ||
+		     url_type == LYNXPRINT_URL_TYPE ||
+		     url_type == LYNXOPTIONS_URL_TYPE ||
+		     url_type == LYNXCFG_URL_TYPE ||
+		     url_type == LYNXCOMPILE_OPTS_URL_TYPE ||
+		     url_type == LYNXHIST_URL_TYPE ||
+		     url_type == LYNXCOOKIE_URL_TYPE ||
+		     url_type == LYNXMESSAGES_URL_TYPE ||
+		     (LYValidate &&
+		      url_type != HTTP_URL_TYPE &&
+		      url_type != HTTPS_URL_TYPE) ||
+		     ((no_file_url || no_goto_file) &&
+		      url_type == FILE_URL_TYPE) ||
+		     (no_goto_lynxcgi &&
+		      url_type == LYNXCGI_URL_TYPE) ||
 #ifndef DISABLE_BIBP
-			 (no_goto_bibp &&
-			  url_type == BIBP_URL_TYPE) ||
+		     (no_goto_bibp &&
+		      url_type == BIBP_URL_TYPE) ||
 #endif
-			 (no_goto_cso &&
-			  url_type == CSO_URL_TYPE) ||
-			 (no_goto_finger &&
-			  url_type == FINGER_URL_TYPE) ||
-			 (no_goto_ftp &&
-			  (url_type == FTP_URL_TYPE ||
-			   url_type == NCFTP_URL_TYPE)) ||
-			 (no_goto_gopher &&
-			  url_type == GOPHER_URL_TYPE) ||
-			 (no_goto_http &&
-			  url_type == HTTP_URL_TYPE) ||
-			 (no_goto_https &&
-			  url_type == HTTPS_URL_TYPE) ||
-			 (no_goto_mailto &&
-			  url_type == MAILTO_URL_TYPE) ||
+		     (no_goto_cso &&
+		      url_type == CSO_URL_TYPE) ||
+		     (no_goto_finger &&
+		      url_type == FINGER_URL_TYPE) ||
+		     (no_goto_ftp &&
+		      (url_type == FTP_URL_TYPE ||
+		       url_type == NCFTP_URL_TYPE)) ||
+		     (no_goto_gopher &&
+		      url_type == GOPHER_URL_TYPE) ||
+		     (no_goto_http &&
+		      url_type == HTTP_URL_TYPE) ||
+		     (no_goto_https &&
+		      url_type == HTTPS_URL_TYPE) ||
+		     (no_goto_mailto &&
+		      url_type == MAILTO_URL_TYPE) ||
 #ifndef DISABLE_NEWS
-			 (no_goto_news &&
-			  url_type == NEWS_URL_TYPE) ||
-			 (no_goto_nntp &&
-			  url_type == NNTP_URL_TYPE) ||
+		     (no_goto_news &&
+		      url_type == NEWS_URL_TYPE) ||
+		     (no_goto_nntp &&
+		      url_type == NNTP_URL_TYPE) ||
 #endif
-			 (no_goto_rlogin &&
-			  url_type == RLOGIN_URL_TYPE) ||
+		     (no_goto_rlogin &&
+		      url_type == RLOGIN_URL_TYPE) ||
 #ifndef DISABLE_NEWS
-			 (no_goto_snews &&
-			  url_type == SNEWS_URL_TYPE) ||
+		     (no_goto_snews &&
+		      url_type == SNEWS_URL_TYPE) ||
 #endif
-			 (no_goto_telnet &&
-			  url_type == TELNET_URL_TYPE) ||
-			 (no_goto_tn3270 &&
-			  url_type == TN3270_URL_TYPE) ||
-			 (no_goto_wais &&
-			  url_type == WAIS_URL_TYPE))) {
-			/*
-			 * Some schemes are not acceptable from server
-			 * redirections.  - KW & FM
-			 */
-			HTAlert(ILLEGAL_REDIRECTION_URL);
-			if (LYCursesON) {
-			    HTUserMsg2(WWW_ILLEGAL_URL_MESSAGE,
-				       use_this_url_instead);
-			} else {
-			    fprintf(stderr,
-				    WWW_ILLEGAL_URL_MESSAGE,
-				    use_this_url_instead);
-			}
-			FREE(use_this_url_instead);
-			return (NULLFILE);
-		    }
-		    if ((pound = findPoundSelector(doc->address)) != NULL
-			&& findPoundSelector(use_this_url_instead) == NULL) {
-			/*
-			 * Our requested URL had a fragment associated with it,
-			 * and the redirection URL doesn't, so we'll append the
-			 * fragment associated with the original request.  If
-			 * it's bogus for the redirection URL, we'll be
-			 * positioned at the top of that document, so there's
-			 * no harm done.  - FM
-			 */
-			CTRACE((tfp,
-				"getfile: Adding fragment '%s' to redirection URL.\n",
-				pound));
-			StrAllocCat(use_this_url_instead, pound);
+		     (no_goto_telnet &&
+		      url_type == TELNET_URL_TYPE) ||
+		     (no_goto_tn3270 &&
+		      url_type == TN3270_URL_TYPE) ||
+		     (no_goto_wais &&
+		      url_type == WAIS_URL_TYPE))) {
+		    /*
+		     * Some schemes are not acceptable from server
+		     * redirections.  - KW & FM
+		     */
+		    HTAlert(ILLEGAL_REDIRECTION_URL);
+		    if (LYCursesON) {
+			HTUserMsg2(WWW_ILLEGAL_URL_MESSAGE,
+				   use_this_url_instead);
+		    } else {
+			fprintf(stderr,
+				WWW_ILLEGAL_URL_MESSAGE,
+				use_this_url_instead);
 		    }
-		    CTRACE_SLEEP(MessageSecs);
-		    HTUserMsg2(WWW_USING_MESSAGE, use_this_url_instead);
-		    CTRACE((tfp, "\n"));
-		    StrAllocCopy(doc->address,
-				 use_this_url_instead);
 		    FREE(use_this_url_instead);
-		    if (redirect_post_content == FALSE) {
-			/*
-			 * Freeing the content also yields a GET request.  - FM
-			 */
-			LYFreePostData(doc);
-		    }
+		    return (NULLFILE);
+		}
+		if ((pound = findPoundSelector(doc->address)) != NULL
+		    && findPoundSelector(use_this_url_instead) == NULL) {
 		    /*
-		     * Go to top to check for URL's which get special handling
-		     * and/or security checks in Lynx.  - FM
+		     * Our requested URL had a fragment associated with it,
+		     * and the redirection URL doesn't, so we'll append the
+		     * fragment associated with the original request.  If
+		     * it's bogus for the redirection URL, we'll be
+		     * positioned at the top of that document, so there's
+		     * no harm done.  - FM
 		     */
-		    goto Try_Redirected_URL;
+		    CTRACE((tfp,
+			    "getfile: Adding fragment '%s' to redirection URL.\n",
+			    pound));
+		    StrAllocCat(use_this_url_instead, pound);
 		}
-		if (HTNoDataOK) {
-		    return (NULLFILE);
+		CTRACE_SLEEP(MessageSecs);
+		HTUserMsg2(WWW_USING_MESSAGE, use_this_url_instead);
+		CTRACE((tfp, "\n"));
+		StrAllocCopy(doc->address,
+			     use_this_url_instead);
+		FREE(use_this_url_instead);
+		if (redirect_post_content == FALSE) {
+		    /*
+		     * Freeing the content also yields a GET request.  - FM
+		     */
+		    LYFreePostData(doc);
 		}
+		/*
+		 * Go to top to check for URL's which get special handling
+		 * and/or security checks in Lynx.  - FM
+		 */
+		goto Try_Redirected_URL;
+	    }
+	    if (HTNoDataOK) {
+		return (NULLFILE);
+	    } else {
 		return (NOT_FOUND);
 	    }
+	} else {
 
 	    lynx_mode = NORMAL_LYNX_MODE;
 
@@ -979,96 +980,93 @@ int getfile(DocInfo *doc)
 	     * then this is a reference to a named anchor within the same
 	     * document; do NOT return NULLFILE in that case.
 	     */
-	    {
-		char *pound;
+
+	    /*
+	     * Check for a #fragment selector.
+	     */
+	    pound = findPoundSelector(doc->address);
+
+	    /*
+	     * Check to see if there is a temp file waiting for us to
+	     * download.
+	     */
+	    if (WWW_Download_File) {
+		HTParentAnchor *tmpanchor = HTAnchor_findAddress(&WWWDoc);
+		char *fname = NULL;
 
 		/*
-		 * Check for a #fragment selector.
+		 * Check for a suggested filename from the
+		 * Content-Disposition header.  - FM
 		 */
-		pound = findPoundSelector(doc->address);
-
+		if (HTAnchor_SugFname(tmpanchor) != NULL) {
+		    StrAllocCopy(fname, HTAnchor_SugFname(tmpanchor));
+		} else {
+		    StrAllocCopy(fname, doc->address);
+		}
 		/*
-		 * Check to see if there is a temp file waiting for us to
-		 * download.
+		 * Check whether this is a compressed file, which we don't
+		 * uncompress for downloads, and adjust any suffix
+		 * appropriately.  - FM
 		 */
-		if (WWW_Download_File) {
-		    HTParentAnchor *tmpanchor = HTAnchor_findAddress(&WWWDoc);
-		    char *fname = NULL;
+		HTCheckFnameForCompression(&fname, tmpanchor, FALSE);
 
-		    /*
-		     * Check for a suggested filename from the
-		     * Content-Disposition header.  - FM
-		     */
-		    if (HTAnchor_SugFname(tmpanchor) != NULL) {
-			StrAllocCopy(fname, HTAnchor_SugFname(tmpanchor));
-		    } else {
-			StrAllocCopy(fname, doc->address);
-		    }
-		    /*
-		     * Check whether this is a compressed file, which we don't
-		     * uncompress for downloads, and adjust any suffix
-		     * appropriately.  - FM
-		     */
-		    HTCheckFnameForCompression(&fname, tmpanchor, FALSE);
-
-		    if (LYdownload_options(&fname,
-					   WWW_Download_File) < 0) {
-			FREE(fname);
-			return (NOT_FOUND);
-		    }
-		    LYAddVisitedLink(doc);
-		    StrAllocCopy(doc->address, fname);
+		if (LYdownload_options(&fname,
+				       WWW_Download_File) < 0) {
 		    FREE(fname);
-		    doc->internal_link = FALSE;
-		    WWWDoc.address = doc->address;
-		    LYFreePostData(doc);
-		    WWWDoc.post_data = NULL;
-		    WWWDoc.post_content_type = NULL;
-		    WWWDoc.bookmark = doc->bookmark = FALSE;
-		    WWWDoc.isHEAD = doc->isHEAD = FALSE;
-		    WWWDoc.safe = doc->safe = FALSE;
-		    HTOutputFormat = WWW_PRESENT;
-		    if (!HTLoadAbsolute(&WWWDoc)) {
-			return (NOT_FOUND);
-		    } else {
-			return (NORMAL);
-		    }
+		    return (NOT_FOUND);
+		}
+		LYAddVisitedLink(doc);
+		StrAllocCopy(doc->address, fname);
+		FREE(fname);
+		doc->internal_link = FALSE;
+		WWWDoc.address = doc->address;
+		LYFreePostData(doc);
+		WWWDoc.post_data = NULL;
+		WWWDoc.post_content_type = NULL;
+		WWWDoc.bookmark = doc->bookmark = FALSE;
+		WWWDoc.isHEAD = doc->isHEAD = FALSE;
+		WWWDoc.safe = doc->safe = FALSE;
+		HTOutputFormat = WWW_PRESENT;
+		if (!HTLoadAbsolute(&WWWDoc)) {
+		    return (NOT_FOUND);
+		} else {
+		    return (NORMAL);
+		}
 
-		} else if (pound == NULL &&
-		    /*
-		     * HTAnchor hash-table searches are now case-sensitive
-		     * (hopefully, without anchor deletion problems), so this
-		     * is too.  - FM
-		     */
-			   (strcmp(doc->address,
-				   HTLoadedDocumentURL()) ||
-		    /*
-		     * Also check the post_data elements.  - FM
-		     */
-			    !BINEQ(doc->post_data,
-				   HTLoadedDocumentPost_data()) ||
-		    /*
-		     * Also check the isHEAD element.  - FM
-		     */
-			    doc->isHEAD != HTLoadedDocumentIsHEAD())) {
-		    /*
-		     * Nothing needed to be shown.
-		     */
-		    LYAddVisitedLink(doc);
-		    return (NULLFILE);
+	    } else if (pound == NULL &&
+		/*
+		 * HTAnchor hash-table searches are now case-sensitive
+		 * (hopefully, without anchor deletion problems), so this
+		 * is too.  - FM
+		 */
+		       (strcmp(doc->address,
+			       HTLoadedDocumentURL()) ||
+		/*
+		 * Also check the post_data elements.  - FM
+		 */
+			!BINEQ(doc->post_data,
+			       HTLoadedDocumentPost_data()) ||
+		/*
+		 * Also check the isHEAD element.  - FM
+		 */
+			doc->isHEAD != HTLoadedDocumentIsHEAD())) {
+		/*
+		 * Nothing needed to be shown.
+		 */
+		LYAddVisitedLink(doc);
+		return (NULLFILE);
 
-		} else {
-		    if (pound != NULL) {
-			if (!HTMainText) {	/* this should not happen... */
-			    return (NULLFILE);	/* but it can. - kw */
-			}
-			/*
-			 * May set www_search_result.
-			 */
-			HTFindPoundSelector(pound + 1);
+	    } else {
+		if (pound != NULL) {
+		    if (!HTMainText) {	/* this should not happen... */
+			return (NULLFILE);	/* but it can. - kw */
 		    }
-		    return (NORMAL);
+		    /*
+		     * May set www_search_result.
+		     */
+		    HTFindPoundSelector(pound + 1);
 		}
+		return (NORMAL);
 	    }
 	}
     } else {
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index d28b66a4..a60b258a 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -204,6 +204,7 @@ extern BOOLEAN bold_name_anchors;
 extern BOOLEAN case_sensitive;	/* TRUE to turn on case sensitive search */
 extern BOOLEAN check_mail;	/* TRUE to report unread/new mail messages */
 extern BOOLEAN child_lynx;	/* TRUE to exit with an arrow */
+extern BOOLEAN dump_links_only;
 extern BOOLEAN dump_output_immediately;
 extern BOOLEAN emacs_keys;	/* TRUE to turn on emacs-like key movement */
 extern BOOLEAN error_logging;	/* TRUE to mail error messages */
@@ -345,7 +346,7 @@ extern char *personal_extension_map;
 extern char *LYHostName;
 extern char *LYLocalDomain;
 extern BOOLEAN use_underscore;
-extern BOOLEAN nolist;
+extern BOOLEAN no_list;
 extern BOOLEAN historical_comments;
 extern BOOLEAN minimal_comments;
 extern BOOLEAN soft_dquotes;
@@ -397,7 +398,7 @@ extern BOOLEAN traversal;
 extern BOOLEAN check_realm;
 extern char *startrealm;
 extern BOOLEAN more_links;
-extern int ccount;
+extern int crawl_count;
 extern BOOLEAN LYCancelledFetch;
 extern char *LYToolbarName;
 
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index 36f50695..604a508a 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -16,6 +16,8 @@
 #include <rot13_kb.h>
 #endif
 
+#define PUTS(buf)    (*target->isa->put_block)(target, buf, strlen(buf))
+
 #ifdef EXP_KEYBOARD_LAYOUT
 int current_layout = 0;		/* Index into LYKbLayouts[]   */
 
@@ -1292,14 +1294,14 @@ static void print_binding(HTStream *target, int i,
     if (prev_lynx_edit_mode && !no_dired_support &&
 	(lac1 = key_override[i]) != LYK_UNKNOWN) {
 	if ((buf = format_binding(key_override, i)) != 0) {
-	    (*target->isa->put_block) (target, buf, strlen(buf));
+	    PUTS(buf);
 	    FREE(buf);
 	}
     } else
 #endif /* DIRED_SUPPORT && OK_OVERRIDE */
     if ((buf = format_binding(keymap, i)) != 0) {
 	lac1 = keymap[i];
-	(*target->isa->put_block) (target, buf, strlen(buf));
+	PUTS(buf);
 	FREE(buf);
     }
 
@@ -1311,13 +1313,13 @@ static void print_binding(HTStream *target, int i,
     if (prev_lynx_edit_mode && !no_dired_support && key_override[i]) {
 	if (key_override[i] != lac1 &&
 	    (buf = format_binding(key_override, i)) != 0) {
-	    (*target->isa->put_block) (target, buf, strlen(buf));
+	    PUTS(buf);
 	    FREE(buf);
 	}
     } else
 #endif /* DIRED_SUPPORT && OK_OVERRIDE */
     if (keymap[i] != lac1 && (buf = format_binding(keymap, i)) != 0) {
-	(*target->isa->put_block) (target, buf, strlen(buf));
+	PUTS(buf);
 	FREE(buf);
     }
 }
@@ -1414,8 +1416,6 @@ static int LYLoadKeymap(const char *arg GCC_UNUSED,
     }
     anAnchor->no_cache = TRUE;
 
-#define PUTS(buf)    (*target->isa->put_block)(target, buf, strlen(buf))
-
     HTSprintf0(&buf, "<html>\n<head>\n<title>%s</title>\n</head>\n<body>\n",
 	       CURRENT_KEYMAP_TITLE);
     PUTS(buf);
diff --git a/src/LYList.c b/src/LYList.c
index 845d82cc..dd8a801b 100644
--- a/src/LYList.c
+++ b/src/LYList.c
@@ -254,10 +254,10 @@ void printlist(FILE *fp, BOOLEAN titles)
 	return;
     } else {
 	fprintf(fp, "\n%s\n\n", gettext("References"));
+	if (LYHiddenLinks == HIDDENLINKS_IGNORE)
+	    hidden_links = 0;
 	if (hidden_links > 0) {
 	    fprintf(fp, "   %s\n", gettext("Visible links"));
-	    if (LYHiddenLinks == HIDDENLINKS_IGNORE)
-		hidden_links = 0;
 	}
 	helper = NULL;		/* init */
 	for (cnt = 1; cnt <= refs; cnt++) {
@@ -304,21 +304,22 @@ void printlist(FILE *fp, BOOLEAN titles)
 #endif /* VMS */
 	}
 
-	if (hidden_links > 0)
+	if (hidden_links > 0) {
 	    fprintf(fp, "%s   %s\n", ((refs > 0) ? "\n" : ""),
 		    gettext("Hidden links:"));
-	for (cnt = 0; cnt < hidden_links; cnt++) {
-	    StrAllocCopy(address, HText_HiddenLinkAt(HTMainText, cnt));
-	    if (!(address && *address)) {
+	    for (cnt = 0; cnt < hidden_links; cnt++) {
+		StrAllocCopy(address, HText_HiddenLinkAt(HTMainText, cnt));
+		if (!(address && *address)) {
+		    FREE(address);
+		    continue;
+		}
+		fprintf(fp, "%4d. %s\n", ((cnt + 1) + refs), address);
 		FREE(address);
-		continue;
-	    }
-	    fprintf(fp, "%4d. %s\n", ((cnt + 1) + refs), address);
-	    FREE(address);
 #ifdef VMS
-	    if (HadVMSInterrupt)
-		break;
+		if (HadVMSInterrupt)
+		    break;
 #endif /* VMS */
+	    }
 	}
     }
     return;
diff --git a/src/LYLocal.c b/src/LYLocal.c
index ac820db4..d0e59e8a 100644
--- a/src/LYLocal.c
+++ b/src/LYLocal.c
@@ -1939,7 +1939,7 @@ int local_dired(DocInfo *doc)
 	buffer = build_command(line, dirname, arg);
 
 	if (buffer != 0) {
-	    if ((int) strlen(buffer) < LYcols - 15) {
+	    if ((int) strlen(buffer) < LYcolLimit - 14) {
 		HTSprintf0(&tmpbuf, gettext("Executing %s "), buffer);
 	    } else {
 		HTSprintf0(&tmpbuf,
@@ -2326,7 +2326,7 @@ BOOLEAN local_install(char *destpath,
 				2);
 	if (n <= 0) {
 	    src = 0;
-	    HTAlert(gettext("Error buiding install args"));
+	    HTAlert(gettext("Error building install args"));
 	    FREE(tmpdest);
 	    return 0;
 	}
diff --git a/src/LYMain.c b/src/LYMain.c
index c2a6175d..38a4fc0f 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -195,6 +195,7 @@ BOOLEAN bold_name_anchors = FALSE;
 BOOLEAN case_sensitive = CASE_SENSITIVE_ALWAYS_ON;
 BOOLEAN check_mail = CHECKMAIL;
 BOOLEAN child_lynx = FALSE;
+BOOLEAN dump_links_only = FALSE;
 BOOLEAN dump_output_immediately = FALSE;
 BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
 BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
@@ -207,7 +208,6 @@ BOOLEAN is_www_index = FALSE;
 BOOLEAN jump_buffer = JUMPBUFFER;	/* TRUE if offering default shortcut */
 BOOLEAN lynx_mode = NORMAL_LYNX_MODE;
 BOOLEAN minimal_comments = FALSE;
-BOOLEAN nolist = FALSE;
 BOOLEAN number_fields_on_left = TRUE;
 BOOLEAN number_links_on_left = TRUE;
 BOOLEAN recent_sizechange = FALSE;	/* the window size changed recently? */
@@ -375,6 +375,7 @@ BOOLEAN crawl = FALSE;		/* Do crawl? */
 BOOLEAN keep_mime_headers = FALSE;	/* Include mime headers with source dump */
 BOOLEAN more = FALSE;		/* is there more text to display? */
 BOOLEAN more_links = FALSE;	/* Links beyond a displayed page with no links? */
+BOOLEAN no_list = FALSE;
 BOOLEAN no_url_redirection = FALSE;	/* Don't follow URL redirections */
 BOOLEAN pseudo_inline_alts = MAKE_PSEUDO_ALTS_FOR_INLINES;
 BOOLEAN scan_for_buried_news_references = TRUE;
@@ -447,7 +448,7 @@ int LYcols = DFT_COLS;
 int LYlines = DFT_ROWS;
 int MessageSecs;		/* time-delay for important Messages   */
 int ReplaySecs;			/* time-delay for command-scripts */
-int ccount = 0;			/* Starting number for lnk#.dat files in crawls */
+int crawl_count = 0;		/* Starting number for lnk#.dat files in crawls */
 int dump_output_width = 0;
 int lynx_temp_subspace = 0;	/* > 0 if we made temp-directory */
 int nhist = 0;			/* number of history entries */
@@ -571,6 +572,7 @@ BOOLEAN FileInitAlreadyDone = FALSE;
 static BOOLEAN stack_dump = FALSE;
 static char *terminal = NULL;
 static char *pgm;
+static BOOLEAN no_numbers = FALSE;
 static BOOLEAN number_links = FALSE;
 static BOOLEAN number_fields = FALSE;
 static BOOLEAN LYPrependBase = FALSE;
@@ -1771,6 +1773,13 @@ int main(int argc,
     if (vi_keys)
 	set_vi_keys();
 
+    if (no_numbers) {
+	number_links = FALSE;
+	number_fields = FALSE;
+	keypad_mode = NUMBERS_AS_ARROWS;
+	set_numbers_as_arrows();
+    }
+
     if (crawl) {
 	/* No numbered links by default, as documented
 	   in CRAWL.announce. - kw */
@@ -2035,7 +2044,9 @@ int main(int argc,
 	 */
 	if (crawl && !number_links && !number_fields) {
 	    keypad_mode = NUMBERS_AS_ARROWS;
-	} else if (!nolist) {
+	} else if (no_numbers) {
+	    keypad_mode = NUMBERS_AS_ARROWS;
+	} else if (!no_list) {
 	    if (!links_are_numbered()) {
 		if (number_fields)
 		    keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED;
@@ -2059,7 +2070,7 @@ int main(int argc,
 	    CTRACE((tfp, "dumping %d:%d %s\n",
 		    i + 1, HTList_count(Goto_URLs), startfile));
 	    status = mainloop();
-	    if (!nolist &&
+	    if (!no_list &&
 		!crawl &&	/* For -crawl it has already been done! */
 		links_are_numbered())
 		printlist(stdout, FALSE);
@@ -2068,7 +2079,7 @@ int main(int argc,
 	}
 #else
 	status = mainloop();
-	if (!nolist &&
+	if (!no_list &&
 	    !crawl &&		/* For -crawl it has already been done! */
 	    links_are_numbered())
 	    printlist(stdout, FALSE);
@@ -2514,9 +2525,9 @@ static int convert_to_fun(char *next_arg)
 	if ((cp1 = strchr(outformat, ';')) != NULL) {
 	    if ((cp2 = LYstrstr(cp1, "charset")) != NULL) {
 		cp2 += 7;
-		while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '\"')
+		while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '"')
 		    cp2++;
-		for (cp4 = cp2; (*cp4 != '\0' && *cp4 != '\"' &&
+		for (cp4 = cp2; (*cp4 != '\0' && *cp4 != '"' &&
 				 *cp4 != ';' &&
 				 !WHITE(*cp4)); cp4++) ;	/* do nothing */
 		*cp4 = '\0';
@@ -3461,10 +3472,14 @@ keys (may be incompatible with some curses packages)"
    ),
 #endif
    PARSE_INT(
-      "link",		4|NEED_INT_ARG,		ccount,
+      "link",		4|NEED_INT_ARG,		crawl_count,
       "=NUMBER\nstarting count for lnk#.dat files produced by -crawl"
    ),
    PARSE_SET(
+      "listonly",	4|TOGGLE_ARG,		dump_links_only,
+      "with -dump, forces it to show only the list of links"
+   ),
+   PARSE_SET(
       "localhost",	4|SET_ARG,		local_host_only,
       "disable URLs that point to remote hosts"
    ),
@@ -3537,7 +3552,7 @@ keys (may be incompatible with some curses packages)"
       "disable transmission of Referer headers for file URLs"
    ),
    PARSE_SET(
-      "nolist",		4|SET_ARG,		nolist,
+      "nolist",		4|SET_ARG,		no_list,
       "disable the link list feature in dumps"
    ),
    PARSE_SET(
@@ -3550,6 +3565,10 @@ keys (may be incompatible with some curses packages)"
       "\nmake window size change handler non-restarting"
    ),
 #endif /* HAVE_SIGACTION */
+   PARSE_SET(
+      "nonumbers",	4|SET_ARG,		no_numbers,
+      "disable the link/form numbering feature in dumps"
+   ),
    PARSE_FUN(
       "nopause",	4|FUNCTION_ARG,		nopause_fun,
       "disable forced pauses for statusline messages"
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index 71f0b0aa..9a5368c9 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -506,16 +506,33 @@ BOOL LYMainLoop_pageDisplay(int line_num)
 }
 #endif /* DISP_PARTIAL */
 
-static void set_curdoc_link(int nextlink)
+static BOOL set_curdoc_link(int nextlink)
 {
+    BOOL result = FALSE;
+
     if (curdoc.link != nextlink
 	&& nextlink >= 0
 	&& nextlink < nlinks) {
-	if (curdoc.link >= 0 && curdoc.link < nlinks)
+	if (curdoc.link >= 0 && curdoc.link < nlinks) {
 	    LYhighlight(OFF, curdoc.link, prev_target);
+	    result = TRUE;
+	}
 	curdoc.link = nextlink;
     }
+    return result;
+}
+
+#ifdef USE_MOUSE
+static void set_curdoc_link_by_mouse(int nextlink)
+{
+    if (set_curdoc_link(nextlink)) {
+	LYhighlight(ON, nextlink, prev_target);
+	LYmsec_delay(20);
+    }
 }
+#else
+#define set_curdoc_link_by_mouse(nextlink) set_curdoc_link(nextlink)
+#endif
 
 static int do_change_link(void)
 {
@@ -535,7 +552,7 @@ static int do_change_link(void)
 	    FREE(msgtmp);
 	    return (-1);	/* indicates unexpected error */
 	}
-	set_curdoc_link(mouse_tmp);
+	set_curdoc_link_by_mouse(mouse_tmp);
     }
 #endif /* USE_MOUSE */
     return (0);			/* indicates OK */
@@ -894,20 +911,21 @@ static int DoTraversal(int c,
 	rlink_allowed = FALSE;
     }
     if (rlink_exists && rlink_allowed) {
-	if (lookup(links[curdoc.link].lname)) {
+	if (lookup_link(links[curdoc.link].lname)) {
 	    if (more_links ||
-		(curdoc.link > -1 && curdoc.link < nlinks - 1))
+		(curdoc.link > -1 && curdoc.link < nlinks - 1)) {
 		c = DNARROW;
-	    else {
+	    } else {
 		if (STREQ(curdoc.title, "Entry into main screen") ||
 		    (nhist <= 0)) {
 		    if (!dump_output_immediately) {
 			cleanup();
 			exit_immediately(EXIT_FAILURE);
 		    }
-		    return (-1);
+		    c = -1;
+		} else {
+		    c = LTARROW;
 		}
-		c = LTARROW;
 	    }
 	} else {
 	    StrAllocCopy(traversal_link_to_add,
@@ -921,9 +939,9 @@ static int DoTraversal(int c,
 	    /* uncomment in previous line to avoid duplicates - kw */
 	    add_to_reject_list(links[curdoc.link].lname);
 	if (more_links ||
-	    (curdoc.link > -1 && curdoc.link < nlinks - 1))
+	    (curdoc.link > -1 && curdoc.link < nlinks - 1)) {
 	    c = DNARROW;
-	else {
+	} else {
 	    /*
 	     * curdoc.title doesn't always work, so bail out if the history
 	     * list is empty.
@@ -934,11 +952,16 @@ static int DoTraversal(int c,
 		    cleanup();
 		    exit_immediately(EXIT_FAILURE);
 		}
-		return (-1);
+		c = -1;
+	    } else {
+		c = LTARROW;
 	    }
-	    c = LTARROW;
 	}
-    }				/* right link not NULL or link to another site */
+    }
+    CTRACE((tfp, "DoTraversal(%d:%d) -> %s\n",
+	    nlinks > 0 ? curdoc.link : 0,
+	    nlinks,
+	    LYKeycodeToString(c, FALSE)));
     return c;
 }
 
@@ -1213,8 +1236,9 @@ static int handle_LYK_ACTIVATE(int *c,
 		default:
 		    if ((real_cmd == LYK_ACTIVATE || real_cmd == LYK_SUBMIT) &&
 			F_TEXTLIKE(links[curdoc.link].l_form->type) &&
-			textinput_activated)
+			textinput_activated) {
 			return 3;
+		    }
 		    break;
 		}
 	    }
@@ -5053,7 +5077,7 @@ static BOOLEAN handle_LYK_LINEWRAP_TOGGLE(int *cmd,
 
     /* Somehow the mouse is over the number instead of being over the
        name, so we decrease x. */
-    c = LYChoosePopup(!LYwideLines, LYlines / 2 - 2, LYcols / 2 - 6,
+    c = LYChoosePopup(!LYwideLines, LYlines / 2 - 2, LYcolLimit / 2 - 6,
 		      choices, TABLESIZE(choices) - 1, FALSE, TRUE);
     /*
      * LYhandlePopupList() wasn't really meant to be used outside of old-style
@@ -5240,7 +5264,7 @@ int mainloop(void)
 	    force_load = TRUE;
 #endif
 	/*
-	 * If newdoc.address is different then curdoc.address then we need to
+	 * If newdoc.address is different from curdoc.address then we need to
 	 * go out and find and load newdoc.address.
 	 */
 	if (LYforce_no_cache || force_load ||
@@ -5771,7 +5795,7 @@ int mainloop(void)
 			/*
 			 * Add the address we sought to TRAVERSE_FILE.
 			 */
-			if (!lookup(traversal_link_to_add))
+			if (!lookup_link(traversal_link_to_add))
 			    add_to_table(traversal_link_to_add);
 			FREE(traversal_link_to_add);
 		    }
@@ -5916,7 +5940,7 @@ int mainloop(void)
 	if (dump_output_immediately) {
 	    if (crawl) {
 		print_crawl_to_fd(stdout, curdoc.address, curdoc.title);
-	    } else {
+	    } else if (!dump_links_only) {
 		print_wwwfile_to_fd(stdout, FALSE, FALSE);
 	    }
 	    return (EXIT_SUCCESS);
@@ -6032,7 +6056,7 @@ int mainloop(void)
 		/*
 		 * Set up the crawl output stuff.
 		 */
-		if (curdoc.address && !lookup(curdoc.address)) {
+		if (curdoc.address && !lookup_link(curdoc.address)) {
 		    if (!isLYNXIMGMAP(curdoc.address))
 			crawl_ok = TRUE;
 		    add_to_table(curdoc.address);
@@ -6357,11 +6381,11 @@ int mainloop(void)
 	    if (crawl && crawl_ok) {
 		crawl_ok = FALSE;
 #ifdef FNAMES_8_3
-		sprintf(cfile, "lnk%05d.dat", ccount);
+		sprintf(cfile, "lnk%05d.dat", crawl_count);
 #else
-		sprintf(cfile, "lnk%08d.dat", ccount);
+		sprintf(cfile, "lnk%08d.dat", crawl_count);
 #endif /* FNAMES_8_3 */
-		ccount = ccount + 1;
+		crawl_count = crawl_count + 1;
 		if ((cfp = LYNewTxtFile(cfile)) != NULL) {
 		    print_crawl_to_fd(cfp, curdoc.address, curdoc.title);
 		    LYCloseOutput(cfp);
@@ -7015,6 +7039,7 @@ int mainloop(void)
 		goto new_keyboard_input;
 	    case 3:
 		pending_form_c = c;
+		break;
 	    }
 	    break;
 
@@ -7506,7 +7531,7 @@ static void show_main_statusline(const LinkInfo curlink,
 	if (is_www_index) {
 	    char *indx = gettext("-index-");
 
-	    LYmove(LYlines - 1, LYcols - strlen(indx) - 1);
+	    LYmove(LYlines - 1, LYcolLimit - strlen(indx));
 	    lynx_start_reverse();
 	    LYaddstr(indx);
 	    lynx_stop_reverse();
@@ -7658,7 +7683,7 @@ static void status_link(char *curlink_name,
 			BOOLEAN show_more,
 			BOOLEAN show_indx)
 {
-#define MAX_STATUS (LYcols - 2)
+#define MAX_STATUS (LYcolLimit - 1)
 #define MIN_STATUS 0
     char format[MAX_LINE];
     int prefix = 0;
diff --git a/src/LYOptions.c b/src/LYOptions.c
index e5a1eeb1..99f0140d 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -2841,6 +2841,7 @@ int postoptions(DocInfo *newdoc)
 	if (!strcmp(data[i].tag, show_scrollbar_string)
 	    && GetOptValues(bool_values, data[i].value, &code)) {
 	    LYShowScrollbar = (BOOL) code;
+	    need_reload = TRUE;
 	}
 #endif
 
@@ -3248,16 +3249,26 @@ static char *NewSecureValue(void)
 static void PutLabel(FILE *fp, char *name,
 		     char *value)
 {
+    int have = strlen(name);
+    int want = LABEL_LEN;
+    int need = LYstrExtent(name, have, want);
+
+    fprintf(fp, "&nbsp;&nbsp;%s", name);
     if (will_save_rc(value) && !no_option_save) {
-	fprintf(fp, "  %-*s: ", LABEL_LEN, name);
+	while (need++ < want)
+	    fprintf(fp, "&nbsp;");
     } else {
-	int l = strlen(name);
-
-	fprintf(fp, "  %s", name);
-	fprintf(fp, "%s%-*s: ",
-		(l < (LABEL_LEN - 3)) ? " " : "",
-		(l < (LABEL_LEN - 3)) ? (LABEL_LEN - 1) - l : 3, "(!)");
+	want -= 3;
+	if (need < want) {
+	    fprintf(fp, "&nbsp;");
+	    ++need;
+	}
+	fprintf(fp, "(!)");
+	while (need++ < want) {
+	    fprintf(fp, "&nbsp;");
+	}
     }
+    fprintf(fp, ": ");
 }
 
 /*
diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c
index 4686dc7a..9a763cd8 100644
--- a/src/LYShowInfo.c
+++ b/src/LYShowInfo.c
@@ -24,6 +24,14 @@
 
 #define ADVANCED_INFO 1		/* to get more info in advanced mode */
 
+#define BEGIN_DL(text) fprintf(fp0, "<h2>%s</h2>\n<dl compact>", text)
+#define END_DL()       fprintf(fp0, "\n</dl>\n")
+
+#define ADD_SS(label,value)       dt_String(fp0, label, value)
+#define ADD_NN(label,value,units) dt_Number(fp0, label, value, units)
+
+static int label_columns;
+
 /*
  * LYNX_VERSION and LYNX_DATE are automatically generated by PRCS, the tool
  * which we use to archive versions of Lynx.  We use a convention for naming
@@ -56,6 +64,45 @@ char *LYVersionDate(void)
     return temp;
 }
 
+static void dt_String(FILE *fp,
+		      const char *label,
+		      const char *value)
+{
+    int have;
+    int need;
+    char *the_label = 0;
+    char *the_value = 0;
+
+    StrAllocCopy(the_label, label);
+    StrAllocCopy(the_value, value);
+
+    have = strlen(the_label);
+    need = LYstrExtent(the_label, have, label_columns);
+
+    LYEntify(&the_label, TRUE);
+    LYEntify(&the_value, TRUE);
+
+    fprintf(fp, "<dt>");
+    while (need++ < label_columns)
+	fprintf(fp, "&nbsp;");
+    fprintf(fp, "<em>%s</em> %s\n", the_label, the_value);
+
+    FREE(the_label);
+    FREE(the_value);
+}
+
+static void dt_Number(FILE *fp0,
+		      const char *label,
+		      long number,
+		      const char *units)
+{
+    char *value = NULL;
+
+    HTSprintf(&value, "%ld %s", number, units);
+    ADD_SS(label, value);
+    FREE(value);
+}
+
 /*
  * LYShowInfo prints a page of info about the current file and the link that
  * the cursor is on.
@@ -68,9 +115,10 @@ int LYShowInfo(DocInfo *doc,
     static char tempfile[LY_MAXPATH] = "\0";
     int url_type;
     FILE *fp0;
-    char *Address = NULL, *Title = NULL;
+    char *Title = NULL;
     char *name;
     const char *cp;
+    char *temp = 0;
 
 #ifdef ADVANCED_INFO
     BOOLEAN LYInfoAdvanced = (BOOL) (user_mode == ADVANCED_MODE);
@@ -107,10 +155,9 @@ int LYShowInfo(DocInfo *doc,
 	}
     }
 
-    fprintf(fp0, "<html>\n<head>\n");
-    LYAddMETAcharsetToFD(fp0, -1);
-    fprintf(fp0, "<title>%s</title>\n</head>\n<body>\n",
-	    SHOWINFO_TITLE);
+    label_columns = 9;
+
+    WriteInternalTitle(fp0, SHOWINFO_TITLE);
 
     fprintf(fp0, "<h1>%s %s (%s) (<a href=\"%s\">%s</a>)",
 	    LYNX_NAME, LYNX_VERSION,
@@ -122,17 +169,16 @@ int LYShowInfo(DocInfo *doc,
 
 #ifdef DIRED_SUPPORT
     if (lynx_edit_mode && nlinks > 0) {
-	char *temp;
 
-	fprintf(fp0, "<pre>\n");
-	fprintf(fp0, "\n%s\n\n",
-		gettext("Directory that you are currently viewing"));
+	BEGIN_DL(gettext("Directory that you are currently viewing"));
 
 	temp = HTfullURL_toFile(doc->address);
-	fprintf(fp0, "   <em>%4s</em>  %s\n", gettext("Name:"), temp);
+	ADD_SS(gettext("Name:"), temp);
 	FREE(temp);
 
-	fprintf(fp0, "   <em>%4s</em>  %s\n", gettext("URL:"), doc->address);
+	ADD_SS(gettext("URL:"), doc->address);
+
+	END_DL();
 
 	temp = HTfullURL_toFile(links[doc->link].lname);
 
@@ -142,22 +188,19 @@ int LYShowInfo(DocInfo *doc,
 	} else {
 	    char modes[80];
 
+	    label_columns = 16;
 	    if (S_ISDIR(dir_info.st_mode)) {
-		fprintf(fp0, "\n%s\n\n",
-			gettext("Directory that you have currently selected"));
+		BEGIN_DL(gettext("Directory that you have currently selected"));
 	    } else if (S_ISREG(dir_info.st_mode)) {
-		fprintf(fp0, "\n%s\n\n",
-			gettext("File that you have currently selected"));
+		BEGIN_DL(gettext("File that you have currently selected"));
 #ifdef S_IFLNK
 	    } else if (S_ISLNK(dir_info.st_mode)) {
-		fprintf(fp0, "\n%s\n\n",
-			gettext("Symbolic link that you have currently selected"));
+		BEGIN_DL(gettext("Symbolic link that you have currently selected"));
 #endif
 	    } else {
-		fprintf(fp0, "\n%s\n\n",
-			gettext("Item that you have currently selected"));
+		BEGIN_DL(gettext("Item that you have currently selected"));
 	    }
-	    fprintf(fp0, "       <em>%s</em>  %s\n", gettext("Full name:"), temp);
+	    ADD_SS(gettext("Full name:"), temp);
 #ifdef S_IFLNK
 	    if (S_ISLNK(dir_info.st_mode)) {
 		char buf[1025];
@@ -168,36 +211,36 @@ int LYShowInfo(DocInfo *doc,
 		} else {
 		    sprintf(buf, "%.1024s", gettext("Unable to follow link"));
 		}
-		fprintf(fp0, "  <em>%s</em>  %s\n",
-			gettext("Points to file:"), buf);
+		ADD_SS(gettext("Points to file:"), buf);
 	    }
 #endif
 	    name = HTAA_UidToName(dir_info.st_uid);
 	    if (*name)
-		fprintf(fp0, "   <em>%s</em>  %s\n",
-			gettext("Name of owner:"), name);
+		ADD_SS(gettext("Name of owner:"), name);
 	    name = HTAA_GidToName(dir_info.st_gid);
 	    if (*name)
-		fprintf(fp0, "      <em>%s</em>  %s\n",
-			gettext("Group name:"), name);
+		ADD_SS(gettext("Group name:"), name);
 	    if (S_ISREG(dir_info.st_mode)) {
-		fprintf(fp0, "       <em>%s</em>  %ld (bytes)\n",
-			gettext("File size:"), (long) dir_info.st_size);
+		ADD_NN(gettext("File size:"),
+		       (long) dir_info.st_size,
+		       gettext("(bytes)"));
 	    }
 	    /*
 	     * Include date and time information.
 	     */
-	    cp = ctime(&dir_info.st_ctime);
-	    fprintf(fp0, "   <em>%s</em>  %s", gettext("Creation date:"), cp);
+	    ADD_SS(gettext("Creation date:"),
+		   ctime(&dir_info.st_ctime));
 
-	    cp = ctime(&dir_info.st_mtime);
-	    fprintf(fp0, "   <em>%s</em>  %s", gettext("Last modified:"), cp);
+	    ADD_SS(gettext("Last modified:"),
+		   ctime(&dir_info.st_mtime));
 
-	    cp = ctime(&dir_info.st_atime);
-	    fprintf(fp0, "   <em>%s</em>  %s\n", gettext("Last accessed:"), cp);
+	    ADD_SS(gettext("Last accessed:"),
+		   ctime(&dir_info.st_atime));
 
-	    fprintf(fp0, "   %s\n", gettext("Access Permissions"));
-	    fprintf(fp0, "      <em>%s</em>  ", gettext("Owner:"));
+	    END_DL();
+
+	    label_columns = 9;
+	    BEGIN_DL(gettext("Access Permissions"));
 	    modes[0] = '\0';
 	    modes[1] = '\0';	/* In case there are no permissions */
 	    modes[2] = '\0';
@@ -214,9 +257,8 @@ int LYShowInfo(DocInfo *doc,
 			strcat(modes, ", setuid");
 		}
 	    }
-	    fprintf(fp0, "%s\n", (char *) &modes[2]);	/* Skip leading ', ' */
+	    ADD_SS(gettext("Owner:"), &modes[2]);
 
-	    fprintf(fp0, "      <em>Group:</em>  ");
 	    modes[0] = '\0';
 	    modes[1] = '\0';	/* In case there are no permissions */
 	    modes[2] = '\0';
@@ -233,9 +275,8 @@ int LYShowInfo(DocInfo *doc,
 			strcat(modes, ", setgid");
 		}
 	    }
-	    fprintf(fp0, "%s\n", (char *) &modes[2]);	/* Skip leading ', ' */
+	    ADD_SS(gettext("Group:"), &modes[2]);
 
-	    fprintf(fp0, "      <em>World:</em>  ");
 	    modes[0] = '\0';
 	    modes[1] = '\0';	/* In case there are no permissions */
 	    modes[2] = '\0';
@@ -254,34 +295,29 @@ int LYShowInfo(DocInfo *doc,
 #endif
 		}
 	    }
-	    fprintf(fp0, "%s\n", (char *) &modes[2]);	/* Skip leading ', ' */
+	    ADD_SS(gettext("World:"), &modes[2]);
+	    END_DL();
 	}
 	FREE(temp);
-	fprintf(fp0, "</pre>\n");
     } else {
 #endif /* DIRED_SUPPORT */
 
-	fprintf(fp0, "<h2>%s</h2>\n<dl compact>",
-		gettext("File that you are currently viewing"));
+	BEGIN_DL(gettext("File that you are currently viewing"));
 
 	LYformTitle(&Title, doc->title);
-	LYEntify(&Title, TRUE);
-	fprintf(fp0, "<dt><em>%s</em> %s%s\n",
-		gettext("Linkname:"),
-		Title,
-		((doc->isHEAD &&
-		  !strstr(Title, " (HEAD)") &&
-		  !strstr(Title, " - HEAD")) ? " (HEAD)" : ""));
-
-	StrAllocCopy(Address, doc->address);
-	LYEntify(&Address, TRUE);
-	fprintf(fp0,
-		"<dt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>URL:</em> %s\n", Address);
+	HTSprintf(&temp, "%s%s",
+		  Title,
+		  ((doc->isHEAD &&
+		    !strstr(Title, " (HEAD)") &&
+		    !strstr(Title, " - HEAD")) ? " (HEAD)" : ""));
+	ADD_SS(gettext("Linkname:"), temp);
+	FREE(temp);
+
+	ADD_SS("URL:", doc->address);
 
 	if (HTLoadedDocumentCharset()) {
-	    fprintf(fp0, "<dt><em>&nbsp;%s</em> %s\n",
-		    gettext("Charset:"),
-		    HTLoadedDocumentCharset());
+	    ADD_SS(gettext("Charset:"),
+		   HTLoadedDocumentCharset());
 	} else {
 	    LYUCcharset *p_in = HTAnchor_getUCInfoStage(HTMainAnchor,
 							UCT_STAGE_PARSER);
@@ -292,41 +328,38 @@ int LYShowInfo(DocInfo *doc,
 	    }
 	    if (p_in && p_in->MIMEname && *(p_in->MIMEname) &&
 		HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_MIME) >= 0) {
-		fprintf(fp0, "<dt><em>&nbsp;%s</em> %s (assumed)\n",
-			gettext("Charset:"),
-			p_in->MIMEname);
+		HTSprintf(&temp, "%s %s",
+			  p_in->MIMEname,
+			  gettext("(assumed)"));
+		ADD_SS(gettext("Charset:"), p_in->MIMEname);
+		FREE(temp);
 	    }
 	}
 
 	if ((cp = HText_getServer()) != NULL && *cp != '\0')
-	    fprintf(fp0, "<dt><em>&nbsp;&nbsp;%s</em> %s\n",
-		    gettext("Server:"), cp);
+	    ADD_SS(gettext("Server:"), cp);
 
 	if ((cp = HText_getDate()) != NULL && *cp != '\0')
-	    fprintf(fp0, "<dt><em>&nbsp;&nbsp;&nbsp;&nbsp;%s</em> %s\n",
-		    gettext("Date:"), cp);
+	    ADD_SS(gettext("Date:"), cp);
 
 	if ((cp = HText_getLastModified()) != NULL && *cp != '\0')
-	    fprintf(fp0, "<dt><em>%s</em> %s\n", gettext("Last Mod:"), cp);
+	    ADD_SS(gettext("Last Mod:"), cp);
 
 #ifdef ADVANCED_INFO
 	if (LYInfoAdvanced) {
 	    if (HTMainAnchor && HTMainAnchor->expires) {
-		fprintf(fp0, "<dt><em>%s</em> %s\n",
-			gettext("&nbsp;Expires:"), HTMainAnchor->expires);
+		ADD_SS(gettext("Expires:"), HTMainAnchor->expires);
 	    }
 	    if (HTMainAnchor && HTMainAnchor->cache_control) {
-		fprintf(fp0, "<dt><em>%s</em> %s\n",
-			gettext("Cache-Control:"), HTMainAnchor->cache_control);
+		ADD_SS(gettext("Cache-Control:"), HTMainAnchor->cache_control);
 	    }
 	    if (HTMainAnchor && HTMainAnchor->content_length > 0) {
-		fprintf(fp0, "<dt><em>%s</em> %d %s\n",
-			gettext("Content-Length:"),
-			HTMainAnchor->content_length, gettext("bytes"));
+		ADD_NN(gettext("Content-Length:"),
+		       HTMainAnchor->content_length,
+		       gettext("bytes"));
 	    }
 	    if (HTMainAnchor && HTMainAnchor->content_language) {
-		fprintf(fp0, "<dt><em>%s</em> %s\n",
-			gettext("Language:"), HTMainAnchor->content_language);
+		ADD_SS(gettext("Language:"), HTMainAnchor->content_language);
 	    }
 	}
 #endif /* ADVANCED_INFO */
@@ -336,94 +369,83 @@ int LYShowInfo(DocInfo *doc,
 		    gettext("Post Data:"),
 		    BStrLen(doc->post_data),
 		    BStrData(doc->post_data));
-	    fprintf(fp0, "<dt><em>%s</em> %s\n",
-		    gettext("Post Content Type:"), doc->post_content_type);
+	    ADD_SS(gettext("Post Content Type:"), doc->post_content_type);
 	}
 
-	if (owner_address) {
-	    StrAllocCopy(Address, owner_address);
-	    LYEntify(&Address, TRUE);
-	} else {
-	    StrAllocCopy(Address, NO_NOTHING);
-	}
-	fprintf(fp0, "<dt><em>%s</em> %s\n", gettext("Owner(s):"), Address);
-
-	fprintf(fp0, "<dt>&nbsp;&nbsp;&nbsp;&nbsp;<em>%s</em> %d %s\n",
-		gettext("size:"), size_of_file, gettext("lines"));
-
-	fprintf(fp0, "<dt>&nbsp;&nbsp;&nbsp;&nbsp;<em>%s</em> %s%s%s",
-		gettext("mode:"),
-		((lynx_mode == FORMS_LYNX_MODE)
-		 ? gettext("forms mode")
-		 : (HTisDocumentSource()
-		    ? gettext("source")
-		    : gettext("normal"))),
-		(doc->safe ? gettext(", safe") : ""),
-		(doc->internal_link ? gettext(", via internal link") : "")
-	    );
+	ADD_SS(gettext("Owner(s):"),
+	       (owner_address
+		? owner_address
+		: NO_NOTHING));
+
+	ADD_NN(gettext("size:"),
+	       size_of_file,
+	       gettext("lines"));
+
+	StrAllocCopy(temp,
+		     ((lynx_mode == FORMS_LYNX_MODE)
+		      ? gettext("forms mode")
+		      : (HTisDocumentSource()
+			 ? gettext("source")
+			 : gettext("normal"))));
+	if (doc->safe)
+	    StrAllocCat(temp, gettext(", safe"));
+	if (doc->internal_link)
+	    StrAllocCat(temp, gettext(", via internal link"));
+
 #ifdef ADVANCED_INFO
 	if (LYInfoAdvanced) {
-	    fprintf(fp0, "%s%s%s\n",
-		    (HText_hasNoCacheSet(HTMainText) ?
-		     gettext(", no-cache") : ""),
-		    (HTAnchor_isISMAPScript((HTAnchor *) HTMainAnchor) ?
-		     gettext(", ISMAP script") : ""),
-		    (doc->bookmark ?
-		     gettext(", bookmark file") : "")
-		);
+	    if (HText_hasNoCacheSet(HTMainText))
+		StrAllocCat(temp, gettext(", no-cache"));
+	    if (HTAnchor_isISMAPScript((HTAnchor *) HTMainAnchor))
+		StrAllocCat(temp, gettext(", ISMAP script"));
+	    if (doc->bookmark)
+		StrAllocCat(temp, gettext(", bookmark file"));
 	}
 #endif /* ADVANCED_INFO */
 
-	fprintf(fp0, "\n</dl>\n");	/* end of list */
+	ADD_SS(gettext("mode:"), temp);
+	FREE(temp);
+
+	END_DL();
 
 	if (nlinks > 0) {
-	    fprintf(fp0, "<h2>%s</h2>\n<dl compact>",
-		    gettext("Link that you currently have selected"));
-	    StrAllocCopy(Title, LYGetHiliteStr(doc->link, 0));
-	    LYEntify(&Title, TRUE);
-	    fprintf(fp0, "<dt><em>%s</em> %s\n",
-		    gettext("Linkname:"),
-		    Title);
+	    BEGIN_DL(gettext("Link that you currently have selected"));
+	    ADD_SS(gettext("Linkname:"),
+		   LYGetHiliteStr(doc->link, 0));
 	    if (lynx_mode == FORMS_LYNX_MODE &&
 		links[doc->link].type == WWW_FORM_LINK_TYPE) {
 		if (links[doc->link].l_form->submit_method) {
 		    int method = links[doc->link].l_form->submit_method;
 		    char *enctype = links[doc->link].l_form->submit_enctype;
 
-		    fprintf(fp0, "<dt>&nbsp;&nbsp;<em>%s</em> %s\n",
-			    gettext("Method:"),
-			    ((method == URL_POST_METHOD) ? "POST" :
-			     ((method == URL_MAIL_METHOD) ? "(email)" :
-			      "GET")));
-		    fprintf(fp0, "<dt>&nbsp;<em>%s</em> %s\n",
-			    gettext("Enctype:"),
-			    (enctype &&
-			     *enctype ?
-			     enctype : "application/x-www-form-urlencoded"));
+		    ADD_SS(gettext("Method:"),
+			   ((method == URL_POST_METHOD) ? "POST" :
+			    ((method == URL_MAIL_METHOD) ? "(email)" :
+			     "GET")));
+		    ADD_SS(gettext("Enctype:"),
+			   (non_empty(enctype)
+			    ? enctype
+			    : "application/x-www-form-urlencoded"));
 		}
 		if (links[doc->link].l_form->submit_action) {
-		    StrAllocCopy(Address, links[doc->link].l_form->submit_action);
-		    LYEntify(&Address, TRUE);
-		    fprintf(fp0, "<dt>&nbsp;&nbsp;<em>Action:</em> %s\n", Address);
+		    ADD_SS(gettext("Action:"),
+			   links[doc->link].l_form->submit_action);
 		}
 		if (!(links[doc->link].l_form->submit_method &&
 		      links[doc->link].l_form->submit_action)) {
 		    fprintf(fp0, "<dt>&nbsp;%s\n", gettext("(Form field)"));
 		}
 	    } else {
-		if (links[doc->link].lname) {
-		    StrAllocCopy(Title, links[doc->link].lname);
-		    LYEntify(&Title, TRUE);
-		} else {
-		    StrAllocCopy(Title, "");
-		}
-		fprintf(fp0,
-			"<dt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>URL:</em> %s\n", Title);
+		ADD_SS("URL:",
+		       (links[doc->link].lname
+			? links[doc->link].lname
+			: ""));
 	    }
-	    fprintf(fp0, "</dl>\n");	/* end of list */
+	    END_DL();
 
-	} else
+	} else {
 	    fprintf(fp0, "<h2>%s</h2>", gettext("No Links on the current page"));
+	}
 
 #ifdef EXP_HTTP_HEADERS
 	if ((cp = HText_getHttpHeaders()) != 0) {
@@ -440,7 +462,6 @@ int LYShowInfo(DocInfo *doc,
     LYrefresh();
 
     LYCloseTemp(tempfile);
-    FREE(Address);
     FREE(Title);
 
     return (0);
diff --git a/src/LYStrings.c b/src/LYStrings.c
index e9704744..8c6983c3 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -372,7 +372,7 @@ static int set_clicked_link(int x,
 			    int clicks)
 {
     int left = 6;
-    int right = LYcols - 6;
+    int right = LYcolLimit - 5;
 
     /* yes, I am assuming that my screen will be a certain width. */
     int i;
@@ -386,7 +386,7 @@ static int set_clicked_link(int x,
 	if (x == 0 && toolbar)	/* On '#' */
 	    c = LAC_TO_LKC0(LYK_TOOLBAR);
 #if defined(CAN_CUT_AND_PASTE) && defined(USE_COLOR_STYLE)
-	else if (y == 0 && x == LYcols - 1 && s_hot_paste != NOSTYLE)
+	else if (y == 0 && x == LYcolLimit && s_hot_paste != NOSTYLE)
 	    c = LAC_TO_LKC0(LYK_PASTE_URL);
 #endif
 	else if (clicks > 1) {
@@ -422,7 +422,7 @@ static int set_clicked_link(int x,
 		c = LAC_TO_LKC0(LYK_PREV_PAGE);
 	}
 #ifdef USE_SCROLLBAR
-    } else if (x == LYcols - 1 && LYShowScrollbar && LYsb_begin >= 0) {
+    } else if (x == (LYcols - 1) && LYShowScrollbar && LYsb_begin >= 0) {
 	int h = display_lines - 2 * (LYsb_arrow != 0);
 
 	mouse_link = -2;
@@ -659,31 +659,33 @@ int LYmbcsstrlen(char *str,
 {
     int i, j, len = 0;
 
-    if (!non_empty(str))
-	return (len);
-
-    for (i = 0; str[i] != '\0'; i++) {
-	if (IsSpecialAttrChar(str[i])) {
-	    continue;
-	} else {
-	    len++;
-	}
-	if (IS_NEW_GLYPH(str[i])) {
-	    j = 0;
-	    while (str[(i + 1)] != '\0' &&
-		   !IsSpecialAttrChar(str[(i + 1)]) &&
-		   j < 5 &&
-		   IS_UTF_EXTRA(str[(i + 1)])) {
-		i++;
-		j++;
+    if (non_empty(str)) {
+#ifdef WIDEC_CURSES
+	if (count_gcells) {
+	    len = LYstrCells(str);
+	} else
+#endif
+	{
+	    for (i = 0; str[i] != '\0'; i++) {
+		if (!IsSpecialAttrChar(str[i])) {
+		    len++;
+		    if (IS_NEW_GLYPH(str[i])) {
+			j = 0;
+			while (IsNormalChar(str[(i + 1)]) &&
+			       j < 5 &&
+			       IS_UTF_EXTRA(str[(i + 1)])) {
+			    i++;
+			    j++;
+			}
+		    } else if (!utf_flag && HTCJK != NOCJK && !count_gcells &&
+			       is8bits(str[i]) &&
+			       IsNormalChar(str[(i + 1)])) {
+			i++;
+		    }
+		}
 	    }
-	} else if (!utf_flag && HTCJK != NOCJK && !count_gcells &&
-		   is8bits(str[i]) && str[(i + 1)] != '\0' &&
-		   !IsSpecialAttrChar(str[(i + 1)])) {
-	    i++;
 	}
     }
-
     return (len);
 }
 
@@ -2253,7 +2255,7 @@ static int LYgetch_for(int code)
 #define V_CMD_AREA	1
 
 		int left = H_CMD_AREA;
-		int right = (LYcols - H_CMD_AREA);
+		int right = (LYcolLimit - H_CMD_AREA - 1);
 
 		/* yes, I am assuming that my screen will be a certain width. */
 
@@ -2680,10 +2682,10 @@ char *LYElideString(char *str,
 
     LYstrncpy(buff, str, sizeof(buff) - 1);
     len = strlen(buff);
-    if (len > (LYcols - 10)) {
+    if (len > (LYcolLimit - 9)) {
 	buff[cut_pos] = '.';
 	buff[cut_pos + 1] = '.';
-	for (s = (buff + len) - (LYcols - 10) + cut_pos + 1,
+	for (s = (buff + len) - (LYcolLimit - 9) + cut_pos + 1,
 	     d = (buff + cut_pos) + 2;
 	     s >= buff &&
 	     d >= buff &&
@@ -4007,10 +4009,13 @@ int LYhandlePopupList(int cur_choice,
     }
 
     if (for_mouse) {
+	int check = (Lnum + (int) width + 4);
+	int limit = LYcols;
+
 	/* shift horizontally to lie within screen width, if possible */
-	if (Lnum + (int) width + 4 < LYcols) {
-	    if (lx - 1 + (Lnum + (int) width + 4) > LYcols)
-		lx = LYcols + 1 - (Lnum + width + 4);
+	if (check < limit) {
+	    if (lx - 1 + check > limit)
+		lx = limit + 1 - check;
 	    else if (lx <= 0)
 		lx = 1;
 	}
@@ -4020,13 +4025,20 @@ int LYhandlePopupList(int cur_choice,
      * Set up the overall window, including the boxing characters ('*'), if it
      * all fits.  Otherwise, set up the widest window possible.  - FM
      */
+    width += Lnum;
+    bottom -= top;
+
     if (num_choices <= 0
 	|| cur_choice > num_choices
-	|| (form_window = LYstartPopup(top, lx,
-				       bottom - top,
-				       Lnum + width)) == 0)
+	|| (form_window = LYstartPopup(&top,
+				       &lx,
+				       &bottom,
+				       &width)) == 0)
 	return (orig_choice);
 
+    width -= Lnum;
+    bottom += top;
+
     /*
      * Clear the command line and write the popup statusline.  - FM
      */
@@ -4785,7 +4797,7 @@ int LYgetstr(char *inputline,
     LYGetYX(y, x);		/* Use screen from cursor position to eol */
     MaxStringSize = (bufsize < sizeof(MyEdit.buffer)) ?
 	(bufsize - 1) : (sizeof(MyEdit.buffer) - 1);
-    LYSetupEdit(&MyEdit, inputline, MaxStringSize, (LYcols - 1) - x);
+    LYSetupEdit(&MyEdit, inputline, MaxStringSize, LYcolLimit - x);
     MyEdit.hidden = (BOOL) hidden;
 
     CTRACE((tfp, "called LYgetstr\n"));
@@ -5252,8 +5264,7 @@ char *LYno_attr_mbcs_case_strstr(char *chptr,
     for (; *chptr != '\0'; chptr++) {
 	if ((!utf_flag && HTCJK != NOCJK && is8bits(*chptr) &&
 	     *chptr == *tarptr &&
-	     *(chptr + 1) != '\0' &&
-	     !IsSpecialAttrChar(*(chptr + 1))) ||
+	     IsNormalChar(*(chptr + 1))) ||
 	    (0 == UPPER8(*chptr, *tarptr))) {
 	    int tarlen = 0;
 
@@ -5278,8 +5289,7 @@ char *LYno_attr_mbcs_case_strstr(char *chptr,
 	    }
 	    if (!utf_flag && HTCJK != NOCJK && is8bits(*chptr) &&
 		*chptr == *tarptr &&
-		*tmpchptr != '\0' &&
-		!IsSpecialAttrChar(*tmpchptr)) {
+		IsNormalChar(*tmpchptr)) {
 		/*
 		 * Check the CJK multibyte.  - FM
 		 */
@@ -5355,8 +5365,7 @@ char *LYno_attr_mbcs_case_strstr(char *chptr,
 	} else if (!(IS_UTF_EXTRA(*chptr) ||
 		     IsSpecialAttrChar(*chptr))) {
 	    if (!utf_flag && HTCJK != NOCJK && is8bits(*chptr) &&
-		*(chptr + 1) != '\0' &&
-		!IsSpecialAttrChar(*(chptr + 1))) {
+		IsNormalChar(*(chptr + 1))) {
 		chptr++;
 		if (count_gcells)
 		    len++;
@@ -5439,8 +5448,7 @@ char *LYno_attr_mbcs_strstr(char *chptr,
 		return (chptr);
 	    }
 	    if (!utf_flag && HTCJK != NOCJK && is8bits(*chptr) &&
-		*tmpchptr != '\0' &&
-		!IsSpecialAttrChar(*tmpchptr)) {
+		IsNormalChar(*tmpchptr)) {
 		/*
 		 * Check the CJK multibyte.  - FM
 		 */
@@ -5515,8 +5523,7 @@ char *LYno_attr_mbcs_strstr(char *chptr,
 	} else if (!(IS_UTF_EXTRA(*chptr) ||
 		     IsSpecialAttrChar(*chptr))) {
 	    if (!utf_flag && HTCJK != NOCJK && is8bits(*chptr) &&
-		*(chptr + 1) != '\0' &&
-		!IsSpecialAttrChar(*(chptr + 1))) {
+		IsNormalChar(*(chptr + 1))) {
 		chptr++;
 		if (count_gcells)
 		    len++;
diff --git a/src/LYTraversal.c b/src/LYTraversal.c
index 387928d0..b6690a01 100644
--- a/src/LYTraversal.c
+++ b/src/LYTraversal.c
@@ -31,7 +31,7 @@ static void exit_with_perror(const char *msg)
     exit_immediately(EXIT_FAILURE);
 }
 
-BOOLEAN lookup(char *target)
+BOOLEAN lookup_link(char *target)
 {
     FILE *ifp;
     char *buffer = NULL;
@@ -119,6 +119,8 @@ void add_to_reject_list(char *target)
 
     FILE *ifp;
 
+    CTRACE((tfp, "add_to_reject_list(%s)\n", target));
+
     if ((ifp = LYAppendToTxtFile(TRAVERSE_REJECT_FILE)) == NULL) {
 	exit_with_perror(CANNOT_OPEN_REJ_FILE);
     }
@@ -149,7 +151,7 @@ BOOLEAN lookup_reject(char *target)
 	return (FALSE);
     }
 
-    HTSprintf0(&line, "%s\n", target);
+    HTSprintf0(&line, "%s", target);
 
     while (LYSafeGets(&buffer, ifp) != NULL && !result) {
 	LYTrimTrailing(buffer);
@@ -171,5 +173,7 @@ BOOLEAN lookup_reject(char *target)
     FREE(line);
 
     LYCloseInput(ifp);
+
+    CTRACE((tfp, "lookup_reject(%s) -> %d\n", target, result));
     return (BOOL) (result);
 }
diff --git a/src/LYTraversal.h b/src/LYTraversal.h
index 0da2a0f9..7da7da36 100644
--- a/src/LYTraversal.h
+++ b/src/LYTraversal.h
@@ -7,7 +7,7 @@
 #include <HTUtils.h>		/* BOOL, ARGS */
 #endif
 
-extern BOOLEAN lookup(char *target);
+extern BOOLEAN lookup_link(char *target);
 extern void add_to_table(char *target);
 extern void add_to_traverse_list(char *fname, char *prev_link_name);
 extern void dump_traversal_history(void);
diff --git a/src/LYUtils.c b/src/LYUtils.c
index a1dd074d..448575c4 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -399,7 +399,7 @@ static BOOL show_whereis_targets(int flag,
 		      (LYGetHiliteStr(cur, count) ?
 		       LYGetHiliteStr(cur, count) : ""),
 		      (sizeof(buffer) - 1),
-		      ((LYcols - 1) - LYGetHilitePos(cur, count)),
+		      (LYcolLimit - LYGetHilitePos(cur, count)),
 		      utf_flag);
 	hlen = strlen(buffer);
 	hLen = ((HTCJK != NOCJK || utf_flag) ?
@@ -1047,7 +1047,7 @@ void LYhighlight(int flag,
 
 	if (links[cur].type == WWW_FORM_LINK_TYPE) {
 	    int len;
-	    int avail_space = (LYcols - links[cur].lx) - 1;
+	    int avail_space = (LYcolLimit - links[cur].lx);
 	    char *text = LYGetHiliteStr(cur, 0);
 
 	    if (avail_space > links[cur].l_form->size)
@@ -1079,7 +1079,7 @@ void LYhighlight(int flag,
 			  (LYGetHiliteStr(cur, 0) ?
 			   LYGetHiliteStr(cur, 0) : ""),
 			  (sizeof(buffer) - 1),
-			  ((LYcols - 1) - links[cur].lx),
+			  (LYcolLimit - links[cur].lx),
 			  utf_flag);
 	    LYaddstr(buffer);
 	}
@@ -1277,8 +1277,9 @@ void statusline(const char *text)
      * set selected, otherwise, strip any escapes.  Also, make sure text is not
      * longer than the statusline window.  - FM
      */
-    max_length = ((LYcols - 2) < (int) sizeof(buffer))
-	? (LYcols - 2) : (int) sizeof(buffer) - 1;
+    max_length = (((LYcolLimit - 1) < (int) sizeof(buffer))
+		  ? (LYcolLimit - 1)
+		  : (int) sizeof(buffer) - 1);
     if ((text_buff[0] != '\0') &&
 	(LYHaveCJKCharacterSet)) {
 	/*
@@ -2788,11 +2789,11 @@ void size_change(int sig GCC_UNUSED)
 #ifdef SLANG_MBCS_HACK
     PHYSICAL_SLtt_Screen_Cols = LYcols;
 #ifdef SLANG_NO_LIMIT		/* define this if slang has been fixed */
-    SLtt_Screen_Cols = (LYcols - 1) * 6;
+    SLtt_Screen_Cols = LYcolLimit * 6;
 #else
     /* Needs to be limited: fixed buffer bugs in slang can cause crash,
        see slang's SLtt_smart_puts - kw */
-    SLtt_Screen_Cols = HTMIN((LYcols - 1) * 6, 255);
+    SLtt_Screen_Cols = HTMIN(LYcolLimit * 6, 255);
 #endif
 #endif /* SLANG_MBCS_HACK */
     if (sig == 0)
@@ -3049,7 +3050,7 @@ void change_sug_filename(char *fname)
 	     * Replace with dashes.
 	     */
 	} else if (*cp == '!' || *cp == '?' || *cp == '\'' ||
-		   *cp == ',' || *cp == ':' || *cp == '\"' ||
+		   *cp == ',' || *cp == ':' || *cp == '"' ||
 		   *cp == '+' || *cp == '@' || *cp == '\\' ||
 		   *cp == '(' || *cp == ')' || *cp == '=' ||
 		   *cp == '<' || *cp == '>' || *cp == '#' ||
@@ -3203,7 +3204,7 @@ void change_sug_filename(char *fname)
     for (cp = fname; *cp != '\0'; cp++) {
 	switch (*cp) {
 	case '\'':
-	case '\"':
+	case '"':
 	case '/':
 	case ' ':
 	    *cp = '-';
@@ -5969,7 +5970,7 @@ FILE *LYOpenTemp(char *result,
 	if (make_it) {
 	    int old_mask = umask(HIDE_UMASK);
 
-	    StrAllocCat(lynx_temp_space, "XXXXXXXXXX");
+	    StrAllocCat(lynx_temp_space, "lynxXXXXXXXXXX");
 	    if (mkdtemp(lynx_temp_space) == 0) {
 		printf("%s: %s\n", lynx_temp_space, LYStrerror(errno));
 		exit(EXIT_FAILURE);
@@ -6720,8 +6721,10 @@ FILE *InternalPageFP(char *filename,
     return fp;
 }
 
-void BeginInternalPage(FILE *fp0, char *Title,
-		       char *HelpURL)
+/*
+ * This part is shared by all internal pages.
+ */
+void WriteInternalTitle(FILE *fp0, char *Title)
 {
     fprintf(fp0,
 	    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
@@ -6743,8 +6746,17 @@ void BeginInternalPage(FILE *fp0, char *Title,
 	    FREE(Address);
 	}
     }
-    fprintf(fp0, "<title>%s</title>\n</head>\n<body>\n",
-	    Title);
+    fprintf(fp0, "<title>%s</title>\n</head>\n<body>\n", Title);
+}
+
+/*
+ * This is used to start most internal pages, except for special cases where
+ * the embedded HREF's in the title differ.
+ */
+void BeginInternalPage(FILE *fp0, char *Title,
+		       char *HelpURL)
+{
+    WriteInternalTitle(fp0, Title);
 
     if ((user_mode == NOVICE_MODE)
 	&& LYwouldPush(Title, NULL)
@@ -7460,6 +7472,30 @@ int put_clip(char *s)
 
 #endif /* __EMX__ */
 
+/*
+ * Sleep for a number of milli-sec.
+ */
+void LYmsec_delay(unsigned msec)
+{
+#if defined(_WINDOWS)
+    Sleep(msec);
+
+#elif defined(HAVE_NAPMS)
+    napms(msec);
+
+#elif defined(DJGPP) || defined(HAVE_USLEEP)
+    usleep(1000 * msec);
+
+#else
+    struct timeval tv;
+    unsigned long usec = 1000UL * msec;
+
+    tv.tv_sec  = usec / 1000000UL;
+    tv.tv_usec = usec % 1000000UL;
+    select (0, NULL, NULL, NULL, &tv);
+#endif
+}
+
 #if defined(WIN_EX)		/* 1997/10/16 (Thu) 20:13:28 */
 
 int put_clip(char *szBuffer)
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 979568c8..e8751592 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -118,9 +118,6 @@ extern BOOLEAN LYisLocalFile(const char *filename);
 extern BOOLEAN LYisLocalHost(const char *filename);
 extern BOOLEAN LYisRootPath(const char *path);
 extern BOOLEAN inlocaldomain(void);
-extern const char *Home_Dir(void);
-extern const char *index_to_restriction(int inx);
-extern const char *wwwName(const char *pathname);
 extern FILE *InternalPageFP(char *filename, int reuse_flag);
 extern FILE *LYAppendToTxtFile(char *name);
 extern FILE *LYNewBinFile(char *name);
@@ -139,6 +136,9 @@ extern char *LYSysShell(void);
 extern char *LYgetXDisplay(void);
 extern char *strip_trailing_slash(char *my_dirname);
 extern char *trimPoundSelector(char *address);
+extern const char *Home_Dir(void);
+extern const char *index_to_restriction(int inx);
+extern const char *wwwName(const char *pathname);
 extern int HTCheckForInterrupt(void);
 extern int LYCheckForProxyURL(char *filename);
 extern int LYConsoleInputFD(BOOLEAN need_selectable);
@@ -181,7 +181,9 @@ extern void LYTrimHtmlSep(char *path);
 extern void LYTrimPathSep(char *path);
 extern void LYTrimRelFromAbsPath(char *path);
 extern void LYhighlight(int flag, int cur, char *target);
+extern void LYmsec_delay(unsigned msec);
 extern void LYsetXDisplay(char *new_display);
+extern void WriteInternalTitle(FILE *fp0, char *Title);
 extern void change_sug_filename(char *fname);
 extern void convert_to_spaces(char *string, BOOL condense);
 extern void free_and_clear(char **obj);
diff --git a/src/TRSTable.c b/src/TRSTable.c
index 586a7593..f25906c8 100644
--- a/src/TRSTable.c
+++ b/src/TRSTable.c
@@ -23,9 +23,9 @@
 #endif
 
 #ifdef USE_CURSES_PADS
-#  define MAX_STBL_POS (LYwideLines ? MAX_COLS - 1 : LYcols-1)
+#  define MAX_STBL_POS (LYwideLines ? MAX_COLS - 1 : LYcolLimit)
 #else
-#  define MAX_STBL_POS (LYcols-1)
+#  define MAX_STBL_POS (LYcolLimit)
 #endif
 
 /* must be different from HT_ALIGN_NONE and HT_LEFT, HT_CENTER etc.: */