about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2012-02-08 01:45:28 -0500
committerThomas E. Dickey <dickey@invisible-island.net>2012-02-08 01:45:28 -0500
commitf0a9358661ef1e5b61037c1862854c2f2acce2e0 (patch)
treea674d1a4aa010a0a3acc5872c19f5809c523512d
parent1c60b1717a1ee37412aa4196f9bc2fbd2899fc65 (diff)
downloadlynx-snapshots-f0a9358661ef1e5b61037c1862854c2f2acce2e0.tar.gz
snapshot of project "lynx", label v2-8-8dev_9k
-rw-r--r--CHANGES7
-rw-r--r--WWW/Library/Implementation/HTChunk.c25
-rw-r--r--WWW/Library/Implementation/HTString.c16
-rw-r--r--WWW/Library/Implementation/HTString.h15
-rw-r--r--src/GridText.c11
-rw-r--r--src/HTAlert.c25
-rw-r--r--src/HTForms.h6
-rw-r--r--src/LYBookmark.c28
-rw-r--r--src/LYForms.c115
-rw-r--r--src/LYKeymap.c23
-rw-r--r--src/LYKeymap.h3
-rw-r--r--src/LYOptions.c153
-rw-r--r--src/LYStrings.c298
-rw-r--r--src/LYStrings.h26
14 files changed, 424 insertions, 327 deletions
diff --git a/CHANGES b/CHANGES
index 7e556a79..58f4fa83 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,12 @@
--- $LynxId: CHANGES,v 1.570 2012/02/07 01:45:24 tom Exp $
+-- $LynxId: CHANGES,v 1.571 2012/02/07 21:21:05 tom Exp $
 ===============================================================================
 Changes since Lynx 2.8 release
 ===============================================================================
 
-2012-02-06 (2.8.8dev.10)
+2012-02-07 (2.8.8dev.10)
+* modify LYgetstr, making it call revised function LYgetBString which handles
+  bstring's, and allows editing fields which can grow without fixed buffer
+  limits -TD
 * extend ^X-e editing of textarea's to include single-line fields -TD
 * modify comparison for splitting lines to allow for long preformatted lines,
   e.g., using &nbsp;'s to not wrap when the line-wrap mode is disabled -TD
diff --git a/WWW/Library/Implementation/HTChunk.c b/WWW/Library/Implementation/HTChunk.c
index 402f32c6..2ea36c85 100644
--- a/WWW/Library/Implementation/HTChunk.c
+++ b/WWW/Library/Implementation/HTChunk.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTChunk.c,v 1.26 2010/09/25 00:32:33 tom Exp $
+ * $LynxId: HTChunk.c,v 1.27 2012/02/07 11:28:44 tom Exp $
  *
  *		Chunk handling:	Flexible arrays
  *		===============================
@@ -150,10 +150,11 @@ HTChunk *HTChunkPutc2(HTChunk *ch, int c)
 	HTChunk *chunk = HTChunkCreateMayFail(ch->growby, ch->failok);
 
 	ch->next = chunk;
-	HTChunkPutc(chunk, UCH(c));
-	return chunk;
+	ch = chunk;
+	HTChunkPutc(ch, UCH(c));
+    } else {
+	ch->data[ch->size++] = (char) c;
     }
-    ch->data[ch->size++] = (char) c;
     return ch;
 }
 
@@ -205,11 +206,12 @@ HTChunk *HTChunkPutb2(HTChunk *ch, const char *b, int l)
 
 	chunk = HTChunkCreateMayFail(ch->growby, ch->failok);
 	ch->next = chunk;
-	HTChunkPutb(chunk, b + m, l - m);
-	return chunk;
+	ch = chunk;
+	HTChunkPutb(ch, b + m, l - m);
+    } else {
+	MemCpy(ch->data + ch->size, b, (unsigned) l);
+	ch->size += l;
     }
-    MemCpy(ch->data + ch->size, b, (unsigned) l);
-    ch->size += l;
     return ch;
 }
 
@@ -305,7 +307,7 @@ void HTChunkPuts(HTChunk *ch, const char *s)
 	for (p = s; *p; p++) {
 	    if (ch->size >= ch->allocated) {
 		if (!HTChunkRealloc(ch, ch->growby))
-		    return;
+		    break;
 	    }
 	    ch->data[ch->size++] = *p;
 	}
@@ -323,8 +325,9 @@ HTChunk *HTChunkPuts2(HTChunk *ch, const char *s)
 		HTChunk *chunk = HTChunkCreateMayFail(ch->growby, ch->failok);
 
 		ch->next = chunk;
-		HTChunkPuts(chunk, p);
-		return chunk;
+		ch = chunk;
+		HTChunkPuts(ch, p);
+		break;
 	    }
 	    ch->data[ch->size++] = *p;
 	}
diff --git a/WWW/Library/Implementation/HTString.c b/WWW/Library/Implementation/HTString.c
index ba332206..9bbc3577 100644
--- a/WWW/Library/Implementation/HTString.c
+++ b/WWW/Library/Implementation/HTString.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTString.c,v 1.65 2010/11/07 21:20:58 tom Exp $
+ * $LynxId: HTString.c,v 1.67 2012/02/08 00:34:44 tom Exp $
  *
  *	Case-independent string comparison		HTString.c
  *
