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.c400
-rw-r--r--src/GridText.h4
-rw-r--r--src/HTAlert.c12
-rw-r--r--src/HTFWriter.c43
-rw-r--r--src/HTInit.c46
-rw-r--r--src/HTML.c24
-rw-r--r--src/HTML.h26
-rw-r--r--src/LYCharSets.c42
-rw-r--r--src/LYCharUtils.c2
-rw-r--r--src/LYClean.c2
-rw-r--r--src/LYCookie.c2
-rw-r--r--src/LYCurses.c162
-rw-r--r--src/LYCurses.h42
-rw-r--r--src/LYDownload.c14
-rw-r--r--src/LYExtern.c2
-rw-r--r--src/LYGlobalDefs.h24
-rw-r--r--src/LYHash.c4
-rw-r--r--src/LYJump.c4
-rw-r--r--src/LYMain.c180
-rw-r--r--src/LYMainLoop.c78
-rw-r--r--src/LYOptions.c18
-rw-r--r--src/LYReadCFG.c44
-rw-r--r--src/LYStrings.c2
-rw-r--r--src/LYStyle.c6
-rw-r--r--src/LYUtils.c103
-rw-r--r--src/LYUtils.h7
-rw-r--r--src/LYrcFile.c8
-rw-r--r--src/LYrcFile.h1
-rw-r--r--src/TRSTable.c426
-rw-r--r--src/TRSTable.h3
-rw-r--r--src/UCdomap.c6
-rw-r--r--src/chrtrans/build-chrtrans.com1
-rw-r--r--src/chrtrans/make-msc.bat1
-rw-r--r--src/chrtrans/makefile.bcb8
-rw-r--r--src/chrtrans/makefile.dos2
-rw-r--r--src/chrtrans/makefile.in21
-rw-r--r--src/chrtrans/makefile.msc2
-rw-r--r--src/chrtrans/makeuctb.c21
-rw-r--r--src/chrtrans/makew32.bat8
-rw-r--r--src/chrtrans/pt154_uni.tbl174
-rw-r--r--src/makefile.dos6
-rw-r--r--src/makefile.dsl2
-rw-r--r--src/makefile.in74
-rw-r--r--src/makefile.wsl2
44 files changed, 1160 insertions, 899 deletions
diff --git a/src/GridText.c b/src/GridText.c
index 04215460..193b4f7b 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -43,7 +43,7 @@
 
 /*#define DEBUG_APPCH 1*/
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 #include <HTFile.h>
 #endif
 
@@ -139,7 +139,7 @@ PUBLIC char * unchecked_radio = "( )";
 PRIVATE BOOLEAN underline_on = OFF;
 PRIVATE BOOLEAN bold_on      = OFF;
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 PUBLIC int LYCacheSource = SOURCE_CACHE_NONE;
 PUBLIC int LYCacheSourceForAborted = SOURCE_CACHE_FOR_ABORTED_DROP;
 #endif
@@ -242,7 +242,7 @@ There are 3 functions - POOL_NEW, POOL_FREE, and ALLOC_IN_POOL.
 #define POOLallocstyles(ptr, n)     ptr = ALLOC_IN_POOL(&HTMainText->pool, n * sizeof(pool_data))
 #define POOLallocHTLine(ptr, size)  ptr = (HTLine*) ALLOC_IN_POOL(&HTMainText->pool, LINE_SIZE(size))
 #define POOLallocstring(ptr, len)   ptr = (char*) ALLOC_IN_POOL(&HTMainText->pool, len + 1)
-#define POOLtypecalloc(T,ptr)	    ptr = (T*) ALLOC_IN_POOL(&HTMainText->pool, sizeof(T))
+#define POOLtypecalloc(T, ptr)      ptr = (T*) ALLOC_IN_POOL(&HTMainText->pool, sizeof(T))
 
 /**************************************************************************/
 /*
@@ -332,7 +332,20 @@ typedef struct _line {
 } HTLine;
 
 
-#define LINE_SIZE(l) (sizeof(HTLine)+(l))	/* Allow for terminator */
+#define LINE_SIZE(size) (sizeof(HTLine)+(size))   /* Allow for terminator */
+
+#define HTLINE_NOT_IN_POOL 0	/* debug with this set to 1 */
+
+#if HTLINE_NOT_IN_POOL
+#define allocHTLine(ptr, size)  { ptr = (HTLine *)calloc(1, LINE_SIZE(size)); }
+#define freeHTLine(self, ptr)   { \
+	if (ptr && ptr != TEMP_LINE(self, 0) && ptr != TEMP_LINE(self, 1)) \
+	    FREE(ptr); \
+    }
+#else
+#define allocHTLine(ptr, size)  POOLallocHTLine(ptr, size)
+#define freeHTLine(self, ptr)   {}
+#endif
 
 /*
  * Last line buffer; the second is used in split_line(). Not in pool!
@@ -445,7 +458,7 @@ struct _HText {
 
 	HTPool*			pool;		/* this HText memory pool */
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	/*
 	* Parse settings when this HText was generated.
 	*/
@@ -585,9 +598,6 @@ PRIVATE int HText_TrueLineSize PARAMS((
 	HText *		text,
 	BOOL		IgnoreSpaces));
 
