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