about summary refs log tree commit diff stats
path: root/WWW/Library
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2003-01-22 10:09:18 -0500
committerThomas E. Dickey <dickey@invisible-island.net>2003-01-22 10:09:18 -0500
commit533c7482785176296637df81cd1a6318a0c29f97 (patch)
treee50cece290409516ee62f08c8912863f5f1ba80a /WWW/Library
parent490d581c911f53008a7eaaed72b655cf40071b03 (diff)
downloadlynx-snapshots-533c7482785176296637df81cd1a6318a0c29f97.tar.gz
snapshot of project "lynx", label v2-8-5dev_13
Diffstat (limited to 'WWW/Library')
-rw-r--r--WWW/Library/Implementation/HTAABrow.c2
-rw-r--r--WWW/Library/Implementation/HTAABrow.h6
-rw-r--r--WWW/Library/Implementation/HTAAProt.c2
-rw-r--r--WWW/Library/Implementation/HTAAProt.h7
-rw-r--r--WWW/Library/Implementation/HTAccess.c19
-rw-r--r--WWW/Library/Implementation/HTAnchor.c152
-rw-r--r--WWW/Library/Implementation/HTAnchor.h19
-rw-r--r--WWW/Library/Implementation/HTAssoc.h3
-rw-r--r--WWW/Library/Implementation/HTAtom.h3
-rw-r--r--WWW/Library/Implementation/HTFTP.h4
-rw-r--r--WWW/Library/Implementation/HTFWriter.h5
-rw-r--r--WWW/Library/Implementation/HTFile.c8
-rw-r--r--WWW/Library/Implementation/HTFile.h3
-rw-r--r--WWW/Library/Implementation/HTFormat.h5
-rw-r--r--WWW/Library/Implementation/HTGopher.h4
-rw-r--r--WWW/Library/Implementation/HTGroup.c2
-rw-r--r--WWW/Library/Implementation/HTGroup.h6
-rw-r--r--WWW/Library/Implementation/HTList.c70
-rw-r--r--WWW/Library/Implementation/HTList.h25
-rw-r--r--WWW/Library/Implementation/HTMIME.c67
-rw-r--r--WWW/Library/Implementation/HTMIME.h4
-rw-r--r--WWW/Library/Implementation/HTMLDTD.h5
-rw-r--r--WWW/Library/Implementation/HTMLGen.h7
-rw-r--r--WWW/Library/Implementation/HTParse.c197
-rw-r--r--WWW/Library/Implementation/HTParse.h13
-rw-r--r--WWW/Library/Implementation/HTPlain.h7
-rw-r--r--WWW/Library/Implementation/HTRules.c11
-rw-r--r--WWW/Library/Implementation/HTStream.h4
-rw-r--r--WWW/Library/Implementation/HTString.c49
-rw-r--r--WWW/Library/Implementation/HTString.h9
-rw-r--r--WWW/Library/Implementation/HTTCP.c19
-rw-r--r--WWW/Library/Implementation/HTTelnet.h5
-rw-r--r--WWW/Library/Implementation/HTUU.h2
-rw-r--r--WWW/Library/Implementation/HTUtils.h3
-rw-r--r--WWW/Library/Implementation/HTWAIS.h5
-rw-r--r--WWW/Library/Implementation/HTWSRC.h8
-rw-r--r--WWW/Library/Implementation/HText.h4
-rw-r--r--WWW/Library/Implementation/LYLeaks.h12
-rw-r--r--WWW/Library/Implementation/SGML.c12
-rw-r--r--WWW/Library/Implementation/www_tcp.h4
40 files changed, 455 insertions, 337 deletions
diff --git a/WWW/Library/Implementation/HTAABrow.c b/WWW/Library/Implementation/HTAABrow.c
index dde97869..5c711b8a 100644
--- a/WWW/Library/Implementation/HTAABrow.c
+++ b/WWW/Library/Implementation/HTAABrow.c
@@ -393,7 +393,7 @@ PRIVATE HTAASetup *HTAASetup_new ARGS4(
 {
     HTAASetup *setup;
 
-    if (!server || !template || !*template)
+    if (!server || isEmpty(template))
 	return NULL;
 
     if ((setup = typecalloc(HTAASetup)) == 0)
diff --git a/WWW/Library/Implementation/HTAABrow.h b/WWW/Library/Implementation/HTAABrow.h
index b19b2e6a..4ebbcf3b 100644
--- a/WWW/Library/Implementation/HTAABrow.h
+++ b/WWW/Library/Implementation/HTAABrow.h
@@ -130,11 +130,5 @@ extern void HTAAForwardAuth_set PARAMS((
 	CONST char *	scheme_name,
 	CONST char *	scheme_specifics));
 extern void HTAAForwardAuth_reset NOPARAMS;
-/*
-
- */
 
 #endif  /* NOT HTAABROW_H */
-/*
-
-   End of file HTAABrow.h.  */
diff --git a/WWW/Library/Implementation/HTAAProt.c b/WWW/Library/Implementation/HTAAProt.c
index 6821068f..5a4e493e 100644
--- a/WWW/Library/Implementation/HTAAProt.c
+++ b/WWW/Library/Implementation/HTAAProt.c
@@ -59,7 +59,7 @@ PRIVATE BOOL isNumber ARGS1(CONST char *, s)
 {
     CONST char *cur = s;
 
-    if (!s || !*s) return NO;
+    if (isEmpty(s)) return NO;
 
     if (*cur == '-')
 	cur++;		/* Allow initial minus sign in a number */
diff --git a/WWW/Library/Implementation/HTAAProt.h b/WWW/Library/Implementation/HTAAProt.h
index ad3af096..c9b20b2a 100644
--- a/WWW/Library/Implementation/HTAAProt.h
+++ b/WWW/Library/Implementation/HTAAProt.h
@@ -247,11 +247,4 @@ extern char * HTAA_GidToName PARAMS((int gid));
 */
 extern int HTAA_NameToGid PARAMS((char *name));
 
-/*
-
- */
-
 #endif /* not HTAAPROT_H */
-/*
-
-   End of file HTAAProt.h.  */
diff --git a/WWW/Library/Implementation/HTAccess.c b/WWW/Library/Implementation/HTAccess.c
index 64ddf380..c623218e 100644
--- a/WWW/Library/Implementation/HTAccess.c
+++ b/WWW/Library/Implementation/HTAccess.c
@@ -382,19 +382,21 @@ PRIVATE int get_physical ARGS2(
 	CONST char *,		addr,
 	HTParentAnchor *,	anchor)
 {
+    int result;
     char * acc_method = NULL;	/* Name of access method */
     char * physical = NULL;
     char * Server_addr = NULL;
     BOOL override_flag = NO;
 
+    CTRACE((tfp, "get_physical %s\n", addr));
+
     /*
     **	Make sure the using_proxy variable is FALSE.
     */
     using_proxy = NO;
 
 #ifndef NO_RULES
-    physical = HTTranslate(addr);
-    if (!physical) {
+    if ((physical = HTTranslate(addr)) == 0) {
 	if (redirecting_url) {
 	    return HT_REDIRECTING;
 	}
@@ -426,8 +428,7 @@ PRIVATE int get_physical ARGS2(
     }
 #endif /* NO_RULES */
 
-    acc_method =  HTParse(HTAnchor_physical(anchor),
-		STR_FILE_URL, PARSE_ACCESS);
+    acc_method = HTParse(HTAnchor_physical(anchor), STR_FILE_URL, PARSE_ACCESS);
 
     /*
     **	Check whether gateway access has been set up for this.
@@ -561,6 +562,7 @@ PRIVATE int get_physical ARGS2(
     /*
     **	Search registered protocols to find suitable one.
     */
+    result = HT_NO_ACCESS;
     {
 	int i, n;
 #ifndef NO_INIT
@@ -572,13 +574,14 @@ PRIVATE int get_physical ARGS2(
 	    if (!strcmp(p->name, acc_method)) {
 		HTAnchor_setProtocol(anchor, p);
 		FREE(acc_method);
-		return (HT_OK);
+		result = HT_OK;
+		break;
 	    }
 	}
     }
 
     FREE(acc_method);
-    return HT_NO_ACCESS;
+    return result;
 }
 
 /*
@@ -682,7 +685,7 @@ PRIVATE int HTLoad ARGS4(
     LYFixCursesOnForAccess(addr, HTAnchor_physical(anchor));
     p = (HTProtocol *)HTAnchor_protocol(anchor);
     anchor->underway = TRUE;		/* Hack to deal with caching */
-    status= (*(p->load))(HTAnchor_physical(anchor),
+    status= p->load(HTAnchor_physical(anchor),
 			anchor, format_out, sink);
     anchor->underway = FALSE;
     LYUCPopAssumed();
@@ -699,7 +702,7 @@ PUBLIC HTStream *HTSaveStream ARGS1(
     if (!p)
 	return NULL;
 
-    return (*p->saveStream)(anchor);
+    return p->saveStream(anchor);
 }
 
 PUBLIC int redirection_attempts = 0; /* counter in HTLoadDocument */
diff --git a/WWW/Library/Implementation/HTAnchor.c b/WWW/Library/Implementation/HTAnchor.c
index 20360edc..4a9e9419 100644
--- a/WWW/Library/Implementation/HTAnchor.c
+++ b/WWW/Library/Implementation/HTAnchor.c
@@ -56,7 +56,9 @@ struct _HyperDoc {
 };
 #endif /* VMS */
 
-PRIVATE HTList **adult_table = 0;  /* Point to table of lists of all parents */
+/* Table of lists of all parents */
+PRIVATE HTList adult_table[HASH_SIZE] = { {NULL, NULL} };
+
 
 /*				Creation Methods
 **				================
@@ -210,10 +212,6 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2(
 	} else {  /* parent doesn't have any children yet : create family */
 	   parent->children = HTBTree_new(compare);
 	}
-    } else { /*  if tag is void */
-	if (!parent->children_notag)
-	   /* create a family of this kind */
-	   parent->children_notag = HTList_new();
     }
 
     child = HTChildAnchor_new();
@@ -228,7 +226,7 @@ PUBLIC HTChildAnchor * HTAnchor_findChild ARGS2(
 	HTBTree_add(parent->children, child);
     } else {
 	child->tag = 0;
-	HTList_addObject(parent->children_notag, child);
+	HTList_linkObject(&parent->children_notag, child, &child->_add_children_notag);
     }
 
     return(child);
@@ -261,15 +259,13 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 
     if (href && *href) {
 	CONST char *fragment = NULL;
-	DocAddress parsed_doc;
 	HTParentAnchor * dest;
 
-	if (*href == '#' && ltype == HTInternalLink) {
+	if (ltype == HTInternalLink) {
 	    dest = parent;
-	    fragment = href+1;
 	} else {
-	    char *relative_to = HTAnchor_address((HTAnchor *)parent);
-	   /* hmm, it seems HTML.c always resolve href to absolute url??? */
+	    CONST char *relative_to = parent->parent->address;
+	    DocAddress parsed_doc;
 	    parsed_doc.address = HTParse(href, relative_to,
 	       PARSE_ACCESS | PARSE_HOST | PARSE_PATH | PARSE_PUNCTUATION);
 	    parsed_doc.post_data = NULL;
@@ -278,11 +274,14 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 	    parsed_doc.isHEAD = FALSE;
 	    parsed_doc.safe = FALSE;
 	    dest = HTAnchor_findAddress_nofragment(&parsed_doc);
-	    FREE(relative_to);
 	    FREE(parsed_doc.address);
-	    fragment = HTParse(href, "", PARSE_ANCHOR);
 	}
 
+	if (*href == '#')
+	    fragment = href+1;
+	else
+	    fragment = HTParseAnchor(href);
+
 	/*
 	** [comment from HTAnchor_findAddress()]
 	** If the address represents a sub-anchor, we load its parent,
@@ -291,9 +290,6 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 	if (*fragment)
 	    dest = (HTParentAnchor *)HTAnchor_findChild(dest, fragment);
 
-	if (!(*href == '#' && ltype == HTInternalLink))
-	    FREE(fragment);
-
 #define DUPLICATE_ANCHOR_NAME_WORKAROUND
 
 #ifdef DUPLICATE_ANCHOR_NAME_WORKAROUND
@@ -317,47 +313,41 @@ PUBLIC HTChildAnchor * HTAnchor_findChildAndLink ARGS4(
 	    }
 	}
 #endif
-	HTAnchor_link((HTAnchor *)child, (HTAnchor *)dest, ltype);
+	HTAnchor_link(child, (HTAnchor *)dest, ltype);
     }
     return(child);
 }
 
 #ifdef LY_FIND_LEAKS
+PRIVATE BOOL free_adults_atexit = FALSE;
+
 /*
 **  Function for freeing the adult hash table. - FM
 */
 PRIVATE void free_adult_table NOARGS
 {
-    int i_counter;
-    HTList * HTAp_freeme;
+    int i;
+    HTList * list;
     HTParentAnchor * parent;
     /*
      *	Loop through all lists.
      */
-    for (i_counter = 0; i_counter < HASH_SIZE; i_counter++) {
+    for (i = 0; i < HASH_SIZE; i++) {
+
+	list = &(adult_table[i]);
 	/*
 	**  Loop through the list.
 	*/
-	while (adult_table[i_counter] != NULL) {
-	    /*
-	    **	Free off items - FM
-	    */
-	    HTAp_freeme = adult_table[i_counter];
-	    adult_table[i_counter] = HTAp_freeme->next;
-	    if (HTAp_freeme->object) {
-		parent = (HTParentAnchor *)HTAp_freeme->object;
-		CTRACE((tfp, "delete anchor:%d/%d,%d,%d %s\n",
-		       i_counter, HTList_count(HTAp_freeme) + 1,
-		       (parent->physical ? 1 : 0),
-		       (int)parent->underway,
-		       (parent->address ? parent->address : "(no address)")));
-		parent->underway = FALSE;
-		HTAnchor_delete(parent);
-	    }
-	    FREE(HTAp_freeme);
+	while ((parent = (HTParentAnchor *)HTList_unlinkLastObject(list)) != 0) {
+	    CTRACE((tfp, "delete anchor:%d/%d,%d,%d %s\n",
+		i, HTList_count(list) + 1,
+		(parent->physical ? 1 : 0),
+		(int)parent->underway,
+		(parent->address ? parent->address : "(no address)")));
+	    parent->underway = FALSE;
+	    HTAnchor_delete(parent);
 	}
     }
-    FREE(adult_table);
 }
 #endif /* LY_FIND_LEAKS */
 
@@ -373,7 +363,7 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	CONST DocAddress *,	newdoc)
 {
     /* Anchor tag specified ? */
-    char *tag = HTParse(newdoc->address, "", PARSE_ANCHOR);
+    CONST char *tag = HTParseAnchor(newdoc->address);
 
     CTRACE((tfp,"Entered HTAnchor_findAddress\n"));
 
@@ -397,13 +387,12 @@ PUBLIC HTAnchor * HTAnchor_findAddress ARGS1(
 	foundParent = HTAnchor_findAddress_nofragment(&parsed_doc);
 	foundAnchor = HTAnchor_findChild (foundParent, tag);
 	FREE(parsed_doc.address);
-	FREE(tag);
 	return (HTAnchor *)foundAnchor;
     }
-    FREE(tag);
     return (HTAnchor *)HTAnchor_findAddress_nofragment(newdoc);
 }
 
+
 /*  The address has no anchor tag for sure.
  */
 PRIVATE HTParentAnchor * HTAnchor_findAddress_nofragment ARGS1(
@@ -417,21 +406,17 @@ PRIVATE HTParentAnchor * HTAnchor_findAddress_nofragment ARGS1(
 	HTList *grownups;
 	HTParentAnchor * foundAnchor;
 
+#ifdef LY_FIND_LEAKS
+	if (!free_adults_atexit) {
+	    atexit(free_adult_table);
+	    free_adults_atexit = TRUE;
+	}
+#endif
 	/*
 	**  Select list from hash table,
 	*/
 	hash = HASH_FUNCTION(newdoc->address);
-	if (!adult_table) {
-	    adult_table = typecallocn(HTList *, HASH_SIZE);
-	    if (!adult_table)
-		outofmem(__FILE__, "HTAnchor_findAddress");
-#ifdef LY_FIND_LEAKS
-	    atexit(free_adult_table);
-#endif
-	}
-	if (!adult_table[hash])
-	    adult_table[hash] = HTList_new();
-	adults = adult_table[hash];
+	adults = &(adult_table[hash]);
 
 	/*
 	**  Search list for anchor.
@@ -471,7 +456,7 @@ PRIVATE HTParentAnchor * HTAnchor_findAddress_nofragment ARGS1(
 	    StrAllocCopy(foundAnchor->bookmark, newdoc->bookmark);
 	foundAnchor->isHEAD = newdoc->isHEAD;
 	foundAnchor->safe = newdoc->safe;
-	HTList_addObject (adults, foundAnchor);
+	HTList_linkObject(adults, foundAnchor, &foundAnchor->_add_adults);
 
 	return foundAnchor;
 }
@@ -538,11 +523,11 @@ PRIVATE void deleteLinks ARGS1(
 	 *  Remove me from the parent's sources so that the
 	 *  parent knows one less anchor is it's dest.
 	 */
-	if (!HTList_isEmpty(parent->sources)) {
+	if (!HTList_isEmpty(&parent->sources)) {
 	    /*
 	     *	Really should only need to deregister once.
 	     */
-	    HTList_removeObject(parent->sources, (void *)me);
+	    HTList_unlinkObject(&parent->sources, (void *)me);
 	}
 
 	/*
@@ -583,12 +568,12 @@ PRIVATE void deleteLinks ARGS1(
 	 */
 	while ((target = (HTLink *)HTList_removeLastObject(me->links)) != 0) {
 	    parent = target->dest->parent;
-	    if (!HTList_isEmpty(parent->sources)) {
+	    if (!HTList_isEmpty(&parent->sources)) {
 		/*
 		 *  Only need to tell destination parent
 		 *  anchor once.
 		 */
-		HTList_removeObject(parent->sources, (void *)me);
+		HTList_unlinkObject(&parent->sources, (void *)me);
 	    }
 
 	    /*
@@ -699,13 +684,13 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
      *	Don't actually delete this anchor, but children are OK to
      *	delete their links.
      */
-    if (!HTList_isEmpty(me->sources)) {
+    if (!HTList_isEmpty(&me->sources)) {
 	/*
 	 *  Delete all outgoing links from children, do not
 	 *  delete the children, though.
 	 */
-	if (!HTList_isEmpty(me->children_notag)) {
-	    cur = me->children_notag;
+	if (!HTList_isEmpty(&me->children_notag)) {
+	    cur = &me->children_notag;
 	    while ((child = (HTChildAnchor *)HTList_nextObject(cur)) != 0) {
 		deleteLinks((HTAnchor *)child);
 	    }
@@ -742,30 +727,23 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
 	me->children = NULL;
     }
     /* ...and this kind of children */
-    if (!HTList_isEmpty(me->children_notag)) {
-	while ((child = (HTChildAnchor *)HTList_removeLastObject(
-						       me->children_notag)) != 0) {
+    if (!HTList_isEmpty(&me->children_notag)) {
+	while ((child = (HTChildAnchor *)HTList_unlinkLastObject(
+						       &me->children_notag)) != 0) {
 	   deleteLinks((HTAnchor *)child);
 	   FREE(child);
 	}
     }
-    me->underway = FALSE;
+    me->children_notag.object = NULL;
+    me->children_notag.next = NULL;
 
-    /*
-     * Delete our empty list of children_notag.
-     */
-    if (me->children_notag) {
-	HTList_delete(me->children_notag);
-	me->children_notag = NULL;
-    }
+    me->underway = FALSE;
 
     /*
-     * Delete our empty list of sources.
+     * Init our empty list of sources.
      */
-    if (me->sources) {
-	HTList_delete(me->sources);
-	me->sources = NULL;
-    }
+    me->sources.object = NULL;
+    me->sources.next = NULL;
 
     /*
      *	Delete the methods list.
@@ -817,6 +795,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
     FREE(me->subject);
     FREE(me->date);
     FREE(me->expires);
+
     FREE(me->last_modified);
     FREE(me->ETag);
     FREE(me->server);
@@ -827,12 +806,9 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
     /*
      *	Remove ourselves from the hash table's list.
      */
-    if (adult_table) {
-	unsigned short usi_hash = (unsigned short) HASH_FUNCTION(me->address);
-
-	if (adult_table[usi_hash])  {
-	    HTList_removeObject(adult_table[usi_hash], (void *)me);
-	}
+    {
+	int i = HASH_FUNCTION(me->address);
+	HTList_unlinkObject(&(adult_table[i]), (void *)me);
     }
 
     /*
@@ -847,7 +823,7 @@ PUBLIC BOOL HTAnchor_delete ARGS1(
      */
     FREE(me->address);
 
-    FREE (me->UCStages);
+    FREE(me->UCStages);
     ImageMapList_free(me->imaps);
 
 
@@ -1216,9 +1192,9 @@ PUBLIC BOOL HTAnchor_setSubject ARGS2(
 **	-------------------------------------
 */
 PUBLIC BOOL HTAnchor_link ARGS3(
-	HTAnchor *,	source,
-	HTAnchor *,	destination,
-	HTLinkType *,	type)
+	HTChildAnchor *,	source,
+	HTAnchor *,		destination,
+	HTLinkType *,		type)
 {
     if (!(source && destination))
 	return(NO);  /* Can't link to/from non-existing anchor */
@@ -1236,9 +1212,7 @@ PUBLIC BOOL HTAnchor_link ARGS3(
 	    source->links = HTList_new();
 	HTList_addObject (source->links, newLink);
     }
-    if (!destination->parent->sources)
-	destination->parent->sources = HTList_new();
-    HTList_addObject (destination->parent->sources, source);
+    HTList_linkObject(&destination->parent->sources, source, &source->_add_sources);
     return(YES);  /* Success */
 }
 
diff --git a/WWW/Library/Implementation/HTAnchor.h b/WWW/Library/Implementation/HTAnchor.h
index b72cb1de..cbf27076 100644
--- a/WWW/Library/Implementation/HTAnchor.h
+++ b/WWW/Library/Implementation/HTAnchor.h
@@ -53,9 +53,11 @@ struct _HTParentAnchor {
   HTParentAnchor * parent;	/* Parent of this anchor (self) */
 
   /* ParentAnchor-specific information */
-  HTList *     children_notag; /* Subanchors <a href=...>, tag is NULL */
-  HTBTree *    children;       /* Subanchors <a name="tag">, sorted by tag */
-  HTList *	sources;	/* List of anchors pointing to this, if any */
+  HTBTree *	children;	/* Subanchors <a name="tag">, sorted by tag */
+  HTList	children_notag;	/* Subanchors <a href=...>, tag is NULL */
+  HTList	sources;	/* List of anchors pointing to this, if any */
+  HTList	_add_adults;	/* - just a memory for list entry:) */
+
   HyperDoc *	document;	/* The document within which this is an anchor */
   char *	address;	/* Absolute address of this node */
   char *	post_data;	/* Posting data */
@@ -115,7 +117,10 @@ typedef struct {
   HTParentAnchor * parent;	/* Parent of this anchor */
 
   /* ChildAnchor-specific information */
-  char *	tag;		/* Address of this anchor relative to parent */
+  char *	tag;		/* #fragment,  relative to the parent */
+
+  HTList	_add_children_notag;	/* - just a memory for list entry:) */
+  HTList	_add_sources;		/* - just a memory for list entry:) */
 } HTChildAnchor;
 
 /*
@@ -363,7 +368,7 @@ extern BOOL HTAnchor_setSubject PARAMS((
 **	-------------------------------------
 */
 extern BOOL HTAnchor_link PARAMS((
-	HTAnchor *		source,
+	HTChildAnchor *		source,
 	HTAnchor *		destination,
 	HTLinkType *		type));
 
@@ -442,7 +447,3 @@ extern LYUCcharset * HTAnchor_copyUCInfoStage PARAMS((
 extern void ImageMapList_free PARAMS((HTList * list));
 
 #endif /* HTANCHOR_H */
-
-/*
-
-    */
diff --git a/WWW/Library/Implementation/HTAssoc.h b/WWW/Library/Implementation/HTAssoc.h
index b08486dd..d45339d9 100644
--- a/WWW/Library/Implementation/HTAssoc.h
+++ b/WWW/Library/Implementation/HTAssoc.h
@@ -28,6 +28,3 @@ PUBLIC char *HTAssocList_lookup PARAMS((HTAssocList *   alist,
                                         CONST char *    name));
 
 #endif /* not HTASSOC_H */
-/*
-
-   End of file HTAssoc.h.  */
diff --git a/WWW/Library/Implementation/HTAtom.h b/WWW/Library/Implementation/HTAtom.h
index e948767d..1af962fc 100644
--- a/WWW/Library/Implementation/HTAtom.h
+++ b/WWW/Library/Implementation/HTAtom.h
@@ -36,6 +36,3 @@ PUBLIC HTList * HTAtom_templateMatches PARAMS((CONST char * templ));
 #define HTAtom_name(a) ((a)->name)
 
 #endif  /* HTATOM_H */
-/*
-
-    */
diff --git a/WWW/Library/Implementation/HTFTP.h b/WWW/Library/Implementation/HTFTP.h
index 60168b61..4189a4b9 100644
--- a/WWW/Library/Implementation/HTFTP.h
+++ b/WWW/Library/Implementation/HTFTP.h
@@ -68,7 +68,3 @@ Return Host Name
 extern CONST char * HTHostName NOPARAMS;
 
 #endif
-
-/*
-
-   end  */
diff --git a/WWW/Library/Implementation/HTFWriter.h b/WWW/Library/Implementation/HTFWriter.h
index b4e79cbc..04acfb18 100644
--- a/WWW/Library/Implementation/HTFWriter.h
+++ b/WWW/Library/Implementation/HTFWriter.h
@@ -23,7 +23,4 @@ extern HTStream * HTSaveLocally PARAMS((
         HTParentAnchor *        anchor, /* Not used */
         HTStream *              sink));
 
-#endif
-/*
-
-   end */
+#endif /* HTFWRITE_H */
diff --git a/WWW/Library/Implementation/HTFile.c b/WWW/Library/Implementation/HTFile.c
index 213e2e24..47754cd7 100644
--- a/WWW/Library/Implementation/HTFile.c
+++ b/WWW/Library/Implementation/HTFile.c
@@ -1279,10 +1279,12 @@ PUBLIC BOOL HTEditable ARGS1(
 PUBLIC HTStream * HTFileSaveStream ARGS1(
 	HTParentAnchor *,	anchor)
 {
-    CONST char * addr = HTAnchor_address((HTAnchor*)anchor);
-    char *  localname = HTLocalName(addr);
+    char * addr = HTAnchor_address((HTAnchor*)anchor);
+    char * localname = HTLocalName(addr);
+    FILE * fp = fopen(localname, BIN_W);
 
-    FILE* fp = fopen(localname, BIN_W);
+    FREE(addr);
+    FREE(localname);
     if (!fp)
 	return NULL;
 
diff --git a/WWW/Library/Implementation/HTFile.h b/WWW/Library/Implementation/HTFile.h
index 258c30f5..30a08045 100644
--- a/WWW/Library/Implementation/HTFile.h
+++ b/WWW/Library/Implementation/HTFile.h
@@ -332,6 +332,5 @@ extern GLOBALREF (HTProtocol,HTFile);
 #else
 GLOBALREF HTProtocol HTFTP, HTFile;
 #endif /* GLOBALREF_IS_MACRO */
-#endif /* HTFILE_H */
 
-/* end of HTFile */
+#endif /* HTFILE_H */
diff --git a/WWW/Library/Implementation/HTFormat.h b/WWW/Library/Implementation/HTFormat.h
index 13daca35..3b7403f5 100644
--- a/WWW/Library/Implementation/HTFormat.h
+++ b/WWW/Library/Implementation/HTFormat.h
@@ -494,8 +494,5 @@ Epilogue
 
  */
 extern BOOL HTOutputSource;     /* Flag: shortcut parser */
-#endif
-
-/*
 
-   end */
+#endif /* HTFORMAT_H */
diff --git a/WWW/Library/Implementation/HTGopher.h b/WWW/Library/Implementation/HTGopher.h
index 03b89675..624c04d4 100644
--- a/WWW/Library/Implementation/HTGopher.h
+++ b/WWW/Library/Implementation/HTGopher.h
@@ -21,7 +21,3 @@ GLOBALREF HTProtocol HTGopher;
 #endif /* GLOBALREF_IS_MACRO */
 
 #endif /* HTGOPHER_H */
-
-/*
-
-   end of gopher module */
diff --git a/WWW/Library/Implementation/HTGroup.c b/WWW/Library/Implementation/HTGroup.c
index 2b16599f..8f9e4d1d 100644
--- a/WWW/Library/Implementation/HTGroup.c
+++ b/WWW/Library/Implementation/HTGroup.c
@@ -652,7 +652,7 @@ PUBLIC GroupDefList *HTAA_readGroupFile ARGS1(CONST char *, filename)
     FILE *fp;
     GroupCache *group_cache;
 
-    if (!filename || !*filename) return NULL;
+    if (isEmpty(filename)) return NULL;
 
     if (!group_cache_list)
 	group_cache_list = HTList_new();
diff --git a/WWW/Library/Implementation/HTGroup.h b/WWW/Library/Implementation/HTGroup.h
index e78ac593..5288b8d6 100644
--- a/WWW/Library/Implementation/HTGroup.h
+++ b/WWW/Library/Implementation/HTGroup.h
@@ -169,11 +169,5 @@ PUBLIC HTAAFailReasonType HTAA_userAndInetInGroup PARAMS((GroupDef * group,
                                                           char *     username,
                                                           char *     ip_number,
                                                           char *     ip_name));
-/*
-
- */
 
 #endif /* not HTGROUP_H */
-/*
-
-   End of file HTGroup.h.  */
diff --git a/WWW/Library/Implementation/HTList.c b/WWW/Library/Implementation/HTList.c
index cc46beda..7a856833 100644
--- a/WWW/Library/Implementation/HTList.c
+++ b/WWW/Library/Implementation/HTList.c
@@ -87,6 +87,31 @@ PUBLIC HTList * HTList_appendList ARGS2(
 }
 
 
+/*	Link object to START of list (so it is pointed to by the head).
+ *
+ *	Unlike HTList_addObject(), it does not malloc memory for HTList entry,
+ *	it use already allocated memory which should not be free'd by any
+ *	list operations (optimization).
+ */
+PUBLIC void HTList_linkObject ARGS3(
+	HTList *,	me,
+	void *,		newObject,
+	HTList *,	newNode)
+{
+    if (me) {
+	newNode->object = newObject;
+	newNode->next = me->next;
+	me->next = newNode;
+
+    } else {
+	CTRACE((tfp, "HTList: Trying to link object %p to a nonexisting list\n",
+		    newObject));
+    }
+
+    return;
+}
+
+
 /*      Add object to START of list (so it is pointed to by the head).
 */
 PUBLIC void HTList_addObject ARGS2(
@@ -175,6 +200,30 @@ PUBLIC void HTList_insertObjectAt ARGS3(
 }
 
 
+/*	Unlink specified object from list.
+ *	It does not free memory.
+ */
+PUBLIC BOOL HTList_unlinkObject ARGS2(
+	HTList *,	me,
+	void *,		oldObject)
+{
+    HTList *temp = me;
+    HTList *prevNode;
+
+    if (temp && oldObject) {
+	while (temp->next) {
+	    prevNode = temp;
+	    temp = temp->next;
+	    if (temp->object == oldObject) {
+		prevNode->next = temp->next;
+		return YES;  /* Success */
+	    }
+	}
+    }
+    return NO;  /* object not found or NULL list */
+}
+
+
 /*	Remove specified object from list.
 */
 PUBLIC BOOL HTList_removeObject ARGS2(
@@ -230,6 +279,27 @@ PUBLIC void * HTList_removeObjectAt  ARGS2(
     return NULL;  /* Reached the end of the list */
 }
 
+/*	Unlink object from START of list (the Last one inserted
+ *	via HTList_linkObject(), and pointed to by the head).
+ *	It does not free memory.
+ */
+PUBLIC void * HTList_unlinkLastObject ARGS1(
+	HTList *,	me)
+{
+    HTList * lastNode;
+    void * lastObject;
+
+    if (me && me->next) {
+	lastNode = me->next;
+	lastObject = lastNode->object;
+	me->next = lastNode->next;
+	return lastObject;
+
+    } else {  /* Empty list */
+	return NULL;
+    }
+}
+
 
 /*	Remove object from START of list (the Last one inserted
 **	via HTList_addObject(), and pointed to by the head).
diff --git a/WWW/Library/Implementation/HTList.h b/WWW/Library/Implementation/HTList.h
index e3ba6a0f..19739d9c 100644
--- a/WWW/Library/Implementation/HTList.h
+++ b/WWW/Library/Implementation/HTList.h
@@ -139,6 +139,29 @@ extern void * HTList_objectAt PARAMS((
 	HTList *	me,
 	int		position));
 
+/*      Link object to START of list (so it is pointed to by the head).
+ *
+ *      Unlike HTList_addObject(), it does not malloc memory for HTList entry,
+ *	it use already allocated memory which should not be free'd by any
+ *	list operations (optimization).
+ */
+extern void HTList_linkObject PARAMS((
+	HTList *	me,
+	void *		newObject,
+	HTList *	newNode));
 
-#endif /* HTLIST_H */
+/*	Unlink object from START of list (the Last one inserted
+ *	via HTList_linkObject(), and pointed to by the head).
+ *	It does not free memory.
+ */
+extern void * HTList_unlinkLastObject PARAMS((
+	HTList *	me));
 
+/*	Unlink specified object from list.
+ *	It does not free memory.
+ */
+extern BOOL HTList_unlinkObject PARAMS((
+	HTList *	me,
+	void *		oldObject));
+
+#endif /* HTLIST_H */
diff --git a/WWW/Library/Implementation/HTMIME.c b/WWW/Library/Implementation/HTMIME.c
index 0838a9a9..05c3a26f 100644
--- a/WWW/Library/Implementation/HTMIME.c
+++ b/WWW/Library/Implementation/HTMIME.c
@@ -22,6 +22,7 @@
 
 #include <LYCookie.h>
 #include <LYCharSets.h>
+#include <LYCharUtils.h>
 #include <LYStrings.h>
 #include <LYUtils.h>
 #include <LYLeaks.h>
@@ -168,36 +169,6 @@ PUBLIC void HTMIME_TrimDoubleQuotes ARGS1(
 	value[i] = cp[(i +1)];
 }
 
-PRIVATE char *parse_parameter ARGS2(
-	char *,		from,
-	char *,		name)
-{
-    size_t len = strlen(name);
-    char *result = NULL;
-    char *string = from;
-
-    do {
-	if ((string = strchr(string, ';')) == NULL)
-	    return NULL;
-	while (*string != '\0' && (*string == ';' || isspace(UCH(*string)))) {
-	    string++;
-	}
-	if (strlen(string) < len) return NULL;
-    } while (strncasecomp(string, name, len) != 0);
-    string += len;
-    while (*string != '\0' && (UCH(isspace(*string)) || *string == '=')) {
-	string++;
-    }
-
-    StrAllocCopy(result, string);
-    len = 0;
-    while (isprint(UCH(string[len])) && string[len] != ';') {
-	len++;
-    }
-    result[len] = '\0';
-    return result;
-}
-
 PRIVATE BOOL content_is_compressed ARGS1(HTStream *, me)
 {
     char *encoding = me->anchor->content_encoding;
@@ -208,6 +179,25 @@ PRIVATE BOOL content_is_compressed ARGS1(HTStream *, me)
 	&& strcmp(encoding, "binary") != 0;
 }
 
+/*
+ * Strip parameters and quotes from a URL.
+ */
+PRIVATE void dequote ARGS1(char *, url)
+{
+    char *p;
+    int len;
+
+    if ((p = strchr(url, '?')) != NULL)
+	*p = '\0';
+    len = strlen(url);
+    if (*url == '\'' && len > 1 && url[len-1] == url[0]) {
+	url[len-1] = '\0';
+	while ((url[0] = url[1]) != '\0') {
+	    ++url;
+	}
+    }
+}
+
 PRIVATE int pumpData ARGS1(HTStream *, me)
 {
     if (strchr(HTAtom_name(me->format), ';') != NULL) {
@@ -476,27 +466,24 @@ PRIVATE int pumpData ARGS1(HTStream *, me)
 	me->state = MIME_IGNORE;	/* What else to do? */
     }
     if (me->refresh_url != NULL && !content_is_compressed(me)) {
-	char *url = parse_parameter(me->refresh_url, "URL");
+	char *url = NULL;
+	char *num = NULL;
 	char *txt = NULL;
-	char *arg = NULL;
 	char *base = "";	/* FIXME: refresh_url may be relative to doc */
-	int num = 0;
 
+	LYParseRefreshURL(me->refresh_url, &num, &url);
 	if (url != NULL) {
 	    CTRACE((tfp, "Formatting refresh-url as first line of result\n"));
-	    while (isdigit(UCH(me->refresh_url[num])))
-	    	++num;
 	    HTSprintf0(&txt, gettext("Refresh: "));
-	    if (num != 0)
-		HTSprintf(&txt, gettext("%.*s seconds "), num, me->refresh_url);
-	    if ((arg = strchr(url, '?')) != NULL)
-		*arg = '\0';
+	    HTSprintf(&txt, gettext("%s seconds "), num);
+	    dequote(url);
 	    HTSprintf(&txt, "<a href=\"%s%s\">%s</a><br>", base, url, url);
 	    CTRACE((tfp, "URL %s%s\n", base, url));
 	    (me->isa->put_string)(me, txt);
-	    free(url);
 	    free(txt);
 	}
+	FREE(num);
+	FREE(url);
     }
     return HT_OK;
 }
diff --git a/WWW/Library/Implementation/HTMIME.h b/WWW/Library/Implementation/HTMIME.h
index 818f38f2..211e21b4 100644
--- a/WWW/Library/Implementation/HTMIME.h
+++ b/WWW/Library/Implementation/HTMIME.h
@@ -88,7 +88,3 @@ extern int HTmaybekanji PARAMS((
 	int	c2));
 
 #endif /* !HTMIME_H */
-
-/*
-
-   end of HTMIME */
diff --git a/WWW/Library/Implementation/HTMLDTD.h b/WWW/Library/Implementation/HTMLDTD.h
index 79d1111f..d6d21096 100644
--- a/WWW/Library/Implementation/HTMLDTD.h
+++ b/WWW/Library/Implementation/HTMLDTD.h
@@ -1034,9 +1034,4 @@ extern void HTStartIsIndex PARAMS((
 		CONST char *	prompt,
 		CONST char *	href));
 
-
 #endif /* HTMLDTD_H */
-
-/*
-
-   End of module definition  */
diff --git a/WWW/Library/Implementation/HTMLGen.h b/WWW/Library/Implementation/HTMLGen.h
index b34b39d2..ee484078 100644
--- a/WWW/Library/Implementation/HTMLGen.h
+++ b/WWW/Library/Implementation/HTMLGen.h
@@ -24,9 +24,4 @@ extern HTStream * HTPlainToHTML PARAMS((
         HTParentAnchor *        anchor,
         HTStream *              sink));
 
-
-#endif
-
-/*
-
-    */
+#endif /* HTMLGEN_H */
diff --git a/WWW/Library/Implementation/HTParse.c b/WWW/Library/Implementation/HTParse.c
index 35a0ad38..e0945d18 100644
--- a/WWW/Library/Implementation/HTParse.c
+++ b/WWW/Library/Implementation/HTParse.c
@@ -7,6 +7,7 @@
 
 #include <LYUtils.h>
 #include <LYLeaks.h>
+#include <LYStrings.h>
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
@@ -49,8 +50,8 @@ PUBLIC char * HTStrip ARGS1(
     return s;
 }
 
-/*	Scan a filename for its consituents.			scan()
-**	------------------------------------
+/*	Scan a filename for its constituents.			scan()
+**	-------------------------------------
 **
 ** On entry,
 **	name	points to a document name which may be incomplete.
@@ -65,9 +66,6 @@ PRIVATE void scan ARGS2(
 {
     char * after_access;
     char * p;
-#ifdef NOTDEFINED
-    int length = strlen(name);
-#endif /* NOTDEFINED */
 
     parts->access = NULL;
     parts->host = NULL;
@@ -91,9 +89,6 @@ PRIVATE void scan ARGS2(
 	    break;
     }
 
-#ifdef NOTDEFINED
-    for (p = (name + length-1); p >= name; p--) {}
-#endif /* NOTDEFINED */
     /*
     **	Scan left-to-right for a fragment (anchor).
     */
@@ -161,7 +156,7 @@ PRIVATE void scan ARGS2(
 
 #if defined(HAVE_ALLOCA) && !defined(LY_FIND_LEAKS)
 #define LYalloca(x)        alloca(x)
-#define LYalloca_free(x)   x = 0 /*avoid warning*/
+#define LYalloca_free(x)   {}
 #else
 #define LYalloca(x)        malloc(x)
 #define LYalloca_free(x)   free(x)
@@ -187,6 +182,7 @@ PUBLIC char * HTParse ARGS3(
 	int,		wanted)
 {
     char * result = NULL;
+    char *tail = NULL; /* a pointer within 'result' string */
     char * return_value = NULL;
     int len, len1, len2;
     char * name = NULL;
@@ -205,6 +201,15 @@ PUBLIC char * HTParse ARGS3(
 	if (wanted & PARSE_PATH) /* if PARSE_PATH wanted */
 	    wanted &= ~(PARSE_STRICTPATH | PARSE_QUERY); /* ignore details */
     }
+    CTRACE((tfp, "   want:%s%s%s%s%s%s%s\n",
+	    wanted & PARSE_PUNCTUATION ? " punc"   : "",
+	    wanted & PARSE_ANCHOR      ? " anchor" : "",
+	    wanted & PARSE_PATH        ? " path"   : "",
+	    wanted & PARSE_HOST        ? " host"   : "",
+	    wanted & PARSE_ACCESS      ? " access" : "",
+	    wanted & PARSE_STRICTPATH  ? " PATH"   : "",
+	    wanted & PARSE_QUERY       ? " QUERY"  : ""));
+
     /*
     ** Allocate the temporary string. Optimized.
     */
@@ -212,7 +217,7 @@ PUBLIC char * HTParse ARGS3(
     len2 = strlen(relatedName) + 1;
     len = len1 + len2 + 8;     /* Lots of space: more than enough */
 
-    result = (char*)LYalloca(len + len1 + len2);
+    result = tail = (char*)LYalloca(len * 2 + len1 + len2);
     if (result == NULL) {
 	outofmem(__FILE__, "HTParse");
     }
@@ -247,9 +252,12 @@ PUBLIC char * HTParse ARGS3(
     acc_method = given.access ? given.access : related.access;
     if (wanted & PARSE_ACCESS) {
 	if (acc_method) {
-	    strcat(result, acc_method);
-	    if (wanted & PARSE_PUNCTUATION)
-		strcat(result, ":");
+	    strcpy(tail, acc_method);
+	    tail += strlen(tail);
+	    if (wanted & PARSE_PUNCTUATION) {
+		*tail++ = ':';
+		*tail = '\0';
+	    }
 	}
     }
 
@@ -284,10 +292,11 @@ PUBLIC char * HTParse ARGS3(
     */
     if (wanted & PARSE_HOST) {
 	if (given.host || related.host) {
-	    char *tail = result + strlen(result);
-	    if (wanted & PARSE_PUNCTUATION)
-		strcat(result, "//");
-	    strcat(result, given.host ? given.host : related.host);
+	    if (wanted & PARSE_PUNCTUATION) {
+		*tail++ = '/';
+		*tail++ = '/';
+	    }
+	    strcpy(tail, given.host ? given.host : related.host);
 #define CLEAN_URLS
 #ifdef CLEAN_URLS
 	    /*
@@ -353,12 +362,17 @@ PUBLIC char * HTParse ARGS3(
     }
 
     /*
+     * Trim any blanks from the result so far - there's no excuse for blanks
+     * in a hostname.
+     */
+    LYRemoveBlanks(result);
+
+    /*
     **	If host in given or related was ended directly with a '?' (no
     **  slash), fake the search part into absolute.  This is the only
     **  case search is returned from scan.  A host must have been present.
     **  this restores the '?' at which the host part had been truncated in
     **  scan, we have to do this after host part handling is done. - kw
-    **
     */
     if (given.search && *(given.search - 1) == '\0') {
 	given.absolute = given.search - 1;
@@ -383,54 +397,65 @@ PUBLIC char * HTParse ARGS3(
     **	Handle the path.
     */
     if (wanted & (PARSE_PATH | PARSE_STRICTPATH | PARSE_QUERY)) {
-	char *tail = NULL;
 	int want_detail = (wanted & (PARSE_STRICTPATH | PARSE_QUERY));
-	if (want_detail)
-	    tail = result + strlen(result);
+
 	if (acc_method && !given.absolute && given.relative) {
-	    if (!strcasecomp(acc_method, "nntp") ||
-		!strcasecomp(acc_method, "snews") ||
-		(!strcasecomp(acc_method, "news") &&
-		 !strncasecomp(result, "news://", 7))) {
-		/*
-		 *  Treat all given nntp or snews paths,
-		 *  or given paths for news URLs with a host,
-		 *  as absolute.
-		 */
-		given.absolute = given.relative;
-		given.relative = NULL;
+	    /*
+	     * Treat all given nntp or snews paths, or given paths for news
+	     * URLs with a host, as absolute.
+	     */
+	    switch (*acc_method) {
+	    case 'N':
+	    case 'n':
+		if (!strcasecomp(acc_method, "nntp") ||
+		    (!strcasecomp(acc_method, "news") &&
+		     !strncasecomp(result, "news://", 7))) {
+		    given.absolute = given.relative;
+		    given.relative = NULL;
+		}
+		break;
+	    case 'S':
+	    case 's':
+		if (!strcasecomp(acc_method, "snews")) {
+		    given.absolute = given.relative;
+		    given.relative = NULL;
+		}
+		break;
 	    }
 	}
+
+	tail = result + strlen(result);
 	if (given.absolute) {			/* All is given */
 	    if (wanted & PARSE_PUNCTUATION)
-		strcat(result, "/");
-	    strcat(result, given.absolute);
+		*tail++ = '/';
+	    strcpy(tail, given.absolute);
 	    CTRACE((tfp, "HTParse: (ABS)\n"));
 	} else if (related.absolute) {		/* Adopt path not name */
-	    strcat(result, "/");
-	    strcat(result, related.absolute);
+	    *tail++ = '/';
+	    strcpy(tail, related.absolute);
 	    if (given.relative) {
-		p = strchr(result, '?');	/* Search part? */
+		p = strchr(tail, '?');	/* Search part? */
 		if (p == NULL)
-		    p = (result + strlen(result) - 1);
+		    p = (tail + strlen(tail) - 1);
 		for (; *p != '/'; p--)
 		    ;				/* last / */
 		p[1] = '\0';			/* Remove filename */
-		strcat(result, given.relative); /* Add given one */
+		strcat(p, given.relative); /* Add given one */
 		HTSimplify (result);
 	    }
 	    CTRACE((tfp, "HTParse: (Related-ABS)\n"));
 	} else if (given.relative) {
-	    strcat(result, given.relative);		/* what we've got */
+	    strcpy(tail, given.relative);		/* what we've got */
 	    CTRACE((tfp, "HTParse: (REL)\n"));
 	} else if (related.relative) {
-	    strcat(result, related.relative);
+	    strcpy(tail, related.relative);
 	    CTRACE((tfp, "HTParse: (Related-REL)\n"));
 	} else {  /* No inheritance */
 	    if (!isLYNXCGI(aName) &&
 		!isLYNXEXEC(aName) &&
 		!isLYNXPROG(aName)) {
-		strcat(result, "/");
+		*tail++ = '/';
+		*tail = '\0';
 	    }
 	    if (!strcmp(result, "news:/"))
 		result[5] = '*';
@@ -456,16 +481,33 @@ PUBLIC char * HTParse ARGS3(
     }
 
     /*
-    **	Handle the fragment (anchor).
+    **	Handle the fragment (anchor). Never inherit.
     */
-    if (wanted & PARSE_ANCHOR)
-	if ((given.anchor && *given.anchor) ||
-	    (!given.anchor && related.anchor)) {
+    if (wanted & PARSE_ANCHOR) {
+	if (given.anchor && *given.anchor) {
+	    tail += strlen(tail);
 	    if (wanted & PARSE_PUNCTUATION)
-		strcat(result, "#");
-	    strcat(result, (given.anchor) ?
-			     given.anchor : related.anchor);
+		*tail++ = '#';
+	    strcpy(tail, given.anchor);
 	}
+    }
+
+    /*
+     * If there are any blanks remaining in the string, escape them as needed.
+     * See the discussion in LYLegitimizeHREF() for example.
+     */
+    if ((p = strchr(result, ' ')) != 0) {
+	do {
+	    char *q = p + strlen(p) + 2;
+	    while (q != p + 1) {
+		q[0] = q[-2];
+		--q;
+	    }
+	    p[0] = '%';
+	    p[1] = '2';
+	    p[2] = '0';
+	} while ((p = strchr(result, ' ')) != 0);
+    }
     CTRACE((tfp, "HTParse:      result:%s\n", result));
 
     StrAllocCopy(return_value, result);
@@ -474,12 +516,46 @@ PUBLIC char * HTParse ARGS3(
     return return_value;		/* exactly the right length */
 }
 
+/*	HTParseAnchor(), fast HTParse() specialization
+**	----------------------------------------------
+**
+** On exit,
+**	returns		A pointer within input string (probably to its end '\0')
+*/
+PUBLIC CONST char * HTParseAnchor ARGS1(
+	CONST char *,	aName)
+{
+    CONST char* p = aName;
+    for ( ; *p && *p != '#'; p++)
+	;
+    if (*p == '#') {
+	/* the safe way based on HTParse() -
+	 * keeping in mind scan() peculiarities on schemes:
+	 */
+	struct struct_parts given;
+
+	char* name = (char*)LYalloca((p - aName) + strlen(p) + 1);
+	if (name == NULL) {
+	    outofmem(__FILE__, "HTParseAnchor");
+	}
+	strcpy(name, aName);
+	scan(name, &given);
+	LYalloca_free(name);
+
+	p++; /*next to '#'*/
+	if (given.anchor == NULL) {
+	    for ( ; *p; p++)  /*scroll to end '\0'*/
+		;
+	}
+    }
+    return p;
+}
 
 /*	Simplify a filename.				HTSimplify()
 **	--------------------
 **
-**  A unix-style file is allowed to contain the seqeunce xxx/../ which may
-**  be replaced by "" , and the seqeunce "/./" which may be replaced by "/".
+**  A unix-style file is allowed to contain the sequence xxx/../ which may
+**  be replaced by "" , and the sequence "/./" which may be replaced by "/".
 **  Simplification helps us recognize duplicate filenames.
 **
 **	Thus,	/etc/junk/../fred	becomes /etc/fred
@@ -547,15 +623,6 @@ PUBLIC void HTSimplify ARGS1(
 			while (*q1 != '\0')
 			    *p++ = *q1++;
 			*p = '\0';		/* terminate */
-#ifdef NOTDEFINED
-			/*
-			**  Make sure filename has at least one slash.
-			*/
-			if (*filename == '\0') {
-			    *filename = '/';
-			    *(filename + 1) = '\0';
-			}
-#endif /* NOTDEFINED */
 			/*
 			**  Start again with previous slash.
 			*/
@@ -639,7 +706,7 @@ PUBLIC void HTSimplify ARGS1(
 **
 ** This function creates and returns a string which gives an expression of
 ** one address as related to another.  Where there is no relation, an absolute
-** address is retured.
+** address is returned.
 **
 **  On entry,
 **	Both names must be absolute, fully qualified names of nodes
@@ -711,7 +778,7 @@ PUBLIC char * HTRelative ARGS2(
 **	It returns a string which has these characters
 **	represented by a '%' character followed by two hex digits.
 **
-**	Unlike HTUnEscape(), this routine returns a calloced string.
+**	Unlike HTUnEscape(), this routine returns a calloc'd string.
 */
 PRIVATE CONST unsigned char isAcceptable[96] =
 
@@ -825,7 +892,7 @@ PUBLIC char * HTEscapeSP ARGS2(
 	if (a == 32) {
 	    *q++ = '+';
 	} else if (!ACCEPTABLE(a)) {
-	    *q++ = HEX_ESCAPE;	/* Means hex commming */
+	    *q++ = HEX_ESCAPE;	/* Means hex coming */
 	    *q++ = hex[a >> 4];
 	    *q++ = hex[a & 15];
 	} else {
@@ -841,7 +908,7 @@ PUBLIC char * HTEscapeSP ARGS2(
 **
 **	This function takes a pointer to a string in which some
 **	characters may have been encoded in %xy form, where xy is
-**	the acsii hex code for character 16x+y.
+**	the ASCII hex code for character 16x+y.
 **	The string is converted in place, as it will never grow.
 */
 PRIVATE char from_hex ARGS1(
@@ -895,7 +962,7 @@ PUBLIC char * HTUnEscape ARGS1(
 **							    (kweide@tezcat.com)
 **	This function takes a pointer to a string in which some
 **	characters may have been encoded in %xy form, where xy is
-**	the acsii hex code for character 16x+y, and a pointer to
+**	the ASCII hex code for character 16x+y, and a pointer to
 **	a second string containing one or more characters which
 **	should be unescaped if escaped in the first string.
 **	The first string is converted in place, as it will never grow.
diff --git a/WWW/Library/Implementation/HTParse.h b/WWW/Library/Implementation/HTParse.h
index 39f276a4..eb334d52 100644
--- a/WWW/Library/Implementation/HTParse.h
+++ b/WWW/Library/Implementation/HTParse.h
@@ -70,6 +70,15 @@ extern char * HTParse PARAMS((
 	CONST char *	relatedName,
 	int		wanted));
 
+/*	HTParseAnchor(), fast HTParse() specialization
+**	----------------------------------------------
+**
+** On exit,
+**	returns		A pointer within input string (probably to its end '\0')
+*/
+extern CONST char * HTParseAnchor PARAMS((
+	CONST char *	aName));
+
 /*	Simplify a filename.				HTSimplify()
 **	--------------------
 **
@@ -183,7 +192,3 @@ extern void HTMake822Word PARAMS((
 	char **		str));
 
 #endif  /* HTPARSE_H */
-
-/*
-   end of HTParse
-    */
diff --git a/WWW/Library/Implementation/HTPlain.h b/WWW/Library/Implementation/HTPlain.h
index 0d363f04..ed9a590f 100644
--- a/WWW/Library/Implementation/HTPlain.h
+++ b/WWW/Library/Implementation/HTPlain.h
@@ -13,9 +13,4 @@ extern HTStream* HTPlainPresent PARAMS((
         HTParentAnchor *        anchor,
         HTStream *              sink));
 
-
-#endif
-
-/*
-
-    */
+#endif /* HTPLAIN_H */
diff --git a/WWW/Library/Implementation/HTRules.c b/WWW/Library/Implementation/HTRules.c
index f2b3432e..c11eb966 100644
--- a/WWW/Library/Implementation/HTRules.c
+++ b/WWW/Library/Implementation/HTRules.c
@@ -192,13 +192,13 @@ PRIVATE BOOL rule_cond_ok ARGS1(
 **	The most recently defined rules are applied first.
 **
 ** On entry,
-**	required	points to a string whose equivalent value is neeed
+**	required	points to a string whose equivalent value is needed
 ** On exit,
 **	returns		the address of the equivalent string allocated from
 **			the heap which the CALLER MUST FREE. If no translation
-**			occured, then it is a copy of te original.
+**			occurred, then it is a copy of the original.
 ** NEW FEATURES:
-**			When a "protect" or "defprot" rule is mathed,
+**			When a "protect" or "defprot" rule is matched,
 **			a call to HTAA_setCurrentProtection() or
 **			HTAA_setDefaultProtection() is made to notify
 **			the Access Authorization module that the file is
@@ -213,6 +213,7 @@ char * HTTranslate ARGS1(
     char *msgtmp = NULL, *pMsg;
     int proxy_none_flag = 0;
     int permitredir_flag = 0;
+
     StrAllocCopy(current, required);
 
     HTAA_clearProtections();	/* Reset from previous call -- AL */
@@ -397,8 +398,7 @@ char * HTTranslate ARGS1(
 
 	case HT_Invalid:
 	case HT_Fail:				/* Unauthorised */
-		CTRACE((tfp, "HTRule: *** FAIL `%s'\n",
-			    current));
+		CTRACE((tfp, "HTRule: *** FAIL `%s'\n", current));
 		FREE(current);
 		return (char *)0;
 	} /* if tail matches ... switch operation */
@@ -409,6 +409,7 @@ char * HTTranslate ARGS1(
 	char * temp = NULL;
 	StrAllocCopy(temp, "NoProxy=");
 	StrAllocCat(temp, current);
+	FREE(current);
 	return temp;
     }
 
diff --git a/WWW/Library/Implementation/HTStream.h b/WWW/Library/Implementation/HTStream.h
index 868e0f41..cf0a4bf3 100644
--- a/WWW/Library/Implementation/HTStream.h
+++ b/WWW/Library/Implementation/HTStream.h
@@ -66,7 +66,3 @@ typedef struct _HTStreamClass {
 extern HTStream * HTErrorStream NOPARAMS;
 
 #endif /* HTSTREAM_H */
-
-/*
-
-   end of HTStream.h */
diff --git a/WWW/Library/Implementation/HTString.c b/WWW/Library/Implementation/HTString.c
index 210eedcf..0aeaa821 100644
--- a/WWW/Library/Implementation/HTString.c
+++ b/WWW/Library/Implementation/HTString.c
@@ -272,11 +272,12 @@ PUBLIC char * HTSACopy ARGS2(
 {
     if (src != 0) {
 	if (src != *dest) {
+	    size_t size = strlen(src) + 1;
 	    FREE(*dest);
-	    *dest = (char *) malloc (strlen(src) + 1);
+	    *dest = (char *) malloc(size);
 	    if (*dest == NULL)
 		outofmem(__FILE__, "HTSACopy");
-	    strcpy (*dest, src);
+	    memcpy(*dest, src, size);
 	}
     } else {
 	FREE(*dest);
@@ -292,7 +293,7 @@ PUBLIC char * HTSACat ARGS2(
 {
     if (src && *src && (src != *dest)) {
 	if (*dest) {
-	    int length = strlen(*dest);
+	    size_t length = strlen(*dest);
 	    *dest = (char *)realloc(*dest, length + strlen(src) + 1);
 	    if (*dest == NULL)
 		outofmem(__FILE__, "HTSACat");
@@ -308,6 +309,45 @@ PUBLIC char * HTSACat ARGS2(
 }
 
 
+/* optimized for heavily realloc'd strings, store length inside */
+
+#define EXTRA_TYPE size_t		/* type we use for length */
+#define EXTRA_SIZE sizeof(void *)	/* alignment >= sizeof(EXTRA_TYPE) */
+
+PUBLIC void   HTSAFree_extra ARGS1(
+	char *,		s)
+{
+    free(s - EXTRA_SIZE);
+}
+
+/* never shrink */
+PUBLIC char * HTSACopy_extra ARGS2(
+	char **,	dest,
+	CONST char *,	src)
+{
+    if (src != 0) {
+	size_t srcsize = strlen(src) + 1;
+	EXTRA_TYPE size = 0;
+
+	if (*dest != 0) {
+	    size = *(EXTRA_TYPE *)((*dest) - EXTRA_SIZE);
+	}
+	if (size < srcsize) {
+	    FREE_extra(*dest);
+	    size = srcsize * 2;   /* x2 step */
+	    *dest = (char *) malloc(size + EXTRA_SIZE);
+	    if (*dest == NULL)
+		outofmem(__FILE__, "HTSACopy_extra");
+	    *(EXTRA_TYPE *)(*dest) = size;
+	    *dest += EXTRA_SIZE;
+	}
+	memcpy(*dest, src, srcsize);
+    } else {
+	Clear_extra(*dest);
+    }
+    return *dest;
+}
+
 /*	Find next Field
 **	---------------
 **
@@ -389,7 +429,8 @@ PUBLIC char * HTNextTok ARGS4(
     BOOL get_comments;
     BOOL get_closing_char_too = FALSE;
     char closer;
-    if (!pstr || !*pstr) return NULL;
+
+    if (isEmpty(pstr)) return NULL;
     if (!delims) delims = " ;,=" ;
     if (!bracks) bracks = "<\"" ;
 
diff --git a/WWW/Library/Implementation/HTString.h b/WWW/Library/Implementation/HTString.h
index be1002be..0a6eaa18 100644
--- a/WWW/Library/Implementation/HTString.h
+++ b/WWW/Library/Implementation/HTString.h
@@ -59,6 +59,15 @@ extern char * HTSACopy PARAMS ((char **dest, CONST char *src));
 extern char * HTSACat  PARAMS ((char **dest, CONST char *src));
 
 /*
+optimized for heavily realloc'd strings in temp objects
+*/
+#define StrAllocCopy_extra(dest, src) HTSACopy_extra (&(dest), src)
+#define FREE_extra(x)   {if (x != NULL) {HTSAFree_extra(x); x = NULL;}}
+#define Clear_extra(x)  {if (x != NULL) {*x = '\0';}}
+extern char * HTSACopy_extra PARAMS ((char **dest, CONST char *src));
+extern void   HTSAFree_extra PARAMS ((char *s));
+
+/*
 
 Next word or quoted string
 
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
index 0863dacb..c07b6c6e 100644
--- a/WWW/Library/Implementation/HTTCP.c
+++ b/WWW/Library/Implementation/HTTCP.c
@@ -106,12 +106,15 @@ static int ResolveYield (void)
 }
 #endif
 
-#ifdef _WINDOWS_NSL
-char host[512];
-struct hostent  *phost;	/* Pointer to host - See netdb.h */
-int donelookup;
-
-static unsigned long _fork_func (void *arglist)
+/*
+ * This chunk of code is used in both win32 and cygwin.
+ */
+#if defined(_WINDOWS_NSL)
+static char host[512];
+static struct hostent *phost; /* Pointer to host - See netdb.h */
+static int donelookup;
+
+static unsigned long _fork_func (void *arglist GCC_UNUSED)
 {
 #ifdef SH_EX
     unsigned long addr;
@@ -1428,10 +1431,6 @@ PRIVATE void free_HTTCP_hostname NOARGS
 **	-------------------------------------------
 **
 */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64		/* Arbitrary limit */
-#endif /* MAXHOSTNAMELEN */
-
 PRIVATE void get_host_details NOARGS
 {
     char name[MAXHOSTNAMELEN+1];	/* The name of this host */
diff --git a/WWW/Library/Implementation/HTTelnet.h b/WWW/Library/Implementation/HTTelnet.h
index b5ce8877..92dbf2ff 100644
--- a/WWW/Library/Implementation/HTTelnet.h
+++ b/WWW/Library/Implementation/HTTelnet.h
@@ -17,8 +17,5 @@ GLOBALREF HTProtocol HTTelnet;
 GLOBALREF HTProtocol HTRlogin;
 GLOBALREF HTProtocol HTTn3270;
 #endif /* GLOBALREF_IS_MACRO */
-#endif /* HTTELNET_H */
-
-/*
 
-   end */
+#endif /* HTTELNET_H */
diff --git a/WWW/Library/Implementation/HTUU.h b/WWW/Library/Implementation/HTUU.h
index 2cff5292..8e06394e 100644
--- a/WWW/Library/Implementation/HTUU.h
+++ b/WWW/Library/Implementation/HTUU.h
@@ -23,4 +23,4 @@ PUBLIC int HTUU_decode PARAMS((char *bufcoded,
                                unsigned char *bufplain,
                                int outbufsize));
 
-#endif
+#endif /* HTUU_H */
diff --git a/WWW/Library/Implementation/HTUtils.h b/WWW/Library/Implementation/HTUtils.h
index a5038dc3..06ff3684 100644
--- a/WWW/Library/Implementation/HTUtils.h
+++ b/WWW/Library/Implementation/HTUtils.h
@@ -22,6 +22,7 @@
 #ifdef DJGPP
 #include <sys/config.h>	/* pseudo-autoconf values for DJGPP libc/headers */
 #define HAVE_TRUNCATE 1
+#define HAVE_ALLOCA 1
 #include <limits.h>
 #endif /* DJGPP */
 
@@ -490,7 +491,7 @@ Upper- and Lowercase macros
 #define TOUPPER(c) (islower(UCH(c)) ? toupper(UCH(c)) : UCH(c))
 #endif /* TOLOWER */
 
-#define FREE(x) if (x != 0) {free((char *)x); x = NULL;}
+#define FREE(x)    {if (x != 0) {free((char *)x); x = NULL;}}
 
 /*
 
diff --git a/WWW/Library/Implementation/HTWAIS.h b/WWW/Library/Implementation/HTWAIS.h
index 613acedf..7314025f 100644
--- a/WWW/Library/Implementation/HTWAIS.h
+++ b/WWW/Library/Implementation/HTWAIS.h
@@ -34,8 +34,3 @@ GLOBALREF HTProtocol HTWAIS;
 #endif /* GLOBALDEF_IS_MACRO */
 
 #endif /* HTWAIS_H */
-
-/*
-                                                                  Tim BL
-
-*/
diff --git a/WWW/Library/Implementation/HTWSRC.h b/WWW/Library/Implementation/HTWSRC.h
index 821cf2ff..bae6e123 100644
--- a/WWW/Library/Implementation/HTWSRC.h
+++ b/WWW/Library/Implementation/HTWSRC.h
@@ -35,10 +35,4 @@ extern char * HTDeSlash PARAMS((CONST char * str));
 
 extern char * HTEnSlash PARAMS((CONST char * str));
 
-#endif
-
-/*
-
-                                                                                    Tim BL
-
-    */
+#endif /* HTWSRC_H */
diff --git a/WWW/Library/Implementation/HText.h b/WWW/Library/Implementation/HText.h
index d35eeed5..b3e03fac 100644
--- a/WWW/Library/Implementation/HText.h
+++ b/WWW/Library/Implementation/HText.h
@@ -220,8 +220,4 @@ extern void             HText_unlinkSelection PARAMS((HText * me));
 extern HTAnchor *       HText_referenceSelected PARAMS((HText * me));
 extern HTAnchor *       HText_linkSelTo PARAMS((HText * me, HTAnchor* anchor));
 
-
 #endif /* HTEXT_H */
-/*
-
-   end */
diff --git a/WWW/Library/Implementation/LYLeaks.h b/WWW/Library/Implementation/LYLeaks.h
index fe995fb6..ebcc2e1b 100644
--- a/WWW/Library/Implementation/LYLeaks.h
+++ b/WWW/Library/Implementation/LYLeaks.h
@@ -86,6 +86,11 @@ typedef struct AllocationList_tag	{
 	struct AllocationList_tag *ALp_Next;
 
 	/*
+	 *	Count the number of mallocs.
+	 */
+	long st_Sequence;
+
+	/*
 	 *	The memory pointer allocated.
 	 *	If set to NULL, then an invalid request was made.
 	 *	The invalid pointer also.
@@ -152,6 +157,7 @@ typedef struct AllocationList_tag	{
 #undef StrAllocCopy
 #endif /* StrAllocCopy */
 #define StrAllocCopy(dest, src) LYLeakSACopy(&(dest), src, __FILE__, __LINE__)
+
 #ifdef StrAllocCat
 #undef StrAllocCat
 #endif /* StrAllocCat */
@@ -160,19 +166,23 @@ typedef struct AllocationList_tag	{
 #define mark_malloced(a,size) LYLeak_mark_malloced(a,size, __FILE__, __LINE__)
 
 #if defined(LY_FIND_LEAKS_EXTENDED) && !defined(NO_EXTENDED_MEMORY_TRACKING)
+
 #ifdef HTSprintf0
 #undef HTSprintf0
 #endif /* HTSprintf0 */
 #define HTSprintf0 (Get_htsprintf0_fn(__FILE__,__LINE__))
+
 #ifdef HTSprintf
 #undef HTSprintf
 #endif /* HTSprintf */
 #define HTSprintf (Get_htsprintf_fn(__FILE__,__LINE__))
+
 #endif /* LY_FIND_LEAKS_EXTENDED and not NO_EXTENDED_MEMORY_TRACKING */
 
 #else /* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */
 
 #define mark_malloced(a,size)	/* no-op */
+#define LYLeakSequence() (-1)
 
 #endif /* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */
 
@@ -181,10 +191,12 @@ typedef struct AllocationList_tag	{
 #else
 #define PUBLIC_IF_FIND_LEAKS PRIVATE
 #endif
+
 /*
 **	Function declarations
 **	See the appropriate source file for usage.
 */
+extern long LYLeakSequence NOPARAMS;
 extern void LYLeaks NOPARAMS;
 #ifdef LY_FIND_LEAKS_EXTENDED
 extern AllocationList *LYLeak_mark_malloced PARAMS((
diff --git a/WWW/Library/Implementation/SGML.c b/WWW/Library/Implementation/SGML.c
index 023aeb8d..4c8062f0 100644
--- a/WWW/Library/Implementation/SGML.c
+++ b/WWW/Library/Implementation/SGML.c
@@ -182,7 +182,7 @@ struct _HTStream {
     void *			callerData;
 #endif /* CALLERDATA */
     BOOL present[MAX_ATTRIBUTES];	/* Flags: attribute is present? */
-    char * value[MAX_ATTRIBUTES];	/* malloc'd strings or NULL if none */
+    char * value[MAX_ATTRIBUTES];	/* NULL, or strings alloc'd with StrAllocCopy_extra() */
 
     BOOL			lead_exclamation;
     BOOL			first_dash;
@@ -496,7 +496,7 @@ PRIVATE void handle_attribute_name ARGS2(
 #endif
 	    {
 	    context->present[i] = YES;
-	    FREE(context->value[i]);
+	    Clear_extra(context->value[i]);
 #ifdef USE_COLOR_STYLE
 #   ifdef USE_PRETTYSRC
 	    current_is_class = IS_C(attributes[i]);
@@ -525,7 +525,7 @@ PRIVATE void handle_attribute_value ARGS2(
 	CONST char *,	s)
 {
     if (context->current_attribute_number != INVALID) {
-	StrAllocCopy(context->value[context->current_attribute_number], s);
+	StrAllocCopy_extra(context->value[context->current_attribute_number], s);
 #ifdef USE_COLOR_STYLE
 	if (current_is_class)
 	{
@@ -631,7 +631,7 @@ PRIVATE void put_pretty_entity ARGS2(HTStream *, context, int, term)
     PUTC('&');
     PUTS(entity_string);
     if (term)
-	PUTC(term);
+	PUTC((char)term);
     PSRCSTOP(entity);
 }
 
@@ -1458,7 +1458,7 @@ PRIVATE void SGML_free ARGS1(
     */
     HTChunkFree(context->string);
     for (i = 0; i < MAX_ATTRIBUTES; i++)
-	FREE(context->value[i]);
+	FREE_extra(context->value[i]);
     FREE(context);
 
 #ifdef USE_PRETTYSRC
@@ -1501,7 +1501,7 @@ PRIVATE void SGML_abort ARGS2(
     */
     HTChunkFree(context->string);
     for (i = 0; i < MAX_ATTRIBUTES; i++)
-	FREE(context->value[i]);
+	FREE_extra(context->value[i]);
     FREE(context);
 
 #ifdef USE_PRETTYSRC
diff --git a/WWW/Library/Implementation/www_tcp.h b/WWW/Library/Implementation/www_tcp.h
index 11a4398f..94db09ee 100644
--- a/WWW/Library/Implementation/www_tcp.h
+++ b/WWW/Library/Implementation/www_tcp.h
@@ -846,4 +846,8 @@ typedef struct sockaddr_in SockA;  /* See netinet/in.h */
 #define SOCKADDR_LEN(soc_address) sizeof(soc_address)
 #endif /* INET6 */
 
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64		/* Arbitrary limit */
+#endif /* MAXHOSTNAMELEN */
+
 #endif /* TCP_H */