Blob Blame History Raw
Index: info/nodes.c
===================================================================
--- info/nodes.c	(revision 5245)
+++ info/nodes.c	(revision 5246)
@@ -563,6 +563,7 @@
       /* Okay, we have isolated the node name, and we know where the
          node starts.  Remember this information. */
       entry = xmalloc (sizeof (TAG));
+      entry->content_cache = NULL;
       entry->nodename = xmalloc (1 + (end - start));
       strncpy (entry->nodename, nodeline + start, end - start);
       entry->nodename[end - start] = 0;
@@ -667,6 +668,7 @@
         break;
 
       entry = xmalloc (sizeof (TAG));
+      entry->content_cache = NULL;
 
       /* Find the beginning of the node definition. */
       tmp_search->start += name_offset;
@@ -981,7 +983,12 @@
 	node->filename    = subfile->fullpath;
 	node->parent      = NULL;
 	node->nodename    = tag->nodename;
-	node->contents    = subfile->contents + tag->nodestart;
+	
+	if (tag->content_cache)
+	  node->contents = tag->content_cache;
+	else
+	  node->contents    = subfile->contents + tag->nodestart;
+
 	node->display_pos = 0;
 	node->flags       = 0;
 	node_set_body_start (node);
@@ -1049,6 +1056,12 @@
 	    node_body.end = buff_end - node_body.buffer;
 	    node_body.flags = 0;
 	    tag->nodelen = get_node_length (&node_body);
+	    /* Expand eventual \b[...\b] constructs in the contents.
+	       If found, update node->contents to point to the resulting
+	       buffer. */
+	    if (tags_expand (node->contents, tag->nodelen,
+			     &tag->content_cache, &tag->nodelen))
+	      node->contents = tag->content_cache;
 	    node->nodelen = tag->nodelen;
 	  }
 	else if (tag->nodelen == 0) /* anchor, return containing node */
@@ -1173,7 +1186,8 @@
 free_info_tag (TAG *tag)
 {
   free (tag->nodename);
-
+  free (tag->content_cache);
+  
   /* We don't free tag->filename, because that filename is part of the
      subfiles list for the containing FILE_BUFFER.  free_info_tags ()
      will free the subfiles when it is appropriate. */
Index: info/tag.c
===================================================================
--- info/tag.c	(revision 5245)
+++ info/tag.c	(revision 5246)
@@ -113,6 +113,8 @@
 	  if (state == state_delim)
 	    continue;
 	}
+      else if (state == state_delim)
+	state = state_kw;
       cur_len = mb_len (mbi_cur (iter));
       cur_ptr = mbi_cur_ptr (iter);
       
@@ -125,6 +127,8 @@
 	  switch (*cur_ptr)
 	    {
 	    case '=':
+	      if (state != state_kw)
+		break;
 	      text_buffer_add_char (&tmpbuf, 0);
 	      kw = tmpbuf.base;
 	      if (!mbi_avail (iter))
@@ -197,22 +201,29 @@
   return NULL;
 }
 
-void
-tags_expand (char **pbuf, size_t *pbuflen)
+/* Expand \b[...\b] constructs in INPUT (of INPUTLEN bytes).  If encountered,
+   put the expanded text into PBUF, store its length in PBUFLEN, and return
+   1.  Otherwise, don't touch neither of the latter and return 0. */
+int
+tags_expand (char *input, size_t inputlen, char **pbuf, size_t *pbuflen)
 {
-  char *input = *pbuf;
-  char *endp = input + *pbuflen;
+  char *endp = input + inputlen;
   struct text_buffer outbuf;
+  int text_buffer_used = 0;
   char *p;
 
-  text_buffer_init (&outbuf);
-
   while ((p = input + strlen (input)) < endp) /* go forward to null */
     {
       if (memcmp(p + 1, "\b[", 2) == 0)       /* opening magic? */
 	{
 	  char *q;
 
+	  if (!text_buffer_used)
+	    {
+	      text_buffer_init (&outbuf);
+	      text_buffer_used = 1;
+	    }
+	  
 	  p += 3;
 	  q = p + strlen (p);                 /* forward to next null */
 	  if (memcmp (q + 1, "\b]", 2) == 0)  /* closing magic? */
@@ -227,10 +238,7 @@
 		  while (p[len] == ' ' || p[len] == '\t')
 		    ++len;                      /* move past whitespace */
 	      
-		  if (!text_buffer_off (&outbuf))
-		    text_buffer_add_string (&outbuf, *pbuf, p - *pbuf - 3);
-		  else
-		    text_buffer_add_string (&outbuf, input, p - input - 3);
+		  text_buffer_add_string (&outbuf, input, p - input - 3);
 		  if (tp->handler (p + len, &outbuf) == 0)
 		    {
 		      input = q + 3;
@@ -240,21 +248,21 @@
 	    }
 	}
 
-      if (text_buffer_off (&outbuf))
-	{
-	  text_buffer_add_string (&outbuf, input, p - input);
-	}
+      if (text_buffer_used)
+	text_buffer_add_string (&outbuf, input, p - input);
+
       input = p + 1;
     }
 
-  if (text_buffer_off (&outbuf))
+  if (text_buffer_used && text_buffer_off (&outbuf))
     {
       if (input < endp)
 	text_buffer_add_string (&outbuf, input, endp - input);
-      free (*pbuf);
       *pbuflen = text_buffer_off (&outbuf);
       *pbuf = text_buffer_base (&outbuf);
+      return 1;
     }
+  return 0;
 }
   
 void
Index: info/nodes.h
===================================================================
--- info/nodes.h	(revision 5245)
+++ info/nodes.h	(revision 5246)
@@ -90,6 +90,9 @@
   char *nodename;               /* The node pointed to by this tag. */
   long nodestart;               /* The offset of the start of this node. */
   long nodelen;                 /* The length of this node. */
+  char *content_cache;          /* Cache of the node contents; used if the
+				   node contents must be preprocessed before
+				   displaying it. */
 } TAG;
 
 /* The following structure is used to remember information about the contents
Index: info/filesys.c
===================================================================
--- info/filesys.c	(revision 5245)
+++ info/filesys.c	(revision 5246)
@@ -645,8 +645,6 @@
      files are coming from some Windows system across a network.  */
   fsize = convert_eols (contents, fsize);
 
-  tags_expand (&contents, &fsize);
-
   /* EOL conversion can shrink the text quite a bit.  We don't
      want to waste storage.  */
   contents = xrealloc (contents, 1 + fsize);
Index: info/tag.h
===================================================================
--- info/tag.h	(revision 5245)
+++ info/tag.h	(revision 5246)
@@ -19,7 +19,7 @@
 #ifndef TAG_H
 #define TAG_H
 
-void tags_expand (char **pbuf, size_t *pbuflen);
+int tags_expand (char *input, size_t inputlen, char **pbuf, size_t *pbuflen);
 void handle_tag (char *tag);
 
 #endif