@@ -1188,6 +1188,20 @@ void HTEndParam(char **result,
  * there is a null on the end, anyway.
  */
 
+/* (Re)allocate a bstring, e.g., to increase its buffer size for ad hoc
+ * operations.
+ */
+void HTSABAlloc(bstring **dest, int len)
+{
+    if (*dest == 0)
+	*dest = typecalloc(bstring);
+
+    if ((*dest)->len != len) {
+	(*dest)->str = typeRealloc(char, (*dest)->str, len);
+	(*dest)->len = len;
+    }
+}
+
 /* Allocate a new bstring, and return it.
 */
 void HTSABCopy(bstring **dest, const char *src,
diff --git a/WWW/Library/Implementation/HTString.h b/WWW/Library/Implementation/HTString.h
index 37c668f6..86cd9382 100644
--- a/WWW/Library/Implementation/HTString.h
+++ b/WWW/Library/Implementation/HTString.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTString.h,v 1.34 2010/09/25 00:32:47 tom Exp $
+ * $LynxId: HTString.h,v 1.37 2012/02/07 23:41:25 tom Exp $
  *						String handling for libwww
  *                                         STRINGS
  *                                            
@@ -128,6 +128,7 @@ extern "C" {
 	int len;
     } bstring;
 
+    extern void HTSABAlloc(bstring **dest, int len);
     extern void HTSABCopy(bstring **dest, const char *src, int len);
     extern void HTSABCopy0(bstring **dest, const char *src);
     extern void HTSABCat(bstring **dest, const char *src, int len);
@@ -142,11 +143,13 @@ extern "C" {
 
 #define isBEmpty(p)   ((p) == 0 || BStrLen(p) == 0)
 
-#define BStrCopy(d,s)  HTSABCopy(  &(d), BStrData(s), BStrLen(s))
-#define BStrCopy0(d,s) HTSABCopy0( &(d), s)
-#define BStrCat(d,s)   HTSABCat(   &(d), BStrData(s), BStrLen(s))
-#define BStrCat0(d,s)  HTSABCat0(  &(d), s)
-#define BStrFree(d)    HTSABFree(  &(d))
+#define BStrAlloc(d,n)   HTSABAlloc( &(d), n)
+#define BStrCopy(d,s)    HTSABCopy( &(d), BStrData(s), BStrLen(s))
+#define BStrCopy0(d,s)   HTSABCopy0( &(d), s)
+#define BStrCopy1(d,s,n) HTSABCopy(  &(d), s, n)
+#define BStrCat(d,s)     HTSABCat( &(d), BStrData(s), BStrLen(s))
+#define BStrCat0(d,s)    HTSABCat0( &(d), s)
+#define BStrFree(d)      HTSABFree( &(d))
 
     extern bstring *HTBprintf(bstring **pstr, const char *fmt,...) GCC_PRINTFLIKE(2,3);
 
diff --git a/src/GridText.c b/src/GridText.c
index 57d9aa78..3277add1 100644
--- a/src/GridText.c
+++ b/src/GridText.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: GridText.c,v 1.224 2012/02/07 01:43:47 tom Exp $
+ * $LynxId: GridText.c,v 1.226 2012/02/07 21:11:50 tom Exp $
  *
  *		Character grid hypertext object
  *		===============================
@@ -7653,7 +7653,10 @@ void HTAddSearchQuery(char *query)
 
 int do_www_search(DocInfo *doc)
 {
-    char searchstring[256], temp[256], *cp, *tmpaddress = NULL;
+    char searchstring[256];
+    char temp[256];
+    char *cp;
+    char *tmpaddress = NULL;
     int ch;
     RecallType recall;
     int QueryTotal;
@@ -10642,7 +10645,7 @@ static void load_a_file(const char *val_used,
 {
     FILE *fd;
     size_t bytes;
-    char buffer[257];
+    char buffer[BUFSIZ + 1];
 
     CTRACE((tfp, "Ok, about to convert \"%s\" to mime/thingy\n", val_used));
 
@@ -10650,7 +10653,7 @@ static void load_a_file(const char *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), (size_t) 256, fd)) != 0) {
+	    while ((bytes = fread(buffer, sizeof(char), BUFSIZ, fd)) != 0) {
 		HTSABCat(result, buffer, (int) bytes);
 	    }
 	    LYCloseInput(fd);
diff --git a/src/HTAlert.c b/src/HTAlert.c
index 23e4a14e..4d7be6fc 100644
--- a/src/HTAlert.c
+++ b/src/HTAlert.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTAlert.c,v 1.94 2010/11/07 21:21:00 tom Exp $
+ * $LynxId: HTAlert.c,v 1.95 2012/02/08 01:45:28 tom Exp $
  *
  *	Displaying messages and getting input for Lynx Browser
  *	==========================================================
@@ -623,20 +623,17 @@ BOOL confirm_post_resub(const char *address,
 char *HTPrompt(const char *Msg, const char *deflt)
 {
     char *rep = NULL;
-    char Tmp[200];
-
-    Tmp[0] = '\0';
-    Tmp[sizeof(Tmp) - 1] = '\0';
+    bstring *data = NULL;
 
     _statusline(Msg);
-    if (deflt)
-	StrNCpy(Tmp, deflt, sizeof(Tmp) - 1);
+    BStrCopy0(data, deflt ? deflt : "");
 
     if (!dump_output_immediately)
-	LYGetStr(Tmp, VISIBLE, sizeof(Tmp), NORECALL);
+	LYgetBString(&data, VISIBLE, 0, NORECALL);
 
-    StrAllocCopy(rep, Tmp);
+    StrAllocCopy(rep, data->str);
 
+    BStrFree(data);
     return rep;
 }
 
@@ -647,14 +644,14 @@ char *HTPrompt(const char *Msg, const char *deflt)
 char *HTPromptPassword(const char *Msg)
 {
     char *result = NULL;
-    char pw[120];
-
-    pw[0] = '\0';
+    bstring *data = NULL;
 
     if (!dump_output_immediately) {
 	_statusline(Msg ? Msg : PASSWORD_PROMPT);
-	LYGetStr(pw, HIDDEN, sizeof(pw), NORECALL);	/* hidden */
-	StrAllocCopy(result, pw);
+	BStrCopy0(data, "");
+	LYgetBString(&data, HIDDEN, 0, NORECALL);
+	StrAllocCopy(result, data->str);
+	BStrFree(data);
     } else {
 	printf("\n%s\n", PASSWORD_REQUIRED);
 	StrAllocCopy(result, "");
diff --git a/src/HTForms.h b/src/HTForms.h
index cfe3ad12..c27f20a2 100644
--- a/src/HTForms.h
+++ b/src/HTForms.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: HTForms.h,v 1.29 2011/05/19 10:53:07 tom Exp $
+ * $LynxId: HTForms.h,v 1.31 2012/02/07 16:24:29 tom Exp $
  */
 #ifndef HTFORMS_H
 #define HTFORMS_H
@@ -75,7 +75,7 @@ extern "C" {
 	char *value;		/* user entered string data */
 	char *orig_value;	/* the original value */
 	int size;		/* width on the screen */
-	unsigned maxlength;	/* max width of data */
+	size_t maxlength;	/* max width of data */
 	int group;		/* a group associated with the link
 				 *  this is used for select's
 				 */
@@ -98,7 +98,7 @@ extern "C" {
 	char *accept_cs;
     } FormInfo;
 
-#define FormIsReadonly(form) ((form)->disabled || (form)->readonly)
+#define FormIsReadonly(form) ((form) && ((form)->disabled || (form)->readonly))
 
 /*
  * As structure for info associated with a form.  There is some redundancy
diff --git a/src/LYBookmark.c b/src/LYBookmark.c
index 08420ead..174fd1e0 100644
--- a/src/LYBookmark.c
+++ b/src/LYBookmark.c
@@ -1,5 +1,5 @@
 /*
- * $LynxId: LYBookmark.c,v 1.69 2010/09/25 11:19:25 tom Exp $
+ * $LynxId: LYBookmark.c,v 1.70 2012/02/08 01:37:55 tom Exp $
  */
 #include <HTUtils.h>
 #include <HTAlert.h>
@@ -207,11 +207,11 @@ void save_bookmark_link(const char *address,
     const char *filename;
     char *bookmark_URL = NULL;
     char filename_buffer[LY_MAXPATH];
-    char string_buffer[BUFSIZ];
-    char tmp_buffer[BUFSIZ];
     char *Address = NULL;
     char *Title = NULL;
     int i, c;
+    bstring *string_data = NULL;
+    bstring *tmp_data = NULL;
     DocAddress WWWDoc;
     HTParentAnchor *tmpanchor;
     HText *text;
@@ -282,28 +282,30 @@ void save_bookmark_link(const char *address,
 	if (HTCJK == JAPANESE) {
 	    switch (kanji_code) {
 	    case EUC:
-		TO_EUC((const unsigned char *) title, (unsigned char *) tmp_buffer);
+		BStrAlloc(tmp_data, MAX_LINE + 2 * (int) strlen(title));
+		TO_EUC((const unsigned char *) title, (unsigned char *) tmp_data->str);
 		break;
 	    case SJIS:
-		TO_SJIS((const unsigned char *) title, (unsigned char *) tmp_buffer);
+		BStrAlloc(tmp_data, MAX_LINE + (int) strlen(title));
+		TO_SJIS((const unsigned char *) title, (unsigned char *) tmp_data->str);
 		break;
 	    default:
 		break;
 	    }
-	    LYStrNCpy(string_buffer, tmp_buffer, sizeof(string_buffer) - 1);
+	    BStrCopy0(string_data, tmp_data->str);
 	} else {
-	    LYStrNCpy(string_buffer, title, sizeof(string_buffer) - 1);
+	    BStrCopy0(string_data, title);
 	}
-	LYReduceBlanks(string_buffer);
+	LYReduceBlanks(string_data->str);
 	LYMBM_statusline(TITLE_PROMPT);
-	LYGetStr(string_buffer, VISIBLE, sizeof(string_buffer), NORECALL);
-	if (*string_buffer == '\0') {
+	LYgetBString(&string_data, VISIBLE, 0, NORECALL);
+	if (isBEmpty(string_data)) {
 	    LYMBM_statusline(CANCELLED);
 	    LYSleepMsg();
 	    FREE(bookmark_URL);
 	    return;
 	}
-    } while (!havevisible(string_buffer));
+    } while (!havevisible(string_data->str));
 
     /*
      * Create the Title with any left-angle-brackets converted to &lt; entities
@@ -313,7 +315,7 @@ void save_bookmark_link(const char *address,
      * character set which may need changing.  Do NOT convert any 8-bit chars
      * if we have CJK display.  - LP
      */
-    LYformTitle(&Title, string_buffer);
+    LYformTitle(&Title, string_data->str);
     LYEntify(&Title, TRUE);
     if (UCSaveBookmarksInUnicode &&
 	have8bit(Title) && (!LYHaveCJKCharacterSet)) {
@@ -432,6 +434,8 @@ Note: if you edit this file manually\n\
     /*
      * Clean up and report success.
      */
+    BStrFree(string_data);
+    BStrFree(tmp_data);
     FREE(Title);
     FREE(Address);
     FREE(bookmark_URL);
diff --git a/src/LYForms.c b/src/LYForms.c
index fd662b55..bb8ad24d 100644
--- a/src/LYForms.c
+++ b/src/LYForms.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYForms.c,v 1.89 2011/06/04 15:08:15 tom Exp $ */
+/* $LynxId: LYForms.c,v 1.95 2012/02/07 17:33:29 tom Exp $ */
 #include <HTUtils.h>
 #include <HTCJK.h>
 #include <HTTP.h>
@@ -365,12 +365,10 @@ static int form_getstr(int cur,
 		       int redraw_only)
 {
     FormInfo *form = links[cur].l_form;
-    char *value = form->value;
+    char *link_value = form->value;
     int ch;
     int far_col;
-    unsigned max_length;
     int startcol, startline;
-    BOOL HaveMaxlength = FALSE;
     int action, repeat;
     int last_xlkc = -1;
 
@@ -378,7 +376,7 @@ static int form_getstr(int cur,
     BOOL refresh_mb = TRUE;
 #endif
 
-    EditFieldData MyEdit;
+    EditFieldData MyEdit, *edit = &MyEdit;
     BOOLEAN Edited = FALSE;	/* Value might be updated? */
 
     /*
@@ -393,16 +391,13 @@ static int form_getstr(int cur,
     /*
      * Make sure the form field value does not exceed our buffer.  - FM
      */
-    max_length = ((form->maxlength > 0 &&
-		   form->maxlength < sizeof(MyEdit.buffer))
-		  ? form->maxlength
-		  : (unsigned) (sizeof(MyEdit.buffer) - 1));
-    if (strlen(form->value) > max_length) {
+    if (form->maxlength != 0 &&
+	strlen(form->value) > form->maxlength) {
 	/*
 	 * We can't fit the entire value into the editing buffer, so enter as
 	 * much of the tail as fits.  - FM
 	 */
-	value += (strlen(form->value) - max_length);
+	link_value += (strlen(form->value) - form->maxlength);
 	if (!FormIsReadonly(form) &&
 	    !(form->submit_method == URL_MAIL_METHOD && no_mail)) {
 	    /*
@@ -417,24 +412,27 @@ static int form_getstr(int cur,
     /*
      * Print panned line
      */
-    LYSetupEdit(&MyEdit, value, (int) max_length, (far_col - startcol));
-    MyEdit.pad = '_';
-    MyEdit.hidden = (BOOL) (form->type == F_PASSWORD_TYPE);
-    if (use_last_tfpos && LastTFPos >= 0 && LastTFPos < MyEdit.strlen) {
+    LYSetupEdit(edit, link_value, form->maxlength, (far_col - startcol));
+    edit->pad = '_';
+    edit->hidden = (BOOL) (form->type == F_PASSWORD_TYPE);
+    if (use_last_tfpos &&
+	LastTFPos >= 0 &&
+	LastTFPos < (int) edit->buffer_used) {
 #if defined(TEXTFIELDS_MAY_NEED_ACTIVATION) && defined(INACTIVE_INPUT_STYLE_VH)
 	if (redraw_only) {
-	    if (!(MyEdit.strlen >= MyEdit.dspwdth &&
-		  LastTFPos >= MyEdit.dspwdth - MyEdit.margin)) {
-		MyEdit.pos = LastTFPos;
-		if (MyEdit.strlen >= MyEdit.dspwdth)
+	    if (!(edit->buffer_used >= edit->dspwdth &&
+		  LastTFPos >= edit->dspwdth - edit->margin)) {
+		edit->pos = LastTFPos;
+		if (edit->buffer_used >= edit->dspwdth)
 		    textinput_redrawn = FALSE;
 	    }
 	} else
 #endif /* TEXTFIELDS_MAY_NEED_ACTIVATION && INACTIVE_INPUT_STYLE_VH */
-	    MyEdit.pos = LastTFPos;
+	    edit->pos = LastTFPos;
 #ifdef ENHANCED_LINEEDIT
-	if (MyEdit.pos == 0)
-	    MyEdit.mark = -1 - MyEdit.strlen;	/* Do not show the region. */
+	if (edit->pos == 0)
+	    /* Do not show the region. */
+	    edit->mark = -(int) (1 + edit->buffer_used);
 #endif
     }
     /* Try to prepare for setting position based on the last mouse event */
@@ -442,7 +440,7 @@ static int form_getstr(int cur,
     if (!redraw_only) {
 	if (peek_mouse_levent()) {
 	    if (!use_last_tfpos && !textinput_redrawn) {
-		MyEdit.pos = 0;
+		edit->pos = 0;
 	    }
 	}
 	textinput_redrawn = FALSE;
@@ -450,11 +448,12 @@ static int form_getstr(int cur,
 #else
     if (peek_mouse_levent()) {
 	if (!use_last_tfpos)
-	    MyEdit.pos = 0;
+	    edit->pos = 0;
     }
 #endif /* TEXTFIELDS_MAY_NEED_ACTIVATION && INACTIVE_INPUT_STYLE_VH */
-    LYRefreshEdit(&MyEdit);
+    LYRefreshEdit(edit);
     if (redraw_only) {
+	LYFinishEdit(edit);
 	return 0;		/*return value won't be analysed */
     }
 #ifdef FEPCTRL
@@ -527,7 +526,7 @@ static int form_getstr(int cur,
 		 * within a mouse menu.  Let's at least make sure here that the
 		 * cursor position gets restored.  - kw
 		 */
-		MyEdit.dirty = TRUE;
+		edit->dirty = TRUE;
 	    }
 	} else
 #  endif /* NCURSES || PDCURSES */
@@ -535,8 +534,8 @@ static int form_getstr(int cur,
 
 	{
 	    if (!(ch & LKC_ISLECLAC))
-		ch |= MyEdit.current_modifiers;
-	    MyEdit.current_modifiers = 0;
+		ch |= edit->current_modifiers;
+	    edit->current_modifiers = 0;
 	    if (last_xlkc != -1) {
 		if (ch == last_xlkc)
 		    ch |= LKC_MOD3;
@@ -558,14 +557,14 @@ static int form_getstr(int cur,
 	    /*
 	     * Set flag for modifier 1.
 	     */
-	    MyEdit.current_modifiers |= LKC_MOD1;
+	    edit->current_modifiers |= LKC_MOD1;
 	    continue;
 	}
 	if (action == LYE_SETM2) {
 	    /*
 	     * Set flag for modifier 2.
 	     */
-	    MyEdit.current_modifiers |= LKC_MOD2;
+	    edit->current_modifiers |= LKC_MOD2;
 	    continue;
 	}
 	/*
@@ -608,10 +607,10 @@ static int form_getstr(int cur,
 		while (e1 < e) {
 		    if (*e1 < ' ') {	/* Stop here? */
 			if (e1 > s)
-			    LYEditInsert(&MyEdit, s, (int) (e1 - s), -1, TRUE);
+			    LYEditInsert(edit, s, (int) (e1 - s), -1, TRUE);
 			s = e1;
 			if (*e1 == '\t') {	/* Replace by space */
-			    LYEditInsert(&MyEdit, (unsigned const char *) " ", 1,
+			    LYEditInsert(edit, (unsigned const char *) " ", 1,
 					 -1, TRUE);
 			    s = ++e1;
 			} else
@@ -620,20 +619,14 @@ static int form_getstr(int cur,
 			++e1;
 		}
 		if (e1 > s)
-		    LYEditInsert(&MyEdit, s, (int) (e1 - s), -1, TRUE);
+		    LYEditInsert(edit, s, (int) (e1 - s), -1, TRUE);
 		while (e1 < e && *e1 == '\r')
 		    e1++;
 		if (e1 + 1 < e && *e1 == '\n')
 		    StrAllocCopy(buf, (char *) e1 + 1);		/* Survive _release() */
 		get_clip_release();
-		if (MyEdit.strlen >= (int) max_length) {
-		    HaveMaxlength = TRUE;
-		} else if (HaveMaxlength &&
-			   MyEdit.strlen < (int) max_length) {
-		    HaveMaxlength = FALSE;
-		    _statusline(ENTER_TEXT_ARROWS_OR_TAB);
-		}
-		if (strcmp(value, MyEdit.buffer) != 0) {
+		_statusline(ENTER_TEXT_ARROWS_OR_TAB);
+		if (strcmp(link_value, edit->buffer) != 0) {
 		    Edited = TRUE;
 		}
 		if (buf) {
@@ -642,7 +635,7 @@ static int form_getstr(int cur,
 		    ch = '\n';	/* Sometimes moves to the next line */
 		    break;
 		}
-		LYRefreshEdit(&MyEdit);
+		LYRefreshEdit(edit);
 	    } else {
 		HTInfoMsg(gettext("Clipboard empty or Not text data."));
 #ifdef FEPCTRL
@@ -665,6 +658,7 @@ static int form_getstr(int cur,
 #ifdef FEPCTRL
 	    fep_off();
 #endif
+	    LYFinishEdit(edit);
 	    return (DO_NOTHING);
 	}
 	if (action == LYE_STOP) {
@@ -673,8 +667,9 @@ static int form_getstr(int cur,
 	    break;
 #else
 #ifdef ENHANCED_LINEEDIT
-	    if (MyEdit.mark >= 0)
-		MyEdit.mark = -1 - MyEdit.strlen;	/* Disable. */
+	    if (edit->mark >= 0)
+		/* Disable. */
+		edit->mark = -(int) (1 + edit->buffer_used);
 #endif
 #endif
 	}
@@ -693,18 +688,19 @@ static int form_getstr(int cur,
 	     * Left arrow in column 0 deserves special treatment here, else
 	     * you can get trapped in a form without submit button!
 	     */
-	    if (action == LYE_BACK && MyEdit.pos == 0 && repeat == -1) {
+	    if (action == LYE_BACK && edit->pos == 0 && repeat == -1) {
 		int c = YES;	/* Go back immediately if no changes */
 
 		if (textfield_prompt_at_left_edge) {
 		    c = HTConfirmDefault(PREV_DOC_QUERY, NO);
-		} else if (strcmp(MyEdit.buffer, value)) {
+		} else if (strcmp(edit->buffer, link_value)) {
 		    c = HTConfirmDefault(PREV_DOC_QUERY, NO);
 		}
 		if (c == YES) {
 #ifdef FEPCTRL
 		    fep_off();
 #endif
+		    LYFinishEdit(edit);
 		    return (ch);
 		} else {
 		    if (FormIsReadonly(form))
@@ -746,7 +742,7 @@ static int form_getstr(int cur,
 	    if (repeat < 0)
 		repeat = 1;
 	    while (repeat--) {
-		int rc = LYEdit1(&MyEdit, ch, action & ~LYE_DF, TRUE);
+		int rc = LYEdit1(edit, ch, action & ~LYE_DF, TRUE);
 
 		if (rc < 0) {
 		    ch = -rc;
@@ -781,26 +777,20 @@ static int form_getstr(int cur,
 			refresh_mb = TRUE;
 		} else {
 		    if (!refresh_mb) {
-			LYEdit1(&MyEdit, 0, LYE_DELP, TRUE);
+			LYEdit1(edit, 0, LYE_DELP, TRUE);
 		    }
 		}
 #endif /* SUPPORT_MULTIBYTE_EDIT */
 	    }
-	    if (MyEdit.strlen >= (int) max_length) {
-		HaveMaxlength = TRUE;
-	    } else if (HaveMaxlength &&
-		       MyEdit.strlen < (int) max_length) {
-		HaveMaxlength = FALSE;
-		_statusline(ENTER_TEXT_ARROWS_OR_TAB);
-	    }
-	    if (strcmp(value, MyEdit.buffer)) {
+	    _statusline(ENTER_TEXT_ARROWS_OR_TAB);
+	    if (strcmp(link_value, edit->buffer)) {
 		Edited = TRUE;
 	    }
 #ifdef SUPPORT_MULTIBYTE_EDIT
 	    if (refresh_mb)
 #endif
-		LYRefreshEdit(&MyEdit);
-	    LYSetLastTFPos(MyEdit.pos);
+		LYRefreshEdit(edit);
+	    LYSetLastTFPos(edit->pos);
 	}
     }
   breakfor:
@@ -809,21 +799,21 @@ static int form_getstr(int cur,
 	/*
 	 * Load the new value.
 	 */
-	if (value == form->value) {
+	if (link_value == form->value) {
 	    /*
 	     * The previous value did fit in the line buffer, so replace it
 	     * with the new value.  - FM
 	     */
-	    StrAllocCopy(form->value, MyEdit.buffer);
+	    StrAllocCopy(form->value, edit->buffer);
 	} else {
 	    int old_len = (int) strlen(form->value);
-	    int new_len = (int) strlen(value);
+	    int new_len = (int) strlen(link_value);
 
 	    /*
 	     * Combine the modified tail with the unmodified head.  - FM
 	     */
 	    form->value[(old_len > new_len) ? (old_len - new_len) : 0] = '\0';
-	    StrAllocCat(form->value, MyEdit.buffer);
+	    StrAllocCat(form->value, edit->buffer);
 	    HTUserMsg(FORM_TAIL_COMBINED_WITH_HEAD);
 	}
 
@@ -854,6 +844,7 @@ static int form_getstr(int cur,
 #ifdef FEPCTRL
     fep_off();
 #endif
+    LYFinishEdit(edit);
     return (ch);
 }
 
diff --git a/src/LYKeymap.c b/src/LYKeymap.c
index dc571203..1c1cc24d 100644
--- a/src/LYKeymap.c
+++ b/src/LYKeymap.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYKeymap.c,v 1.79 2011/06/11 12:36:28 tom Exp $ */
+/* $LynxId: LYKeymap.c,v 1.80 2012/02/07 16:04:24 tom Exp $ */
 #include <HTUtils.h>
 #include <LYUtils.h>
 #include <LYGlobalDefs.h>
@@ -1350,15 +1350,32 @@ int lecname_to_lec(const char *func)
 {
     int i;
     struct emap *mp;
+    int result = -1;
 
     if (non_empty(func)) {
 	for (i = 0, mp = ekmap; (*mp).name != NULL; mp++, i++) {
 	    if (strcmp((*mp).name, func) == 0) {
-		return (*mp).code;
+		result = (*mp).code;
+		break;
 	    }
 	}
     }
-    return (-1);
+    return result;
+}
+
+const char *lec_to_lecname(int code)
+{
+    struct emap *mp;
+    int i;
+    const char *result = 0;
+
+    for (i = 0, mp = ekmap; (*mp).name != NULL; mp++, i++) {
+	if ((*mp).code == code) {
+	    result = (*mp).name;
+	    break;
+	}
+    }
+    return result;
 }
 
 /*
diff --git a/src/LYKeymap.h b/src/LYKeymap.h
index 8e665d45..9f1f28e1 100644
--- a/src/LYKeymap.h
+++ b/src/LYKeymap.h
@@ -1,4 +1,4 @@
-/* $LynxId: LYKeymap.h,v 1.44 2011/06/05 19:05:41 tom Exp $ */
+/* $LynxId: LYKeymap.h,v 1.45 2012/02/07 16:02:11 tom Exp $ */
 #ifndef LYKEYMAP_H
 #define LYKEYMAP_H
 
@@ -11,6 +11,7 @@ extern "C" {
 #endif
     extern BOOLEAN LYisNonAlnumKeyname(int ch, int KeyName);
     extern HTList *LYcommandList(void);
+    extern const char *lec_to_lecname(int code);
     extern char *LYKeycodeToString(int c, int upper8);
     extern char *fmt_keys(int lkc_first, int lkc_second);
     extern char *key_for_func(int func);
diff --git a/src/LYOptions.c b/src/LYOptions.c
index b11b175c..9d2bfb5f 100644
--- a/src/LYOptions.c
+++ b/src/LYOptions.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYOptions.c,v 1.144 2011/06/06 08:52:56 tom Exp $ */
+/* $LynxId: LYOptions.c,v 1.147 2012/02/08 01:02:48 tom Exp $ */
 #include <HTUtils.h>
 #include <HTFTP.h>
 #include <HTTP.h>		/* 'reloading' flag */
@@ -344,7 +344,7 @@ void LYoptions(void)
     /*
      * If the user changes the display we need memory to put it in.
      */
-    char display_option[MAX_LINE];
+    bstring *my_data = NULL;
     char *choices[MAXCHOICES];
     int CurrentCharSet = current_char_set;
     int CurrentAssumeCharSet = UCLYhndl_for_unspec;
@@ -642,29 +642,28 @@ void LYoptions(void)
 	    } else if (system_editor) {
 		_statusline(EDITOR_LOCKED);
 	    } else {
-		if (non_empty(editor))
-		    LYStrNCpy(display_option, editor, sizeof(display_option) - 1);
-		else {		/* clear the NONE */
+		if (non_empty(editor)) {
+		    BStrCopy0(my_data, editor);
+		} else {	/* clear the NONE */
 		    LYmove(L_EDITOR, COL_OPTION_VALUES);
 		    LYaddstr("    ");
-		    *display_option = '\0';
+		    BStrCopy0(my_data, "");
 		}
 		_statusline(ACCEPT_DATA);
 		LYmove(L_EDITOR, COL_OPTION_VALUES);
 		lynx_start_bold();
-		ch = LYGetStr(display_option, VISIBLE,
-			      sizeof(display_option), NORECALL);
+		ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 		lynx_stop_bold();
 		LYmove(L_EDITOR, COL_OPTION_VALUES);
 		if (term_options || ch == -1) {
 		    LYaddstr(non_empty(editor) ?
 			     editor : "NONE");
-		} else if (*display_option == '\0') {
+		} else if (isBEmpty(my_data)) {
 		    FREE(editor);
 		    LYaddstr("NONE");
 		} else {
-		    StrAllocCopy(editor, display_option);
-		    LYaddstr(display_option);
+		    StrAllocCopy(editor, my_data->str);
+		    LYaddstr(editor);
 		}
 		LYclrtoeol();
 		if (ch == -1) {
@@ -679,17 +678,16 @@ void LYoptions(void)
 
 	case 'D':		/* Change the display. */
 	    if (non_empty(x_display)) {
-		LYStrNCpy(display_option, x_display, sizeof(display_option) - 1);
+		BStrCopy0(my_data, x_display);
 	    } else {		/* clear the NONE */
 		LYmove(L_DISPLAY, COL_OPTION_VALUES);
 		LYaddstr("    ");
-		*display_option = '\0';
+		BStrCopy0(my_data, "");
 	    }
 	    _statusline(ACCEPT_DATA);
 	    LYmove(L_DISPLAY, COL_OPTION_VALUES);
 	    lynx_start_bold();
-	    ch = LYGetStr(display_option, VISIBLE,
-			  sizeof(display_option), NORECALL);
+	    ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 	    lynx_stop_bold();
 	    LYmove(L_DISPLAY, COL_OPTION_VALUES);
 
@@ -701,7 +699,7 @@ void LYoptions(void)
 
 	    if ((term_options || ch == -1) ||
 		(x_display != NULL &&
-		 !CompareEnvVars(x_display, display_option))) {
+		 !CompareEnvVars(x_display, my_data->str))) {
 		/*
 		 * Cancelled, or a non-NULL display string wasn't changed.  -
 		 * FM
@@ -716,7 +714,7 @@ void LYoptions(void)
 		}
 		response = ' ';
 		break;
-	    } else if (*display_option == '\0') {
+	    } else if (isBEmpty(my_data)) {
 		if ((x_display == NULL) ||
 		    (x_display != NULL && *x_display == '\0')) {
 		    /*
@@ -732,12 +730,12 @@ void LYoptions(void)
 	    /*
 	     * Set the new DISPLAY variable.  - FM
 	     */
-	    LYsetXDisplay(display_option);
+	    LYsetXDisplay(my_data->str);
 	    validate_x_display();
 	    cp = NULL;
 	    LYaddstr(x_display ? x_display : "NONE");
 	    LYclrtoeol();
-	    summarize_x_display(display_option);
+	    summarize_x_display(my_data->str);
 	    response = ' ';
 	    break;
 
@@ -796,27 +794,24 @@ void LYoptions(void)
 		    goto draw_options;
 		}
 		if (non_empty(bookmark_page)) {
-		    LYStrNCpy(display_option,
-			      bookmark_page,
-			      sizeof(display_option) - 1);
+		    BStrCopy0(my_data, bookmark_page);
 		} else {	/* clear the NONE */
 		    LYmove(L_HOME, C_DEFAULT);
 		    LYclrtoeol();
-		    *display_option = '\0';
+		    BStrCopy0(my_data, "");
 		}
 		_statusline(ACCEPT_DATA);
 		LYmove(L_HOME, C_DEFAULT);
 		lynx_start_bold();
-		ch = LYGetStr(display_option, VISIBLE,
-			      sizeof(display_option), NORECALL);
+		ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 		lynx_stop_bold();
 		LYmove(L_HOME, C_DEFAULT);
+		BStrAlloc(my_data, my_data->len + LY_MAXPATH);	/* lengthen */
 		if (term_options ||
-		    ch == -1 || *display_option == '\0') {
+		    ch == -1 || isBEmpty(my_data)) {
 		    LYaddstr(non_empty(bookmark_page) ?
 			     bookmark_page : "NONE");
-		} else if (!LYPathOffHomeOK(display_option,
-					    sizeof(display_option))) {
+		} else if (!LYPathOffHomeOK(my_data->str, my_data->len)) {
 		    LYaddstr(non_empty(bookmark_page) ?
 			     bookmark_page : "NONE");
 		    LYclrtoeol();
@@ -824,7 +819,7 @@ void LYoptions(void)
 		    response = ' ';
 		    break;
 		} else {
-		    StrAllocCopy(bookmark_page, display_option);
+		    StrAllocCopy(bookmark_page, my_data->str);
 		    StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
 		    LYaddstr(bookmark_page);
 		}
@@ -865,31 +860,28 @@ void LYoptions(void)
 
 	case 'P':		/* Change personal mail address for From headers. */
 	    if (non_empty(personal_mail_address)) {
-		LYStrNCpy(display_option,
-			  personal_mail_address,
-			  sizeof(display_option) - 1);
+		BStrCopy0(my_data, personal_mail_address);
 	    } else {		/* clear the NONE */
 		LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
 		LYaddstr("    ");
-		*display_option = '\0';
+		BStrCopy0(my_data, "");
 	    }
 	    _statusline(ACCEPT_DATA);
 	    LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
 	    lynx_start_bold();
-	    ch = LYGetStr(display_option, VISIBLE,
-			  sizeof(display_option), NORECALL);
+	    ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 	    lynx_stop_bold();
 	    LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
 	    if (term_options || ch == -1) {
 		LYaddstr((personal_mail_address &&
 			  *personal_mail_address) ?
 			 personal_mail_address : "NONE");
-	    } else if (*display_option == '\0') {
+	    } else if (isBEmpty(my_data)) {
 		FREE(personal_mail_address);
 		LYaddstr("NONE");
 	    } else {
-		StrAllocCopy(personal_mail_address, display_option);
-		LYaddstr(display_option);
+		StrAllocCopy(personal_mail_address, my_data->str);
+		LYaddstr(personal_mail_address);
 	    }
 	    LYclrtoeol();
 	    if (ch == -1) {
@@ -1081,28 +1073,27 @@ void LYoptions(void)
 
 	case 'G':		/* Change language preference. */
 	    if (non_empty(language)) {
-		LYStrNCpy(display_option, language, sizeof(display_option) - 1);
+		BStrCopy0(my_data, language);
 	    } else {		/* clear the NONE */
 		LYmove(L_LANGUAGE, COL_OPTION_VALUES);
 		LYaddstr("    ");
-		*display_option = '\0';
+		BStrCopy0(my_data, "");
 	    }
 	    _statusline(ACCEPT_DATA);
 	    LYmove(L_LANGUAGE, COL_OPTION_VALUES);
 	    lynx_start_bold();
-	    ch = LYGetStr(display_option, VISIBLE,
-			  sizeof(display_option), NORECALL);
+	    ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 	    lynx_stop_bold();
 	    LYmove(L_LANGUAGE, COL_OPTION_VALUES);
 	    if (term_options || ch == -1) {
 		LYaddstr(non_empty(language) ?
 			 language : "NONE");
-	    } else if (*display_option == '\0') {
+	    } else if (isBEmpty(my_data)) {
 		FREE(language);
 		LYaddstr("NONE");
 	    } else {
-		StrAllocCopy(language, display_option);
-		LYaddstr(display_option);
+		StrAllocCopy(language, my_data->str);
+		LYaddstr(language);
 	    }
 	    LYclrtoeol();
 	    if (ch == -1) {
@@ -1116,30 +1107,27 @@ void LYoptions(void)
 
 	case 'H':		/* Change charset preference. */
 	    if (non_empty(pref_charset)) {
-		LYStrNCpy(display_option,
-			  pref_charset,
-			  sizeof(display_option) - 1);
+		BStrCopy0(my_data, pref_charset);
 	    } else {		/* clear the NONE */
 		LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
 		LYaddstr("    ");
-		*display_option = '\0';
+		BStrCopy0(my_data, "");
 	    }
 	    _statusline(ACCEPT_DATA);
 	    LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
 	    lynx_start_bold();
-	    ch = LYGetStr(display_option, VISIBLE,
-			  sizeof(display_option), NORECALL);
+	    ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 	    lynx_stop_bold();
 	    LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
 	    if (term_options || ch == -1) {
 		LYaddstr(non_empty(pref_charset) ?
 			 pref_charset : "NONE");
-	    } else if (*display_option == '\0') {
+	    } else if (isBEmpty(my_data)) {
 		FREE(pref_charset);
 		LYaddstr("NONE");
 	    } else {
-		StrAllocCopy(pref_charset, display_option);
-		LYaddstr(display_option);
+		StrAllocCopy(pref_charset, my_data->str);
+		LYaddstr(pref_charset);
 	    }
 	    LYclrtoeol();
 	    if (ch == -1) {
@@ -1450,33 +1438,30 @@ void LYoptions(void)
 	case 'A':		/* Change user agent string. */
 	    if (!no_useragent) {
 		if (non_empty(LYUserAgent)) {
-		    LYStrNCpy(display_option,
-			      LYUserAgent,
-			      sizeof(display_option) - 1);
+		    BStrCopy0(my_data, LYUserAgent);
 		} else {	/* clear the NONE */
 		    LYmove(L_HOME, COL_OPTION_VALUES);
 		    LYaddstr("    ");
-		    *display_option = '\0';
+		    BStrCopy0(my_data, "");
 		}
 		_statusline(ACCEPT_DATA_OR_DEFAULT);
 		LYmove(L_User_Agent, COL_OPTION_VALUES);
 		lynx_start_bold();
-		ch = LYGetStr(display_option, VISIBLE,
-			      sizeof(display_option), NORECALL);
+		ch = LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 		lynx_stop_bold();
 		LYmove(L_User_Agent, COL_OPTION_VALUES);
 		if (term_options || ch == -1) {
 		    LYaddstr((LYUserAgent &&
 			      *LYUserAgent) ?
 			     LYUserAgent : "NONE");
-		} else if (*display_option == '\0') {
+		} else if (isBEmpty(my_data)) {
 		    StrAllocCopy(LYUserAgent, LYUserAgentDefault);
 		    LYaddstr((LYUserAgent &&
 			      *LYUserAgent) ?
 			     LYUserAgent : "NONE");
 		} else {
-		    StrAllocCopy(LYUserAgent, display_option);
-		    LYaddstr(display_option);
+		    StrAllocCopy(LYUserAgent, my_data->str);
+		    LYaddstr(LYUserAgent);
 		}
 		LYclrtoeol();
 		if (ch == -1) {
@@ -1586,6 +1571,8 @@ void LYoptions(void)
     term_options = FALSE;
     LYStatusLine = -1;		/* let user_mode have some of the screen */
     signal(SIGINT, cleanup_sig);
+    BStrFree(my_data);
+    return;
 }
 
 static int widest_choice(const char **choices)
@@ -1782,7 +1769,7 @@ void edit_bookmarks(void)
 
 #define MULTI_OFFSET 8
     int a;			/* misc counter */
-    char MBM_tmp_line[LY_MAXPATH];	/* buffer for LYGetStr */
+    bstring *my_data = NULL;
 
     /*
      * We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display the whole list
@@ -1981,18 +1968,16 @@ void edit_bookmarks(void)
 			       9);
 		    else
 			LYmove((3 + a), 9);
-		    LYStrNCpy(MBM_tmp_line,
+		    BStrCopy0(my_data,
 			      (!MBM_A_subdescript[a] ?
-			       "" : MBM_A_subdescript[a]),
-			      sizeof(MBM_tmp_line) - 1);
-		    (void) LYGetStr(MBM_tmp_line, VISIBLE,
-				    sizeof(MBM_tmp_line), NORECALL);
+			       "" : MBM_A_subdescript[a]));
+		    (void) LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 		    lynx_stop_bold();
 
-		    if (strlen(MBM_tmp_line) < 1) {
+		    if (isBEmpty(my_data)) {
 			FREE(MBM_A_subdescript[a]);
 		    } else {
-			StrAllocCopy(MBM_A_subdescript[a], MBM_tmp_line);
+			StrAllocCopy(MBM_A_subdescript[a], my_data->str);
 		    }
 		    if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
 			LYmove((3 + a)
@@ -2019,26 +2004,25 @@ void edit_bookmarks(void)
 		LYaddstr("| ");
 
 		lynx_start_bold();
-		LYStrNCpy(MBM_tmp_line,
-			  NonNull(MBM_A_subbookmark[a]),
-			  sizeof(MBM_tmp_line) - 1);
-		(void) LYGetStr(MBM_tmp_line, VISIBLE,
-				sizeof(MBM_tmp_line), NORECALL);
+		BStrCopy0(my_data, NonNull(MBM_A_subbookmark[a]));
+		(void) LYgetBString(&my_data, VISIBLE, 0, NORECALL);
 		lynx_stop_bold();
 
-		if (*MBM_tmp_line == '\0') {
+		if (isBEmpty(my_data)) {
 		    if (a == 0)
 			StrAllocCopy(MBM_A_subbookmark[a], bookmark_page);
 		    else
 			FREE(MBM_A_subbookmark[a]);
-		} else if (!LYPathOffHomeOK(MBM_tmp_line,
-					    sizeof(MBM_tmp_line))) {
-		    LYMBM_statusline(USE_PATH_OFF_HOME);
-		    LYSleepAlert();
 		} else {
-		    StrAllocCopy(MBM_A_subbookmark[a], MBM_tmp_line);
-		    if (a == 0) {
-			StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]);
+		    BStrAlloc(my_data, my_data->len + LY_MAXPATH);
+		    if (!LYPathOffHomeOK(my_data->str, my_data->len)) {
+			LYMBM_statusline(USE_PATH_OFF_HOME);
+			LYSleepAlert();
+		    } else {
+			StrAllocCopy(MBM_A_subbookmark[a], my_data->str);
+			if (a == 0) {
+			    StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]);
+			}
 		    }
 		}
 		if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
@@ -2059,6 +2043,7 @@ void edit_bookmarks(void)
 	}			/* end for */
     }				/* end while */
 
+    BStrFree(my_data);
     term_options = FALSE;
     signal(SIGINT, cleanup_sig);
 }
diff --git a/src/LYStrings.c b/src/LYStrings.c
index 749b3187..88c20443 100644
--- a/src/LYStrings.c
+++ b/src/LYStrings.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYStrings.c,v 1.184 2011/06/06 08:26:37 tom Exp $ */
+/* $LynxId: LYStrings.c,v 1.198 2012/02/08 01:22:55 tom Exp $ */
 #include <HTUtils.h>
 #include <HTCJK.h>
 #include <UCAux.h>
@@ -1766,7 +1766,7 @@ static int LYgetch_for(int code)
     }
 #endif /* !USE_SLANG || VMS */
 
-    CTRACE((tfp, "GETCH: Got %#x.\n", c));
+    CTRACE((tfp, "GETCH%d: Got %#x.\n", code, c));
 #ifdef MISC_EXP
     if (LYNoZapKey > 1 && errno != EINTR &&
 	(c == EOF
@@ -2857,8 +2857,9 @@ void LYTrimAllStartfile(char *buffer)
 #define StartY	 edit->sy
 #define Buf	 edit->buffer
 #define Pos	 edit->pos	/* current editing position (bytes) */
-#define StrLen	 edit->strlen	/* length (bytes) */
-#define MaxLen	 edit->maxlen
+#define StrLen	 edit->buffer_used	/* length (bytes) */
+#define MaxLen	 edit->buffer_size
+#define BufLimit edit->buffer_limit
 #define DspWdth  edit->dspwdth
 #define DspStart edit->xpan	/* display-start (columns) */
 #define Margin	 edit->margin
@@ -2867,15 +2868,67 @@ void LYTrimAllStartfile(char *buffer)
 #ifdef ENHANCED_LINEEDIT
 #define Mark	 edit->mark
 #endif
+#define CurModif edit->current_modifiers
+#define Offs2Col edit->offset2col
 
 #ifdef ENHANCED_LINEEDIT
-static char killbuffer[MAX_EDIT] = "\0";
+static bstring *killbuffer;
 #endif
 
-void LYSetupEdit(EDREC * edit, char *old,
-		 int maxstr,
-		 int maxdsp)
+static void updateMargin(EDREC * edit)
 {
+    if ((int) MaxLen > DspWdth) {	/* Need panning? */
+	if (DspWdth > 4)	/* Else "{}" take up precious screen space */
+	    PanOn = TRUE;
+
+	/*
+	 * Figure out margins.  If too big, we do a lot of unnecessary
+	 * scrolling.  If too small, user doesn't have sufficient look-ahead. 
+	 * Let's say 25% for each margin, upper bound is 10 columns.
+	 */
+	Margin = DspWdth / 4;
+	if (Margin > 10)
+	    Margin = 10;
+    }
+}
+
+/*
+ * Before using an array position, make sure that the array is long enough.
+ * Reallocate if needed.
+ */
+static void ExtendEditor(EDREC * edit, int position)
+{
+    size_t need = (size_t) (++position);
+
+    if (need >= MaxLen && (BufLimit == 0 || need < BufLimit)) {
+	CTRACE((tfp, "ExtendEditor from %d to %d\n", MaxLen, need));
+	Buf = typeRealloc(char, Buf, need);
+	Offs2Col = typeRealloc(int, Offs2Col, need + 1);
+
+	MaxLen = need;
+	updateMargin(edit);
+    }
+}
+
+void LYFinishEdit(EDREC * edit)
+{
+    CTRACE((tfp, "LYFinishEdit:%s\n", NonNull(Buf)));
+
+    FREE(Buf);
+    FREE(Offs2Col);
+}
+
+void LYSetupEdit(EDREC * edit, char *old_value, size_t buffer_limit, int display_limit)
+{
+    CTRACE((tfp, "LYSetupEdit buffer %d, display %d:%s\n",
+	    buffer_limit,
+	    display_limit,
+	    NonNull(old_value)));
+
+    BufLimit = buffer_limit;
+    if (buffer_limit == 0)
+	buffer_limit = strlen(old_value) + 1;
+
     /*
      * Initialize edit record
      */
@@ -2883,33 +2936,24 @@ void LYSetupEdit(EDREC * edit, char *old,
     PadChar = ' ';
     IsDirty = TRUE;
     PanOn = FALSE;
-    edit->current_modifiers = 0;
+    CurModif = 0;
 
-    MaxLen = maxstr;
-    DspWdth = maxdsp;
+    MaxLen = buffer_limit;
+    DspWdth = display_limit;
     Margin = 0;
-    Pos = (int) strlen(old);
+    Pos = (int) strlen(old_value);
 #ifdef ENHANCED_LINEEDIT
     Mark = -1;			/* pos=0, but do not show it yet */
 #endif
     DspStart = 0;
 
-    if (maxstr > maxdsp) {	/* Need panning? */
-	if (DspWdth > 4)	/* Else "{}" take up precious screen space */
-	    PanOn = TRUE;
+    updateMargin(edit);
 
-	/*
-	 * Figure out margins.  If too big, we do a lot of unnecessary
-	 * scrolling.  If too small, user doesn't have sufficient look-ahead. 
-	 * Let's say 25% for each margin, upper bound is 10 columns.
-	 */
-	Margin = DspWdth / 4;
-	if (Margin > 10)
-	    Margin = 10;
-    }
+    StrLen = strlen(old_value);
+    Buf = typecallocn(char, MaxLen + 1);
 
-    LYStrNCpy(Buf, old, maxstr);
-    StrLen = (int) strlen(Buf);
+    LYStrNCpy(Buf, old_value, buffer_limit);
+    Offs2Col = typecallocn(int, MaxLen + 1);
 }
 
 #ifdef SUPPORT_MULTIBYTE_EDIT
@@ -3018,7 +3062,7 @@ int LYEditInsert(EDREC * edit, unsigned const char *s,
 		 int maxMessage)
 {
     int length = (int) strlen(Buf);
-    int remains = MaxLen - (length + len);
+    int remains = (int) MaxLen - (length + len);
     int edited = 0, overflow = 0;
 
     /*
@@ -3027,11 +3071,12 @@ int LYEditInsert(EDREC * edit, unsigned const char *s,
     if (remains < 0) {
 	overflow = 1;
 	len = 0;
-	if (MaxLen > length)	/* Insert as much as we can */
-	    len = MaxLen - length;
+	if ((int) MaxLen > length)	/* Insert as much as we can */
+	    len = (int) MaxLen - length;
 	else
 	    goto finish;
     }
+    ExtendEditor(edit, length + len);
     Buf[length + len] = '\0';
     for (; length >= Pos; length--)	/* Make room */
 	Buf[length + len] = Buf[length];
@@ -3106,7 +3151,7 @@ int LYEditInsert(EDREC * edit, unsigned const char *s,
 
   finish:
     Pos += len;
-    StrLen += len;
+    StrLen += (size_t) len;
     if (edited)
 	IsDirty = TRUE;
     if (overflow && maxMessage)
@@ -3114,10 +3159,10 @@ int LYEditInsert(EDREC * edit, unsigned const char *s,
 #ifdef ENHANCED_LINEEDIT
     if (Mark > Pos)
 	Mark += len;
-    else if (Mark < -1 - Pos)
+    else if (Mark < -(1 + Pos))
 	Mark -= len;
     if (Mark >= 0)
-	Mark = -1 - Mark;	/* Disable it */
+	Mark = -(1 + Mark);	/* Disable it */
 #endif
     return edited;
 }
@@ -3135,11 +3180,11 @@ int LYEdit1(EDREC * edit, int ch,
     unsigned char uch;
     int offset;
 
-    if (MaxLen <= 0)
+    if ((int) MaxLen <= 0)
 	return (0);		/* Be defensive */
 
-    length = (int) strlen(&Buf[0]);
-    StrLen = length;
+    StrLen = strlen(&Buf[0]);
+    length = (int) StrLen;
 
     switch (action) {
 #ifdef EXP_KEYBOARD_LAYOUT
@@ -3180,15 +3225,16 @@ int LYEdit1(EDREC * edit, int ch,
 	if (ch + 64 >= LYlowest_eightbit[current_char_set])
 	    ch += 64;
 
-	if (Pos <= (MaxLen) && StrLen < (MaxLen)) {
+	if (Pos <= ((int) MaxLen) && StrLen < MaxLen) {
 #ifdef ENHANCED_LINEEDIT
 	    if (Mark > Pos)
 		Mark++;
-	    else if (Mark < -1 - Pos)
+	    else if (Mark < -(1 + Pos))
 		Mark--;
 	    if (Mark >= 0)
-		Mark = -1 - Mark;	/* Disable it */
+		Mark = -(1 + Mark);	/* Disable it */
 #endif
+	    ExtendEditor(edit, length + 1);
 	    for (i = length; i >= Pos; i--)	/* Make room */
 		Buf[i + 1] = Buf[i];
 	    Buf[length + 1] = '\0';
@@ -3285,11 +3331,11 @@ int LYEdit1(EDREC * edit, int ch,
 	    Buf[i] = Buf[i + offset];
 #ifdef ENHANCED_LINEEDIT
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
-	if (Mark <= -1 - Pos - offset)
+	    Mark = -(1 + Mark);	/* Disable it */
+	if (Mark <= -(1 + Pos + offset))
 	    Mark += offset;	/* Shift it */
-	if (-1 - Pos - offset < Mark && Mark < -1 - Pos)
-	    Mark = -1 - Pos;	/* Set to the current position */
+	if (-(1 + Pos + offset) < Mark && Mark < -(1 + Pos))
+	    Mark = -(1 + Pos);	/* Set to the current position */
 #endif
 
 	break;
@@ -3303,8 +3349,8 @@ int LYEdit1(EDREC * edit, int ch,
 
 #ifdef ENHANCED_LINEEDIT
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
-	if (Mark <= -1 - Pos)
+	    Mark = -(1 + Mark);	/* Disable it */
+	if (Mark <= -(1 + Pos))
 	    Mark += Pos;	/* Shift it */
 	else
 	    Mark = -1;		/* Reset it */
@@ -3319,8 +3365,8 @@ int LYEdit1(EDREC * edit, int ch,
 	Buf[Pos] = '\0';
 #ifdef ENHANCED_LINEEDIT
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
-	if (Mark <= -1 - Pos)
+	    Mark = -(1 + Mark);	/* Disable it */
+	if (Mark <= -(1 + Pos))
 	    Mark = -1;		/* Reset it */
 #endif
 	break;
@@ -3349,8 +3395,8 @@ int LYEdit1(EDREC * edit, int ch,
 #ifndef SUPPORT_MULTIBYTE_EDIT
 #ifdef ENHANCED_LINEEDIT
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
-	if (Mark <= -1 - Pos)
+	    Mark = -(1 + Mark);	/* Disable it */
+	if (Mark <= -(1 + Pos))
 	    Mark++;
 #endif
 	Pos--;
@@ -3364,8 +3410,8 @@ int LYEdit1(EDREC * edit, int ch,
 
 #ifdef ENHANCED_LINEEDIT
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
-	if (Mark <= -1 - Pos)
+	    Mark = -(1 + Mark);	/* Disable it */
+	if (Mark <= -(1 + Pos))
 	    Mark += offset;	/* Shift it */
 #endif
 
@@ -3420,11 +3466,11 @@ int LYEdit1(EDREC * edit, int ch,
 	if (Pos == length)
 	    Pos--;
 	if (Mark < 0)
-	    Mark = -1 - Mark;	/* Temporary enable it */
+	    Mark = -(1 + Mark);	/* Temporary enable it */
 	if (Mark == Pos || Mark == Pos + 1)
 	    Mark = Pos - 1;
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
+	    Mark = -(1 + Mark);	/* Disable it */
 	if (Buf[Pos - 1] == Buf[Pos]) {
 	    Pos++;
 	    break;
@@ -3446,7 +3492,7 @@ int LYEdit1(EDREC * edit, int ch,
 	 * emacs-like exchange-point-and-mark
 	 */
 	if (Mark < 0)
-	    Mark = -1 - Mark;	/* Enable it */
+	    Mark = -(1 + Mark);	/* Enable it */
 	if (Mark == Pos)
 	    return (0);
 	i = Pos;
@@ -3459,9 +3505,9 @@ int LYEdit1(EDREC * edit, int ch,
 	 * primitive emacs-like kill-region
 	 */
 	if (Mark < 0)
-	    Mark = -1 - Mark;	/* Enable it */
+	    Mark = -(1 + Mark);	/* Enable it */
 	if (Mark == Pos) {
-	    killbuffer[0] = '\0';
+	    BStrFree(killbuffer);
 	    return (0);
 	}
 	if (Mark > Pos)
@@ -3469,34 +3515,37 @@ int LYEdit1(EDREC * edit, int ch,
 	{
 	    int reglen = Pos - Mark;
 
-	    LYStrNCpy(killbuffer, &Buf[Mark],
-		      HTMIN(reglen, (int) sizeof(killbuffer) - 1));
+	    BStrCopy1(killbuffer, Buf + Mark, reglen);
 	    for (i = Mark; Buf[i + reglen]; i++)
 		Buf[i] = Buf[i + reglen];
 	    Buf[i] = Buf[i + reglen];	/* terminate */
 	    Pos = Mark;
 	}
 	if (Mark >= 0)
-	    Mark = -1 - Mark;	/* Disable it */
+	    Mark = -(1 + Mark);	/* Disable it */
 	break;
 
     case LYE_YANK:
 	/*
 	 * primitive emacs-like yank
 	 */
-	if (!killbuffer[0]) {
-	    Mark = -1 - Pos;
+	if (!killbuffer) {
+	    Mark = -(1 + Pos);
 	    return (0);
-	} {
-	    int yanklen = (int) strlen(killbuffer);
+	} else {
+	    int yanklen = killbuffer->len;
+
+	    if ((Pos + yanklen) <= (int) MaxLen &&
+		StrLen + (size_t) yanklen <= MaxLen) {
+
+		ExtendEditor(edit, Pos + yanklen);
 
-	    if (Pos + yanklen <= (MaxLen) && StrLen + yanklen <= (MaxLen)) {
-		Mark = -1 - Pos;
+		Mark = -(1 + Pos);
 
 		for (i = length; i >= Pos; i--)		/* Make room */
 		    Buf[i + yanklen] = Buf[i];
 		for (i = 0; i < yanklen; i++)
-		    Buf[Pos++] = killbuffer[i];
+		    Buf[Pos++] = killbuffer->str[i];
 
 	    } else if (maxMessage) {
 		_statusline(MAXLEN_REACHED_DEL_OR_MOV);
@@ -3518,7 +3567,7 @@ int LYEdit1(EDREC * edit, int ch,
 	return (ch);
     }
     IsDirty = TRUE;
-    StrLen = (int) strlen(&Buf[0]);
+    StrLen = strlen(&Buf[0]);
     return (0);
 }
 
@@ -3607,7 +3656,7 @@ static void remember_column(EDREC * edit, int offset)
 #else
     getyx(stdscr, y0, x0);
 #endif
-    edit->offset2col[offset] = x0;
+    Offs2Col[offset] = x0;
 }
 
 static void fill_edited_line(int prompting GCC_UNUSED, int length, int ch)
@@ -3672,10 +3721,12 @@ void LYRefreshEdit(EDREC * edit)
     if (!IsDirty || (DspWdth == 0))
 	return;
 
+    CTRACE((tfp, "LYRefreshEdit:%s\n", Buf));
+
     IsDirty = FALSE;
 
-    all_bytes = (int) strlen(&Buf[0]);
-    StrLen = all_bytes;
+    StrLen = strlen(&Buf[0]);
+    all_bytes = (int) StrLen;
 
     all_cells = LYstrCells(Buf);
     pos_cells = LYstrExtent2(Buf, Pos);
@@ -3825,11 +3876,11 @@ void LYRefreshEdit(EDREC * edit)
 	    int j = (int) (next - str);
 
 	    while (i < j) {
-		edit->offset2col[i++] = cell + StartX;
+		Offs2Col[i++] = cell + StartX;
 	    }
 	    cell += LYstrExtent2(last, (int) (next - last));
 	} while (i < dpy_bytes);
-	edit->offset2col[i] = cell + StartX;
+	Offs2Col[i] = cell + StartX;
     } else {
 #if defined(ENHANCED_LINEEDIT) && defined(USE_COLOR_STYLE)
 	if (Mark >= 0 && DspStart > Mark)
@@ -3853,7 +3904,7 @@ void LYRefreshEdit(EDREC * edit)
 		      & UCT_R_8859SPECL))))) {
 		LYaddch(' ');
 	    } else if (str[i] == '\t') {
-		int col = edit->offset2col[i] - StartX;
+		int col = Offs2Col[i] - StartX;
 
 		/*
 		 * Like LYwaddnstr(), expand tabs from the beginning of the
@@ -3880,7 +3931,7 @@ void LYRefreshEdit(EDREC * edit)
     /*
      * Erase rest of input area.
      */
-    padsize = DspWdth - (edit->offset2col[dpy_bytes] - StartX);
+    padsize = DspWdth - (Offs2Col[dpy_bytes] - StartX);
     fill_edited_line(prompting, padsize, PadChar);
 
     /*
@@ -3898,7 +3949,7 @@ void LYRefreshEdit(EDREC * edit)
     /*
      * Finally, move the cursor to the point where the next edit will occur.
      */
-    LYmove(StartY, edit->offset2col[Pos - DspStart]);
+    LYmove(StartY, Offs2Col[Pos - DspStart]);
 
 #ifdef USE_COLOR_STYLE
     if (estyle != NOSTYLE)
@@ -5007,42 +5058,41 @@ int LYhandlePopupList(int cur_choice,
     return (disabled ? orig_choice : cur_choice);
 }
 
-#define CurModif MyEdit.current_modifiers
-
-int LYgetstr(char *inputline,
-	     int hidden,
-	     size_t bufsize,
-	     RecallType recall)
+/*
+ * Allow the user to edit a string.
+ */
+int LYgetBString(bstring **inputline,
+		 int hidden,
+		 size_t max_cols,
+		 RecallType recall)
 {
-    int x, y, MaxStringSize;
+    int x, y;
     int ch;
     int xlec = -2;
     int last_xlec = -1;
     int last_xlkc = -1;
-    EditFieldData MyEdit;
+    EditFieldData MyEdit, *edit = &MyEdit;
 
 #ifdef SUPPORT_MULTIBYTE_EDIT
     BOOL refresh_mb = TRUE;
 #endif /* SUPPORT_MULTIBYTE_EDIT */
 
+    CTRACE((tfp, "called LYgetBString hidden %d, recall %d\n", hidden, recall));
+
     LYGetYX(y, x);		/* Use screen from cursor position to eol */
-    MaxStringSize = (int) ((bufsize < sizeof(MyEdit.buffer))
-			   ? (bufsize - 1)
-			   : (sizeof(MyEdit.buffer) - 1));
-    LYSetupEdit(&MyEdit, inputline, MaxStringSize, LYcolLimit - x);
-    MyEdit.hidden = (BOOL) hidden;
+    LYSetupEdit(edit, (*inputline)->str, max_cols, LYcolLimit - x);
+    IsHidden = (BOOL) hidden;
 #ifdef FEPCTRL
     fep_on();
 #endif
 
-    CTRACE((tfp, "called LYgetstr\n"));
     for (;;) {
       again:
 #ifndef SUPPORT_MULTIBYTE_EDIT
-	LYRefreshEdit(&MyEdit);
+	LYRefreshEdit(edit);
 #else /* SUPPORT_MULTIBYTE_EDIT */
 	if (refresh_mb)
-	    LYRefreshEdit(&MyEdit);
+	    LYRefreshEdit(edit);
 #endif /* SUPPORT_MULTIBYTE_EDIT */
 	ch = LYReadCmdKey(FOR_PROMPT);
 #ifdef SUPPORT_MULTIBYTE_EDIT
@@ -5073,12 +5123,13 @@ int LYgetstr(char *inputline,
 	}
 
 	if (recall != NORECALL && (ch == UPARROW || ch == DNARROW)) {
-	    LYStrNCpy(inputline, MyEdit.buffer, bufsize);
-	    LYAddToCloset(recall, MyEdit.buffer);
-	    CTRACE((tfp, "LYgetstr(%s) recall\n", inputline));
+	    BStrCopy0(*inputline, Buf);
+	    LYAddToCloset(recall, Buf);
+	    CTRACE((tfp, "LYgetstr(%s) recall\n", (*inputline)->str));
 #ifdef FEPCTRL
 	    fep_off();
 #endif
+	    LYFinishEdit(edit);
 	    return (ch);
 	}
 	ch |= CurModif;
@@ -5124,7 +5175,7 @@ int LYgetstr(char *inputline,
 		    int num_options = LYarrayLength((const char **) data);
 
 		    while (cur_choice < num_options
-			   && strcasecomp(data[cur_choice], MyEdit.buffer) < 0)
+			   && strcasecomp(data[cur_choice], Buf) < 0)
 			cur_choice++;
 
 		    LYGetYX(old_y, old_x);
@@ -5139,13 +5190,13 @@ int LYgetstr(char *inputline,
 		    if (cur_choice >= 0) {
 			if (recall == RECALL_CMD)
 			    _statusline(": ");
-			reinsertEdit(&MyEdit, data[cur_choice]);
+			reinsertEdit(edit, data[cur_choice]);
 		    }
 		    LYmove(old_y, old_x);
 		    FREE(data);
 		}
 	    } else {
-		reinsertEdit(&MyEdit, LYFindInCloset(recall, MyEdit.buffer));
+		reinsertEdit(edit, LYFindInCloset(recall, Buf));
 	    }
 	    break;
 
@@ -5160,7 +5211,7 @@ int LYgetstr(char *inputline,
 	    if (ch != '\t' &&
 		(IS_CJK_TTY ||
 		 LYlowest_eightbit[current_char_set] <= 0x97)) {
-		LYLineEdit(&MyEdit, ch, FALSE);
+		LYLineEdit(edit, ch, FALSE);
 		break;
 	    }
 	    /* FALLTHRU */
@@ -5169,13 +5220,14 @@ int LYgetstr(char *inputline,
 	    /*
 	     * Terminate the string and return.
 	     */
-	    LYStrNCpy(inputline, MyEdit.buffer, bufsize);
+	    BStrCopy0(*inputline, Buf);
 	    if (!hidden)
-		LYAddToCloset(recall, MyEdit.buffer);
-	    CTRACE((tfp, "LYgetstr(%s) LYE_ENTER\n", inputline));
+		LYAddToCloset(recall, Buf);
+	    CTRACE((tfp, "LYgetstr(%s) LYE_ENTER\n", (*inputline)->str));
 #ifdef FEPCTRL
 	    fep_off();
 #endif
+	    LYFinishEdit(edit);
 	    return (ch);
 
 #ifdef CAN_CUT_AND_PASTE
@@ -5197,11 +5249,11 @@ int LYgetstr(char *inputline,
 		    while (e1 < e) {
 			if (*e1 < ' ') {	/* Stop here? */
 			    if (e1 > s)
-				LYEditInsert(&MyEdit, s, (int) (e1 - s),
+				LYEditInsert(edit, s, (int) (e1 - s),
 					     map_active, TRUE);
 			    s = e1;
 			    if (*e1 == '\t') {	/* Replace by space */
-				LYEditInsert(&MyEdit,
+				LYEditInsert(edit,
 					     (unsigned const char *) " ",
 					     1,
 					     map_active,
@@ -5213,7 +5265,7 @@ int LYgetstr(char *inputline,
 			    ++e1;
 		    }
 		    if (e1 > s)
-			LYEditInsert(&MyEdit, s, (int) (e1 - s), map_active, TRUE);
+			LYEditInsert(edit, s, (int) (e1 - s), map_active, TRUE);
 		}
 		get_clip_release();
 		break;
@@ -5224,11 +5276,11 @@ int LYgetstr(char *inputline,
 	    /*
 	     * Control-C or Control-G aborts.
 	     */
-	    inputline[0] = '\0';
 	    CTRACE((tfp, "LYgetstr LYE_ABORT\n"));
 #ifdef FEPCTRL
 	    fep_off();
 #endif
+	    LYFinishEdit(edit);
 	    return (-1);
 
 	case LYE_STOP:
@@ -5238,14 +5290,15 @@ int LYgetstr(char *inputline,
 	    CTRACE((tfp, "LYgetstr LYE_STOP\n"));
 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
 	    textfields_need_activation = TRUE;
+	    LYFinishEdit(edit);
 	    return (-1);
 #else
 #ifdef ENHANCED_LINEEDIT
 	    if (Mark >= 0)
-		Mark = -1 - Mark;	/* Disable it */
-#endif
+		Mark = -(1 + Mark);	/* Disable it */
 #endif
 	    break;
+#endif
 
 	case LYE_LKCMD:
 	    /*
@@ -5271,24 +5324,45 @@ int LYgetstr(char *inputline,
 		break;
 	    }
 #ifndef SUPPORT_MULTIBYTE_EDIT
-	    LYLineEdit(&MyEdit, ch, FALSE);
+	    LYLineEdit(edit, ch, FALSE);
 #else /* SUPPORT_MULTIBYTE_EDIT */
-	    if (LYLineEdit(&MyEdit, ch, FALSE) == 0) {
+	    if (LYLineEdit(edit, ch, FALSE) == 0) {
 		if (refresh_mb && IS_CJK_TTY && (0x81 <= ch) && (ch <= 0xfe))
 		    refresh_mb = FALSE;
 		else
 		    refresh_mb = TRUE;
 	    } else {
 		if (!refresh_mb) {
-		    LYEdit1(&MyEdit, 0, LYE_DELP, FALSE);
+		    LYEdit1(edit, 0, LYE_DELP, FALSE);
 		}
 	    }
 #endif /* SUPPORT_MULTIBYTE_EDIT */
 	}
     }
-#ifdef FEPCTRL
-    fep_off();
-#endif
+}
+
+/*
+ * Use this for fixed-buffer edits which have not been converted to use
+ * LYgetBString().
+ */
+int LYgetstr(char *inputline,	/* fixed-size buffer for input/output */
+	     int hidden,	/* true to suppress from command-history */
+	     size_t bufsize,	/* sizeof(inputline) */
+	     RecallType recall)	/* type of command-history */
+{
+    int ch;
+    bstring *my_bstring = NULL;
+
+    BStrCopy0(my_bstring, inputline);
+    if (my_bstring != 0) {
+	ch = LYgetBString(&my_bstring, hidden, bufsize, recall);
+	if (ch >= 0 && my_bstring != 0)
+	    LYStrNCpy(inputline, my_bstring->str, bufsize);
+	BStrFree(my_bstring);
+    } else {
+	ch = -1;
+    }
+    return ch;
 }
 
 const char *LYLineeditHelpURL(void)
diff --git a/src/LYStrings.h b/src/LYStrings.h
index b3b27af3..f661d59b 100644
--- a/src/LYStrings.h
+++ b/src/LYStrings.h
@@ -1,5 +1,5 @@
 /*
- * $LynxId: LYStrings.h,v 1.79 2011/05/28 13:07:55 tom Exp $
+ * $LynxId: LYStrings.h,v 1.86 2012/02/07 19:47:45 tom Exp $
  */
 #ifndef LYSTRINGS_H
 #define LYSTRINGS_H
@@ -50,6 +50,10 @@ extern "C" {
 			RecallType recall);
 #define LYGetStr(input,hidden,bufsize,recall) \
 	LYgetstr(input,hidden,(size_t)(bufsize),recall)
+    extern int LYgetBString(bstring **inputline,
+			    int hidden,
+			    size_t max_cols,
+			    RecallType recall);
     extern int LYscanFloat(const char *source, float *result);
     extern int LYscanFloat2(const char **source, float *result);
     extern char *LYstrsep(char **stringp,
@@ -195,18 +199,17 @@ extern "C" {
 #define ENHANCED_LINEEDIT
 #endif
 
-#define MAX_EDIT 1024
-
 /* EditFieldData preserves state between calls to LYEdit1
  */
     typedef struct _EditFieldData {
 
 	int sx;			/* Origin of editfield                       */
 	int sy;
-	int dspwdth;		/* Screen real estate for editting           */
+	int dspwdth;		/* Screen real estate for editing            */
 
-	int strlen;		/* Current size of string.                   */
-	int maxlen;		/* Max size of string, excluding zero at end */
+	size_t buffer_used;	/* current size of string.                   */
+	size_t buffer_size;	/* current buffer-size, excluding nul at end */
+	size_t buffer_limit;	/* buffer size limit, zero if indefinite     */
 	char pad;		/* Right padding  typically ' ' or '_'       */
 	BOOL hidden;		/* Masked password entry flag                */
 
@@ -221,10 +224,8 @@ extern "C" {
 				   unactive mark.  */
 #endif
 
-	char buffer[MAX_EDIT];	/* String buffer                          */
-
-	int offset2col[MAX_EDIT * 2];
-	int col2offset[MAX_EDIT * 2];
+	char *buffer;		/* the buffer which is being edited */
+	int *offset2col;	/* fixups for multibyte characters */
 
     } EditFieldData;
 
@@ -318,9 +319,10 @@ extern "C" {
     extern void LYTrimTrailing(char *buffer);
     extern void LYTrimAllStartfile(char *buffer);
     extern BOOLEAN LYTrimStartfile(char *buffer);
+    extern void LYFinishEdit(EditFieldData *edit);
     extern void LYSetupEdit(EditFieldData *edit, char *old,
-			    int maxstr,
-			    int maxdsp);
+			    size_t buffer_limit,
+			    int display_limit);
     extern void LYRefreshEdit(EditFieldData *edit);
     extern int EditBinding(int ch);	/* in LYEditmap.c */
     extern BOOL LYRemapEditBinding(int xlkc,