-PRIVATE void HText_RemoveEmptyLastLine PARAMS((
-	HText *		text));
-
 #ifdef CHECK_FREE_MEM
 
 /*
@@ -656,8 +666,6 @@ PRIVATE void * LY_check_calloc ARGS2(
     n = HTList_count(loaded_texts);
     for (i = n - 1; i > 0; i--) {
 	HText * t = (HText *) HTList_objectAt(loaded_texts, i);
-	if (t == HTMainText)
-	    t = NULL;		/* shouldn't happen */
 	CTRACE((tfp, "\nBUG *** Emergency freeing document %d/%d for '%s'%s!\n",
 		    i + 1, n,
 		    ((t && t->node_anchor &&
@@ -705,6 +713,7 @@ PRIVATE void LYClearHiText ARGS1(
     a->lites.hl_base.hl_text = NULL;
     a->lites.hl_len = 0;
 }
+#define LYFreeHiText(a)     FREE((a)->lites.hl_info)
 
 /*
  * Set the initial highlight information for a given anchor.
@@ -787,7 +796,6 @@ PRIVATE char *LYGetHiTextStr ARGS2(
     else
 	result = a->lites.hl_base.hl_text;
     result += LYAdjHiTextPos(a, count);
-    CTRACE((tfp, "FIXME text '%s'\n", result));
     return result;
 }
 
@@ -807,7 +815,6 @@ PRIVATE int LYGetHiTextPos ARGS2(
     else
 	result = a->line_pos;
     result += LYAdjHiTextPos(a, count);
-    CTRACE((tfp, "FIXME cols '%d'\n", result));
     return result;
 }
 
@@ -857,6 +864,54 @@ PRIVATE void PerFormInfo_free ARGS1(
     }
 }
 
+PRIVATE void free_form_fields ARGS1(
+	FormInfo *,	input_field)
+{
+    /*
+     *  Free form fields.
+     */
+    if (input_field->type == F_OPTION_LIST_TYPE &&
+	input_field->select_list != NULL) {
+	/*
+	 *  Free off option lists if present.
+	 *  It should always be present for F_OPTION_LIST_TYPE
+	 *  unless we had invalid markup which prevented
+	 *  HText_setLastOptionValue from finishing its job
+	 *  and left the input field in an insane state. - kw
+	 */
+	OptionType *optptr = input_field->select_list;
+	OptionType *tmp;
+	while (optptr) {
+	    tmp = optptr;
+	    optptr = tmp->next;
+	    FREE(tmp->name);
+	    FREE(tmp->cp_submit_value);
+	    FREE(tmp);
+	}
+	input_field->select_list = NULL;
+	/*
+	 *  Don't free the value field on option
+	 *  lists since it points to a option value
+	 *  same for orig value.
+	 */
+	input_field->value = NULL;
+	input_field->orig_value = NULL;
+	input_field->cp_submit_value = NULL;
+	input_field->orig_submit_value = NULL;
+    } else {
+	FREE(input_field->value);
+	FREE(input_field->orig_value);
+	FREE(input_field->cp_submit_value);
+	FREE(input_field->orig_submit_value);
+    }
+    FREE(input_field->name);
+    FREE(input_field->submit_action);
+    FREE(input_field->submit_enctype);
+    FREE(input_field->submit_title);
+
+    FREE(input_field->accept_cs);
+}
+
 PRIVATE void FormList_delete ARGS1(
     HTList *,		forms)
 {
@@ -915,8 +970,7 @@ PUBLIC HText *	HText_new ARGS1(
     /*
      *  Links between anchors & documents are a 1-1 relationship.  If
      *  an anchor is already linked to a document we didn't call
-     *  HTuncache_current_document(), e.g., for the showinfo, options,
-     *  download, print, etc., temporary file URLs, so we'll check now
+     *  HTuncache_current_document(),  so we'll check now
      *  and free it before reloading. - Dick Wesseling (ftu@fi.ruu.nl)
      */
     if (anchor->document) {
@@ -967,7 +1021,7 @@ PUBLIC HText *	HText_new ARGS1(
     self->stale = YES;
     self->toolbar = NO;
     self->tabs = NULL;
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     /*
      * Remember the parse settings.
      */
@@ -1126,57 +1180,29 @@ PUBLIC void HText_free ARGS1(
     if (!self)
 	return;
 
+#if HTLINE_NOT_IN_POOL
+    {
+	HTLine *f = FirstHTLine(self);
+	HTLine *l = self->last_line;
+
+	while (l != f) {	/* Free off line array */
+	    self->last_line = l->prev;
+	    freeHTLine(self, l);
+	    l = self->last_line;
+	}
+	freeHTLine(self, f);
+    }
+#endif
+
     while (self->first_anchor) {		/* Free off anchor array */
 	TextAnchor * l = self->first_anchor;
 	self->first_anchor = l->next;
 
 	if (l->link_type == INPUT_ANCHOR && l->input_field) {
-	    /*
-	     *  Free form fields.
-	     */
-	    if (l->input_field->type == F_OPTION_LIST_TYPE &&
-		l->input_field->select_list != NULL) {
-		/*
-		 *  Free off option lists if present.
-		 *  It should always be present for F_OPTION_LIST_TYPE
-		 *  unless we had invalid markup which prevented
-		 *  HText_setLastOptionValue from finishing its job
-		 *  and left the input field in an insane state. - kw
-		 */
-		OptionType *optptr = l->input_field->select_list;
-		OptionType *tmp;
-		while (optptr) {
-		    tmp = optptr;
-		    optptr = tmp->next;
-		    FREE(tmp->name);
-		    FREE(tmp->cp_submit_value);
-		    FREE(tmp);
-		}
-		l->input_field->select_list = NULL;
-		/*
-		 *  Don't free the value field on option
-		 *  lists since it points to a option value
-		 *  same for orig value.
-		 */
-		l->input_field->value = NULL;
-		l->input_field->orig_value = NULL;
-		l->input_field->cp_submit_value = NULL;
-		l->input_field->orig_submit_value = NULL;
-	    } else {
-		FREE(l->input_field->value);
-		FREE(l->input_field->orig_value);
-		FREE(l->input_field->cp_submit_value);
-		FREE(l->input_field->orig_submit_value);
-	    }
-	    FREE(l->input_field->name);
-	    FREE(l->input_field->submit_action);
-	    FREE(l->input_field->submit_enctype);
-	    FREE(l->input_field->submit_title);
-
-	    FREE(l->input_field->accept_cs);
+	    free_form_fields(l->input_field);
 	}
 
-	LYClearHiText(l);
+	LYFreeHiText(l);
     }
     FormList_delete(self->forms);
 
@@ -1217,7 +1243,7 @@ PUBLIC void HText_free ARGS1(
 				  UCT_SETBY_NONE);
 	HTAnchor_resetUCInfoStage(self->node_anchor, -1, UCT_STAGE_HTEXT,
 				  UCT_SETBY_NONE);
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	/* Remove source cache files and chunks always, even if the
 	 * HTAnchor_delete call does not actually remove the anchor.
 	 * Keeping them would just be a waste of space - they won't
@@ -2464,10 +2490,6 @@ PUBLIC void HText_beginAppend ARGS1(
 */
 #define new_line(text) split_line(text, 0)
 
-#define AT_START_OF_CELL(text)	\
-  (text->stbl			\
-   && Stbl_at_start_of_cell(text->stbl, text->Lines, text->last_line->size))
-
 #define DEBUG_SPLITLINE
 
 #ifdef DEBUG_SPLITLINE
@@ -2566,7 +2588,7 @@ PRIVATE void move_anchors_in_region ARGS7(
  *  Some necessary changes for anchors starting on this line are also done
  *  here if needed. Updates 'prev_anchor' internally.
  *  Returns a newly allocated HTLine* if changes were made
- *    (lines allocated in pool, caller should not free the old one).
+ *    (caller has to free the old one).
  *  Returns NULL if no changes needed.  (Remove-spaces code may be buggy...)
  * - kw
  */
@@ -2607,7 +2629,7 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
 	else
 	   mod_line = TEMP_LINE(text, 0);
     } else {
-	POOLallocHTLine(mod_line, line->size + added_chars);
+	allocHTLine(mod_line, line->size + added_chars);
     }
     if (!mod_line)
 	return NULL;
@@ -2679,32 +2701,6 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7(
     return mod_line;
 }
 
-PRIVATE void reset_cached_linedata ARGS3(
-	HText *,	text,
-	char *,		p,
-	unsigned,	plen)
-{			/* Count funny characters */
-    int i;
-
-    text->permissible_split = ctrl_chars_on_this_line =
-	utfxtra_on_this_line = 0;
-    for (i = (plen - 1); i >= 0; i--) {
-	if (p[i] == LY_UNDERLINE_START_CHAR ||
-	    p[i] == LY_UNDERLINE_END_CHAR ||
-	    p[i] == LY_BOLD_START_CHAR ||
-	    p[i] == LY_BOLD_END_CHAR ||
-	    p[i] == LY_SOFT_HYPHEN) {
-	    ctrl_chars_on_this_line++;
-	} else if (IS_UTF_EXTRA(p[i])) {
-	    utfxtra_on_this_line++;
-	}
-	if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i)
-	    text->permissible_split = i + 1;
-    }
-    ctrl_chars_on_this_line += utfxtra_on_this_line;
-}
-
-
 #if defined(USE_COLOR_STYLE)
 PRIVATE HTStyleChange * skip_matched_and_correct_offsets ARGS3(
 	HTStyleChange *,	end,
@@ -2856,6 +2852,7 @@ PRIVATE void split_line ARGS2(
     if (split > 0) {	/* Delete space at "split" splitting line */
 	char *prevdata = previous->data, *linedata = line->data;
 	unsigned plen;
+	int i;
 
 	/* Split the line. -FM */
 	prevdata[previous->size] = '\0';
@@ -2888,7 +2885,20 @@ PRIVATE void split_line ARGS2(
 
 	plen = strlen(p);
 	if (plen) {			/* Count funny characters */
-	    reset_cached_linedata(text,	p, plen);
+	    for (i = (plen - 1); i >= 0; i--) {
+		if (p[i] == LY_UNDERLINE_START_CHAR ||
+		    p[i] == LY_UNDERLINE_END_CHAR ||
+		    p[i] == LY_BOLD_START_CHAR ||
+		    p[i] == LY_BOLD_END_CHAR ||
+		    p[i] == LY_SOFT_HYPHEN) {
+		    ctrl_chars_on_this_line++;
+		} else if (IS_UTF_EXTRA(p[i])) {
+		    utfxtra_on_this_line++;
+		}
+		if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i)
+		    text->permissible_split = i + 1;
+	    }
+	    ctrl_chars_on_this_line += utfxtra_on_this_line;
 
 	    /* Add the data to the new line. -FM */
 	    strcat(linedata, p);
@@ -3046,7 +3056,7 @@ PRIVATE void split_line ARGS2(
 
     {
     HTLine* temp;
-    POOLallocHTLine(temp, previous->size);
+    allocHTLine(temp, previous->size);
     if (!temp)
 	outofmem(__FILE__, "split_line_2");
     memcpy(temp, previous, LINE_SIZE(previous->size));
@@ -3340,6 +3350,8 @@ PRIVATE void split_line ARGS2(
 	    previous->next->prev = jline;
 	    previous->prev->next = jline;
 
+	    freeHTLine(text, previous);
+
 	    previous = jline;
 	}
 	{ /* (ht_num_runs==1) */
@@ -3408,15 +3420,14 @@ PRIVATE void blank_lines ARGS2(
 	    return;			/* Do not add a blank line at start */
 #endif
 
-	while (line != text->last_line &&
-			HText_TrueEmptyLine(line, text, FALSE)) {
+	while (line != NULL &&
+	       line != text->last_line &&
+	       HText_TrueEmptyLine(line, text, FALSE)) {
 	    if (newlines == 0)
 		break;
 	    newlines--;		/* Don't bother: already blank */
 	    line = line->prev;
 	}
-    } else if (AT_START_OF_CELL(text)) {
-	newlines = 1;			/* New line to get a correct offset */
     } else {
 	newlines++;			/* Need also to finish this line */
     }
@@ -3437,8 +3448,7 @@ PUBLIC void HText_appendParagraph ARGS1(
 {
     int after = text->style->spaceAfter;
     int before = text->style->spaceBefore;
-    if (!AT_START_OF_CELL(text))
-	blank_lines(text, ((after > before) ? after : before));
+    blank_lines(text, ((after > before) ? after : before));
 }
 
 
@@ -4021,8 +4031,6 @@ PUBLIC void HText_appendCharacter ARGS2(
      *  New Line.
      */
     if (ch == '\n') {
-	if (AT_START_OF_CELL(text))
-	    return;
 	new_line(text);
 	text->in_line_1 = YES;	/* First line of new paragraph */
 	/*
@@ -4056,8 +4064,6 @@ PUBLIC void HText_appendCharacter ARGS2(
      *  i.e., use the second line indenting.
      */
     if (ch == '\r') {
-	if (AT_START_OF_CELL(text))
-	    return;
 	new_line(text);
 	text->in_line_1 = NO;
 	/*
@@ -4612,6 +4618,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2(
 	    lines_changed++;
 	    if (line == first_line)
 		first_line = mod_line;
+	    freeHTLine(me, line);
 	    line = mod_line;
 #ifdef DISP_PARTIAL
 	    /*
@@ -4833,72 +4840,6 @@ PRIVATE void free_enclosed_stbl ARGS1(
 #define free_enclosed_stbl(me) /* nothing */
 #endif
 
-/*	Remove trailing blank lines from the last cell.  */
-PUBLIC int HText_trimCellLines ARGS1(
-	HText *,	text)
-{
-    int ret = 0;
-    HTLine *lastline;
-#if defined(USE_COLOR_STYLE)
-    HTStyleChange *laststyles;
-#endif
-
-    if (!(text && text->stbl))
-	return 0;
-
-    lastline = text->last_line;
-#if defined(USE_COLOR_STYLE)
-    laststyles = lastline->styles;
-#endif
-    while ( text->last_line && text->Lines >= 1
-	    && HText_LastLineSize(text, FALSE) == 0 ) {
-	/* Empty line should survive only if
-	   a) It is a first line of a row;
-	   b) This is not a fake row.
-	   */
-	if (Stbl_trimFakeRows(text->stbl, text->Lines, text->last_line->size))
-	    ret++, HText_RemoveEmptyLastLine(text);
-	else
-	    break;
-    }
-
-    if (!ret)
-	return 0;
-
-#ifndef FIXME_FIXME_XXXX
-    /* De-POOL the line */
-    memcpy(lastline, text->last_line, LINE_SIZE(text->last_line->size));
-#if defined(USE_COLOR_STYLE)
-    /* De-POOL the style buffers */
-    memcpy(laststyles, lastline->styles,
-	   sizeof(HTStyleChange)*lastline->numstyles);
-    lastline->styles = laststyles;
-#endif
-
-    if (text->last_line->next == text->last_line)
-	lastline->next = lastline->prev = lastline;
-    text->last_line = lastline;
-    lastline->prev->next = lastline;	/* Link in new line */
-    lastline->next->prev = lastline;	/* Could be same node of course */
-
-#endif	/* FIXME_FIXME_XXXX */
-
-    /* Fix global state for the last line */
-    reset_cached_linedata(text, text->last_line->data,
-			  text->last_line->size);
-#if 0
-    /* XXXX This is not enough.  Actually we need also to clear the
-       me->in_word flag of HTML.c.  Since this is not
-       possible, fake a real space. */
-    text->LastChar = (text->last_line->size
-		      ? text->last_line->data[text->last_line->size - 1]
-		      : ' ');
-#else
-    HText_appendCharacter(text, ' ');
-#endif
-    return ret;
-}
-
 /*	Finish simple table handling
  *	Return TRUE if the table is nested inside another table.
  */
@@ -4975,8 +4916,9 @@ PUBLIC void HText_startStblTR ARGS2(
 PUBLIC void HText_endStblTR ARGS1(
 	HText *,	me)
 {
-    if (me && me->stbl)
-	Stbl_finishRowInTable(me->stbl);
+    if (!me || !me->stbl)
+	return;
+    /* should this do something?? */
 }
 
 /*	Start simple table cell
@@ -5012,7 +4954,6 @@ PUBLIC void HText_endStblTD ARGS1(
 {
     if (!me || !me->stbl)
 	return;
-    HText_trimCellLines(me);
     if (Stbl_finishCellInTable(me->stbl, TRST_ENDCELL_ENDTD,
 			       me->Lines, HText_LastLineOffset(me), HText_LastLineSize(me,FALSE)) < 0)
 	HText_cancelStbl(me);	/* give up */
@@ -5724,6 +5665,7 @@ PUBLIC void HText_endAppend ARGS1(
 	 */
 	next_to_the_last_line->next = line_ptr;
 	line_ptr->prev = next_to_the_last_line;
+	freeHTLine(text, text->last_line);
 	text->last_line = next_to_the_last_line;
 	text->Lines--;
 	CTRACE((tfp, "GridText: New bottom line: `%s'\n",
@@ -8277,13 +8219,6 @@ PUBLIC void HTuncache_current_document NOARGS
     if (HTMainText) {
 	HTParentAnchor * htmain_anchor = HTMainText->node_anchor;
 
-	if (HText_HaveUserChangedForms()) {
-	    /*
-	     * Issue a warning.  User forms content will be lost.
-	     */
-	    HTAlert(RELOADING_FORM);
-	}
-
 	if (htmain_anchor) {
 	    if (!(HTOutputFormat && HTOutputFormat == WWW_SOURCE)) {
 		FREE(htmain_anchor->UCStages);
@@ -8305,7 +8240,7 @@ PUBLIC void HTuncache_current_document NOARGS
     }
 }
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 
 PRIVATE HTProtocol scm = { "source-cache-mem", 0, 0 }; /* dummy - kw */
 
@@ -8360,7 +8295,7 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	    return FALSE;
 	}
 
-	if (HText_HaveUserChangedForms()) {
+	if (HText_HaveUserChangedForms(HTMainText)) {
 	    /*
 	     * Issue a warning.  Will not restore changed forms, currently.
 	     */
@@ -8413,7 +8348,7 @@ PUBLIC BOOLEAN HTreparse_document NOARGS
 	}
 	/* not UCLYhndl_HTFile_for_unspec - we are talking about remote documents... */
 
-	if (HText_HaveUserChangedForms()) {
+	if (HText_HaveUserChangedForms(HTMainText)) {
 	    /*
 	     * Issue a warning.  Will not restore changed forms, currently.
 	     */
@@ -8778,7 +8713,7 @@ PUBLIC void HText_RemovePreviousLine ARGS1(
 {
     HTLine *line, *previous;
 
-    if (!(text && text->Lines >= 1))	/* Lines is 0-based */
+    if (!(text && text->Lines > 1))
 	return;
 
     line = text->last_line->prev;
@@ -8786,29 +8721,7 @@ PUBLIC void HText_RemovePreviousLine ARGS1(
     previous->next = text->last_line;
     text->last_line->prev = previous;
     text->Lines--;
-}
-
-/*
- *  This function is for removing the last blank lines.
- *  It should be called after
- *  checking the situation with HText_LastLineSize().
- *  With POOLed allocation is should be wrapped into code restoring the
- *  expected POOLed/unPOOLed state of the line chain.
- */
-PRIVATE void HText_RemoveEmptyLastLine ARGS1(
-	HText *,	text)
-{
-    HTLine *line, *previous;
-
-    if (!(text && text->Lines >= 1))	/* Lines is 0-based */
-	return;
-
-    line = text->last_line;
-    previous = line->prev;
-    previous->next = line->next;
-    previous->next->prev = previous;
-    text->last_line = previous;
-    text->Lines--;
+    freeHTLine(text, line);
 }
 
 /*
@@ -9882,7 +9795,7 @@ PUBLIC int HText_beginInput ARGS3(
 	 *  for types that are not yet implemented.
 	 */
 	case F_HIDDEN_TYPE:
-#ifndef EXP_FILE_UPLOAD
+#ifndef USE_FILE_UPLOAD
 	case F_FILE_TYPE:
 #endif
 	case F_RANGE_TYPE:
@@ -10137,7 +10050,7 @@ PRIVATE int find_best_target_cs ARGS3(
     return (-1);
 }
 
-#ifdef EXP_FILE_UPLOAD
+#ifdef USE_FILE_UPLOAD
 PRIVATE void load_a_file ARGS2(
     char *,	val_used,
     bstring **,	result)
@@ -10148,13 +10061,15 @@ PRIVATE void load_a_file ARGS2(
 
     CTRACE((tfp, "Ok, about to convert %s to mime/thingy\n", val_used));
 
-    if ((fd = fopen(val_used, BIN_R)) == 0) {
-	HTAlert(gettext("Can't open file for uploading"));
-    } else {
-	while ((bytes = fread(buffer, sizeof(char), 256, fd)) != 0) {
-	    HTSABCat(result, buffer, bytes);
+    if (*val_used) {		/* ignore empty form field */
+	if ((fd = fopen(val_used, BIN_R)) == 0) {
+	    HTAlert(gettext("Can't open file for uploading"));
+	} else {
+	    while ((bytes = fread(buffer, sizeof(char), 256, fd)) != 0) {
+		HTSABCat(result, buffer, bytes);
+	    }
+	    LYCloseInput(fd);
 	}
-	LYCloseInput(fd);
     }
 }
 
@@ -10167,7 +10082,7 @@ PRIVATE CONST char *guess_content_type ARGS1(CONST char *, filename)
 	    ? format->name
 	    : "text/plain";
 }
-#endif /* EXP_FILE_UPLOAD */
+#endif /* USE_FILE_UPLOAD */
 
 
 PRIVATE void cannot_transcode ARGS2(
@@ -10753,7 +10668,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 	    case F_RESET_TYPE:
 		CTRACE((tfp, "reset\n"));
 		break;
-#ifdef EXP_FILE_UPLOAD
+#ifdef USE_FILE_UPLOAD
 	    case F_FILE_TYPE:
 		val_used = NonNull(form_ptr->value);
 		CTRACE((tfp, "I will submit %s (from %s)\n",
@@ -10945,11 +10860,11 @@ PUBLIC int HText_SubmitForm ARGS4(
 		skip_field = TRUE;
 		break;
 
-#ifdef EXP_FILE_UPLOAD
+#ifdef USE_FILE_UPLOAD
 	    case F_FILE_TYPE:
 		load_a_file(val_used, &(my_data[anchor_count].data));
 		break;
-#endif /* EXP_FILE_UPLOAD */
+#endif /* USE_FILE_UPLOAD */
 
 	    case F_SUBMIT_TYPE:
 	    case F_TEXT_SUBMIT_TYPE:
@@ -11014,7 +10929,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 				BStrLen(my_data[anchor_count].data));
 		    BStrCopy0(my_data[anchor_count].data, escaped2);
 		    FREE(escaped2);
-	        }
+		}
 	    }
 	    ++anchor_count;
 
@@ -11241,7 +11156,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 	    case F_RANGE_TYPE:
 		/* not implemented */
 		break;
-#ifdef EXP_FILE_UPLOAD
+#ifdef USE_FILE_UPLOAD
 	    case F_FILE_TYPE:
 		if (PlainText) {
 		    StrAllocCopy(escaped1, my_data[anchor_count].name);
@@ -11277,7 +11192,7 @@ PUBLIC int HText_SubmitForm ARGS4(
 			HTBprintf(&my_query, "\n");
 		}
 		break;
-#endif /* EXP_FILE_UPLOAD */
+#endif /* USE_FILE_UPLOAD */
 	    case F_KEYGEN_TYPE:
 		/* not implemented */
 		break;
@@ -11418,18 +11333,19 @@ PUBLIC void HText_ResetForm ARGS1(
  * whether any forms content was changed by user so any information will be
  * lost.
  */
-PUBLIC BOOLEAN HText_HaveUserChangedForms NOARGS
+PUBLIC BOOLEAN HText_HaveUserChangedForms ARGS1(
+	HText *,	text)
 {
     TextAnchor * anchor_ptr;
 
-    if (HTMainText == 0)
+    if (text == 0)
 	return FALSE;
 
     /*
      *  Go through list of anchors to check if any value was changed.
      *  This code based on HText_ResetForm()
      */
-    for (anchor_ptr = HTMainText->first_anchor;
+    for (anchor_ptr = text->first_anchor;
 	 anchor_ptr != NULL;
 	 anchor_ptr = anchor_ptr->next) {
 	if (anchor_ptr->link_type == INPUT_ANCHOR) {
@@ -12161,8 +12077,25 @@ PRIVATE int increment_tagged_htline ARGS6(
     *s = '\0';
 
     n = strlen (ht->data);
-    if (mode == CHOP)
+    if (mode == CHOP) {
 	*(buf + n) = '\0';
+    } else if (strlen(buf) > ht->size) {
+	/* we didn't allocate enough space originally - increase it */
+	HTLine* temp;
+	allocHTLine(temp, strlen(buf));
+	if (!temp)
+	    outofmem(__FILE__, "increment_tagged_htline");
+	memcpy(temp, ht, LINE_SIZE(0));
+#if defined(USE_COLOR_STYLE)
+	POOLallocstyles(temp->styles, ht->numstyles);
+	if (!temp->styles)
+	    outofmem(__FILE__, "increment_tagged_htline");
+	memcpy(temp->styles, ht->styles, sizeof(HTStyleChange)*ht->numstyles);
+#endif
+	ht = temp;
+	ht->prev->next = ht;	/* Link in new line */
+	ht->next->prev = ht;	/* Could be same node of course */
+    }
     strcpy (ht->data, buf);
 
     return (strlen (buf) - n + fixup);
@@ -12216,7 +12149,7 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
      *  Clone and initialize the struct's needed to add a new TEXTAREA
      *  anchor.
      */
-    POOLallocHTLine(l, MAX_LINE);
+    allocHTLine(l, MAX_LINE);
     POOLtypecalloc(TextAnchor, a);
     POOLtypecalloc(FormInfo, f);
     if (a == NULL || l == NULL || f == NULL)
@@ -12261,6 +12194,13 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
     l->styles = htline->styles;
 #endif
     strcpy (l->data,     htline->data);
+
+    /*
+     *  Link in the new HTLine.
+     */
+    htline->next->prev = l;
+    htline->next       = l;
+
     if (fields_are_numbered()) {
 	a->number++;
 	increment_tagged_htline (l, a, &lx, &curr_tag, 1, CHOP);
@@ -12277,13 +12217,11 @@ PRIVATE void insert_new_textarea_anchor ARGS2(
 
     /*
      *  Link in the new TextAnchor and point the entry anchor arg at it;
-     *  link in the new HTLine and point the entry htline arg at it, too.
+     *  point the entry HTLine arg at it, too.
      */
     anchor->next = a;
    *curr_anchor  = a;
 
-    htline->next->prev = l;
-    htline->next       = l;
    *exit_htline        = l->next;
 
     return;
@@ -13040,7 +12978,7 @@ PUBLIC int HText_InsertFile ARGS1(
 	    break;
     }
 
-    POOLallocHTLine(l, MAX_LINE);
+    allocHTLine(l, MAX_LINE);
     POOLtypecalloc(TextAnchor, a);
     POOLtypecalloc(FormInfo, f);
     if (a == NULL || l == NULL || f == NULL)
diff --git a/src/GridText.h b/src/GridText.h
index b4130128..db3b034d 100644
--- a/src/GridText.h
+++ b/src/GridText.h
@@ -139,7 +139,7 @@ extern BOOL HText_getFirstTargetInLine PARAMS((
 extern int HTisDocumentSource NOPARAMS;
 extern void HTuncache_current_document NOPARAMS;
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 extern BOOLEAN HTreparse_document NOPARAMS;
 extern BOOLEAN HTcan_reparse_document NOPARAMS;
 extern BOOLEAN HTdocument_settings_changed NOPARAMS;
@@ -222,7 +222,7 @@ extern int HText_SubmitForm PARAMS((
 extern void HText_DisableCurrentForm NOPARAMS;
 extern void HText_ResetForm PARAMS((FormInfo *form));
 extern void HText_activateRadioButton PARAMS((FormInfo *form));
-extern BOOLEAN HText_HaveUserChangedForms NOPARAMS;
+extern BOOLEAN HText_HaveUserChangedForms PARAMS((HText *text));
 
 extern HTList * search_queries; /* Previous isindex and whereis queries */
 extern void HTSearchQueries_free NOPARAMS;
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 74276513..d9a5f37b 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -172,7 +172,7 @@ PRIVATE char *sprint_bytes ARGS3(
     return u;
 }
 
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
 #define TIME_HMS_LENGTH (16)
 PRIVATE char *sprint_tbuf ARGS2(
 	char *,	       s,
@@ -186,7 +186,7 @@ PRIVATE char *sprint_tbuf ARGS2(
 	sprintf (s, "%ld sec", t);
     return s;
 }
-#endif /* EXP_READPROGRESS */
+#endif /* USE_READPROGRESS */
 
 /*	Issue a read-progress message.			HTReadProgress()
 **	------------------------------
@@ -204,10 +204,10 @@ PUBLIC void HTReadProgress ARGS2(
 
 #ifdef HAVE_GETTIMEOFDAY
     struct timeval tv;
-    int dummy = gettimeofday(&tv, (struct timezone *)0);
-    double now = tv.tv_sec + tv.tv_usec/1000000. ;
+    double now;
     static double first, last, last_active;
-    (void)dummy;		/* quiet unused-assignment warning */
+    gettimeofday(&tv, (struct timezone *)0);
+    now = tv.tv_sec + tv.tv_usec/1000000. ;
 #else
 #if defined(HAVE_FTIME) && defined(HAVE_SYS_TIMEB_H)
     static double now, first, last, last_active;
@@ -281,7 +281,7 @@ PUBLIC void HTReadProgress ARGS2(
 		HTSprintf (&line, gettext(", %s/sec"), transferp);
 	    }
 
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
 	    if (LYTransferRate == rateEtaBYTES
 	     || LYTransferRate == rateEtaKB) {
 		char tbuf[TIME_HMS_LENGTH];
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index 170fedbc..0d09eea1 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -37,7 +37,7 @@ extern int exec_command(char * cmd, int wait_flag); /* xsystem.c */
 #include <LYLeaks.h>
 #include <LYKeymap.h>
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 #include <LYCookie.h>
 #endif
 
@@ -136,7 +136,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
     char *path = NULL;
     char *addr = NULL;
     int status;
-    BOOL use_gzread = NO;
+    BOOL use_zread = NO;
     BOOLEAN found = FALSE;
 #ifdef WIN_EX
     HANDLE cur_handle;
@@ -183,7 +183,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 		    !strcasecomp(&path[len-2], "gz")) {
 #ifdef USE_ZLIB
 		    if (!skip_loadfile) {
-			use_gzread = YES;
+			use_zread = YES;
 		    } else
 #endif /* USE_ZLIB */
 		    {
@@ -191,13 +191,20 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 			remove(path);
 		    }
 		} else if (len > 4 && !strcasecomp(&path[len-3], "bz2")) {
-		    path[len-4] = '\0';
-		    remove(path);
+#ifdef USE_BZLIB
+		    if (!skip_loadfile) {
+			use_zread = YES;
+		    } else
+#endif /* USE_BZLIB */
+		    {
+			path[len-4] = '\0';
+			remove(path);
+		    }
 		} else if (len > 2 && !strcasecomp(&path[len-1], "Z")) {
 		    path[len-2] = '\0';
 		    remove(path);
 		}
-		if (!use_gzread) {
+		if (!use_zread) {
 		    if (!dump_output_immediately) {
 			/*
 			 *  Tell user what's happening. - FM
@@ -255,7 +262,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 		    }
 #endif /* FNAMES_8_3 */
 		    LYLocalFileToURL (&addr, path);
-		    if (!use_gzread) {
+		    if (!use_zread) {
 			LYRenamedTemp(me->anchor->FileCache, path);
 			StrAllocCopy(me->anchor->FileCache, path);
 			StrAllocCopy(me->anchor->content_encoding, "binary");
@@ -424,14 +431,14 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
 	if (me->anchor->FileCache)
 	    remove(me->anchor->FileCache);
 	FREE(me);
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 	/*
 	 *  We want to save cookies picked up when in source
 	 *  mode.  ...
 	 */
 	if (persistent_cookies)
 	    LYStoreCookies(LYCookieSaveFile);
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
 	exit_immediately(EXIT_SUCCESS);
     }
 
@@ -1216,12 +1223,22 @@ PUBLIC HTStream* HTCompressed ARGS3(
     /*
      *	Make command to process file. - FM
      */
+#ifdef USE_BZLIB
+    if (compress_suffix[0] == 'b'	/* must be bzip2 */
+	&& !me->viewer_command) {
+	/*
+	 * We won't call bzip2 externally, so we don't need to supply a command
+	 * for it.
+	 */
+	StrAllocCopy(me->end_command, "");
+    } else
+#endif
 #ifdef USE_ZLIB
-    if (compress_suffix[0] == 'g' && /* must be gzip */
-	!me->viewer_command) {
+    if (compress_suffix[0] == 'g'	/* must be gzip */
+	&& !me->viewer_command) {
 	/*
-	 *  We won't call gzip externally, so we don't need to supply
-	 *  a command for it. - kw
+	 * We won't call gzip or compress externally, so we don't need to
+	 * supply a command for it.
 	 */
 	StrAllocCopy(me->end_command, "");
     } else
diff --git a/src/HTInit.c b/src/HTInit.c
index f1207e8d..8415876c 100644
--- a/src/HTInit.c
+++ b/src/HTInit.c
@@ -42,7 +42,7 @@ PUBLIC void HTFormatInit NOARGS
 #else
  if (LYgetXDisplay() != 0) {	/* Must have X11 */
   HTSetPresentation("application/postscript", "ghostview %s&",
-  							    1.0, 3.0, 0.0, 0);
+							    1.0, 3.0, 0.0, 0);
   if (XLoadImageCommand && *XLoadImageCommand) {
       HTSetPresentation("image/gif",	XLoadImageCommand,  1.0, 3.0, 0.0, 0);
       HTSetPresentation("image/x-xbm",	XLoadImageCommand,  1.0, 3.0, 0.0, 0);
@@ -88,25 +88,25 @@ PUBLIC void HTFormatInit NOARGS
  *  Add our compressed file handlers.
  */
  HTSetConversion("www/compressed", "www/download",
- 					      HTCompressed,   1.0, 0.0, 0.0, 0);
+					      HTCompressed,   1.0, 0.0, 0.0, 0);
  HTSetConversion("www/compressed", "www/present",
- 					      HTCompressed,   1.0, 0.0, 0.0, 0);
+					      HTCompressed,   1.0, 0.0, 0.0, 0);
  HTSetConversion("www/compressed", "www/source",
- 					      HTCompressed,   1.0, 0.0, 0.0, 0);
+					      HTCompressed,   1.0, 0.0, 0.0, 0);
  HTSetConversion("www/compressed", "www/dump",
- 					      HTCompressed,   1.0, 0.0, 0.0, 0);
+					      HTCompressed,   1.0, 0.0, 0.0, 0);
 
  /*
   * Added the following to support some content types beginning to surface.
   */
  HTSetConversion("application/html", "text/x-c",
- 					HTMLToC,	0.5, 0.0, 0.0, 0);
+					HTMLToC,	0.5, 0.0, 0.0, 0);
  HTSetConversion("application/html", "text/plain",
- 					HTMLToPlain,	0.5, 0.0, 0.0, 0);
+					HTMLToPlain,	0.5, 0.0, 0.0, 0);
  HTSetConversion("application/html", "www/present",
- 					HTMLPresent,	2.0, 0.0, 0.0, 0);
+					HTMLPresent,	2.0, 0.0, 0.0, 0);
  HTSetConversion("application/html", "www/source",
- 					HTPlainPresent,	1.0, 0.0, 0.0, 0);
+					HTPlainPresent,	1.0, 0.0, 0.0, 0);
  HTSetConversion("application/x-wais-source", "www/source",
 					HTPlainPresent,	1.0, 0.0, 0.0, 0);
  HTSetConversion("application/x-wais-source", "www/present",
@@ -120,32 +120,32 @@ PUBLIC void HTFormatInit NOARGS
   *  Save all unknown mime types to disk.
   */
  HTSetConversion("www/source",  "www/present",
- 					HTSaveToFile,	1.0, 3.0, 0.0, 0);
+					HTSaveToFile,	1.0, 3.0, 0.0, 0);
  HTSetConversion("www/source",  "www/source",
- 					HTSaveToFile,	1.0, 3.0, 0.0, 0);
+					HTSaveToFile,	1.0, 3.0, 0.0, 0);
  HTSetConversion("www/source",  "www/download",
- 					HTSaveToFile,	1.0, 3.0, 0.0, 0);
+					HTSaveToFile,	1.0, 3.0, 0.0, 0);
  HTSetConversion("www/source",  "*",	HTSaveToFile,	1.0, 3.0, 0.0, 0);
 
  /*
   *  Output all www/dump presentations to stdout.
   */
  HTSetConversion("www/source",  "www/dump",
- 					HTDumpToStdout,	1.0, 3.0, 0.0, 0);
+					HTDumpToStdout,	1.0, 3.0, 0.0, 0);
 
 /*
  *  Now add our basic conversions.
  */
  HTSetConversion("text/x-sgml",
- 			      "www/source",  HTPlainPresent, 1.0, 0.0, 0.0, 0);
+			      "www/source",  HTPlainPresent, 1.0, 0.0, 0.0, 0);
  HTSetConversion("text/x-sgml",
- 			      "www/present", HTMLPresent,    2.0, 0.0, 0.0, 0);
+			      "www/present", HTMLPresent,    2.0, 0.0, 0.0, 0);
  HTSetConversion("text/sgml", "www/source",  HTPlainPresent, 1.0, 0.0, 0.0, 0);
  HTSetConversion("text/sgml", "www/present", HTMLPresent,    1.0, 0.0, 0.0, 0);
  HTSetConversion("text/plain","www/present", HTPlainPresent, 1.0, 0.0, 0.0, 0);
  HTSetConversion("text/plain","www/source",  HTPlainPresent, 1.0, 0.0, 0.0, 0);
  HTSetConversion("text/html", "www/source",  HTPlainPresent, 1.0, 0.0, 0.0, 0);
- HTSetConversion("text/html", "text/x-c",    HTMLToC, 	     0.5, 0.0, 0.0, 0);
+ HTSetConversion("text/html", "text/x-c",    HTMLToC,	     0.5, 0.0, 0.0, 0);
  HTSetConversion("text/html", "text/plain",  HTMLToPlain,    0.5, 0.0, 0.0, 0);
  HTSetConversion("text/html", "www/present", HTMLPresent,    1.0, 0.0, 0.0, 0);
 
@@ -417,7 +417,7 @@ assign_presentation:
 }
 
 PRIVATE void BuildCommand ARGS5(
-	char **, 	pBuf,
+	char **,	pBuf,
 	size_t,		Bufsize,
 	char *,		controlstring,
 	char *,		TmpFileName,
@@ -540,7 +540,7 @@ PRIVATE int PassesTest ARGS1(
 	0 == strcasecomp(mc->testcommand, "test -n \"$DISPLAY\"")) {
 	FREE(mc->testcommand);
 	CTRACE((tfp, "PassesTest: Testing for XWINDOWS environment.\n"));
-    	if (LYgetXDisplay() != NULL) {
+	if (LYgetXDisplay() != NULL) {
 	    CTRACE((tfp, "PassesTest: Test passed!\n"));
 	    return(0 == 0);
 	} else {
@@ -551,7 +551,7 @@ PRIVATE int PassesTest ARGS1(
     if (0 == strcasecomp(mc->testcommand, "test -z \"$DISPLAY\"")) {
 	FREE(mc->testcommand);
 	CTRACE((tfp, "PassesTest: Testing for NON_XWINDOWS environment.\n"));
-    	if (LYgetXDisplay() == NULL) {
+	if (LYgetXDisplay() == NULL) {
 	    CTRACE((tfp,"PassesTest: Test passed!\n"));
 	    return(0 == 0);
 	} else {
@@ -775,7 +775,7 @@ PUBLIC void HTFileInit NOARGS
 
 #ifdef TRADITIONAL_SUFFIXES
     HTSetSuffix(".exe.Z",	"application/x-Comp. Executable",
-    							     "binary", 1.0);
+							     "binary", 1.0);
     HTSetSuffix(".Z",	        "application/UNIX Compressed", "binary", 1.0);
     HTSetSuffix(".tar_Z",	"application/UNIX Compr. Tar", "binary", 1.0);
     HTSetSuffix(".tar.Z",	"application/UNIX Compr. Tar", "binary", 1.0);
@@ -783,7 +783,7 @@ PUBLIC void HTFileInit NOARGS
     HTSetSuffix5(".Z",	        "application/x-compress", "binary", "UNIX Compressed", 1.0);
     HTSetSuffix5(".Z",	        NULL, "compress",      "UNIX Compressed", 1.0);
     HTSetSuffix5(".exe.Z",	"application/octet-stream", "compress",
-    						       "Executable", 1.0);
+						       "Executable", 1.0);
     HTSetSuffix5(".tar_Z",	"application/x-tar", "compress",
 						       "UNIX Compr. Tar", 1.0);
     HTSetSuffix5(".tar.Z",	"application/x-tar", "compress",
@@ -858,12 +858,12 @@ PUBLIC void HTFileInit NOARGS
 
 #ifdef TRADITIONAL_SUFFIXES
     HTSetSuffix(".latex",	"application/x-Latex", "8bit", 1.0);
-    HTSetSuffix(".tex",  	"application/x-Tex", "8bit", 1.0);
+    HTSetSuffix(".tex",		"application/x-Tex", "8bit", 1.0);
     HTSetSuffix(".texinfo",	"application/x-Texinfo", "8bit", 1.0);
     HTSetSuffix(".texi",	"application/x-Texinfo", "8bit", 1.0);
 #else
     HTSetSuffix5(".latex",	"application/x-latex", "8bit", "LaTeX", 1.0);
-    HTSetSuffix5(".tex",  	"text/x-tex", "8bit", "TeX", 1.0);
+    HTSetSuffix5(".tex",	"text/x-tex", "8bit", "TeX", 1.0);
     HTSetSuffix5(".texinfo",	"application/x-texinfo", "8bit", "Texinfo", 1.0);
     HTSetSuffix5(".texi",	"application/x-texinfo", "8bit", "Texinfo", 1.0);
 #endif
diff --git a/src/HTML.c b/src/HTML.c
index 8ea5d2bf..963e9271 100644
--- a/src/HTML.c
+++ b/src/HTML.c
@@ -73,7 +73,7 @@
 
 #endif /* USE_COLOR_STYLE */
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 #include <HTAccess.h>
 #endif
 
@@ -87,7 +87,7 @@
 
 struct _HTStream {
     CONST HTStreamClass *	isa;
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     HTParentAnchor *		anchor;
     FILE *			fp;
     char *			filename;
@@ -150,7 +150,7 @@ PRIVATE char* MakeNewMapValue PARAMS((CONST char ** value, CONST char* mapstr));
 PUBLIC void strtolower ARGS1(char*, i)
 {
     if (!i) return;
-    while (*i) { *i=(char)tolower(*i); i++; }
+    while (*i) { *i = (char)TOLOWER(*i); i++; }
 }
 
 /*		Flattening the style structure
@@ -2912,11 +2912,11 @@ PRIVATE int HTML_start_element ARGS6(
 	    me->inBoldA = TRUE;
 
 	    StrAllocCopy(href, value[HTML_A_HREF]);
-	    CHECK_FOR_INTERN(intern_flag,href);  /*NULL, '\0', or '#'*/
+	    if (isEmpty(href))
+		StrAllocCopy(href, "#");
+	    CHECK_FOR_INTERN(intern_flag,href);	 /* '#'*/
 
 	    if (intern_flag) { /*** FAST WAY: ***/
-		if (isEmpty(href))
-		    StrAllocCopy(href, "#");
 		TRANSLATE_AND_UNESCAPE_TO_STD(&href);
 
 	    } else {
@@ -4609,7 +4609,7 @@ PRIVATE int HTML_start_element ARGS6(
 		} else if (!strcasecomp(I.type, "file")) {
 		    if (present[HTML_INPUT_ACCEPT])
 			I.accept = value[HTML_INPUT_ACCEPT];
-#ifndef EXP_FILE_UPLOAD
+#ifndef USE_FILE_UPLOAD
 		    not_impl = "[FILE Input]";
 		    CTRACE((tfp, "Attempting to fake as: %s\n", I.type));
 #ifdef NOTDEFINED
@@ -4617,7 +4617,7 @@ PRIVATE int HTML_start_element ARGS6(
 			HText_DisableCurrentForm();
 #endif /* NOTDEFINED */
 		    CTRACE((tfp, "HTML: Ignoring TYPE=\"file\"\n"));
-#endif /* EXP_FILE_UPLOAD */
+#endif /* USE_FILE_UPLOAD */
 
 		} else if (!strcasecomp(I.type, "button")) {
 		    /*
@@ -4778,7 +4778,7 @@ PRIVATE int HTML_start_element ARGS6(
 		if (!I.type)
 		    me->UsePlainSpace = TRUE;
 		else if (!strcasecomp(I.type, "text") ||
-#ifdef EXP_FILE_UPLOAD
+#ifdef USE_FILE_UPLOAD
 			 !strcasecomp(I.type, "file") ||
 #endif
 			 !strcasecomp(I.type, "submit") ||
@@ -4885,7 +4885,7 @@ PRIVATE int HTML_start_element ARGS6(
 		I.md = value[HTML_INPUT_MD];
 
 	    chars = HText_beginInput(me->text, me->inUnderline, &I);
-#ifndef EXP_FILE_UPLOAD
+#ifndef USE_FILE_UPLOAD
 	    CTRACE((tfp, "I.%s have %d chars, or something\n", NONNULL(I.type), chars));
 #endif
 	    /*
@@ -4962,7 +4962,7 @@ PRIVATE int HTML_start_element ARGS6(
 		}
 		HText_setIgnoreExcess(me->text, TRUE);
 	    }
-#ifndef EXP_FILE_UPLOAD
+#ifndef USE_FILE_UPLOAD
 	    CTRACE((tfp, "I.%s, %d\n", NONNULL(I.type), IsSubmitOrReset));
 #endif
 	    if (IsSubmitOrReset == FALSE) {
@@ -7913,7 +7913,7 @@ PUBLIC HTStructured* HTML_new ARGS3(
     return (HTStructured*) me;
 }
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 
 /*
  *  A flag set by a file write error.  Used for only generating an alert
diff --git a/src/HTML.h b/src/HTML.h
index bbf9de45..a324ae10 100644
--- a/src/HTML.h
+++ b/src/HTML.h
@@ -66,9 +66,9 @@ typedef struct _stack_element {
 #define MAX_NESTING 800		/* Should be checked by parser */
 
 struct _HTStructured {
-    CONST HTStructuredClass * 	isa;
-    HTParentAnchor * 		node_anchor;
-    HText * 			text;
+    CONST HTStructuredClass *	isa;
+    HTParentAnchor *		node_anchor;
+    HText *			text;
 
     HTStream*			target;			/* Output stream */
     HTStreamClass		targetClass;		/* Output routines */
@@ -78,7 +78,7 @@ struct _HTStructured {
     char *			base_href;	/* current HTML_BASE href */
     char *			map_address;	/* current HTML_MAP address */
 
-    HTChunk 			title;		/* Grow by 128 */
+    HTChunk			title;		/* Grow by 128 */
     HTChunk			object;		/* Grow by 128 */
     BOOL			object_started;
     BOOL			object_declare;
@@ -94,7 +94,7 @@ struct _HTStructured {
     char *			object_codetype;
     char *			object_name;
     int				objects_mixed_open,
-    				objects_figged_open;
+				objects_figged_open;
     HTChunk			option;		/* Grow by 128 */
     BOOL			first_option;	/* First OPTION in SELECT? */
     char *			LastOptionValue;
@@ -105,7 +105,7 @@ struct _HTStructured {
     int				textarea_name_cs;
     char *			textarea_accept_cs;
     char *			textarea_cols;
-    int 			textarea_rows;
+    int				textarea_rows;
     int				textarea_disabled;
     char *			textarea_id;
     HTChunk			math;		/* Grow by 128 */
@@ -116,10 +116,10 @@ struct _HTStructured {
      *  Used for nested lists. - FM
      */
     int		List_Nesting_Level;	/* counter for list nesting level */
-    int 	OL_Counter[12];		/* counter for ordered lists */
-    char 	OL_Type[12];		/* types for ordered lists */
-    int 	Last_OL_Count;		/* last count in ordered lists */
-    char 	Last_OL_Type;		/* last type in ordered lists */
+    int		OL_Counter[12];		/* counter for ordered lists */
+    char	OL_Type[12];		/* types for ordered lists */
+    int		Last_OL_Count;		/* last count in ordered lists */
+    char	Last_OL_Type;		/* last type in ordered lists */
 
     int				Division_Level;
     short			DivisionAlignments[MAX_NESTING];
@@ -139,8 +139,8 @@ struct _HTStructured {
     HTStyle *			old_style;
     int				current_default_alignment;
     BOOL			in_word;  /* Have just had a non-white char */
-    stack_element 	stack[MAX_NESTING];
-    stack_element 	*sp;		/* Style stack pointer */
+    stack_element	stack[MAX_NESTING];
+    stack_element	*sp;		/* Style stack pointer */
     BOOL		stack_overrun;	/* Was MAX_NESTING exceeded? */
     int			skip_stack; /* flag to skip next style stack operation */
 
@@ -212,7 +212,7 @@ struct _HTStructured {
     */
     UCTransParams	T;
 
-    int 		tag_charset; /* charset for attribute values etc. */
+    int			tag_charset; /* charset for attribute values etc. */
 };
 
 extern  HTStyle *LYstyles PARAMS((int style_number));
diff --git a/src/LYCharSets.c b/src/LYCharSets.c
index a9ccbf54..d5baf0a2 100644
--- a/src/LYCharSets.c
+++ b/src/LYCharSets.c
@@ -736,17 +736,17 @@ PUBLIC int UCGetLYhndl_byAnyName ARGS1 (char *, value)
  */
 PRIVATE CONST char * LYEntityNames[] = {
 /*	 NAME		   DECIMAL VALUE */
-	"nbsp", 	/* 160, non breaking space */
+	"nbsp",		/* 160, non breaking space */
 	"iexcl",	/* 161, inverted exclamation mark */
-	"cent", 	/* 162, cent sign */
+	"cent",		/* 162, cent sign */
 	"pound",	/* 163, pound sign */
 	"curren",	/* 164, currency sign */
 	"yen",		/* 165, yen sign */
 	"brvbar",	/* 166, broken vertical bar, (brkbar) */
-	"sect", 	/* 167, section sign */
+	"sect",		/* 167, section sign */
 	"uml",		/* 168, spacing dieresis */
-	"copy", 	/* 169, copyright sign */
-	"ordf", 	/* 170, feminine ordinal indicator */
+	"copy",		/* 169, copyright sign */
+	"ordf",		/* 170, feminine ordinal indicator */
 	"laquo",	/* 171, angle quotation mark, left */
 	"not",		/* 172, negation sign */
 	"shy",		/* 173, soft hyphen */
@@ -754,15 +754,15 @@ PRIVATE CONST char * LYEntityNames[] = {
 	"hibar",	/* 175, spacing macron */
 	"deg",		/* 176, degree sign */
 	"plusmn",	/* 177, plus-or-minus sign */
-	"sup2", 	/* 178, superscript 2 */
-	"sup3", 	/* 179, superscript 3 */
+	"sup2",		/* 178, superscript 2 */
+	"sup3",		/* 179, superscript 3 */
 	"acute",	/* 180, spacing acute (96) */
 	"micro",	/* 181, micro sign */
-	"para", 	/* 182, paragraph sign */
+	"para",		/* 182, paragraph sign */
 	"middot",	/* 183, middle dot */
 	"cedil",	/* 184, spacing cedilla */
-	"sup1", 	/* 185, superscript 1 */
-	"ordm", 	/* 186, masculine ordinal indicator */
+	"sup1",		/* 185, superscript 1 */
+	"ordm",		/* 186, masculine ordinal indicator */
 	"raquo",	/* 187, angle quotation mark, right */
 	"frac14",	/* 188, fraction 1/4 */
 	"frac12",	/* 189, fraction 1/2 */
@@ -772,31 +772,31 @@ PRIVATE CONST char * LYEntityNames[] = {
 	"Aacute",	/* 193, capital A, acute accent */
 	"Acirc",	/* 194, capital A, circumflex accent */
 	"Atilde",	/* 195, capital A, tilde */
-	"Auml", 	/* 196, capital A, dieresis or umlaut mark */
+	"Auml",		/* 196, capital A, dieresis or umlaut mark */
 	"Aring",	/* 197, capital A, ring */
 	"AElig",	/* 198, capital AE diphthong (ligature) */
 	"Ccedil",	/* 199, capital C, cedilla */
 	"Egrave",	/* 200, capital E, grave accent */
 	"Eacute",	/* 201, capital E, acute accent */
 	"Ecirc",	/* 202, capital E, circumflex accent */
-	"Euml", 	/* 203, capital E, dieresis or umlaut mark */
+	"Euml",		/* 203, capital E, dieresis or umlaut mark */
 	"Igrave",	/* 204, capital I, grave accent */
 	"Iacute",	/* 205, capital I, acute accent */
 	"Icirc",	/* 206, capital I, circumflex accent */
-	"Iuml", 	/* 207, capital I, dieresis or umlaut mark */
+	"Iuml",		/* 207, capital I, dieresis or umlaut mark */
 	"ETH",		/* 208, capital Eth, Icelandic (or Latin2 Dstrok) */
 	"Ntilde",	/* 209, capital N, tilde */
 	"Ograve",	/* 210, capital O, grave accent */
 	"Oacute",	/* 211, capital O, acute accent */
 	"Ocirc",	/* 212, capital O, circumflex accent */
 	"Otilde",	/* 213, capital O, tilde */
-	"Ouml", 	/* 214, capital O, dieresis or umlaut mark */
+	"Ouml",		/* 214, capital O, dieresis or umlaut mark */
 	"times",	/* 215, multiplication sign */
 	"Oslash",	/* 216, capital O, slash */
 	"Ugrave",	/* 217, capital U, grave accent */
 	"Uacute",	/* 218, capital U, acute accent */
 	"Ucirc",	/* 219, capital U, circumflex accent */
-	"Uuml", 	/* 220, capital U, dieresis or umlaut mark */
+	"Uuml",		/* 220, capital U, dieresis or umlaut mark */
 	"Yacute",	/* 221, capital Y, acute accent */
 	"THORN",	/* 222, capital THORN, Icelandic */
 	"szlig",	/* 223, small sharp s, German (sz ligature) */
@@ -804,34 +804,34 @@ PRIVATE CONST char * LYEntityNames[] = {
 	"aacute",	/* 225, small a, acute accent */
 	"acirc",	/* 226, small a, circumflex accent */
 	"atilde",	/* 227, small a, tilde */
-	"auml", 	/* 228, small a, dieresis or umlaut mark */
+	"auml",		/* 228, small a, dieresis or umlaut mark */
 	"aring",	/* 229, small a, ring */
 	"aelig",	/* 230, small ae diphthong (ligature) */
 	"ccedil",	/* 231, small c, cedilla */
 	"egrave",	/* 232, small e, grave accent */
 	"eacute",	/* 233, small e, acute accent */
 	"ecirc",	/* 234, small e, circumflex accent */
-	"euml", 	/* 235, small e, dieresis or umlaut mark */
+	"euml",		/* 235, small e, dieresis or umlaut mark */
 	"igrave",	/* 236, small i, grave accent */
 	"iacute",	/* 237, small i, acute accent */
 	"icirc",	/* 238, small i, circumflex accent */
-	"iuml", 	/* 239, small i, dieresis or umlaut mark */
+	"iuml",		/* 239, small i, dieresis or umlaut mark */
 	"eth",		/* 240, small eth, Icelandic */
 	"ntilde",	/* 241, small n, tilde */
 	"ograve",	/* 242, small o, grave accent */
 	"oacute",	/* 243, small o, acute accent */
 	"ocirc",	/* 244, small o, circumflex accent */
 	"otilde",	/* 245, small o, tilde */
-	"ouml", 	/* 246, small o, dieresis or umlaut mark */
+	"ouml",		/* 246, small o, dieresis or umlaut mark */
 	"divide",	/* 247, division sign */
 	"oslash",	/* 248, small o, slash */
 	"ugrave",	/* 249, small u, grave accent */
 	"uacute",	/* 250, small u, acute accent */
 	"ucirc",	/* 251, small u, circumflex accent */
-	"uuml", 	/* 252, small u, dieresis or umlaut mark */
+	"uuml",		/* 252, small u, dieresis or umlaut mark */
 	"yacute",	/* 253, small y, acute accent */
 	"thorn",	/* 254, small thorn, Icelandic */
-	"yuml", 	/* 255, small y, dieresis or umlaut mark */
+	"yuml",		/* 255, small y, dieresis or umlaut mark */
 };
 
 /*
diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c
index a0a68ecf..85a65383 100644
--- a/src/LYCharUtils.c
+++ b/src/LYCharUtils.c
@@ -2058,7 +2058,7 @@ PUBLIC char *LYParseTagParam ARGS2(
 
     StrAllocCopy(result, string);
     len = 0;
-    while (isprint(UCH(string[len])) && string[len] != ';') {
+    while (isprint(UCH(string[len])) && !isspace(UCH(string[len]))) {
 	len++;
     }
     result[len] = '\0';
diff --git a/src/LYClean.c b/src/LYClean.c
index 9c7a3012..d3d3de84 100644
--- a/src/LYClean.c
+++ b/src/LYClean.c
@@ -191,7 +191,7 @@ PUBLIC void cleanup NOARGS
     UCChangeTerminalCodepage(-1, (LYUCcharset*)0);
 #endif /* EXP_CHARTRANS_AUTOSWITCH */
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
     /*
      * This can go right here for now.  We need to work up a better place
      * to save cookies for the next release, preferably whenever a new
diff --git a/src/LYCookie.c b/src/LYCookie.c
index 6e558247..5dce429f 100644
--- a/src/LYCookie.c
+++ b/src/LYCookie.c
@@ -1864,7 +1864,7 @@ PUBLIC char * LYAddCookieHeader ARGS4(
     return(NULL);
 }
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 PRIVATE int number_of_file_cookies = 0;
 
 /* rjp - experiment cookie loading */
diff --git a/src/LYCurses.c b/src/LYCurses.c
index c2bf87e1..bced0f3f 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -406,7 +406,7 @@ PUBLIC void setHashStyle ARGS5(
 /*
  * set the curses attributes to be color or mono - RP
  */
-PRIVATE int LYAttrset ARGS3(
+PRIVATE void LYAttrset ARGS3(
     WINDOW *,	win,
     int,	color,
     int,	mono)
@@ -416,15 +416,12 @@ PRIVATE int LYAttrset ARGS3(
      && color >= 0) {
 	CTRACE2(TRACE_STYLE, (tfp, "CSS:LYAttrset color (%s)\n", attr_to_string(color)));
 	wattrset(win, color);
-	return color;
     } else if (mono >= 0) {
 	CTRACE2(TRACE_STYLE, (tfp, "CSS:LYAttrset mono (%s)\n", attr_to_string(mono)));
 	wattrset(win, mono);
-	return mono;
     } else {
 	CTRACE2(TRACE_STYLE, (tfp, "CSS:LYAttrset (A_NORMAL)\n"));
 	wattrset(win, A_NORMAL);
-	return A_NORMAL;
     }
 }
 
@@ -485,7 +482,7 @@ PUBLIC void curses_w_style ARGS3(
 			"in LynxChangeStyle(curses_w_style)"));
 	    last_colorattr_ptr--;
 	}
-	last_styles[last_colorattr_ptr++] = getattrs(win);
+	last_styles[last_colorattr_ptr++] = LYgetattrs(win);
 	/* don't cache style changes for active links */
 #if OMIT_SCN_KEEPING
 	/* since we don't compute the hcode to stack off in HTML.c, we
@@ -587,16 +584,15 @@ PUBLIC int lynx_default_colors NOARGS
 
 PRIVATE struct {
     int fg, bg;
-    chtype attr;
 } lynx_color_cfg[] = {
-    /*0*/ { DEFAULT_FG,    DEFAULT_BG,	A_NORMAL}, /* A_NORMAL */
-    /*1*/ { COLOR_BLUE,    DEFAULT_BG,	A_NORMAL}, /* A_BOLD */
-    /*2*/ { COLOR_YELLOW,  COLOR_BLUE,	A_BOLD},   /* A_REVERSE */
-    /*3*/ { COLOR_GREEN,   DEFAULT_BG,	A_NORMAL}, /* A_REVERSE | A_BOLD */
-    /*4*/ { COLOR_MAGENTA, DEFAULT_BG,	A_NORMAL}, /* A_UNDERLINE */
-    /*5*/ { COLOR_BLUE,    DEFAULT_BG,	A_NORMAL}, /* A_UNDERLINE | A_BOLD */
-    /*6*/ { COLOR_RED,	   DEFAULT_BG,	A_NORMAL}, /* A_UNDERLINE | A_REVERSE */
-    /*7*/ { COLOR_MAGENTA, COLOR_CYAN,	A_NORMAL}  /* A_UNDERLINE | A_BOLD | A_REVERSE */
+    /*0*/ { DEFAULT_FG,    DEFAULT_BG},
+    /*1*/ { COLOR_BLUE,    DEFAULT_BG},
+    /*2*/ { COLOR_YELLOW+8,COLOR_BLUE},
+    /*3*/ { COLOR_GREEN,   DEFAULT_BG},
+    /*4*/ { COLOR_MAGENTA, DEFAULT_BG},
+    /*5*/ { COLOR_BLUE,    DEFAULT_BG},
+    /*6*/ { COLOR_RED,	   DEFAULT_BG},
+    /*7*/ { COLOR_MAGENTA, COLOR_CYAN}
 };
 
 /*
@@ -618,12 +614,37 @@ PRIVATE int get_color_pair ARGS1(int, n)
 #ifdef USE_CURSES_PAIR_0
     if (lynx_color_pairs[n].fg == default_fg
      && lynx_color_pairs[n].bg == default_bg)
-    	return 0;
+	return 0;
 #endif
     return COLOR_PAIR(n);
 }
 
 /*
+ * Lynx "knows" about 16 colors.  ANSI colors (and most color terminal
+ * emulators) only go to 8, though some curses implementations (ncurses and
+ * PDCurses) handle 16.  If lynx's configuration calls for a color past the
+ * number of colors that the terminal handles (COLORS), map the extra value
+ * to bold.
+ */
+#define is_boldc(c) ((c) > (COLORS-1))
+#define map2bold(c) (is_boldc(c) ? ((c) & (COLORS-1)) : (c))
+
+/*
+ * Return the extra color as A_BOLD.
+ * If there is no extra color, return A_NORMAL.
+ */
+PRIVATE int lynx_color_cfg_attr ARGS1(int, code)
+{
+    int result = A_NORMAL;
+    if (code >= 0 && code < 8) {
+	int fg = lynx_color_cfg[code].fg;
+	if (is_boldc(fg) && (fg & COLORS))
+	    result = A_BOLD;
+    }
+    return result;
+}
+
+/*
  * Map the SGR attributes (0-7) into ANSI colors, modified with the actual BOLD
  * attribute we'll get 16 colors.
  */
@@ -640,7 +661,7 @@ PRIVATE void LYsetWAttr ARGS1(WINDOW *, win)
 	    code |= 2;
 	if (Current_Attr & A_UNDERLINE)
 	    code |= 4;
-	attr = lynx_color_cfg[code].attr;
+	attr = lynx_color_cfg_attr(code);
 
 	if (code+offs < COLOR_PAIRS) {
 	    attr |= get_color_pair(code+offs);
@@ -652,10 +673,28 @@ PRIVATE void LYsetWAttr ARGS1(WINDOW *, win)
     }
 }
 
-PRIVATE void lynx_map_color ARGS1(int, n)
+/*
+ * Initialize a curses color-pair based on our configured color values.
+ */
+PRIVATE void lynx_init_color_pair ARGS1(int, n)
 {
     int m;
 
+    if (lynx_called_initscr) {
+	for (m = 0; m <= 16; m += 8) {
+	    int pair = n + m + 1;
+	    if (pair < COLOR_PAIRS)
+		init_pair((short)pair,
+		    (short)map2bold(lynx_color_pairs[pair].fg),
+		    (short)map2bold(lynx_color_pairs[pair].bg));
+	}
+	if (n == 0 && LYShowColor >= SHOW_COLOR_ON)
+	    wbkgd(LYwin, COLOR_BKGD | ' ');
+    }
+}
+
+PRIVATE void lynx_map_color ARGS1(int, n)
+{
     CTRACE((tfp, "lynx_map_color(%d)\n", n));
 
     lynx_color_pairs[n+1].fg = lynx_color_cfg[n].fg;
@@ -667,19 +706,13 @@ PRIVATE void lynx_map_color ARGS1(int, n)
     lynx_color_pairs[n+17].fg = lynx_color_cfg[n].bg;
     lynx_color_pairs[n+17].bg = lynx_color_cfg[n].bg;
 
-    if (lynx_called_initscr) {
-	for (m = 0; m <= 16; m += 8) {
-	    int pair = n + m + 1;
-	    if (pair < COLOR_PAIRS)
-		init_pair((short)pair,
-		    (short)lynx_color_pairs[pair].fg,
-		    (short)lynx_color_pairs[pair].bg);
-	}
-	if (n == 0 && LYShowColor >= SHOW_COLOR_ON)
-	    wbkgd(LYwin, COLOR_BKGD | ' ');
-    }
+    lynx_init_color_pair(n);
 }
 
+/*
+ * Change a configured color value.  This may be called before initscr(), so
+ * we may not be able to call init_pair() to finish the change.
+ */
 PUBLIC int lynx_chg_color ARGS3(
 	int, color,
 	int, fg,
@@ -688,9 +721,8 @@ PUBLIC int lynx_chg_color ARGS3(
 {
     if (fg == ERR_COLOR || bg == ERR_COLOR) return -1;
     if (color >= 0 && color < 8) {
-	lynx_color_cfg[color].fg = (fg > 7) ? (fg & 7) : fg;
-	lynx_color_cfg[color].bg = (bg > 7) ? (bg & 7) : bg;
-	lynx_color_cfg[color].attr = ((fg > 7) && (fg & 8)) ? A_BOLD : A_NORMAL;
+	lynx_color_cfg[color].fg = fg;
+	lynx_color_cfg[color].bg = bg;
 	lynx_map_color(color);
     } else {
 	return -1;
@@ -701,7 +733,7 @@ PUBLIC int lynx_chg_color ARGS3(
 PUBLIC void lynx_set_color ARGS1(int, a)
 {
     if (lynx_has_color && LYShowColor >= SHOW_COLOR_ON) {
-	wattrset(LYwin, lynx_color_cfg[a].attr
+	wattrset(LYwin, lynx_color_cfg_attr(a)
 		| (((a+1) < COLOR_PAIRS)
 			? get_color_pair(a+1)
 			: A_NORMAL));
@@ -719,7 +751,7 @@ PUBLIC void lynx_standout ARGS1(int, flag)
 PRIVATE void lynx_init_colors NOARGS
 {
     if (lynx_has_color) {
-	size_t n, m;
+	size_t n;
 
 	CTRACE((tfp, "lynx_init_colors (default %d/%d)\n",
 		     default_fg, default_bg));
@@ -728,15 +760,7 @@ PRIVATE void lynx_init_colors NOARGS
 	lynx_color_cfg[0].bg = default_bg;
 
 	for (n = 0; n < TABLESIZE(lynx_color_cfg); n++) {
-	    for (m = 0; m <= 16; m += 8) {
-		int pair = n + m + 1;
-		if (pair < COLOR_PAIRS)
-		    init_pair((short)pair,
-			(short)lynx_color_pairs[pair].fg,
-			(short)lynx_color_pairs[pair].bg);
-	    }
-	    if (n == 0 && LYShowColor >= SHOW_COLOR_ON)
-		wbkgd(LYwin, COLOR_BKGD | ' ');
+	    lynx_init_color_pair(n);
 	}
     } else if (LYShowColor != SHOW_COLOR_NEVER) {
 	LYShowColor = SHOW_COLOR_OFF;
@@ -804,6 +828,11 @@ static WINDOW *LYscreen = NULL;
 #define LYDELSCR()  /* nothing */
 #endif /* !defined(VMS) && !defined(USE_SLANG) */
 
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+PUBLIC int saved_scrsize_x = 0;
+PUBLIC int saved_scrsize_y = 0;
+#endif
+
 PUBLIC void start_curses NOARGS
 {
 #ifdef USE_SLANG
@@ -980,6 +1009,8 @@ PUBLIC void start_curses NOARGS
 	initscr();
 #endif /* HAVE_NEWTERM */
 	lynx_called_initscr = TRUE;
+	LYlines = LYscreenHeight();
+	LYcols = LYscreenWidth();
 
 #if defined(SIGWINCH) && defined(NCURSES_VERSION)
 	size_change(0);
@@ -1034,6 +1065,17 @@ PUBLIC void start_curses NOARGS
 	if (has_colors()) {
 	    lynx_has_color = TRUE;
 	    start_color();
+
+#ifndef COLORS
+	    /* map2boldc() relies on COLORS being a power of 2 */
+	    if (COLORS > 16)
+		COLORS = 16;
+	    if (COLORS < 8)
+		COLORS = 2;
+	    if (COLORS > 8 && COLORS != 16)
+		COLORS = 8;
+#endif
+
 #ifdef USE_DEFAULT_COLORS
 #if defined(EXP_ASSUMED_COLOR) && defined(USE_COLOR_TABLE)
 	    /*
@@ -1118,6 +1160,18 @@ PUBLIC void start_curses NOARGS
 #endif
 
     LYCursesON = TRUE;
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+    if ((scrsize_x != 0) && (scrsize_y != 0)) {
+	if (saved_scrsize_x == 0) {
+	    saved_scrsize_x = COLS;
+	    saved_scrsize_y = LINES;
+	}
+	CTRACE((tfp, "resize_term: x=%d, y=%d\n", scrsize_x, scrsize_y));
+	CTRACE((tfp, "saved terminal size: x=%d, y=%d\n", saved_scrsize_x, saved_scrsize_y));
+	resize_term(scrsize_y, scrsize_x);
+        LYclear();
+    }
+#endif
     CTRACE((tfp, "start_curses: done.\n"));
 }  /* end of start_curses() */
 
@@ -1266,6 +1320,9 @@ PUBLIC void stop_curses NOARGS
 {
     if (LYCursesON)
 	echo();
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+    resetty ();
+#endif
 #ifdef __DJGPP__
     _eth_release();
 #endif /* __DJGPP__ */
@@ -1281,7 +1338,10 @@ PUBLIC void stop_curses NOARGS
     if(LYCursesON == TRUE)	{
 	lynx_nl2crlf(TRUE);
 	lynx_enable_mouse (0);
-#if (!defined(WIN_EX) || defined(__CYGWIN__))	/* @@@ */
+#if 1 /* (!defined(WIN_EX) || defined(__CYGWIN__)) */	/* @@@ */
+#ifdef WIN_EX
+	if (system_is_NT)
+#endif
 	if(LYscreen || lynx_called_initscr) {
 	    endwin();	/* stop curses */
 	    LYDELSCR();
@@ -1603,7 +1663,7 @@ PUBLIC WINDOW *LYstartPopup ARGS4(
 
 	    /* Get a proper value for the attribute */
 	    LynxWChangeStyle(form_window, s_menu_bg, STACK_ON);
-	    b = getattrs(form_window);
+	    b = LYgetattrs(form_window);
 	    LynxWChangeStyle(form_window, s_menu_bg, STACK_OFF);
 	    wbkgd(form_window, b | ' ');
 	    /* wbkgdset does not make a lot of sense with USE_COLOR_STYLE
@@ -2594,3 +2654,17 @@ PRIVATE void make_blink_boldbg NOARGS
     VioSetState(&buf,0);
 }
 #endif
+
+#if defined(HAVE_WATTR_GET)
+/*
+ * getattrs() is not in X/Open curses, but it is more convenient than this.
+ */
+PUBLIC long LYgetattrs ARGS1(WINDOW *, win)
+{
+    attr_t result;
+    short pair;
+
+    wattr_get(win, &result, &pair, NULL);
+    return result;
+}
+#endif /* HAVE_WATTR_GET */
diff --git a/src/LYCurses.h b/src/LYCurses.h
index 9c533f39..e2943a24 100644
--- a/src/LYCurses.h
+++ b/src/LYCurses.h
@@ -85,7 +85,7 @@ typedef struct {
 #define SLSMG_BLOCK_CHAR '#'
 #endif
 
-#ifndef ACS_UARROW  
+#ifndef ACS_UARROW
 #define ACS_UARROW  SLSMG_UARROW_CHAR
 #endif
 
@@ -274,9 +274,13 @@ typedef struct {
  * 8 colors, but it actually implements 16.  That makes it hard to optimize
  * color settings against color pair 0 in a portable fashion.
  */
-#if defined(COLOR_CURSES) && !(defined(PDCURSES) || defined(HAVE_XCURSES))
+#if defined(COLOR_CURSES)
+#if defined(PDCURSES) || defined(HAVE_XCURSES)
+#define COLORS 16		/* should be a variable... */
+#else
 #define USE_CURSES_PAIR_0
 #endif
+#endif
 
 #endif /* USE_SLANG */
 
@@ -295,9 +299,6 @@ extern WINDOW *LYstartPopup PARAMS((int top_y, int left_x, int height, int width
 /*
  * Useful macros not in PDCurses or very old ncurses headers.
  */
-#if !defined(HAVE_GETATTRS) && !defined(getattrs)
-#define getattrs(win) ((win)->_attrs)
-#endif
 #if !defined(HAVE_GETBEGX) && !defined(getbegx)
 #define getbegx(win) ((win)->_begx)
 #endif
@@ -308,6 +309,16 @@ extern WINDOW *LYstartPopup PARAMS((int top_y, int left_x, int height, int width
 #define getbkgd(win) ((win)->_bkgd)
 #endif
 
+#if defined(HAVE_WATTR_GET)
+extern long LYgetattrs PARAMS((WINDOW *win));
+#else
+#if defined(HAVE_GETATTRS) || defined(getattrs)
+#define LYgetattrs(win) getattrs(win)
+#else
+#define LYgetattrs(win) ((win)->_attrs)
+#endif
+#endif /* HAVE_WATTR_GET */
+
 #if defined(PDCURSES)
 #define HAVE_GETBKGD 1	/* can use fallback definition */
 #define HAVE_NAPMS 1	/* can use millisecond-delays */
@@ -622,7 +633,16 @@ FANCY_CURSES.  Check your config.log to see why the FANCY_CURSES test failed.
 
 #endif /* FANCY_CURSES */
 
-#ifndef ACS_UARROW  
+#ifdef __hpux			/* FIXME: configure check */
+#undef ACS_UARROW
+#undef ACS_DARROW
+#undef ACS_LARROW
+#undef ACS_RARROW
+#undef ACS_BLOCK
+#undef ACS_CKBOARD
+#endif
+
+#ifndef ACS_UARROW
 #define ACS_UARROW  '^'
 #endif
 
@@ -638,6 +658,14 @@ FANCY_CURSES.  Check your config.log to see why the FANCY_CURSES test failed.
 #define ACS_RARROW '}'
 #endif
 
+#ifndef ACS_BLOCK
+#define ACS_BLOCK  '}'
+#endif
+
+#ifndef ACS_CKBOARD
+#define ACS_CKBOARD '}'
+#endif
+
 #define LYaddch(ch)		waddch(LYwin, ch)
 
 #define addch_raw(ch)           LYaddch(ch)
@@ -655,7 +683,7 @@ FANCY_CURSES.  Check your config.log to see why the FANCY_CURSES test failed.
 #endif /* USE_SLANG */
 
 /*
- * If the screen library allows us to specify "default" color, allow user to 
+ * If the screen library allows us to specify "default" color, allow user to
  * control it.
  */
 #ifdef USE_DEFAULT_COLORS
diff --git a/src/LYDownload.c b/src/LYDownload.c
index 869a7e4e..7f938374 100644
--- a/src/LYDownload.c
+++ b/src/LYDownload.c
@@ -500,7 +500,7 @@ PUBLIC int LYdownload_options ARGS2(
 
     if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
 	return(-1);
- 
+
     StrAllocCopy(downloaded_url, *newfile);
     LYLocalFileToURL(newfile, tempfile);
 
@@ -548,11 +548,17 @@ PUBLIC int LYdownload_options ARGS2(
 	     */
 	    if (SuffixIs(data_file, HTML_SUFFIX)
 	     || SuffixIs(data_file, TEXT_SUFFIX)) {
+		char *target = NULL;
+		char *source = LYAddPathToSave(data_file);
+
+		LYLocalFileToURL(&target, source);
 		fprintf(fp0,
-			"   <a href=\"file://localhost%s%s\">%s</a>\n",
-			NonNull(lynx_save_space),
-			data_file,
+			"   <a href=\"%s\">%s</a>\n",
+			target,
 			gettext("View temporary file"));
+
+		FREE(source);
+		FREE(target);
 	    }
 	}
     } else {
diff --git a/src/LYExtern.c b/src/LYExtern.c
index a9589e38..2a46c131 100644
--- a/src/LYExtern.c
+++ b/src/LYExtern.c
@@ -149,7 +149,7 @@ PRIVATE char *format_command ARGS2(
 	    /* Less ==> short filename with backslashes,
 	     * less ==> long filename with forward slashes, may be quoted
 	     */
-	    if (isupper(command[0])) {
+	    if (ISUPPER(command[0])) {
 		format(&cmdbuf,
 			command, HTDOS_short_name(e_buff));
 	    } else {
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index 6a2fcd5b..21c56613 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -34,7 +34,7 @@
 #define VISITED_LINKS_HELP	"keystrokes/visited_help.html"
 #endif /* LYHELP_H */
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 #include <HTChunk.h>
 #endif
 
@@ -167,13 +167,13 @@ typedef enum {
     rateOFF = 0
     , rateBYTES = 1
     , rateKB
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
     , rateEtaBYTES
     , rateEtaKB
 #endif
 } TransferRate;
 
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
 #  define rateEtaKB_maybe	rateEtaKB
 #else
 #  define rateEtaKB_maybe	rateKB
@@ -204,6 +204,8 @@ extern BOOLEAN emacs_keys;        /* TRUE to turn on emacs-like key movement */
 extern BOOLEAN error_logging;     /* TRUE to mail error messages */
 extern BOOLEAN ftp_ok;
 extern BOOLEAN ftp_passive;	/* TRUE if we want to use passive mode ftp */
+extern BOOLEAN ftp_local_passive;
+extern char *ftp_lasthost;
 extern BOOLEAN goto_buffer;     /* TRUE if offering default goto URL */
 extern BOOLEAN is_www_index;
 extern BOOLEAN jump_buffer;     /* TRUE if offering default shortcut */
@@ -335,7 +337,7 @@ extern BOOLEAN historical_comments;
 extern BOOLEAN minimal_comments;
 extern BOOLEAN soft_dquotes;
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 extern BOOLEAN source_cache_file_error;
 extern int LYCacheSource;
 #define SOURCE_CACHE_NONE	0
@@ -436,11 +438,11 @@ extern BOOLEAN BibP_bibhost_checked;    /* bibhost has been checked      */
 extern BOOLEAN BibP_bibhost_available;  /* bibhost is responding         */
 #endif
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 extern BOOLEAN persistent_cookies;
 extern char *LYCookieFile;              /* cookie read file              */
 extern char *LYCookieSaveFile;          /* cookie save file              */
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
 
 extern char *XLoadImageCommand;		/* Default image viewer for X	 */
 
@@ -501,6 +503,11 @@ extern int justify_max_void_percent;
 extern BOOLEAN with_backspaces;
 #endif
 
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+extern int scrsize_x;
+extern int scrsize_y;
+#endif
+
 #ifndef NO_LYNX_TRACE
 extern FILE *LYTraceLogFP;		/* Pointer for TRACE log	 */
 extern char *LYTraceLogPath;		/* Path for TRACE log		 */
@@ -535,6 +542,11 @@ extern char *lynx_lss_file;
 extern int HTNoDataOK;		/* HT_NO_DATA-is-ok hack */
 extern BOOLEAN FileInitAlreadyDone;
 
+#ifdef __DJGPP__
+extern BOOLEAN watt_debug;
+extern BOOLEAN dj_is_bash;
+#endif /* __DJGPP__ */
+
 #ifdef WIN_EX
 /* LYMain.c */
 extern BOOLEAN focus_window;
diff --git a/src/LYHash.c b/src/LYHash.c
index 13d2e6a1..93bc93f3 100644
--- a/src/LYHash.c
+++ b/src/LYHash.c
@@ -30,7 +30,7 @@ PUBLIC int hash_code_lowercase_on_fly ARGS1 (CONST char*, string)
     CONST char *p;
 
     for (p = string, hash = 0; *p; p++)
-	hash = HASH_OF(hash,tolower(*p));
+	hash = HASH_OF(hash, TOLOWER(*p));
 
     return hash;
 }
@@ -46,7 +46,7 @@ PUBLIC int hash_code_aggregate_lower_str ARGS2 (CONST char*, string,int,hash_was
     CONST char *p;
 
     for (p = string, hash = hash_was ; *p; p++)
-	hash = HASH_OF(hash,tolower(*p));
+	hash = HASH_OF(hash, TOLOWER(*p));
 
     return hash;
 }
diff --git a/src/LYJump.c b/src/LYJump.c
index 7d04f27b..bed7133e 100644
--- a/src/LYJump.c
+++ b/src/LYJump.c
@@ -238,7 +238,7 @@ PUBLIC char *LYJump ARGS1(int, key)
 
   check_recall:
     bp = buf;
-    if (toupper(key) == 'G' && strncmp(buf, "o ", 2) == 0)
+    if (TOUPPER(key) == 'G' && strncmp(buf, "o ", 2) == 0)
 	bp++;
     bp = LYSkipBlanks(bp);
     if (*bp == '\0' &&
@@ -335,7 +335,7 @@ PUBLIC char *LYJump ARGS1(int, key)
 		       (!jump_buffer && ShortcutTotal == 1)) {
 		_statusline(EDIT_THE_PREV_SHORTCUT);
 	    } else {
-		_statusline(EDIT_THE_PREV_SHORTCUT);
+		_statusline(EDIT_A_PREV_SHORTCUT);
 	    }
 	    if ((ch = LYgetstr(buf, VISIBLE, sizeof(buf), recall)) < 0) {
 		/*
diff --git a/src/LYMain.c b/src/LYMain.c
index 79cd47ab..df11538d 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -76,7 +76,7 @@ PUBLIC BOOLEAN sigint = FALSE;
 #endif /* IGNORE_CTRL_C */
 
 #ifdef __DJGPP__
-char init_ctrl_break[1];
+PRIVATE char init_ctrl_break[1];
 #endif /* __DJGPP__ */
 
 #if USE_VMS_MAILER
@@ -189,6 +189,8 @@ PUBLIC BOOLEAN dump_output_immediately = FALSE;
 PUBLIC BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
 PUBLIC BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
 PUBLIC BOOLEAN ftp_passive = FTP_PASSIVE; /* TRUE if doing ftp in passive mode */
+PUBLIC BOOLEAN ftp_local_passive;
+PUBLIC char *ftp_lasthost;
 PUBLIC BOOLEAN goto_buffer = GOTOBUFFER; /* TRUE if offering default goto URL */
 PUBLIC BOOLEAN historical_comments = FALSE;
 PUBLIC BOOLEAN is_www_index = FALSE;
@@ -294,6 +296,7 @@ PUBLIC BOOLEAN LYfind_leaks = TRUE;
 
 #ifdef __DJGPP__
 PUBLIC BOOLEAN watt_debug = FALSE;	/* WATT-32 debugging */
+PUBLIC BOOLEAN dj_is_bash = FALSE;  /* Check for bash shell under DJGPP */
 #endif /* __DJGPP__ */
 
 #ifdef WIN_EX
@@ -444,11 +447,11 @@ PUBLIC char *BibP_bibhost = NULL;	 /* local server for bibp: links  */
 PUBLIC char *BibP_globalserver = NULL;   /* global server for bibp: links */
 #endif
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 PUBLIC BOOLEAN persistent_cookies = FALSE; /* disabled by default! */
 PUBLIC char *LYCookieFile = NULL;	/* cookie read file */
 PUBLIC char *LYCookieSaveFile = NULL;	/* cookie save file */
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
 
 #ifdef EXP_NESTED_TABLES
 PUBLIC BOOLEAN nested_tables =
@@ -461,7 +464,7 @@ PUBLIC BOOLEAN nested_tables =
 #endif
 
 PUBLIC BOOLEAN LYShowTransferRate = TRUE;
-PUBLIC int LYTransferRate = rateEtaKB_maybe;
+PUBLIC int LYTransferRate = rateKB;
 
 PUBLIC char *XLoadImageCommand = NULL;	/* Default image viewer for X */
 PUBLIC BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */
@@ -504,6 +507,11 @@ PUBLIC int justify_max_void_percent = 35;
 PUBLIC BOOLEAN with_backspaces = FALSE;
 #endif
 
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+PUBLIC int scrsize_x = 0;
+PUBLIC int scrsize_y = 0;
+#endif
+
 PUBLIC BOOL force_empty_hrefless_a = FALSE;
 
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
@@ -668,7 +676,7 @@ PRIVATE void free_lynx_globals NOARGS
     FREE(BibP_bibhost);
     FREE(BibP_globalserver);
 #endif
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
     FREE(LYCookieFile);
     FREE(LYCookieSaveFile);
 #endif
@@ -866,6 +874,49 @@ PRIVATE BOOL cleanup_win32(DWORD fdwCtrlType)
 #endif
 
 /*
+ * Append the SSL version to lynx version or user-agent string.
+ */
+#ifdef USE_SSL
+PRIVATE void append_ssl_version ARGS2(
+	char **,	target,
+	char *,		separator)
+{
+    char SSLLibraryVersion[256];
+    char *SSLcp;
+
+    HTSprintf(target, " SSL-MM%s1.4.1", separator);
+
+#undef LYNX_SSL_VERSION
+
+#if defined(SSLEAY_VERSION)
+#define LYNX_SSL_VERSION SSLeay_version(SSLEAY_VERSION)
+#else
+#if defined(OPENSSL_VERSION_TEXT)
+#define LYNX_SSL_VERSION OPENSSL_VERSION_TEXT
+#else
+#if defined(GNUTLS_VERSION)
+#define LYNX_SSL_VERSION GNUTLS_VERSION
+#endif /* GNUTLS_VERSION */
+#endif /* OPENSSL_VERSION_TEXT */
+#endif
+
+#ifdef LYNX_SSL_VERSION
+    if (*separator == ' ')
+	StrAllocCat(*target, ",");
+    LYstrncpy(SSLLibraryVersion, LYNX_SSL_VERSION, sizeof(SSLLibraryVersion)-1);
+    if ((SSLcp = strchr(SSLLibraryVersion, ' ')) != NULL) {
+	*SSLcp++ = *separator;
+	if ((SSLcp = strchr(SSLcp, ' ')) != NULL) {
+	    *SSLcp = '\0';
+	    StrAllocCat(*target, " ");
+	    StrAllocCat(*target, SSLLibraryVersion);
+	}
+    }
+#endif /* LYNX_SSL_VERSION */
+}
+#endif /* USE_SSL */
+
+/*
  * Wow!  Someone wants to start up Lynx.
  */
 PUBLIC int main ARGS2(
@@ -883,10 +934,6 @@ PUBLIC int main ARGS2(
 #ifdef _WINDOWS
     WSADATA WSAData;
 #endif /* _WINDOWS */
-#ifdef USE_SSL
-    char SSLLibraryVersion[256];
-    char *SSLcp;
-#endif /* USE_SSL */
 
     /*
      * Just in case someone has the idea to install lynx set-uid, let's try
@@ -900,6 +947,11 @@ PUBLIC int main ARGS2(
     FixCharacters();
 #endif /* NOT_ASCII */
 
+#ifndef DISABLE_FTP
+    /* malloc a sizeof(char) so 1st strcmp() won't dump in HTLoadFile() */
+    ftp_lasthost = calloc(1,sizeof(char));
+#endif
+
 #ifdef EXP_CHARSET_CHOICE
     memset((char*)charset_subsets, 0, sizeof(charset_subset_t)*MAXCHARSETS);
 #endif
@@ -955,6 +1007,10 @@ PUBLIC int main ARGS2(
     __djgpp_set_sigquit_key(0x082D); /* Bind ALT-X to SIGQUIT */
     signal(SIGQUIT, cleanup_sig);
     atexit(reset_break);
+
+    if (((cp = LYGetEnv("SHELL")) != NULL)
+      && (strstr(LYPathLeaf(cp), "sh") != NULL))
+	dj_is_bash = TRUE;
 #endif /* __DJGPP__ */
 
     /*
@@ -1070,6 +1126,7 @@ PUBLIC int main ARGS2(
 #else
     StrAllocCopy(system_mail_flags, "");
 #endif
+
     StrAllocCopy(LYUserAgent, LYNX_NAME);
     StrAllocCat(LYUserAgent, "/");
     StrAllocCat(LYUserAgent, LYNX_VERSION);
@@ -1078,20 +1135,10 @@ PUBLIC int main ARGS2(
 	StrAllocCat(LYUserAgent, HTLibraryVersion);
     }
 #ifdef USE_SSL
-    StrAllocCat(LYUserAgent, " SSL-MM/1.4.1");
-#ifdef OPENSSL_VERSION_TEXT
-    LYstrncpy(SSLLibraryVersion, OPENSSL_VERSION_TEXT, sizeof(SSLLibraryVersion)-1);
-    if ((SSLcp = strchr(SSLLibraryVersion, ' ')) != NULL) {
-	*SSLcp++ = '/';
-	if ((SSLcp = strchr(SSLcp, ' ')) != NULL) {
-	    *SSLcp = '\0';
-	    StrAllocCat(LYUserAgent, " ");
-	    StrAllocCat(LYUserAgent, SSLLibraryVersion);
-	}
-    }
-#endif /* OPENSSL_VERSION_TEXT */
+    append_ssl_version(&LYUserAgent, "/");
 #endif /* USE_SSL */
     StrAllocCopy(LYUserAgentDefault, LYUserAgent);
+
 #ifdef VMS
     Define_VMSLogical("LYNX_VERSION", LYNX_VERSION);
 #else
@@ -1601,7 +1648,7 @@ PUBLIC int main ARGS2(
      */
     HTMLUseCharacterSet(current_char_set);
 
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
     /*
      * Sod it, this looks like a reasonable place to load the
      * cookies file, probably.  - RP
@@ -1785,7 +1832,7 @@ PUBLIC int main ARGS2(
 	no_multibook = TRUE;
     }
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     /*
      * Disable source caching if not interactive.
      */
@@ -2021,7 +2068,7 @@ PUBLIC int main ARGS2(
 	    !crawl &&		/* For -crawl it has already been done! */
 	    links_are_numbered())
 	    printlist(stdout, FALSE);
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 	/*
 	 *  We want to save cookies picked up when in immediate dump
 	 *  mode.  Instead of calling cleanup() here, let's only call
@@ -2029,7 +2076,7 @@ PUBLIC int main ARGS2(
 	 */
 	if (persistent_cookies)
 	    LYStoreCookies(LYCookieSaveFile);
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
 	exit_immediately(status);
     } else {
 	/*
@@ -2058,6 +2105,15 @@ PUBLIC int main ARGS2(
 	LYCloseCloset(RECALL_URL);
 	LYCloseCloset(RECALL_MAIL);
 	cleanup();
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+	if (! isendwin()) {
+	    extern int saved_scrsize_x;
+	    extern int saved_scrsize_y;
+	    if ((saved_scrsize_x != 0) && (saved_scrsize_y != 0)) {
+	        resize_term(saved_scrsize_y, saved_scrsize_x);
+	    }
+	}
+#endif
 	exit(status);
     }
 
@@ -2162,7 +2218,7 @@ PUBLIC void reload_read_cfg NOARGS
 
     {
 	/* set few safe flags: */
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 	BOOLEAN persistent_cookies_flag = persistent_cookies;
 	char * LYCookieFile_flag = NULL;
 	char * LYCookieSaveFile_flag = NULL;
@@ -2183,7 +2239,7 @@ PUBLIC void reload_read_cfg NOARGS
 #endif
 	/* free downloaders, printers, environments, dired menu */
 	free_lynx_cfg();
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	source_cache_file_error = FALSE; /* reset flag */
 #endif
 
@@ -2230,7 +2286,7 @@ PUBLIC void reload_read_cfg NOARGS
 		 * a major problem: file paths
 		 * like lynx_save_space, LYCookieFile etc.
 		 */
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
 	/* restore old settings */
 	if (persistent_cookies != persistent_cookies_flag) {
 	    persistent_cookies = persistent_cookies_flag;
@@ -3057,30 +3113,20 @@ PRIVATE int traversal_fun ARGS1(
 PRIVATE int version_fun ARGS1(
 	char *,			next_arg GCC_UNUSED)
 {
-#ifdef USE_SSL
-    char SSLLibraryVersion[256];
-    char *SSLcp;
-#endif
+    char *result = NULL;
 
     SetOutputMode( O_TEXT );
 
-    printf(gettext("%s Version %s (%s)\n"),
-	  LYNX_NAME, LYNX_VERSION,
-	  LYVersionDate());
+    HTSprintf0(&result, gettext("%s Version %s (%s)"),
+	       LYNX_NAME, LYNX_VERSION,
+	       LYVersionDate());
 #ifdef USE_SSL
-    printf("libwww-FM %s, SSL-MM 1.4.1", HTLibraryVersion);
-#ifdef OPENSSL_VERSION_TEXT
-    LYstrncpy(SSLLibraryVersion, OPENSSL_VERSION_TEXT, sizeof(SSLLibraryVersion)-1);
-    if ((SSLcp = strchr(SSLLibraryVersion, ' ')) != NULL) {
-	*SSLcp++ = ' ';
-	if ((SSLcp = strchr(SSLcp, ' ')) != NULL) {
-	    *SSLcp = '\0';
-	    printf(", %s", SSLLibraryVersion);
-	}
-    }
-#endif /* OPENSSL_VERSION_TEXT */
-    printf("\n");
+    StrAllocCat(result, "\n");
+    HTSprintf(&result, "libwww-FM %s,", HTLibraryVersion);
+    append_ssl_version(&result, " ");
 #endif /* USE_SSL */
+    printf("%s\n", result);
+    free(result);
 
 #ifndef __DATE__
 #define __DATE__ ""
@@ -3151,6 +3197,34 @@ PRIVATE int width_fun ARGS1(
     return 0;
 }
 
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+/* -scrsize */
+PRIVATE int scrsize_fun ARGS1(
+	char *,			next_arg)
+{
+    if (next_arg != 0) {
+	char *cp;
+
+	if ((cp = strchr(next_arg, ',')) != 0) {
+	    *cp++ = '\0';	/* Terminate ID */
+	    scrsize_x = atoi(next_arg);
+	    scrsize_y = atoi(cp);
+	    if ((scrsize_x <= 1) || (scrsize_y <= 1)) {
+		scrsize_x = scrsize_y = 0;
+	    }
+	    if ((scrsize_x > 0) && (scrsize_x < 80)) {
+		scrsize_x = 80;
+	    }
+	    if ((scrsize_y > 0) && (scrsize_y < 4)) {
+		scrsize_y = 4;
+	    }
+	    CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y));
+	}
+    }
+    return 0;
+}
+#endif
+
 /* NOTE: This table is sorted by name to make the help message useful */
 PRIVATE Config_Type Arg_Table [] =
 {
@@ -3248,7 +3322,7 @@ PRIVATE Config_Type Arg_Table [] =
       "=FORMAT\nconvert input, FORMAT is in MIME type notation\n(experimental)"
    ),
 #endif
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
    PARSE_STR(
       "cookie_file",	4|LYSTRING_ARG,		LYCookieFile,
       "=FILENAME\nspecifies a file to use to read cookies"
@@ -3257,7 +3331,7 @@ PRIVATE Config_Type Arg_Table [] =
       "cookie_save_file",	4|LYSTRING_ARG,	LYCookieSaveFile,
       "=FILENAME\nspecifies a file to use to store cookies"
    ),
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
    PARSE_SET(
       "cookies",	4|TOGGLE_ARG,		LYSetCookies,
       "toggles handling of Set-Cookie headers"
@@ -3618,6 +3692,12 @@ with the PREV_DOC command or from the History List"
       "rlogin",		4|UNSET_ARG,		rlogin_ok,
       "disable rlogins"
    ),
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+   PARSE_FUN(
+      "scrsize",	4|NEED_FUNCTION_ARG,	scrsize_fun,
+      "=width,height\nsize of window"
+   ),
+#endif
 #ifdef USE_SCROLLBAR
    PARSE_SET(
       "scrollbar",	4|TOGGLE_ARG,		LYShowScrollbar,
@@ -3646,7 +3726,7 @@ with the PREV_DOC command or from the History List"
       "show_cursor",	4|TOGGLE_ARG,		LYUseDefShoCur,
       "toggles hiding of the cursor in the lower right corner"
    ),
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
    PARSE_SET(
       "show_rate",	4|TOGGLE_ARG,		LYShowTransferRate,
       "toggles display of transfer rate"
diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c
index e5c10bc7..bcd0148f 100644
--- a/src/LYMainLoop.c
+++ b/src/LYMainLoop.c
@@ -393,7 +393,7 @@ PUBLIC int LYGetNewline NOARGS
     return Newline;
 }
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 PRIVATE BOOLEAN from_source_cache = FALSE;
 
 /*
@@ -410,7 +410,7 @@ PRIVATE BOOLEAN reparse_document NOARGS
     from_source_cache = FALSE;
     return ok;
 }
-#endif /* SOURCE_CACHE */
+#endif /* USE_SOURCE_CACHE */
 
 /*
  * Prefer reparsing if we can, but reload if we must - to force regeneration
@@ -419,7 +419,7 @@ PRIVATE BOOLEAN reparse_document NOARGS
 PRIVATE BOOLEAN reparse_or_reload ARGS1(
     int *,	cmd)
 {
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (reparse_document()) {
 	return FALSE;
     }
@@ -478,7 +478,7 @@ PUBLIC BOOL LYMainLoop_pageDisplay ARGS1(
      */
     Newline = line_num;
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     /*
      * reparse_document() acts on 'curdoc' which always on top of the
      * history stack: no need to resolve #fragment position since
@@ -1850,7 +1850,7 @@ PRIVATE void handle_LYK_DIRED_MENU ARGS3(
 {
 #ifdef VMS
     char *cp, *temp = 0;
-    char *test = HTGetProgramPath(ppCSWING);
+    const char *test = HTGetProgramPath(ppCSWING);
 
     /*
      *	Check if the CSwing Directory/File Manager is available.
@@ -2947,7 +2947,7 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		    LYforce_no_cache = TRUE;
 		    StrAllocCopy(newdoc.title, curdoc.title);
 		    if (HTLoadedDocumentIsHEAD()) {
-			HTuncache_current_document();
+			HText_setNoCache(HTMainText);
 			free_address(&curdoc);
 		    } else {
 			StrAllocCat(newdoc.title, " - HEAD");
@@ -3025,7 +3025,7 @@ PRIVATE BOOLEAN handle_LYK_HEAD ARGS1(
 		    LYforce_no_cache = TRUE;
 		    StrAllocCopy(newdoc.title, curdoc.title);
 		    if (HTLoadedDocumentIsHEAD()) {
-			HTuncache_current_document();
+			HText_setNoCache(HTMainText);
 			free_address(&curdoc);
 		    } else {
 			StrAllocCat(newdoc.title, " - HEAD");
@@ -3062,7 +3062,7 @@ PRIVATE void handle_LYK_HELP ARGS1(
 
 PRIVATE void handle_LYK_HISTORICAL NOARGS
 {
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (!HTcan_reparse_document()) {
 #endif
     /*
@@ -3075,12 +3075,12 @@ PRIVATE void handle_LYK_HISTORICAL NOARGS
 	confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
 	HTInfoMsg(WILL_NOT_RELOAD_DOC);
     } else {
-	HTuncache_current_document();
+	HText_setNoCache(HTMainText);
 	move_address(&newdoc, &curdoc);
 	newdoc.line = curdoc.line;
 	newdoc.link = curdoc.link;
     }
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     } /* end if no bypass */
 #endif
     historical_comments = !historical_comments;
@@ -3091,7 +3091,7 @@ PRIVATE void handle_LYK_HISTORICAL NOARGS
 	HTAlert(historical_comments ?
 		HISTORICAL_ON_VALID_OFF : HISTORICAL_OFF_VALID_ON);
     }
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     (void) reparse_document();
 #endif
     return;
@@ -3570,7 +3570,7 @@ PRIVATE void handle_LYK_MAIN_MENU ARGS2(
 PRIVATE void handle_LYK_MINIMAL NOARGS
 {
     if (!historical_comments) {
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (!HTcan_reparse_document()) {
 #endif
 	/*
@@ -3583,12 +3583,12 @@ PRIVATE void handle_LYK_MINIMAL NOARGS
 	    confirm_post_resub(curdoc.address, NULL, 0, 0) == FALSE) {
 	    HTInfoMsg(WILL_NOT_RELOAD_DOC);
 	} else {
-	    HTuncache_current_document();
+	    HText_setNoCache(HTMainText);
 	    move_address(&newdoc, &curdoc);
 	    newdoc.line = curdoc.line;
 	    newdoc.link = curdoc.link;
 	}
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     } /* end if no bypass */
 #endif
     }
@@ -3600,7 +3600,7 @@ PRIVATE void handle_LYK_MINIMAL NOARGS
 	HTAlert(minimal_comments ?
 		MINIMAL_ON_BUT_HISTORICAL : MINIMAL_OFF_HISTORICAL_ON);
     }
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     (void)reparse_document();
 #endif
     return;
@@ -3700,7 +3700,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 	     */
 	    if ((curdoc.post_data != NULL &&
 		 curdoc.safe != TRUE) &&
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 		(!(canreparse_post = HTcan_reparse_document())) &&
 #endif
 		confirm_post_resub(curdoc.address, curdoc.title,
@@ -3730,7 +3730,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 		if (HTisDocumentSource()) {
 		    srcmode_for_next_retrieval(1);
 		}
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 		if (reloading == FALSE) {
 		    /* one more attempt to be smart enough: */
 		    if (reparse_document()) {
@@ -3754,7 +3754,7 @@ PRIVATE BOOLEAN handle_LYK_OPTIONS ARGS2(
 		}
 
 		HEAD_request = HTLoadedDocumentIsHEAD();
-		HTuncache_current_document();
+		HText_setNoCache(HTMainText);
 #ifdef NO_ASSUME_SAME_DOC
 		newdoc.line = 1;
 		newdoc.link = 0;
@@ -4138,13 +4138,13 @@ PRIVATE BOOLEAN handle_LYK_RAW_TOGGLE ARGS1(
     }
 }
 
-/*
- * Check if this is a reply from a POST, and if so,
- * seek confirmation if the safe element is not set.  - FM
- */
 PRIVATE void handle_LYK_RELOAD ARGS1(
     int,	real_cmd)
 {
+    /*
+     * Check if this is a reply from a POST, and if so,
+     * seek confirmation if the safe element is not set.  - FM
+     */
     if ((curdoc.post_data != NULL &&
 	 curdoc.safe != TRUE) &&
 	HTConfirm(CONFIRM_POST_RESUBMISSION) == FALSE) {
@@ -4163,7 +4163,7 @@ PRIVATE void handle_LYK_RELOAD ARGS1(
     }
 
     HEAD_request = HTLoadedDocumentIsHEAD();
-    HTuncache_current_document();
+    HText_setNoCache(HTMainText);
 #ifdef NO_ASSUME_SAME_DOC
     /*
      *	Don't assume the reloaded document will be the same. - FM
@@ -4248,7 +4248,7 @@ PRIVATE void handle_LYK_SHELL ARGS3(
 
 PRIVATE void handle_LYK_SOFT_DQUOTES NOARGS
 {
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (!HTcan_reparse_document()) {
 #endif
     /*
@@ -4261,36 +4261,36 @@ PRIVATE void handle_LYK_SOFT_DQUOTES NOARGS
 	confirm_post_resub(curdoc.address, NULL, 1, 1) == FALSE) {
 	HTInfoMsg(WILL_NOT_RELOAD_DOC);
     } else {
-	HTuncache_current_document();
+	HText_setNoCache(HTMainText);
 	move_address(&newdoc, &curdoc);
 	newdoc.line = curdoc.line;
 	newdoc.link = curdoc.link;
     }
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     } /* end if no bypass */
 #endif
     soft_dquotes = !soft_dquotes;
     HTUserMsg(soft_dquotes ?
 	      SOFT_DOUBLE_QUOTE_ON : SOFT_DOUBLE_QUOTE_OFF);
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     (void)reparse_document();
 #endif
     return;
 }
 
-/*
- * Check if this is a reply from a POST, and if so,
- * seek confirmation if the safe element is not set.  - FM
- */
 PRIVATE void handle_LYK_SOURCE ARGS1(
     char **,	ownerS_address_p)
 {
-#ifdef SOURCE_CACHE
+    /*
+     * Check if this is a reply from a POST, and if so,
+     * seek confirmation if the safe element is not set.  - FM
+     */
+#ifdef USE_SOURCE_CACHE
     BOOLEAN canreparse_post = FALSE;
 #endif
     if ((curdoc.post_data != NULL &&
 	 curdoc.safe != TRUE) &&
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	(!(canreparse_post = HTcan_reparse_document())) &&
 #endif
 	(curdoc.isHEAD ? HTConfirm(CONFIRM_POST_RESUBMISSION) :
@@ -4308,7 +4308,7 @@ PRIVATE void handle_LYK_SOURCE ARGS1(
 	srcmode_for_next_retrieval(1);
     }
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (reparse_document()) {
 	/*
 	 * These normally get cleaned up after getfile() returns;
@@ -4341,7 +4341,7 @@ PRIVATE void handle_LYK_SOURCE ARGS1(
 
 PRIVATE void handle_LYK_SWITCH_DTD NOARGS
 {
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     BOOLEAN canreparse = FALSE;
     if (!(canreparse = HTcan_reparse_document())) {
 #endif
@@ -4369,7 +4369,7 @@ PRIVATE void handle_LYK_SWITCH_DTD NOARGS
 	    if (HTisDocumentSource() && LYPreparsedSource) {
 		srcmode_for_next_retrieval(1);
 	    }
-	    HTuncache_current_document();
+	    HText_setNoCache(HTMainText);
 	    move_address(&newdoc, &curdoc);
 #ifdef NO_ASSUME_SAME_DOC
 	    newdoc.line = 1;
@@ -4379,13 +4379,13 @@ PRIVATE void handle_LYK_SWITCH_DTD NOARGS
 	    newdoc.link = curdoc.link;
 #endif /* NO_ASSUME_SAME_DOC */
 	}
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     } /* end if no bypass */
 #endif
     Old_DTD = !Old_DTD;
     HTSwitchDTD(!Old_DTD);
     HTUserMsg(Old_DTD ? USING_DTD_0 : USING_DTD_1);
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
     if (canreparse) {
 	if (HTisDocumentSource() && LYPreparsedSource) {
 	    srcmode_for_next_retrieval(1);
@@ -6191,7 +6191,7 @@ try_again:
 	    }
 	}
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	/*
 	 * If the parse settings have changed since this HText was
 	 * generated, we need to reparse and redraw it.  -dsb
diff --git a/src/LYOptions.c b/src/LYOptions.c
index 0c5970a3..23db216a 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -2128,7 +2128,7 @@ static char * emacs_keys_string		= RC_EMACS_KEYS;
 #define EXEC_ALWAYS 2
 #define EXEC_LOCAL  1
 #define EXEC_NEVER  0
-static char * exec_links_string		= "exec_options";
+static char * exec_links_string		= RC_RUN_ALL_EXECUTION_LINKS;
 static OptValues exec_links_values[]	= {
 	{ EXEC_NEVER,	"ALWAYS OFF",		"ALWAYS OFF" },
 	{ EXEC_LOCAL,	"FOR LOCAL FILES ONLY",	"FOR LOCAL FILES ONLY" },
@@ -2243,7 +2243,7 @@ static OptValues mbm_values[] = {
 	{ MBM_ADVANCED,		"ADVANCED",		"ADVANCED" },
 	{ 0, 0, 0 }};
 
-static char * single_bookmark_string	= "single_bookmark_name";
+static char * single_bookmark_string	= RC_BOOKMARK_FILE;
 
 /*
  * Character Set Options
@@ -2293,7 +2293,7 @@ static OptValues rate_values[] = {
 	{ rateOFF,		"Do not show rate",	"rate_off" },
 	{ rateBYTES,		"Show Bytes/sec rate",	"rate_bytes" },
 	{ rateKB,		"Show KB/sec rate",	"rate_kb" },
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
 	{ rateEtaBYTES,		"Show Bytes/sec, ETA",	"rate_eta_bytes" },
 	{ rateEtaKB,		"Show KB/sec, ETA",	"rate_eta_kb" },
 #endif
@@ -2984,8 +2984,7 @@ PUBLIC int postoptions ARGS1(
     if (!HTLoadAbsolute(&WWWDoc))
 	return(NOT_FOUND);
 
-    /* comment out to avoid warning when removing forms content... */
-    /* HTuncache_current_document(); */ /* will never use again */
+    HTuncache_current_document(); /* will never use again */
 
     /*
      *  Return to previous doc, not to options menu!
@@ -3052,7 +3051,7 @@ PUBLIC int postoptions ARGS1(
 	if (HTisDocumentSource()) {
 	    srcmode_for_next_retrieval(1);
 	}
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 	if (reloading == FALSE) {
 	    /* one more attempt to be smart enough: */
 	    if (HTcan_reparse_document()) {
@@ -3198,8 +3197,7 @@ PRIVATE int gen_options ARGS1(
        LYReuseTempfiles==FALSE.  Even for LYReuseTempfiles=TRUE, code
        at the end of postoptions() may remove an older cached version
        from memory if that version of the page was left by submitting
-       changes. (But that code doesn't do that - HTuncache_current_document
-       is currently commented out.) - kw 1999-11-27
+       changes. - kw 1999-11-27
        If access to the actual file via getfile() later fails
        (maybe because of some restrictions), mainloop may leave
        this flag on after popping the previous doc which is then
@@ -3586,13 +3584,13 @@ PRIVATE int gen_options ARGS1(
     EndSelect(fp0);
 #endif /* ENABLE_OPTS_CHANGE_EXEC */
 
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
     /* Local Directory Sort: SELECT */
     PutLabel(fp0, gettext("Show transfer rate"), show_rate_string);
     BeginSelect(fp0, show_rate_string);
     PutOptValues(fp0, LYTransferRate, rate_values);
     EndSelect(fp0);
-#endif /* EXP_READPROGRESS */
+#endif /* USE_READPROGRESS */
 
     /*
      * Special Files and Screens
diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c
index c19d1787..4297de76 100644
--- a/src/LYReadCFG.c
+++ b/src/LYReadCFG.c
@@ -396,7 +396,7 @@ PRIVATE void parse_color ARGS1(
 }
 #endif /* USE_COLOR_TABLE */
 
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
 static Config_Enum tbl_source_cache[] = {
     { "FILE",	SOURCE_CACHE_FILE },
     { "MEMORY",	SOURCE_CACHE_MEMORY },
@@ -1208,6 +1208,31 @@ PRIVATE int read_htmlsrc_tagname_xform ARGS1( char*,str)
 }
 #endif
 
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+PRIVATE int screen_size_fun ARGS1(
+	char *,		value)
+{
+    char *cp;
+
+    if ((cp = strchr(value, ',')) != 0) {
+	*cp++ = '\0';       /* Terminate ID */
+	scrsize_x = atoi(value);
+	scrsize_y = atoi(cp);
+	if ((scrsize_x <= 1) || (scrsize_y <= 1)) {
+	    scrsize_x = scrsize_y = 0;
+	}
+	if ((scrsize_x > 0) && (scrsize_x < 80)) {
+	    scrsize_x = 80;
+	}
+	if ((scrsize_y > 0) && (scrsize_y < 4)) {
+	    scrsize_y = 4;
+	}
+	CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y));
+    }
+    return 0;
+}
+#endif
+
 /* This table is searched ignoring case */
 PRIVATE Config_Type Config_Table [] =
 {
@@ -1254,15 +1279,15 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_PRG(RC_COPY_PATH,            ppCOPY),
      PARSE_INT(RC_CONNECT_TIMEOUT,      connect_timeout),
      PARSE_STR(RC_COOKIE_ACCEPT_DOMAINS, LYCookieSAcceptDomains),
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
      PARSE_STR(RC_COOKIE_FILE,          LYCookieFile),
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
      PARSE_STR(RC_COOKIE_LOOSE_INVALID_DOMAINS, LYCookieSLooseCheckDomains),
      PARSE_STR(RC_COOKIE_QUERY_INVALID_DOMAINS, LYCookieSQueryCheckDomains),
      PARSE_STR(RC_COOKIE_REJECT_DOMAINS, LYCookieSRejectDomains),
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
      PARSE_STR(RC_COOKIE_SAVE_FILE,     LYCookieSaveFile),
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
      PARSE_STR(RC_COOKIE_STRICT_INVALID_DOMAIN, LYCookieSStrictCheckDomains),
      PARSE_Env(RC_CSO_PROXY,		0),
 #ifdef VMS
@@ -1400,9 +1425,9 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_SET(RC_PARTIAL,              display_partial_flag),
      PARSE_INT(RC_PARTIAL_THRES,        partial_threshold),
 #endif
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
      PARSE_SET(RC_PERSISTENT_COOKIES,   persistent_cookies),
-#endif /* EXP_PERSISTENT_COOKIES */
+#endif /* USE_PERSISTENT_COOKIES */
      PARSE_STR(RC_PERSONAL_EXTENSION_MAP, personal_extension_map),
      PARSE_STR(RC_PERSONAL_MAILCAP,     personal_type_map),
      PARSE_STR(RC_PREFERRED_CHARSET,    pref_charset),
@@ -1429,6 +1454,9 @@ PRIVATE Config_Type Config_Table [] =
 #endif /* NO_RULES */
      PARSE_STR(RC_SAVE_SPACE,           lynx_save_space),
      PARSE_SET(RC_SCAN_FOR_BURIED_NEWS_REFS, scan_for_buried_news_references),
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+     PARSE_FUN(RC_SCREEN_SIZE,          screen_size_fun),
+#endif
 #ifdef USE_SCROLLBAR
      PARSE_SET(RC_SCROLLBAR,            LYShowScrollbar),
      PARSE_SET(RC_SCROLLBAR_ARROW,      LYsb_arrow),
@@ -1442,7 +1470,7 @@ PRIVATE Config_Type Config_Table [] =
      PARSE_Env(RC_SNEWSPOST_PROXY,      0),
      PARSE_Env(RC_SNEWSREPLY_PROXY,     0),
      PARSE_SET(RC_SOFT_DQUOTES,         soft_dquotes),
-#ifdef SOURCE_CACHE
+#ifdef USE_SOURCE_CACHE
      PARSE_ENU(RC_SOURCE_CACHE,         LYCacheSource, tbl_source_cache),
      PARSE_ENU(RC_SOURCE_CACHE_FOR_ABORTED, LYCacheSourceForAborted, tbl_abort_source_cache),
 #endif
diff --git a/src/LYStrings.c b/src/LYStrings.c
index a47d9356..e12d6cbc 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -2544,7 +2544,7 @@ PUBLIC char * LYTrimNewline ARGS1(
 	char *,		buffer)
 {
     size_t i = strlen(buffer);
-    while (i != 0 && buffer[i-1] == '\n')
+    while (i != 0 && (buffer[i-1] == '\n' || buffer[i-1] == '\r'))
 	buffer[--i] = 0;
     return buffer;
 }
diff --git a/src/LYStyle.c b/src/LYStyle.c
index 16ab70d3..08f5cd11 100644
--- a/src/LYStyle.c
+++ b/src/LYStyle.c
@@ -1,6 +1,6 @@
 /* character level styles for Lynx
  * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-)
- * @Id: LYStyle.c 1.52 Sun, 01 Jun 2003 18:16:28 -0700 dickey @
+ * @Id: LYStyle.c 1.53 Wed, 07 Jan 2004 18:03:09 -0800 dickey @
  */
 #include <HTUtils.h>
 #include <HTML.h>
@@ -191,10 +191,11 @@ PRIVATE void parse_attributes ARGS5(
 	int iBold = !!(cA & A_BOLD);
 	int iBlink = !!(cA & M_BLINK);
 
+	CTRACE((tfp, "FIXME:%d/%d %d/%d %#x\n", fA, default_fg, bA, default_bg, cA));
 	if (fA < MAX_COLOR
 	 && bA < MAX_COLOR
 #ifdef USE_CURSES_PAIR_0
-	 && (fA != default_fg || bA != default_bg)
+	 && (cA != A_NORMAL || fA != default_fg || bA != default_bg)
 #endif
 	 && curPair < 255) {
 	    if (our_pairs[iBold][iBlink][iFg][iBg] != 0) {
@@ -268,6 +269,7 @@ PRIVATE void parse_style ARGS1(char*, param)
 
     if (param == 0)
 	return;
+    CTRACE((tfp, "FIXME parse_style(%s)\n", param));
     StrAllocCopy(buffer, param);
     if (buffer == 0)
 	return;
diff --git a/src/LYUtils.c b/src/LYUtils.c
index ff2ede72..813c273c 100644
--- a/src/LYUtils.c
+++ b/src/LYUtils.c
@@ -191,6 +191,37 @@ PUBLIC char *LYGetEnv ARGS1(CONST char *, name)
 }
 
 /*
+ * ascii versions of locale sensitive functions needed because in
+ * Turkish locales tolower("I") is not "i". That's fatal for case
+ * sensitive operations with charset names, HTML tags etc.
+ */
+#ifdef EXP_ASCII_CTYPES
+PUBLIC int ascii_tolower ARGS1(int, i)
+{
+    if ( 91 > i && i > 64 )
+	return (i+32);
+    else
+	return i;
+}
+
+PUBLIC int ascii_toupper ARGS1(int, i)
+{
+    if ( 123 > i && i > 96 )
+	return (i-32);
+    else
+	return i;
+}
+
+PUBLIC int ascii_isupper ARGS1(int, i)
+{
+    if ( 91 > i && i > 64 )
+	return 1;
+    else
+	return 0;
+}
+#endif /* EXP_ASCII_CTYPES */
+
+/*
  * Check for UTF-8 data, returning the length past the first character.
  * Return zero if we found an ordinary character rather than UTF-8.
  */
@@ -1536,7 +1567,7 @@ PUBLIC int HTCheckForInterrupt NOARGS
     int c;
     int cmd;
 #ifndef VMS /* UNIX stuff: */
-#if !defined(USE_SLANG) && (defined(UNIX) || defined(__DJGPP__))
+#if !defined(USE_SLANG)
     struct timeval socket_timeout;
     int ret = 0;
     fd_set readfds;
@@ -5319,6 +5350,30 @@ PUBLIC void LYAddPathToHome ARGS3(
 }
 
 /*
+ * Given a filename, concatenate it to the save-space pathname, unless it is
+ * an absolute pathname.  If there is no save-space defined, use the home
+ * directory. Return a new string with the result.
+ */
+PUBLIC char * LYAddPathToSave ARGS1(
+	char *,		fname)
+{
+    char *result = NULL;
+
+    if (LYisAbsPath(fname)) {
+	StrAllocCopy(result, fname);
+    } else {
+	if (lynx_save_space != NULL) {
+	    StrAllocCopy(result, lynx_save_space);
+	} else {
+	    char temp[LY_MAXPATH];
+	    LYAddPathToHome(temp, sizeof(temp), fname);
+	    StrAllocCopy(result, temp);
+	}
+    }
+    return result;
+}
+
+/*
  *  This function takes a string in the format
  *	"Mon, 01-Jan-96 13:45:35 GMT" or
  *	"Mon,  1 Jan 1996 13:45:35 GMT"" or
@@ -5933,7 +5988,7 @@ PUBLIC FILE *LYOpenTemp ARGS3(
      * Verify if the given space looks secure enough.  Otherwise, make a
      * secure subdirectory of that.
      */
-#if defined(MULTI_USER_UNIX) && defined(HAVE_MKTEMP)
+#if defined(MULTI_USER_UNIX) && (defined(HAVE_MKTEMP) || defined(HAVE_MKDTEMP))
     if (lynx_temp_subspace == 0)
     {
 	BOOL make_it = FALSE;
@@ -6681,6 +6736,8 @@ PUBLIC void LYLocalFileToURL ARGS2(
     if (!LYisAbsPath(source)) {
 	char temp[LY_MAXPATH];
 	Current_Dir(temp);
+	if (!LYIsHtmlSep(*temp))
+	    LYAddHtmlSep(target);
 	StrAllocCat(*target, temp);
     }
     if (!LYIsHtmlSep(*leaf))
@@ -6931,6 +6988,33 @@ PUBLIC int LYCopyFile ARGS2(
     return code;
 }
 
+#ifdef __DJGPP__
+PRIVATE char *escape_backslashes ARGS1(char *, source)
+{
+    char *result = 0;
+    int count = 0;
+    int n;
+
+    for (n = 0; source[n] != '\0'; ++n) {
+	if (source[n] == '\\')
+	    ++count;
+    }
+    if (count != 0) {
+	result = malloc(count + n + 1);
+	if (result != 0) {
+	    int ch;
+	    char *target = result;
+	    while ((ch = *source++) != '\0') {
+		if (ch == '\\')
+		    *target++ = ch;
+		*target++ = ch;
+	    }
+	    *target = '\0';
+	}
+    }
+    return result;
+}
+#endif /* __DJGPP__ */
 /*
  * Invoke a shell command, return nonzero on error.
  */
@@ -7042,6 +7126,17 @@ PUBLIC int LYSystem ARGS1(
     }
 #endif
 
+#ifdef __DJGPP__
+    if (dj_is_bash) {
+	char *new_command = escape_backslashes(command);
+	if (new_command != 0) {
+	    if (do_free)
+		free(command);
+	    command = new_command;
+	}
+    }
+#endif /* __DJGPP__ */
+
 #ifdef _WIN_CC
     code = exec_command(command, TRUE);	/* Wait exec */
 #else /* !_WIN_CC */
@@ -7351,7 +7446,7 @@ PUBLIC void get_clip_release NOARGS
 
 PRIVATE int clip_grab NOARGS
 {
-    char *cmd = getenv ("RL_PASTE_CMD");
+    char *cmd = LYGetEnv("RL_PASTE_CMD");
 
     if (paste_handle)
 	pclose(paste_handle);
@@ -7397,7 +7492,7 @@ PUBLIC char* get_clip_grab NOARGS
 PUBLIC int
 put_clip ARGS1(char *, s)
 {
-    char *cmd = getenv ("RL_CLCOPY_CMD");
+    char *cmd = LYGetEnv("RL_CLCOPY_CMD");
     FILE *fh;
     int l = strlen(s), res;
 
diff --git a/src/LYUtils.h b/src/LYUtils.h
index 4c030db4..f86a04aa 100644
--- a/src/LYUtils.h
+++ b/src/LYUtils.h
@@ -130,6 +130,7 @@ extern FILE *LYOpenTemp PARAMS((char *result, CONST char *suffix, CONST char *mo
 extern FILE *LYOpenTempRewrite PARAMS((char *result, CONST char *suffix, CONST char *mode));
 extern FILE *LYReopenTemp PARAMS((char *name));
 extern char *Current_Dir PARAMS((char * pathname));
+extern char *LYAddPathToSave PARAMS((char *fname));
 extern char *LYGetEnv PARAMS((CONST char * name));
 extern char *LYGetHiliteStr PARAMS(( int cur, int count));
 extern char *LYLastPathSep PARAMS((CONST char *path));
@@ -192,6 +193,12 @@ extern void size_change PARAMS((int sig));
 extern void statusline PARAMS((CONST char *text));
 extern void toggle_novice_line NOPARAMS;
 
+#ifdef EXP_ASCII_CTYPES
+extern int ascii_tolower PARAMS((int i));
+extern int ascii_toupper PARAMS((int i));
+extern int ascii_isupper PARAMS((int i));
+#endif
+
 #ifdef __CYGWIN__
 extern int Cygwin_Shell PARAMS((void));
 #endif
diff --git a/src/LYrcFile.c b/src/LYrcFile.c
index e8ae7fe6..781d5964 100644
--- a/src/LYrcFile.c
+++ b/src/LYrcFile.c
@@ -98,7 +98,7 @@ PUBLIC Config_Enum tbl_transfer_rate[] = {
     { "TRUE",		rateKB },
     { "BYTES",		rateBYTES },
     { "FALSE",		rateBYTES },
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
     { "KB,ETA",		rateEtaKB },
     { "BYTES,ETA",	rateEtaBYTES },
 #endif
@@ -122,7 +122,7 @@ PRIVATE Config_Enum tbl_visited_links[] = {
 };
 
 PUBLIC Config_Enum tbl_force_prompt[] = {
-    { "default",	FORCE_PROMPT_DFT	},
+    { "prompt",		FORCE_PROMPT_DFT	},
     { "yes",		FORCE_PROMPT_YES	},
     { "no",		FORCE_PROMPT_NO		},
     { NULL,		-1			}
@@ -323,7 +323,7 @@ all cookies.  If a domain is specified in both options, rejection will\n\
 take precedence.  The accept_all_cookies parameter will override any\n\
 settings made here.\n\
 ")),
-#ifdef EXP_PERSISTENT_COOKIES
+#ifdef USE_PERSISTENT_COOKIES
     PARSE_STR(RC_COOKIE_FILE,	        LYCookieFile, N_("\
 cookie_file specifies the file from which to read persistent cookies.\n\
 The default is ~/.lynx_cookies.\n\
@@ -513,7 +513,7 @@ honored only if enabled via userdefs.h and/or lynx.cfg, and not\n\
 restricted via a command line switch.  If display of hidden files\n\
 is disabled, creation of such files via Lynx also is disabled.\n\
 ")),
-#ifdef EXP_READPROGRESS
+#ifdef USE_READPROGRESS
     MAYBE_ENU(RC_SHOW_KB_RATE,          LYTransferRate,    tbl_transfer_rate,
 	      MSG_ENABLE_LYNXRC),
 #endif
diff --git a/src/LYrcFile.h b/src/LYrcFile.h
index 8718bfbd..ad6c4086 100644
--- a/src/LYrcFile.h
+++ b/src/LYrcFile.h
@@ -173,6 +173,7 @@
 #define RC_RUN_EXECUTION_LINKS_LOCAL    "run_execution_links_on_local_files"
 #define RC_SAVE_SPACE                   "save_space"
 #define RC_SCAN_FOR_BURIED_NEWS_REFS    "scan_for_buried_news_refs"
+#define RC_SCREEN_SIZE                  "screen_size"
 #define RC_SCROLLBAR                    "scrollbar"
 #define RC_SCROLLBAR_ARROW              "scrollbar_arrow"
 #define RC_SEEK_FRAG_AREA_IN_CUR        "seek_frag_area_in_cur"
diff --git a/src/TRSTable.c b/src/TRSTable.c
index f905f68c..7fbd6631 100644
--- a/src/TRSTable.c
+++ b/src/TRSTable.c
@@ -17,19 +17,11 @@
 #ifdef SAVE_TIME_NOT_SPACE
 #define CELLS_GROWBY 16
 #define ROWS_GROWBY 16
-#define ROWS_GROWBY_DIVISOR 2
-#else  /* This is very silly, and leads to *larger* memory consumption... */
+#else
 #define CELLS_GROWBY 2
 #define ROWS_GROWBY 2
-#define ROWS_GROWBY_DIVISOR 10
 #endif
 
-#define  REUSE_ROWS_AS_CELLS_POOLS 0	/* Turns out to be not beneficial */
-
-/* Experiments show that 2 is better than 1.5 is better than 1.25 (all by
-   a small margin only)??? */
-#define CELLS_GROWBY_FACTOR 2
-
 #ifdef USE_CURSES_PADS
 #  define MAX_STBL_POS (LYwideLines ? MAX_COLS - 1 : LYcols-1)
 #else
@@ -79,10 +71,10 @@ typedef struct _STable_cellinfo {
 				   contentless cells (and cells we do
 				   not want to measure and count?),
 				   line-of-the-start otherwise.  */
-	short	pos;		/* column where cell starts */
-	short	len;		/* number of character positions */
-	short	colspan;	/* number of columns to span */
-	short	alignment;	/* one of HT_LEFT, HT_CENTER, HT_RIGHT,
+	int	pos;		/* column where cell starts */
+	int	len;		/* number of character positions */
+	int	colspan;	/* number of columns to span */
+	int	alignment;	/* one of HT_LEFT, HT_CENTER, HT_RIGHT,
 				   or RESERVEDCELL */
 } STable_cellinfo;
 
@@ -98,13 +90,12 @@ enum ended_state {
 #define OFFSET_IS_VALID			8
 #define OFFSET_IS_VALID_LAST_CELL	0x10
 #define BELIEVE_OFFSET			0x20
-#define IS_CONTINUATION_OF_MULTICELL	0x40
 
 typedef struct _STable_rowinfo {
     /* Each row may be displayed on many display lines, but we fix up
        positions of cells on this display line only: */
 	int	Line;		/* lineno in doc (zero-based) */
-	short	ncells;		/* number of table cells */
+	int	ncells;		/* number of table cells */
 
     /* What is the meaning of this?!  It is set if:
        [search for	def of fixed_line	below]
@@ -128,25 +119,15 @@ typedef struct _STable_rowinfo {
        REMARK: If this variable is not set, but icell_core is, Line is
        reset to the line of icell_core.
      */
-	short	fixed_line;	/* if we have a 'core' line of cells */
+	BOOL	fixed_line;	/* if we have a 'core' line of cells */
 	enum ended_state ended;	/* if we saw </tr> etc */
-	short	content;	/* Whether contains end-of-cell etc */
-	short	offset;		/* >=0 after line break in a multiline cell */
-	short	allocated;	/* number of table cells allocated or 0
-				   if the .cells should not be free()ed */
-	short	alignment;	/* global align attribute for this row */
+	int	content;	/* Whether contains end-of-cell etc */
+	int	offset;		/* >=0 after line break in a multiline cell */
+	int	allocated;	/* number of table cells allocated */
 	STable_cellinfo * cells;
+	int	alignment;	/* global align attribute for this row */
 } STable_rowinfo;
 
-struct _STable_chunk;
-typedef struct _STable_chunk {
-    struct _STable_chunk *next;
-    int alloc_cells;
-    int used_cells;
-    STable_cellinfo cells[1];
-} STable_chunk;
-
-
 struct _STable_info {
 #ifdef EXP_NESTED_TABLES
 	struct _STable_info *enclosing;	/* The table which contain us */
@@ -159,8 +140,7 @@ struct _STable_info {
 	int	maxpos;		/* max. of max. cell pos's of any row */
 	int	allocated_rows; /* number of rows allocated */
 	int	allocated_sumcols;	/* number of sumcols allocated */
-	int	ncolinfo;	/* number of COL info collected */
-	int	last_reserved;	/* -1 or last line with reserved cells */
+	int	ncolinfo;		/* number of COL info collected */
 	STable_cellinfo * sumcols; /* for summary (max len/pos) col info */
 	STable_rowinfo * rows;
 	STable_rowinfo	rowspans2eog;
@@ -169,8 +149,6 @@ struct _STable_info {
 	short	pending_colgroup_align;
 	int	pending_colgroup_next;
 	STable_states s;
-	STable_chunk *free_chunks;
-	STable_chunk *used_chunks;
 };
 
 /*
@@ -227,7 +205,7 @@ PRIVATE int Stbl_finishCellInRow PARAMS((
     int			end_td,
     int			lineno,
     int			pos));
-PRIVATE int Stbl_DOfinishRowInTable PARAMS((
+PRIVATE int Stbl_finishRowInTable PARAMS((
     STable_info *	me));
 
 PRIVATE CONST char * cellstate_s ARGS1(
@@ -266,12 +244,10 @@ PUBLIC struct _STable_info * Stbl_startTABLE ARGS1(
 	me->pending_colgroup_align = HT_ALIGN_NONE;
 	me->s.x_td = -1;
 	me->s.icell_core = -1;
-	me->last_reserved = -1;
 #ifdef EXP_NESTED_TABLES
 	if (nested_tables)
 	    me->enclosing = 0;
 #endif
-	me->used_chunks = me->free_chunks = NULL;
     }
     return me;
 }
@@ -284,95 +260,6 @@ PRIVATE void free_rowinfo ARGS1(
     }
 }
 
-PRIVATE int addmem_rowinfo ARGS2(
-    STable_info *,	me,
-    int,		incr)
-{
-    int i;
-    int growby = 0;
-    STable_rowinfo *rows, *row;
-
-    while (me->nrows + incr + 1 > me->allocated_rows + growby)
-	growby += ROWS_GROWBY + me->allocated_rows/ROWS_GROWBY_DIVISOR;
-    if (growby) {
-	if (me->allocated_rows == 0 && !me->rows) {
-	    rows = typecallocn(STable_rowinfo, growby);
-	} else {
-#if REUSE_ROWS_AS_CELLS_POOLS		/* Turns out to be not beneficial */
-	    /* Work in a regime which has a chance to work efficiently
-	       even with lousy malloc()s: do not realloc() until we
-	       have many (2) free chunks available (possible with very
-	       simple structure of each row).  Simultaneously,
-	       make it possible to use an effecient realloc() which
-	       would grow the region in place - so DO use realloc() if
-	       we already have many free chunks to put the cellinfo into.
-	     */
-	    if ( me->free_chunks && me->free_chunks->next
-		 || (me->allocated_rows*sizeof(STable_rowinfo) <
-		    (sizeof(STable_chunk)
-		     + (CELLS_GROWBY-1)*sizeof(STable_cellinfo)))
-		 || 1)
-#endif
-	    {
-		rows = realloc(me->rows,
-			       (me->allocated_rows + growby)
-			       * sizeof(STable_rowinfo));
-	    }
-#if REUSE_ROWS_AS_CELLS_POOLS
-	    else {
-		rows = malloc((me->allocated_rows + growby)
-			      * sizeof(STable_rowinfo));
-		if (rows) {
-		    STable_chunk *p;
-
-		    memcpy(rows, me->rows,
-			   (me->allocated_rows + growby)
-			   * sizeof(STable_rowinfo));
-		    p = (STable_chunk*)me->rows;
-		    p->alloc_cells =
-			1 + (me->allocated_rows*sizeof(STable_rowinfo)
-			     - sizeof(STable_chunk))/sizeof(STable_cellinfo);
-		    p->used_cells = 0;
-		    p->next = me->free_chunks;
-		    me->free_chunks = p;
-		}
-	    }
-#endif
-	    for (i = 0; rows && i < growby; i++) {
-		row = rows + me->allocated_rows + i;
-		if (!me->rowspans2eog.allocated) {
-		    row->allocated = 0;
-		    row->cells = NULL;
-		} else {
-		    row->cells = typecallocn(STable_cellinfo,
-					     me->rowspans2eog.allocated);
-		    if (row->cells) {
-			row->allocated = me->rowspans2eog.allocated;
-			memcpy(row->cells, me->rowspans2eog.cells,
-			       row->allocated * sizeof(STable_cellinfo));
-		    } else {
-			FREE(rows);
-			break;
-		    }
-		}
-		row->ncells = 0;
-		row->fixed_line = NO;
-		row->alignment = HT_ALIGN_NONE;
-		row->offset = 0;
-		row->content = 0;
-	    }
-	}
-	if (rows) {
-	    me->allocated_rows += growby;
-	    me->rows = rows;
-	} else {
-	    return 0;
-	}
-    }
-    return 1;
-}
-
-
 PUBLIC void Stbl_free ARGS1(
     STable_info *,	me)
 {
@@ -387,17 +274,6 @@ PUBLIC void Stbl_free ARGS1(
     free_rowinfo(&me->rowspans2eog);
     if (me)
 	FREE(me->sumcols);
-    if (me) {
-	STable_chunk *this;
-	while ((this = me->free_chunks)) {
-	    me->free_chunks = this->next;
-	    FREE(this);
-	}
-	while ((this = me->used_chunks)) {
-	    me->used_chunks = this->next;
-	    FREE(this);
-	}
-    }
     FREE(me);
 }
 
@@ -1072,7 +948,9 @@ PRIVATE int Stbl_reserveCellsInTable ARGS4(
     int,		colspan,
     int,		rowspan)
 {
-    int i, last;
+    STable_rowinfo *rows, *row;
+    int growby;
+    int i;
 
     if (me->nrows <= 0)
 	return -1;		/* must already have at least one row */
@@ -1091,13 +969,39 @@ PRIVATE int Stbl_reserveCellsInTable ARGS4(
 	Stbl_reserveCellsInRow(&me->rowspans2eog, icell, colspan);
     }
 
-    if (!addmem_rowinfo(me, rowspan - 1))
-	return 0; /* ignore silently, no free memory, may be recoverable */
-
-    last = (rowspan == 0 ? me->allocated_rows : me->nrows + rowspan - 1);
-    if (me->last_reserved < last)
-	me->last_reserved = last;
-    for (i = me->nrows; i < last; i++) {
+    growby = me->nrows + rowspan - 1 - me->allocated_rows;
+    if (growby > 0) {
+	rows = realloc(me->rows,
+		       (me->allocated_rows + growby)
+		       * sizeof(STable_rowinfo));
+	if (!rows)
+	    return 0; /* ignore silently, no free memory, may be recoverable */
+	for (i = 0; i < growby; i++) {
+	    row = rows + me->allocated_rows + i;
+	    row->allocated = 0;
+	    row->offset = 0;
+	    row->content = 0;
+	    if (!me->rowspans2eog.allocated) {
+		row->cells = NULL;
+	    } else {
+		row->cells = typecallocn(STable_cellinfo,
+					 me->rowspans2eog.allocated);
+		if (row->cells) {
+		    row->allocated = me->rowspans2eog.allocated;
+		    memcpy(row->cells, me->rowspans2eog.cells,
+			   row->allocated * sizeof(STable_cellinfo));
+		}
+	    }
+	    row->ncells = 0;
+	    row->fixed_line = NO;
+	    row->alignment = HT_ALIGN_NONE;
+	}
+	me->allocated_rows += growby;
+	me->rows = rows;
+    }
+    for (i = me->nrows;
+	 i < (rowspan == 0 ? me->allocated_rows : me->nrows + rowspan - 1);
+	 i++) {
 	if (!me->rows[i].allocated) {
 	    me->rows[i].cells = typecallocn(STable_cellinfo, icell + colspan);
 	    if (!me->rows[i].cells)
@@ -1136,6 +1040,7 @@ PUBLIC int Stbl_addRowToTable ARGS3(
     int,		alignment,
     int,		lineno)
 {
+    STable_rowinfo *rows, *row;
     STable_states * s = &me->s;
 
     CTRACE2(TRACE_TRST,
@@ -1146,14 +1051,56 @@ PUBLIC int Stbl_addRowToTable ARGS3(
 	    me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len;
 	s->pending_len = 0;
     }
-    Stbl_DOfinishRowInTable(me);
+    Stbl_finishRowInTable(me);
     if (me->nrows > 0 && me->rows[me->nrows-1].Line == lineno)
 	me->rows[me->nrows-1].Line = -1;
     s->pending_len = 0;
     s->x_td = -1;
 
-    if (!addmem_rowinfo(me, 1))
-	return -1;
+    {
+	int i;
+	int growby = 0;
+	while (me->nrows + 2 > me->allocated_rows + growby)
+	    growby += ROWS_GROWBY;
+	if (growby) {
+	    if (me->allocated_rows == 0 && !me->rows) {
+		rows = typecallocn(STable_rowinfo, growby);
+	    } else {
+		rows = realloc(me->rows,
+				  (me->allocated_rows + growby)
+				  * sizeof(STable_rowinfo));
+		for (i = 0; rows && i < growby; i++) {
+		    row = rows + me->allocated_rows + i;
+		    if (!me->rowspans2eog.allocated) {
+			row->allocated = 0;
+			row->cells = NULL;
+		    } else {
+			row->cells = typecallocn(STable_cellinfo,
+						 me->rowspans2eog.allocated);
+			if (row->cells) {
+			    row->allocated = me->rowspans2eog.allocated;
+			    memcpy(row->cells, me->rowspans2eog.cells,
+				   row->allocated * sizeof(STable_cellinfo));
+			} else {
+			    FREE(rows);
+			    break;
+			}
+		    }
+		    row->ncells = 0;
+		    row->fixed_line = NO;
+		    row->alignment = HT_ALIGN_NONE;
+		    row->offset = 0;
+		    row->content = 0;
+		}
+	    }
+	    if (rows) {
+		me->allocated_rows += growby;
+		me->rows = rows;
+	    } else {
+		return -1;
+	    }
+	}
+    }
 
     me->rows[me->nrows].Line = lineno;
     if (me->nrows == 0)
@@ -1164,49 +1111,6 @@ PUBLIC int Stbl_addRowToTable ARGS3(
 	me->rows[me->nrows].alignment =
 	    (me->rowgroup_align==HT_ALIGN_NONE) ?
 				  me->alignment : me->rowgroup_align;
-    if (me->nrows >= 2	/* We may use RESERVEDCELL flag of cells in nrows-1 */
-	&& me->rows[me->nrows - 2].allocated > me->rows[me->nrows - 2].ncells) {
-	int c = me->rows[me->nrows - 2].ncells;
-	STable_cellinfo *p  = me->rows[me->nrows - 2].cells;
-
-#if 0	/* Leads to no memory savings and quadratic time with EMX malloc */
-	/* Do not need extra cells any more */
-	me->rows[me->nrows - 2].cells = realloc(p,c * sizeof(STable_cellinfo));
-	me->rows[me->nrows - 2].allocated = me->rows[me->nrows - 2].ncells;
-#else
-	if (!me->used_chunks
-	    || ((me->used_chunks->alloc_cells - me->used_chunks->used_cells)
-		< c)) {
-	    if (me->free_chunks && (me->free_chunks->alloc_cells >= c)) {
-	        STable_chunk *p2 = me->free_chunks;
-
-		me->free_chunks = p2->next;
-		p2->next = me->used_chunks;
-		me->used_chunks = p2;
-	    } else {			/* Need to get a new guy */
-	        STable_chunk *p2;
-
-		if (c < CELLS_GROWBY)
-		    c = CELLS_GROWBY;
-		if ( me->used_chunks
-		     && c < me->used_chunks->alloc_cells*CELLS_GROWBY_FACTOR )
-		    c = 2*me->used_chunks->alloc_cells * CELLS_GROWBY_FACTOR;
-		p2 = malloc(sizeof(STable_chunk) + (c-1)*sizeof(STable_cellinfo));
-		p2->alloc_cells = c;
-		p2->used_cells = 0;
-		p2->next = me->used_chunks;
-		me->used_chunks = p2;
-	    }
-	}
-	memcpy(me->used_chunks->cells + me->used_chunks->used_cells,
-	       p, me->rows[me->nrows - 2].ncells * sizeof(STable_cellinfo));
-	me->rows[me->nrows - 2].cells =
-	    me->used_chunks->cells + me->used_chunks->used_cells;
-	me->used_chunks->used_cells += me->rows[me->nrows - 2].ncells;
-	me->rows[me->nrows - 2].allocated = 0; /* Do not FREE() */
-	FREE(p);
-#endif
-    }
     me->nrows++;
     if (me->pending_colgroup_next > me->ncolinfo) {
 	me->ncolinfo = me->pending_colgroup_next;
@@ -1220,20 +1124,19 @@ PUBLIC int Stbl_addRowToTable ARGS3(
 /*
  * Returns -1 on error, otherwise current number of rows.
  */
-PRIVATE int Stbl_DOfinishRowInTable ARGS1(
+PRIVATE int Stbl_finishRowInTable ARGS1(
     STable_info *,	me)
 {
     STable_rowinfo *lastrow;
     STable_states * s = &me->s;
     int ncells;
 
-    CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_DOfinishRowInTable()\n"));
+    CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_finishRowInTable()\n"));
     if (!me->rows || !me->nrows)
 	return -1;		/* no row started! */
     lastrow = me->rows + (me->nrows - 1);
     ncells = lastrow->ncells;
-    if (lastrow->ended != ROW_ended_by_splitline)
-	lastrow->ended = ROW_ended_by_endtr;
+    lastrow->ended = ROW_ended_by_endtr;
     if (lastrow->ncells > 0) {
 	if (s->pending_len > 0)
 	    lastrow->cells[lastrow->ncells - 1].len = s->pending_len;
@@ -1366,17 +1269,11 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4(
 	int prev_reserved_last = -1;
 	STable_rowinfo *prev_row;
 	int prev_row_n2 = lastrow - me->rows;
-	int is_multicell = 0;
 
 	CTRACE2(TRACE_TRST,
 		(tfp, "TRST:Stbl_fakeFinishCellInTable(lineno=%d, finishing=%d) START FAKING\n",
 		      lineno, finishing));
 
-	if ( lastrow->ncells > 1
-	     && (lastrow->cells[lastrow->ncells - 2].pos
-		 != lastrow->cells[lastrow->ncells - 1].pos))
-	    is_multicell = 1;
-
 	/* Although here we use pos=0, this may commit the previous
 	   cell which had <BR> as a last element.  This may overflow
 	   the screen width, so the additional checks performed in
@@ -1398,10 +1295,6 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4(
 	}
 	lastrow = me->rows + (me->nrows - 1);
 	lastrow->content = IS_CONTINUATION_OF_CELL;
-	if (is_multicell)
-	    lastrow->content = IS_CONTINUATION_OF_MULTICELL;
-	else
-	    lastrow->content = IS_CONTINUATION_OF_CELL;
 	for (i = 0; i < lastrow->allocated; i++) {
 	    if (lastrow->cells[i].alignment == RESERVEDCELL) {
 		need_reserved = 1;
@@ -1438,13 +1331,11 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4(
 	    lastrow = me->rows + (me->nrows - 1);
 	    prev_row = me->rows + prev_row_n;
 	    me->allocated_rows++;
-	    me->last_reserved++;
 
 	    /* Insert a duplicate row after lastrow */
 	    for (n = me->allocated_rows - me->nrows - 1; n >= 0; --n)
 		lastrow[n + 1] = lastrow[n];
 
-	    lastrow[1].content = 0;
 	    /* Ignore cells, they belong to the next row now */
 	    lastrow->allocated = 0;
 	    lastrow->cells = 0;
@@ -1609,116 +1500,6 @@ PUBLIC int Stbl_addCellToTable ARGS8(
     return 0;
 }
 
-PUBLIC BOOL Stbl_at_start_of_cell ARGS3(
-    STable_info *,	me,
-    int,		lineno,
-    int,		pos)
-{
-    STable_rowinfo *lastrow;
-    int icell;
-
-    CTRACE2(TRACE_TRST,
-	    (tfp, "TRST:Stbl_at_start_of_cell(lineno=%d, pos=%d): ",
-		  lineno, pos));
-    if (me->nrows == 0)
-	goto yes;
-    lastrow = me->rows + (me->nrows - 1);
-    if (lastrow->ended != ROW_not_ended)
-	goto no;			/* E.g., may be processing </tr> */
-    icell = lastrow->ncells - 1;
-    if (icell < 0)
-	goto yes;
-    if (lastrow->cells[icell].cLine != lineno
-	|| lastrow->cells[icell].pos != pos) {
-      no:
-	CTRACE2(TRACE_TRST, (tfp, "no\n"));
-	return FALSE;			/* XXXX  What to do if cLine is -1? */
-    }
-  yes:
-    CTRACE2(TRACE_TRST, (tfp, "yes\n"));
-    return TRUE;
-}
-
-PUBLIC void Stbl_finishRowInTable ARGS1(
-    STable_info *,	me)
-{
-    STable_rowinfo *lastrow;
-
-    CTRACE2(TRACE_TRST,
-	    (tfp, "TRST:Stbl_finishRowInTable()\n"));
-    if (me->nrows <= 0)
-	return;
-    lastrow = me->rows + (me->nrows - 1);
-    if (lastrow->ended == ROW_not_ended)
-	lastrow->ended = ROW_ended_by_endtr;
-}
-
-/* Assumes that the current pos is at beginning of line.
-   Checks whether the last row was a fake row, and undo it if possible.
-   Returns TRUE if the last line (empty!) can be safely trimmed. */
-PUBLIC int Stbl_trimFakeRows ARGS3(
-    STable_info *,	me,
-    int,		lineno,
-    int,		pos GCC_UNUSED)
-{
-    STable_rowinfo *prevrow, *lastrow;
-    int icell;
-
-    CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_trimFakeRows()\n"));
-
-    /* XXXX The logic may be much better if we support removal of
-       RESERVED cells.  Until this is done, bail out early: */
-    if (me->nrows <= 0 || me->nrows <= me->last_reserved)
-	return 0;
-    lastrow = me->rows + (me->nrows - 1);
-    icell = lastrow->ncells - 1;
-    if (icell >= 0 && lastrow->cells[icell].cLine < lineno) {
-	/* The last cell start on a preceeding line; keep lastrow */
-	lastrow->ended = ROW_not_ended; /* Give it new life */
-	/* We do not use state info for a lot of things any more, so do
-	   not try to do anything special here */
-	me->s.state = CS__0new;		/* This is enough to revive things. */
-	me->s.x_td = lastrow->cells[lastrow->ncells - 1].pos;
-	me->s.lineno = lastrow->cells[lastrow->ncells - 1].cLine;
-	CTRACE2(TRACE_TRST, (tfp, "  un-ended the last row.\n"));
-	return 1;
-    }
-    if (me->nrows <= 1 || !(lastrow->content & IS_CONTINUATION_OF_CELL))
-	return 0;
-    prevrow = me->rows + (me->nrows - 2);
-    if (prevrow->ncells != icell + 1)	/* Empty cells were added after the break */
-	return 0;
-    if ( prevrow->ended != ROW_ended_by_splitline) /* Lastrow non-fake */
-	return 0;
-    me->nrows--;
-    /* prevrow is now the last row, so its cells should be realloc()able */
-    if (prevrow->cells && prevrow->allocated == 0) { /* Moved to pool */
-	int c = prevrow->ncells;
-	STable_cellinfo *p;
-
-	if (lastrow->allocated > c)	/* May have RESERVED info */
-	    c = lastrow->allocated;
-	p = malloc(c * sizeof(STable_cellinfo));
-	memcpy(p, prevrow->cells, prevrow->ncells * sizeof(STable_cellinfo));
-	/* Copy back the possibly present RESERVED info.
-	   XXXX remove duplicated RESERVED stuff from the followup rows too! */
-	memcpy(p + prevrow->ncells, lastrow->cells + prevrow->ncells,
-	       (c - prevrow->ncells) * sizeof(STable_cellinfo));
-	prevrow->cells = p;	/* XXXX How would ride with RESERVED? */
-	prevrow->allocated = c;
-    }
-    lastrow->ncells = 0;
-    lastrow->content = 0;
-    prevrow->ended = ROW_not_ended;	/* Give it new life */
-    /* We do not use state info for a lot of things any more, so do
-       not try to do anything special here */
-    me->s.state = CS__0new;
-    me->s.x_td = prevrow->cells[prevrow->ncells - 1].pos;
-    me->s.lineno = prevrow->cells[prevrow->ncells - 1].cLine;
-    CTRACE2(TRACE_TRST, (tfp, "  Removed the last row.\n"));
-    return 1;
-}
-
 /*
  * Returns -1 on error, otherwise 0.
  */
@@ -1945,7 +1726,7 @@ PUBLIC int Stbl_finishTABLE ARGS1(
 	    me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len = s->pending_len;
 	s->pending_len = 0;
     }
-    Stbl_DOfinishRowInTable(me);
+    Stbl_finishRowInTable(me);
     /* take into account offsets on multi-line cells.
        XXX We cannot do it honestly, since two cells on the same row may
        participate in multi-line table entries, and we preserve only
@@ -2124,18 +1905,11 @@ PUBLIC int Stbl_getFixupPositions ARGS4(
     STable_rowinfo * row;
     int j;
     int ninserts = -1;
-    static int prev_row = 0;
-
     if (!me || !me->nrows)
 	return -1;
-    if (prev_row < me->nrows && me->rows[prev_row].Line <= lineno)
-	j = prev_row;
-    else
-	j = 0;
-    for ( ; j < me->nrows; j++) {
+    for (j = 0; j < me->nrows; j++) {
 	row = me->rows + j;
 	if (row->Line == lineno) {
-	    prev_row = j;
 	    ninserts = get_fixup_positions(row, oldpos, newpos,
 					   me->sumcols);
 	    break;
diff --git a/src/TRSTable.h b/src/TRSTable.h
index 0c162d9c..8512bc2b 100644
--- a/src/TRSTable.h
+++ b/src/TRSTable.h
@@ -8,16 +8,13 @@
 typedef struct _STable_info STable_info;
 extern STable_info * Stbl_startTABLE PARAMS((short));
 extern int Stbl_finishTABLE PARAMS((STable_info *));
-extern void Stbl_finishRowInTable PARAMS((STable_info *));
 extern void Stbl_free PARAMS((STable_info *));
 extern int Stbl_addRowToTable PARAMS((STable_info *, int, int));
 extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int, int, int));
-extern BOOL Stbl_at_start_of_cell PARAMS((STable_info *, int, int));
 extern int Stbl_finishCellInTable PARAMS((STable_info *, int, int, int, int));
 extern int Stbl_addColInfo PARAMS((STable_info *, int, short, BOOL));
 extern int Stbl_finishColGroup PARAMS((STable_info *));
 extern int Stbl_addRowGroup PARAMS((STable_info *, short));
-extern int Stbl_trimFakeRows PARAMS((STable_info *, int, int));
 
 #define TRST_ENDCELL_ENDTD	1
 #define TRST_ENDCELL_LINEBREAK	0
diff --git a/src/UCdomap.c b/src/UCdomap.c
index a42c34b1..1e4c6cff 100644
--- a/src/UCdomap.c
+++ b/src/UCdomap.c
@@ -69,6 +69,7 @@
 #include <viscii_uni.h>		/* Vietnamese (VISCII)	*/
 #include <cp866u_uni.h>		/* Ukrainian Cyrillic (866) */
 #include <koi8u_uni.h>		/* Ukrainian Cyrillic (koi8-u */
+#include <pt154_uni.h>		/* Cyrillic-Asian (PT154) */
 
 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
 int auto_display_charset = -1;
@@ -648,7 +649,7 @@ PUBLIC int UCLYhndl_for_unrec = -1;
  /* easy to type, will initialize later */
 PUBLIC int LATIN1 = -1;        /* UCGetLYhndl_byMIME("iso-8859-1") */
 PUBLIC int US_ASCII = -1;      /* UCGetLYhndl_byMIME("us-ascii")   */
-PUBLIC int UTF8 = -1;          /* UCGetLYhndl_byMIME("utf-8")      */
+PUBLIC int UTF8_handle = -1;   /* UCGetLYhndl_byMIME("utf-8")      */
 PUBLIC int TRANSPARENT = -1;   /* UCGetLYhndl_byMIME("x-transparent")  */
 
 
@@ -2075,6 +2076,7 @@ PUBLIC void UCInit NOARGS
     UC_CHARSET_SETUP_mnemonic;		  /* RFC 1345 Mnemonic	  */
     UC_CHARSET_SETUP_cp866u;		  /* Ukrainian Cyrillic (866) */
     UC_CHARSET_SETUP_koi8_u;		  /* Ukrainian Cyrillic (koi8-u) */
+    UC_CHARSET_SETUP_ptcp154;		  /* Cyrillic-Asian (PT154) */
 
 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
 #  ifdef __EMX__
@@ -2108,7 +2110,7 @@ PUBLIC void UCInit NOARGS
 /* for coding/performance - easy to type: */
     LATIN1   = UCGetLYhndl_byMIME("iso-8859-1");
     US_ASCII = UCGetLYhndl_byMIME("us-ascii");
-    UTF8     = UCGetLYhndl_byMIME("utf-8");
+    UTF8_handle = UCGetLYhndl_byMIME("utf-8");
     TRANSPARENT = UCGetLYhndl_byMIME("x-transparent");
 }
 
diff --git a/src/chrtrans/build-chrtrans.com b/src/chrtrans/build-chrtrans.com
index 0ba35058..ac8c932d 100644
--- a/src/chrtrans/build-chrtrans.com
+++ b/src/chrtrans/build-chrtrans.com
@@ -114,6 +114,7 @@ $ makeuctb mnem_suni.tbl
 $ makeuctb mnem2_suni.tbl
 $ makeuctb mnem_suni.tbl
 $ makeuctb next_uni.tbl
+$ makeuctb pt154_uni.tbl
 $ makeuctb rfc_suni.tbl
 $ makeuctb utf8_uni.tbl
 $ makeuctb viscii_uni.tbl
diff --git a/src/chrtrans/make-msc.bat b/src/chrtrans/make-msc.bat
index e17389cb..7d7ca0f7 100644
--- a/src/chrtrans/make-msc.bat
+++ b/src/chrtrans/make-msc.bat
@@ -43,6 +43,7 @@ makeuctb mnem_suni.tbl
 makeuctb mnem2_suni.tbl

 makeuctb mnem_suni.tbl

 makeuctb next_uni.tbl

+makeuctb pt154_uni.tbl

 makeuctb rfc_suni.tbl

 makeuctb utf8_uni.tbl

 makeuctb viscii_uni.tbl

diff --git a/src/chrtrans/makefile.bcb b/src/chrtrans/makefile.bcb
index 04b9585b..bc70b798 100644
--- a/src/chrtrans/makefile.bcb
+++ b/src/chrtrans/makefile.bcb
@@ -112,3 +112,11 @@ BccW32.cfg :
 -v-
 | $@
 
+clean :
+	-del *_uni.h
+	-del *.exe
+	-del *.map
+	-del *.obj
+	-del *.tds
+	-del BccW32.cfg
+	-del /f/s/q *.i
diff --git a/src/chrtrans/makefile.dos b/src/chrtrans/makefile.dos
index 03bb135d..1ee118c7 100644
--- a/src/chrtrans/makefile.dos
+++ b/src/chrtrans/makefile.dos
@@ -64,6 +64,7 @@ TABLES= \
  mnem2_suni.h \
  mnem_suni.h \
  next_uni.h \
+ pt154_uni.h \
  rfc_suni.h \
  utf8_uni.h \
  viscii_uni.h
@@ -116,6 +117,7 @@ mac_uni.h:		mac_uni.tbl		makeuctb.exe
 mnem2_suni.h:		mnem2_suni.tbl		makeuctb.exe
 mnem_suni.h:		mnem_suni.tbl		makeuctb.exe
 next_uni.h:		next_uni.tbl		makeuctb.exe
+pt154_uni.h:		pt154_uni.tbl		makeuctb.exe
 rfc_suni.h:		rfc_suni.tbl		makeuctb.exe
 utf8_uni.h:		utf8_uni.tbl		makeuctb.exe
 viscii_uni.h:		viscii_uni.tbl		makeuctb.exe
diff --git a/src/chrtrans/makefile.in b/src/chrtrans/makefile.in
index d399a0e5..3db427e3 100644
--- a/src/chrtrans/makefile.in
+++ b/src/chrtrans/makefile.in
@@ -6,8 +6,6 @@
 #
 SHELL		= @CONFIG_SHELL@
 
-x		= @PROG_EXT@
-
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
 top_srcdir	= @top_srcdir@
@@ -29,7 +27,9 @@ SITE_DEFS	= # FIXME: set in parent makefile
 CC		= @CC@
 CPP		= @CPP@
 CFLAGS		= @CFLAGS@
-_O		= .o
+
+x		= @EXEEXT@
+o		= .@OBJEXT@
 
 CPP_OPTS	= @DEFS@ @CPPFLAGS@ \
 		-I$(top_builddir) \
@@ -86,6 +86,8 @@ TABLES= \
  mnem2_suni.h \
  mnem_suni.h \
  next_uni.h \
+ next_uni.h \
+ pt154_uni.h \
  rfc_suni.h \
  utf8_uni.h \
  viscii_uni.h
@@ -94,14 +96,14 @@ default: $(FONTMAP_INC)
 
 tables: $(TABLES)
 
-makeuctb$x: makeuctb$(_O)
-	$(CC) $(CC_OPTS) $(LDFLAGS) -o $@ makeuctb$(_O) $(INTLLIB) $(LIBS)
+makeuctb$x: makeuctb$o
+	$(CC) $(CC_OPTS) $(LDFLAGS) -o $@ makeuctb$o $(INTLLIB) $(LIBS)
 
-makeuctb$(_O): $(srcdir)/UCkd.h $(srcdir)/makeuctb.c
+makeuctb$o: $(srcdir)/UCkd.h $(srcdir)/makeuctb.c
 
-.SUFFIXES : $(_O) .tbl .i
+.SUFFIXES : $o .tbl .i
 
-.c$(_O):
+.c$o:
 @RULE_CC@
 	@ECHO_CC@$(CC) $(CC_OPTS) -c $(srcdir)/$*.c
 
@@ -151,12 +153,13 @@ mac_uni.h:		$(srcdir)/mac_uni.tbl		makeuctb$x
 mnem2_suni.h:		$(srcdir)/mnem2_suni.tbl	makeuctb$x
 mnem_suni.h:		$(srcdir)/mnem_suni.tbl		makeuctb$x
 next_uni.h:		$(srcdir)/next_uni.tbl		makeuctb$x
+pt154_uni.h:		$(srcdir)/pt154_uni.tbl 	makeuctb$x
 rfc_suni.h:		$(srcdir)/rfc_suni.tbl		makeuctb$x
 utf8_uni.h:		$(srcdir)/utf8_uni.tbl		makeuctb$x
 viscii_uni.h:		$(srcdir)/viscii_uni.tbl	makeuctb$x
 
 clean:
-	rm -f makeuctb$x *$(_O) *uni.h *uni2.h
+	rm -f makeuctb$x *$o *uni.h *uni2.h *.i
 
 distclean: clean
 	-rm -rf obsolete
diff --git a/src/chrtrans/makefile.msc b/src/chrtrans/makefile.msc
index a57d93c4..228af43e 100644
--- a/src/chrtrans/makefile.msc
+++ b/src/chrtrans/makefile.msc
@@ -61,6 +61,7 @@ TABLES= \
  mnem2_suni.h \
  mnem_suni.h \
  next_uni.h \
+ pt154_uni.h \
  rfc_suni.h \
  utf8_uni.h \
  viscii_uni.h
@@ -115,6 +116,7 @@ mac_uni.h:		mac_uni.tbl		makeuctb.exe
 mnem2_suni.h:		mnem2_suni.tbl		makeuctb.exe
 mnem_suni.h:		mnem_suni.tbl		makeuctb.exe
 next_uni.h:		next_uni.tbl		makeuctb.exe
+pt154_uni.h:		pt154_uni.tbl		makeuctb.exe
 rfc_suni.h:		rfc_suni.tbl		makeuctb.exe
 utf8_uni.h:		utf8_uni.tbl		makeuctb.exe
 viscii_uni.h:		viscii_uni.tbl		makeuctb.exe
diff --git a/src/chrtrans/makeuctb.c b/src/chrtrans/makeuctb.c
index 611e737d..04d05234 100644
--- a/src/chrtrans/makeuctb.c
+++ b/src/chrtrans/makeuctb.c
@@ -18,6 +18,7 @@
 
 #define DONT_USE_SOCKS5
 #include <HTUtils.h>
+
 /*
  *  Don't try to use LYexit().
  */
@@ -25,14 +26,6 @@
 #undef exit
 #endif /* exit */
 
-#ifndef TOUPPER
-#define TOUPPER(c) (islower(UCH(c)) ? toupper(UCH(c)) : (c))
-#endif /* !TOLOWER */
-
-#ifndef TOLOWER
-#define TOLOWER(c) (isupper(UCH(c)) ? tolower(UCH(c)) : (c))
-#endif /* !TOLOWER */
-
 #include <UCkd.h>
 #include <UCDefs.h>
 
@@ -79,6 +72,16 @@ PRIVATE void usage NOARGS
     done(EX_USAGE);
 }
 
+#ifdef EXP_ASCII_CTYPES
+PUBLIC int ascii_tolower ARGS1(int, i)
+{
+    if ( 91 > i && i > 64 )
+	return (i+32);
+    else
+	return i;
+}
+#endif
+
 /* copied from HTString.c, not everybody has strncasecmp */
 PUBLIC int strncasecomp ARGS3(
 	CONST char*,	a,
@@ -434,7 +437,7 @@ PUBLIC int main ARGS2(
 		while (*p == ' ' || *p == '\t') {
 		    p++;
 		}
-		useDefaultMap = (*p == '1' || tolower(*p) == 'y');
+		useDefaultMap = (*p == '1' || TOLOWER(*p) == 'y');
 		continue;
 
 	    case 'M':
diff --git a/src/chrtrans/makew32.bat b/src/chrtrans/makew32.bat
index 6339101d..e03e1743 100644
--- a/src/chrtrans/makew32.bat
+++ b/src/chrtrans/makew32.bat
@@ -3,6 +3,11 @@
 @echo .

 @echo off

 

+if "%1"=="" goto normal

+make -l -f makefile.bcb %1

+goto done

+

+:normal

 make -l -f makefile.bcb

 

 makeuctb cp1250_uni.tbl

@@ -42,6 +47,9 @@ makeuctb mac_uni.tbl
 makeuctb mnem2_suni.tbl

 makeuctb mnem_suni.tbl

 makeuctb next_uni.tbl

+makeuctb pt154_uni.tbl

 makeuctb rfc_suni.tbl

 makeuctb utf8_uni.tbl

 makeuctb viscii_uni.tbl

+

+:done

diff --git a/src/chrtrans/pt154_uni.tbl b/src/chrtrans/pt154_uni.tbl
new file mode 100644
index 00000000..a15c22e8
--- /dev/null
+++ b/src/chrtrans/pt154_uni.tbl
@@ -0,0 +1,174 @@
+Mptcp154

+#
+OCyrillic-Asian (PT154)
+#
+C1540
+
+#####
+#
+# Charset aliases:
+# csPTCP154
+# PT154
+# CP154
+# Cyrillic-Asian
+#
+# Suitability for use in MIME text:

+# Yes

+#
+# ISO 10646 equivalency table:

+#    Format: Three tab-separated columns

+#        Column #1 is the Paratype CP154 code (in hex)

+#        Column #2 is the Unicode (in hex as 0xXXXX)

+#        Column #3 is the Unicode name (follows a comment sign, '#')

+#

+#    The entries are in Paratype CP154 order

+#

+#####
+
+0x20-0x7e		 idem
+#
+0x80  U+0496     #       CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER

+0x81  U+0492     #       CYRILLIC CAPITAL LETTER GHE WITH STROKE

+0x82  U+04EE     #       CYRILLIC CAPITAL LETTER U WITH MACRON

+0x83  U+0493     #       CYRILLIC SMALL LETTER GHE WITH STROKE

+0x84  U+201E     #       DOUBLE LOW-9 QUOTATION MARK

+0x85  U+2026     #       HORIZONTAL ELLIPSIS

+0x86  U+04B6     #       CYRILLIC CAPITAL LETTER CHE WITH DESCENDER

+0x87  U+04AE     #       CYRILLIC CAPITAL LETTER STRAIGHT U

+0x88  U+04B2     #       CYRILLIC CAPITAL LETTER HA WITH DESCENDER

+0x89  U+04AF     #       CYRILLIC SMALL LETTER STRAIGHT U

+0x8a  U+04A0     #       CYRILLIC CAPITAL LETTER BASHKIR KA

+0x8b  U+04E2     #       CYRILLIC CAPITAL LETTER I WITH MACRON

+0x8c  U+04A2     #       CYRILLIC CAPITAL LETTER EN WITH DESCENDER

+0x8d  U+049A     #       CYRILLIC CAPITAL LETTER KA WITH DESCENDER

+0x8e  U+04BA     #       CYRILLIC CAPITAL LETTER SHHA

+0x8f  U+04B8     #       CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE

+0x90  U+0497     #       CYRILLIC SMALL LETTER ZHE WITH DESCENDER

+0x91  U+2018     #       LEFT SINGLE QUOTATION MARK

+0x92  U+2019     #       RIGHT SINGLE QUOTATION MARK

+0x93  U+201C     #       LEFT DOUBLE QUOTATION MARK

+0x94  U+201D     #       RIGHT DOUBLE QUOTATION MARK

+0x95  U+2022     #       BULLET

+0x96  U+2013     #       EN DASH

+0x97  U+2014     #       EM DASH

+0x98  U+04B3     #       CYRILLIC SMALL LETTER HA WITH DESCENDER

+0x99  U+04B7     #       CYRILLIC SMALL LETTER CHE WITH DESCENDER

+0x9a  U+04A1     #       CYRILLIC SMALL LETTER BASHKIR KA

+0x9b  U+04E3     #       CYRILLIC SMALL LETTER I WITH MACRON

+0x9c  U+04A3     #       CYRILLIC SMALL LETTER EN WITH DESCENDER

+0x9d  U+049B     #       CYRILLIC SMALL LETTER KA WITH DESCENDER

+0x9e  U+04BB     #       CYRILLIC SMALL LETTER SHHA

+0x9f  U+04B9     #       CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE

+0xa0  U+00A0     #       NO-BREAK SPACE

+0xa1  U+040E     #       CYRILLIC CAPITAL LETTER SHORT U (Byelorussian)

+0xa2  U+045E     #       CYRILLIC SMALL LETTER SHORT U (Byelorussian)

+0xa3  U+0408     #       CYRILLIC CAPITAL LETTER JE

+0xa4  U+04E8     #       CYRILLIC CAPITAL LETTER BARRED O

+0xa5  U+0498     #       CYRILLIC CAPITAL LETTER ZE WITH DESCENDER

+0xa6  U+04B0     #       CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE

+0xa7  U+00A7     #       SECTION SIGN

+0xa8  U+0401     #       CYRILLIC CAPITAL LETTER IO

+0xa9  U+00A9     #       COPYRIGHT SIGN

+0xaa  U+04D8     #       CYRILLIC CAPITAL LETTER SCHWA

+0xab  U+00AB     #       LEFT-POINTING DOUBLE ANGLE QUOTATION MARK

+0xac  U+00AC     #       NOT SIGN

+0xad  U+04EF     #       CYRILLIC SMALL LETTER U WITH MACRON

+0xae  U+00AE     #       REGISTERED SIGN

+0xaf  U+049C     #       CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE

+0xb0  U+00B0     #       DEGREE SIGN

+0xb1  U+04B1     #       CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE

+0xb2  U+0406     #       CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I

+0xb3  U+0456     #       CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I

+0xb4  U+0499     #       CYRILLIC SMALL LETTER ZE WITH DESCENDER

+0xb5  U+04E9     #       CYRILLIC SMALL LETTER BARRED O

+0xb6  U+00B6     #       PILCROW SIGN

+0xb7  U+00B7     #       MIDDLE DOT

+0xb8  U+0451     #       CYRILLIC SMALL LETTER IO

+0xb9  U+2116     #       NUMERO SIGN

+0xba  U+04D9     #       CYRILLIC SMALL LETTER SCHWA

+0xbb  U+00BB     #       RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK

+0xbc  U+0458     #       CYRILLIC SMALL LETTER JE

+0xbd  U+04AA     #       CYRILLIC CAPITAL LETTER ES WITH DESCENDER

+0xbe  U+04AB     #       CYRILLIC SMALL LETTER ES WITH DESCENDER

+0xbf  U+049D     #       CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE

+0xc0  U+0410     #       CYRILLIC CAPITAL LETTER A

+0xc1  U+0411     #       CYRILLIC CAPITAL LETTER BE

+0xc2  U+0412     #       CYRILLIC CAPITAL LETTER VE

+0xc3  U+0413     #       CYRILLIC CAPITAL LETTER GHE

+0xc4  U+0414     #       CYRILLIC CAPITAL LETTER DE

+0xc5  U+0415     #       CYRILLIC CAPITAL LETTER IE

+0xc6  U+0416     #       CYRILLIC CAPITAL LETTER ZHE

+0xc7  U+0417     #       CYRILLIC CAPITAL LETTER ZE

+0xc8  U+0418     #       CYRILLIC CAPITAL LETTER I

+0xc9  U+0419     #       CYRILLIC CAPITAL LETTER SHORT I

+0xca  U+041A     #       CYRILLIC CAPITAL LETTER KA

+0xcb  U+041B     #       CYRILLIC CAPITAL LETTER EL

+0xcc  U+041C     #       CYRILLIC CAPITAL LETTER EM

+0xcd  U+041D     #       CYRILLIC CAPITAL LETTER EN

+0xce  U+041E     #       CYRILLIC CAPITAL LETTER O

+0xcf  U+041F     #       CYRILLIC CAPITAL LETTER PE

+0xd0  U+0420     #       CYRILLIC CAPITAL LETTER ER

+0xd1  U+0421     #       CYRILLIC CAPITAL LETTER ES

+0xd2  U+0422     #       CYRILLIC CAPITAL LETTER TE

+0xd3  U+0423     #       CYRILLIC CAPITAL LETTER U

+0xd4  U+0424     #       CYRILLIC CAPITAL LETTER EF

+0xd5  U+0425     #       CYRILLIC CAPITAL LETTER HA

+0xd6  U+0426     #       CYRILLIC CAPITAL LETTER TSE

+0xd7  U+0427     #       CYRILLIC CAPITAL LETTER CHE

+0xd8  U+0428     #       CYRILLIC CAPITAL LETTER SHA

+0xd9  U+0429     #       CYRILLIC CAPITAL LETTER SHCHA

+0xda  U+042A     #       CYRILLIC CAPITAL LETTER HARD SIGN

+0xdb  U+042B     #       CYRILLIC CAPITAL LETTER YERU

+0xdc  U+042C     #       CYRILLIC CAPITAL LETTER SOFT SIGN

+0xdd  U+042D     #       CYRILLIC CAPITAL LETTER E

+0xde  U+042E     #       CYRILLIC CAPITAL LETTER YU

+0xdf  U+042F     #       CYRILLIC CAPITAL LETTER YA

+0xe0  U+0430     #       CYRILLIC SMALL LETTER A

+0xe1  U+0431     #       CYRILLIC SMALL LETTER BE

+0xe2  U+0432     #       CYRILLIC SMALL LETTER VE

+0xe3  U+0433     #       CYRILLIC SMALL LETTER GHE

+0xe4  U+0434     #       CYRILLIC SMALL LETTER DE

+0xe5  U+0435     #       CYRILLIC SMALL LETTER IE

+0xe6  U+0436     #       CYRILLIC SMALL LETTER ZHE

+0xe7  U+0437     #       CYRILLIC SMALL LETTER ZE

+0xe8  U+0438     #       CYRILLIC SMALL LETTER I

+0xe9  U+0439     #       CYRILLIC SMALL LETTER SHORT I

+0xea  U+043A     #       CYRILLIC SMALL LETTER KA

+0xeb  U+043B     #       CYRILLIC SMALL LETTER EL

+0xec  U+043C     #       CYRILLIC SMALL LETTER EM

+0xed  U+043D     #       CYRILLIC SMALL LETTER EN

+0xee  U+043E     #       CYRILLIC SMALL LETTER O

+0xef  U+043F     #       CYRILLIC SMALL LETTER PE

+0xf0  U+0440     #       CYRILLIC SMALL LETTER ER

+0xf1  U+0441     #       CYRILLIC SMALL LETTER ES

+0xf2  U+0442     #       CYRILLIC SMALL LETTER TE

+0xf3  U+0443     #       CYRILLIC SMALL LETTER U

+0xf4  U+0444     #       CYRILLIC SMALL LETTER EF

+0xf5  U+0445     #       CYRILLIC SMALL LETTER HA

+0xf6  U+0446     #       CYRILLIC SMALL LETTER TSE

+0xf7  U+0447     #       CYRILLIC SMALL LETTER CHE

+0xf8  U+0448     #       CYRILLIC SMALL LETTER SHA

+0xf9  U+0449     #       CYRILLIC SMALL LETTER SHCHA

+0xfa  U+044A     #       CYRILLIC SMALL LETTER HARD SIGN

+0xfb  U+044B     #       CYRILLIC SMALL LETTER YERU

+0xfc  U+044C     #       CYRILLIC SMALL LETTER SOFT SIGN

+0xfd  U+044D     #       CYRILLIC SMALL LETTER E

+0xfe  U+044E     #       CYRILLIC SMALL LETTER YU

+0xff  U+044F     #       CYRILLIC SMALL LETTER YA

+
+#####
+#
+# Additional information:

+# This charset based on CP1251 with added asian cyrillic symbols.

+#
+# Person & email address to contact for further information:

+# Alexander Uskov

+# InternetDataCenter of KazakhTelecom.

+# e-mail: auskov@idc.kz

+#
+# Intended usage:

+# COMMON

+#

+# (record created 2002-09-27)
+#
+#####
diff --git a/src/makefile.dos b/src/makefile.dos
index daaa5b62..e58e1cf5 100644
--- a/src/makefile.dos
+++ b/src/makefile.dos
@@ -35,17 +35,17 @@ MCFLAGS = \
  -DDOSPATH \
  -DEXP_ADDRLIST_PAGE \
  -DEXP_ALT_BINDINGS \
- -DEXP_FILE_UPLOAD \
  -DEXP_NESTED_TABLES \
- -DEXP_PERSISTENT_COOKIES \
+ -DUSE_PERSISTENT_COOKIES \
  -DFANCY_CURSES \
  -DNOUSERS \
  -DNO_CUSERID \
  -DNO_TTYTYPE \
  -DNO_UTMP \
  -DPDCURSES \
- -DSOURCE_CACHE \
+ -DUSE_SOURCE_CACHE \
  -DUSE_EXTERNALS \
+ -DUSE_FILE_UPLOAD \
  -DUSE_PRETTYSRC \
  -DUSE_ZLIB \
  -DWATT32 \
diff --git a/src/makefile.dsl b/src/makefile.dsl
index 0c6bca42..1893b3ab 100644
--- a/src/makefile.dsl
+++ b/src/makefile.dsl
@@ -32,10 +32,10 @@ MCFLAGS = \
  -DNO_CUSERID \
  -DNO_TTYTYPE \
  -DNO_UTMP \
- -DSOURCE_CACHE \
  -DUSE_EXTERNALS \
  -DUSE_PRETTYSRC \
  -DUSE_SLANG \
+ -DUSE_SOURCE_CACHE \
  -DUSE_ZLIB \
  -DWATT32 \
  -I./chrtrans \
diff --git a/src/makefile.in b/src/makefile.in
index 53066c09..f96df3a2 100644
--- a/src/makefile.in
+++ b/src/makefile.in
@@ -3,8 +3,6 @@
 SHELL		= @CONFIG_SHELL@
 CDPATH		= .
 
-x		= @PROG_EXT@
-
 @SET_MAKE@
 prefix		= @prefix@
 exec_prefix	= @exec_prefix@
@@ -24,7 +22,9 @@ CFLAGS		= @CFLAGS@
 DEFS		= @DEFS@
 CHARSET_DEFS	= @CHARSET_DEFS@
 CPPFLAGS	= @CPPFLAGS@
-_O		= .o
+
+x		= @EXEEXT@
+o		= .@OBJEXT@
 
 LIBS		= @LIBS@ $(RESOLVLIB) $(WAISLIB) $(SITE_LIBS)
 LDFLAGS		= @LDFLAGS@
@@ -59,26 +59,26 @@ LINTOPTS	=
 COMPRESS_PROG	=@COMPRESS_PROG@
 COMPRESS_EXT	=@COMPRESS_EXT@
 
-CHARTRANS_OBJS	= UCdomap$(_O) UCAux$(_O) UCAuto$(_O)
+CHARTRANS_OBJS	= UCdomap$o UCAux$o UCAuto$o
 OBJS	= \
-	LYClean$(_O) LYShowInfo$(_O) LYEdit$(_O) LYStrings$(_O) LYMail$(_O) \
-	HTAlert$(_O) GridText$(_O) LYGetFile$(_O) LYMain$(_O) LYMainLoop$(_O) \
-	LYCurses$(_O) LYBookmark$(_O) LYUtils$(_O) LYOptions$(_O) \
-	LYReadCFG$(_O) LYSearch$(_O) LYHistory$(_O) LYForms$(_O) LYPrint$(_O) \
-	LYrcFile$(_O) LYDownload$(_O) LYNews$(_O) LYKeymap$(_O) HTML$(_O) \
-	HTFWriter$(_O) HTInit$(_O) DefaultStyle$(_O) LYUpload$(_O) \
-	LYLeaks$(_O) LYexit$(_O) LYJump$(_O) LYList$(_O) LYCgi$(_O) \
-	LYTraversal$(_O) LYEditmap$(_O) LYCharSets$(_O) LYCharUtils$(_O) \
-	LYMap$(_O) LYCookie$(_O) LYStyle$(_O) LYHash$(_O) LYPrettySrc$(_O) \
-	TRSTable$(_O) $(CHARTRANS_OBJS) @LIBOBJS@
-
-C_SRC	= $(OBJS:$(_O)=.c)
+	LYClean$o LYShowInfo$o LYEdit$o LYStrings$o LYMail$o \
+	HTAlert$o GridText$o LYGetFile$o LYMain$o LYMainLoop$o \
+	LYCurses$o LYBookmark$o LYUtils$o LYOptions$o \
+	LYReadCFG$o LYSearch$o LYHistory$o LYForms$o LYPrint$o \
+	LYrcFile$o LYDownload$o LYNews$o LYKeymap$o HTML$o \
+	HTFWriter$o HTInit$o DefaultStyle$o LYUpload$o \
+	LYLeaks$o LYexit$o LYJump$o LYList$o LYCgi$o \
+	LYTraversal$o LYEditmap$o LYCharSets$o LYCharUtils$o \
+	LYMap$o LYCookie$o LYStyle$o LYHash$o LYPrettySrc$o \
+	TRSTable$o $(CHARTRANS_OBJS) @LIBOBJS@
+
+C_SRC	= $(OBJS:$o=.c)
 
 all: lynx$x
 
-.SUFFIXES : $(_O) .i
+.SUFFIXES : $o .i
 
-.c$(_O):
+.c$o:
 @RULE_CC@
 	@ECHO_CC@$(CC) $(CC_OPTS) -c $(srcdir)/$*.c
 
@@ -108,28 +108,28 @@ lint:
 	$(LINT) $(LINTOPTS) $(CPP_OPTS) *.c  > $(top_builddir)/lint.lynx
 
 clean:
-	rm -f lynx$x core *.core *.leaks *.[oi] *.bak tags TAGS
+	rm -f lynx$x core *.core *.leaks *.i *$o *.bak tags TAGS
 	cd chrtrans && $(MAKE) clean
 
 distclean: clean
 
 CMN=$(top_srcdir)/WWW/Library/Implementation/
 
-HTFWriter$(_O):		$(top_srcdir)/userdefs.h
-HTInit$(_O):		$(top_srcdir)/userdefs.h
-LYCharSets$(_O):	$(top_srcdir)/userdefs.h
-LYGetFile$(_O):		$(top_srcdir)/userdefs.h
-LYKeymap$(_O):		$(top_srcdir)/userdefs.h
-LYMail$(_O):		$(top_srcdir)/userdefs.h
-LYMain$(_O):		$(top_srcdir)/userdefs.h $(top_builddir)/lynx_cfg.h
-LYMainLoop$(_O):	$(top_srcdir)/userdefs.h
-LYOptions$(_O):		$(top_srcdir)/userdefs.h
-LYReadCFG$(_O):		$(top_srcdir)/userdefs.h
-LYShowInfo$(_O):	$(top_builddir)/cfg_defs.h
-LYTraversal$(_O):	$(top_srcdir)/userdefs.h
-LYUtils$(_O):		$(top_srcdir)/userdefs.h
-LYrcFile$(_O):		$(top_srcdir)/userdefs.h
-LYLeaks$(_O):		$(CMN)LYLeaks.h $(CMN)HTString.h
+HTFWriter$o :		$(top_srcdir)/userdefs.h
+HTInit$o :		$(top_srcdir)/userdefs.h
+LYCharSets$o :		$(top_srcdir)/userdefs.h
+LYGetFile$o :		$(top_srcdir)/userdefs.h
+LYKeymap$o :		$(top_srcdir)/userdefs.h
+LYMail$o :		$(top_srcdir)/userdefs.h
+LYMain$o :		$(top_srcdir)/userdefs.h $(top_builddir)/lynx_cfg.h
+LYMainLoop$o :		$(top_srcdir)/userdefs.h
+LYOptions$o :		$(top_srcdir)/userdefs.h
+LYReadCFG$o :		$(top_srcdir)/userdefs.h
+LYShowInfo$o :		$(top_builddir)/cfg_defs.h
+LYTraversal$o :		$(top_srcdir)/userdefs.h
+LYUtils$o :		$(top_srcdir)/userdefs.h
+LYrcFile$o :		$(top_srcdir)/userdefs.h
+LYLeaks$o :		$(CMN)LYLeaks.h $(CMN)HTString.h
 
 CHRTR= chrtrans/
 
@@ -176,14 +176,14 @@ TABLES= \
 $(TABLES):
 	-cd chrtrans && $(MAKE) tables
 
-UCdomap$(_O): UCdomap.c chrtrans/UCkd.h chrtrans/makeuctb$x chrtrans/makeuctb.c \
+UCdomap$o : UCdomap.c chrtrans/UCkd.h chrtrans/makeuctb$x chrtrans/makeuctb.c \
 	UCdomap.h $(CMN)UCMap.h $(TABLES) $(top_srcdir)/userdefs.h
 
 chrtrans/makeuctb$x:
 	cd chrtrans; make makeuctb$x
 
-UCAux$(_O) : UCAux.c $(CMN)UCAux.h $(CMN)UCDefs.h
-LYCookie$(_O): $(top_srcdir)/userdefs.h
+UCAux$o : UCAux.c $(CMN)UCAux.h $(CMN)UCDefs.h
+LYCookie$o : $(top_srcdir)/userdefs.h
 
 depend : $(TABLES)
 	makedepend -fmakefile -- $(CC_OPTS) -- $(C_SRC)
diff --git a/src/makefile.wsl b/src/makefile.wsl
index 1d771a6e..ad594411 100644
--- a/src/makefile.wsl
+++ b/src/makefile.wsl
@@ -13,7 +13,7 @@ CFLAGS= -O1 $(MCFLAGS) -I. -I.. $(SLANGINC)
 
 CC = gcc
 MCFLAGS = -DDISP_PARTIAL -DUSE_ZLIB -DUSE_EXTERNALS \
--DSOURCE_CACHE -DUSE_PRETTYSRC \
+-DUSE_SOURCE_CACHE -DUSE_PRETTYSRC \
 -DUSE_SLANG -DACCESS_AUTH -DNO_CUSERID \
 -DNOUSERS -DDOSPATH -DNO_TTYTYPE -DNO_UTMP -I../WWW/library/implement -I../djgpp/tcplib/include \
 -I./chrtrans -I../djgpp/tcplib/include/tcp