a->start	       = anchor_ptr->start;
PUBLIC int HText_InsertFile ARGS1(	   struct link *,  form_link){    struct stat stat_info;    size_t	size;    FILE       *fp;    char       *fn;    TextAnchor *anchor_ptr;    TextAnchor *prev_anchor = NULL;    TextAnchor *end_anchor  = NULL;    BOOLEAN	firstanchor = TRUE;    FormInfo   *form	 = form_link->form;    char       *areaname = form->name;    int		form_num = form->number;    HTLine     *htline	 = NULL;    TextAnchor *a = 0;    FormInfo   *f = 0;    HTLine     *l = 0;    char       *fbuf;    char       *line;    char       *lp;    char       *cp;    int		entry_line = form_link->anchor_line_num;    int		match_tag  = 0;    int		newlines   = 0;    int		len;    int		i;    CTRACE(tfp, "GridText: entered HText_InsertFile()\n");    /*     * Get the filename of the insert file.     */    if (!(fn = GetFileName())) {	HTInfoMsg (FILE_INSERT_CANCELLED);	CTRACE(tfp, "GridText: file insert cancelled - no filename provided\n");	return (0);    }    /*     *	Read it into our buffer (abort on 0-length file).     */    if ((stat (fn, &stat_info) < 0)        ||	((size = stat_info.st_size) == 0)) {	HTInfoMsg (FILE_INSERT_0_LENGTH);	CTRACE(tfp, "GridText: file insert aborted - file=|%s|- was 0-length\n",		    fn);	FREE(fn);	return (0);    } else {	if ((fbuf = (char *) calloc (size + 1, (sizeof(char)))) == NULL)	    outofmem(__FILE__, "HText_InsertFile");	fp   = fopen (fn, "r");	size = fread (fbuf, 1, size, fp);	fclose (fp);	FREE(fn);    }    /*     *	Begin at the beginning, to find the TEXTAREA we're in, then     *	the current cursorline.     *     *	[Finding the TEXTAREA we're actually *in* with these attributes     *	 isn't foolproof.  The form_num isn't unique to a given TEXTAREA,     *	 and there *could* be TEXTAREA's with the same "name".	If that     *	 should ever be true, we'll actually insert data into the *1st*     *	 TEXTAREA in the page that matches.  We should probably assign     *	 a unique id to each TEXTAREA in a page, and match on that, to     *	 avoid this (potential) problem.     *     *	 Since the odds of "false matches" *actually* happening in real     *	 life seem rather small though, we'll hold off doing this, for a     *	 rainy day ...]     */    anchor_ptr = HTMainText->first_anchor;    while (anchor_ptr) {	if ((anchor_ptr->link_type	     == INPUT_ANCHOR)    &&	    (anchor_ptr->input_field->type   == F_TEXTAREA_TYPE) &&	    (anchor_ptr->input_field->number == form_num)	 &&	    !strcmp (anchor_ptr->input_field->name, areaname))   {	   if (anchor_ptr->line_num == entry_line)	      break;	}	prev_anchor = anchor_ptr;	anchor_ptr  = anchor_ptr->next;    }    /*     *  Clone a new TEXTAREA line/anchor using the cursorline anchor as     *  a template, but link it in BEFORE the cursorline anchor/htline.     *     *  [We can probably combine this with insert_new_textarea_anchor()     *   along with a flag to indicate "insert before" as we do here,     *   or the "normal" mode of operation (add after "current" anchor/     *   line).  Beware of the differences ... some are a bit subtle to     *   notice.]     */    for (htline = HTMainText->last_line->next, i = 0;	 anchor_ptr->line_num != i;            i++) {	htline = htline->next;	if (htline == HTMainText->last_line)	    break;    }    if (((a = (TextAnchor *) calloc (1, sizeof(*a)))          == 0)  ||	((f = (FormInfo   *) calloc (1, sizeof(*f)))          == 0)  ||	((l = (HTLine     *) calloc (1, LINE_SIZE(MAX_LINE))) == 0))	outofmem(__FILE__, "HText_InsertFile");    /*  Init all the fields in the new TextAnchor.                 */    /*  [anything "special" needed based on ->show_anchor value ?] */    a->next	       = anchor_ptr;    a->number	       = anchor_ptr->number;    a->start	       = anchor_ptr->start;    a->line_pos	       = anchor_ptr->line_pos;    a->extent	       = anchor_ptr->extent;    a->line_num	       = anchor_ptr->line_num;    StrAllocCopy (a->hightext,  anchor_ptr->hightext);    StrAllocCopy (a->hightext2, anchor_ptr->hightext2);    a->hightext2offset = anchor_ptr->hightext2offset;    a->link_type       = anchor_ptr->link_type;    a->input_field     = f;    a->show_anchor     = anchor_ptr->show_anchor;    a->inUnderline     = anchor_ptr->inUnderline;    a->expansion_anch  = TRUE;    a->anchor	       = NULL;    /*  Just the (seemingly) relevant fields in the new FormInfo.  */    /*  [do we need to do anything "special" based on ->disabled]  */    StrAllocCopy (f->name, anchor_ptr->input_field->name);    f->number	       = anchor_ptr->input_field->number;    f->type	       = anchor_ptr->input_field->type;    StrAllocCopy (f->orig_value, "");    f->size	       = anchor_ptr->input_field->size;    f->maxlength       = anchor_ptr->input_field->maxlength;    f->no_cache        = anchor_ptr->input_field->no_cache;    f->disabled        = anchor_ptr->input_field->disabled;    /*  Init all the fields in the new HTLine (but see the #if).   */    l->offset	       = htline->offset;    l->size	       = htline->size;    l->split_after     = htline->split_after;    l->bullet	       = htline->bullet;    l->expansion_line  = TRUE;#if defined(USE_COLOR_STYLE)    /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */    l->numstyles       = htline->numstyles;#endif    strcpy (l->data,     htline->data);    /*     *  If we're at the head of the TextAnchor list, the new node becomes     *  the first node.     */    if (anchor_ptr == HTMainText->first_anchor)	HTMainText->first_anchor = a;    /*     *  Link in the new TextAnchor, and corresponding HTLine.     */    if (prev_anchor)	prev_anchor->next = a;    htline             = htline->prev;    l->next	       = htline->next;    l->prev	       = htline;    htline->next->prev = l;    htline->next       = l;    /*     *  update_subsequent_anchors() expects htline to point to 1st potential     *  line needing fixup; we need to do this just in case the inserted file     *  was only a single line (yes, it's pathological ... ).     */    htline = htline->next; /* ->new (current) htline, for 1st inserted line  */    htline = htline->next; /* ->1st potential (following) [tag] fixup htline */    anchor_ptr = a;    newlines++;    /*     *	Copy each line from the insert file into the corresponding anchor     *  struct.     *     *  Begin with the new line/anchor we just added (above the cursorline).     */    if ((line = (char *) malloc (MAX_LINE)) == 0)	outofmem(__FILE__, "HText_InsertFile");    match_tag = anchor_ptr->number;    len = 0;    lp  = fbuf;    while (*lp) {	if ((cp = strchr (lp, '\n')) != 0)	   len = cp - lp;	else	   len = strlen (lp);	strncpy (line, lp, len);	*(line + len) = '\0';	cleanup_line_for_textarea (line, len);	/*	 *  If not the first line from the insert file, we need to add	 *  a new line/anchor, continuing on until the buffer is empty.	 */	if (!firstanchor) {	   insert_new_textarea_anchor (&end_anchor, &htline);	   anchor_ptr = end_anchor;   /* make the new anchor current */	   newlines++;	}	/*	 *  Copy the new line from the buffer into the anchor.	 */	StrAllocCopy(anchor_ptr->input_field->value, line);	/*	 *  And do the next line of insert text, for the next anchor ...	 */	lp += len;	if (*lp) lp++;	firstanchor = FALSE;	end_anchor  = anchor_ptr;	anchor_ptr  = anchor_ptr->next;    }    CTRACE(tfp, "GridText: file inserted into lynx struct's\n");    /*     *	Now adjust various things in all anchor-bearing lines following the     *  last newly added line/anchor.  Some say this is the fun part ...     */    update_subsequent_anchors (newlines, end_anchor, htline, match_tag);    /*     *  Cleanup time.     */    FREE(line);    FREE(fbuf);    CTRACE(tfp, "GridText: exiting HText_InsertFile()\n");    return (newlines);}