diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-09-26 23:06:02 +0000 |
---|---|---|
committer | <> | 2015-02-03 11:56:22 +0000 |
commit | e0b511b834f3529395df67126a7314097c2cf97e (patch) | |
tree | 89945ae53183ab2acdc61659c8b0b3e57e4a1f3a /info/info-utils.c | |
parent | 2d8ae7b161658c4a589172db0072fc99f76fa979 (diff) | |
download | texinfo-tarball-master.tar.gz |
Imported from /home/lorry/working-area/delta_texinfo-tarball/texinfo-5.2.tar.xz.HEADtexinfo-5.2master
Diffstat (limited to 'info/info-utils.c')
-rw-r--r-- | info/info-utils.c | 291 |
1 files changed, 250 insertions, 41 deletions
diff --git a/info/info-utils.c b/info/info-utils.c index 7236452..37659d0 100644 --- a/info/info-utils.c +++ b/info/info-utils.c @@ -1,8 +1,8 @@ /* info-utils.c -- miscellanous. - $Id: info-utils.c,v 1.12 2008/06/11 09:55:42 gray Exp $ + $Id: info-utils.c 5379 2013-09-19 09:00:48Z eliz $ - Copyright (C) 1993, 1998, 2003, 2004, 2007, 2008 - Free Software Foundation, Inc. + Copyright 1993, 1998, 2003, 2004, 2007, 2008, 2009, 2011, 2012, + 2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. - Originally written by Brian Fox (bfox@ai.mit.edu). */ + Originally written by Brian Fox. */ #include "info.h" #include "info-utils.h" @@ -25,6 +25,10 @@ # include "man.h" #endif /* HANDLE_MAN_PAGES */ +#ifdef __hpux +#define va_copy(ap1,ap2) memcpy((&ap1),(&ap2),sizeof(va_list)) +#endif + /* When non-zero, various display and input functions handle ISO Latin character sets correctly. */ int ISO_Latin_p = 1; @@ -41,6 +45,9 @@ char *info_parsed_nodename = NULL; calling info_parse_xxx (). */ int info_parsed_line_number = 0; +static void save_string (char *string, char **string_p, int *string_size_p); +static void saven_string (char *string, int len, char **string_p, + int *string_size_p); /* Functions to remember a filename or nodename for later return. */ static void save_filename (char *filename); static void saven_filename (char *filename, int len); @@ -53,11 +60,16 @@ static REFERENCE **info_references_internal (char *label, /* Parse the filename and nodename out of STRING. If STRING doesn't contain a filename (i.e., it is NOT (FILENAME)NODENAME) then set - INFO_PARSED_FILENAME to NULL. If second argument NEWLINES_OKAY is - non-zero, it says to allow the nodename specification to cross a - newline boundary (i.e., only `,', `.', or `TAB' can end the spec). */ + INFO_PARSED_FILENAME to NULL. The second argument is one of + the PARSE_NODE_* constants. It specifies how to parse the node name: + + PARSE_NODE_DFLT Node name stops at LF, `,', `.', or `TAB' + PARSE_NODE_SKIP_NEWLINES Node name stops at `,', `.', or `TAB' + PARSE_NODE_VERBATIM Don't parse nodename +*/ + void -info_parse_node (char *string, int newlines_okay) +info_parse_node (char *string, int flag) { register int i = 0; @@ -74,14 +86,34 @@ info_parse_node (char *string, int newlines_okay) /* Check for (FILENAME)NODENAME. */ if (*string == '(') { + int bcnt; + int bfirst; + i = 0; /* Advance past the opening paren. */ string++; - /* Find the closing paren. */ - while (string[i] && string[i] != ')') - i++; + /* Find the closing paren. Handle nested parens correctly. */ + for (bcnt = 0, bfirst = -1; string[i]; i++) + { + if (string[i] == ')') + { + if (bcnt == 0) + { + bfirst = -1; + break; + } + else if (!bfirst) + bfirst = i; + bcnt--; + } + else if (string[i] == '(') + bcnt++; + } + if (bfirst >= 0) + i = bfirst; + /* Remember parsed filename. */ saven_filename (string, i); @@ -93,7 +125,7 @@ info_parse_node (char *string, int newlines_okay) } /* Parse out nodename. */ - i = skip_node_characters (string, newlines_okay); + i = skip_node_characters (string, flag); saven_nodename (string, i); canonicalize_whitespace (info_parsed_nodename); if (info_parsed_nodename && !*info_parsed_nodename) @@ -157,7 +189,7 @@ info_parse_label (char *label, NODE *node) nodeline += i; nodeline += skip_whitespace (nodeline); - info_parse_node (nodeline, DONT_SKIP_NEWLINES); + info_parse_node (nodeline, PARSE_NODE_DFLT); } /* **************************************************************** */ @@ -181,9 +213,8 @@ info_menu_of_node (NODE *node) tmp_search.flags = S_FoldCase; /* Find the start of the menu. */ - position = search_forward (INFO_MENU_LABEL, &tmp_search); - - if (position == -1) + if (search_forward (INFO_MENU_LABEL, &tmp_search, &position) + != search_success) return NULL; /* We have the start of the menu now. Glean menu items from the rest @@ -241,7 +272,7 @@ info_references_internal (char *label, SEARCH_BINDING *binding) { SEARCH_BINDING tmp_search; REFERENCE **refs = NULL; - int refs_index = 0, refs_slots = 0; + size_t refs_index = 0, refs_slots = 0; int searching_for_menu_items = 0; long position; @@ -252,7 +283,7 @@ info_references_internal (char *label, SEARCH_BINDING *binding) searching_for_menu_items = (mbscasecmp (label, INFO_MENU_ENTRY_LABEL) == 0); - while ((position = search_forward (label, &tmp_search)) != -1) + while (search_forward (label, &tmp_search, &position) == search_success) { int offset, start; char *refdef; @@ -310,9 +341,9 @@ info_references_internal (char *label, SEARCH_BINDING *binding) refdef += skip_whitespace_and_newlines (refdef); if (searching_for_menu_items) - info_parse_node (refdef, DONT_SKIP_NEWLINES); + info_parse_node (refdef, PARSE_NODE_DFLT); else - info_parse_node (refdef, SKIP_NEWLINES); + info_parse_node (refdef, PARSE_NODE_SKIP_NEWLINES); if (info_parsed_filename) entry->filename = xstrdup (info_parsed_filename); @@ -323,8 +354,7 @@ info_references_internal (char *label, SEARCH_BINDING *binding) entry->line_number = info_parsed_line_number; } - add_pointer_to_array - (entry, refs_index, refs, refs_slots, 50, REFERENCE *); + add_pointer_to_array (entry, refs_index, refs, refs_slots, 50); } return refs; } @@ -404,6 +434,18 @@ info_copy_reference (REFERENCE *src) +void +info_reference_free (REFERENCE *ref) +{ + if (ref) + { + free (ref->label); + free (ref->filename); + free (ref->nodename); + free (ref); + } +} + /* Free the data associated with REFERENCES. */ void info_free_references (REFERENCE **references) @@ -414,13 +456,7 @@ info_free_references (REFERENCE **references) if (references) { for (i = 0; references && (entry = references[i]); i++) - { - maybe_free (entry->label); - maybe_free (entry->filename); - maybe_free (entry->nodename); - - free (entry); - } + info_reference_free (entry); free (references); } @@ -485,10 +521,11 @@ static size_t the_rep_size; /* Return a pointer to a string which is the printed representation of CHARACTER if it were printed at HPOS. */ char * -printed_representation (const unsigned char *cp, size_t len, size_t hpos, +printed_representation (const char *character, size_t len, size_t hpos, /* Return: */ size_t *plen) { + const unsigned char *cp = (const unsigned char *) character; register int i = 0; int printable_limit = ISO_Latin_p ? 255 : 127; #define REPSPACE(s) \ @@ -574,10 +611,6 @@ static int parsed_filename_size = 0; /* Amount of space allocated to INFO_PARSED_NODENAME via xmalloc (). */ static int parsed_nodename_size = 0; -static void save_string (char *string, char **string_p, int *string_size_p); -static void saven_string (char *string, int len, char **string_p, - int *string_size_p); - /* Remember FILENAME in PARSED_FILENAME. An empty FILENAME is translated to a NULL pointer in PARSED_FILENAME. */ static void @@ -624,14 +657,19 @@ save_string (char *string, char **string_p, int *string_size_p) *string_p = NULL; *string_size_p = 0; } - else + else if (string_size_p) { if (strlen (string) >= (unsigned int) *string_size_p) - *string_p = xrealloc - (*string_p, (*string_size_p = 1 + strlen (string))); + *string_p = xrealloc (*string_p, + (*string_size_p = 1 + strlen (string))); strcpy (*string_p, string); } + else + { + free (*string_p); + *string_p = xstrdup (string); + } } /* Just like save_string (), but you also pass the length of STRING. */ @@ -646,11 +684,18 @@ saven_string (char *string, int len, char **string_p, int *string_size_p) *string_p = NULL; *string_size_p = 0; } - else + else { - if (len >= *string_size_p) - *string_p = xrealloc (*string_p, (*string_size_p = 1 + len)); - + if (string_size_p) + { + if (len >= *string_size_p) + *string_p = xrealloc (*string_p, (*string_size_p = 1 + len)); + } + else + { + free (*string_p); + *string_p = xmalloc (1 + len); + } strncpy (*string_p, string, len); (*string_p)[len] = '\0'; } @@ -727,3 +772,167 @@ get_window_of_node (NODE *node) return win; } + +/* Flexible Text Buffer */ + +void +text_buffer_init (struct text_buffer *buf) +{ + memset (buf, 0, sizeof *buf); +} + +void +text_buffer_free (struct text_buffer *buf) +{ + free (buf->base); +} + +size_t +text_buffer_vprintf (struct text_buffer *buf, const char *format, va_list ap) +{ + ssize_t n; + va_list ap_copy; + + if (!buf->base) + { + if (buf->size == 0) + buf->size = MIN_TEXT_BUF_ALLOC; /* Initial allocation */ + + buf->base = xmalloc (buf->size); + } + + for (;;) + { + va_copy (ap_copy, ap); + n = vsnprintf (buf->base + buf->off, buf->size - buf->off, + format, ap_copy); + va_end (ap_copy); + if (n < 0 || buf->off + n >= buf->size || + !memchr (buf->base + buf->off, '\0', buf->size - buf->off + 1)) + { + size_t newlen = buf->size * 2; + if (newlen < buf->size) + xalloc_die (); + buf->size = newlen; + buf->base = xrealloc (buf->base, buf->size); + } + else + { + buf->off += n; + break; + } + } + return n; +} + +void +text_buffer_alloc (struct text_buffer *buf, size_t len) +{ + if (buf->off + len > buf->size) + { + buf->size = buf->off + len; + if (buf->size < MIN_TEXT_BUF_ALLOC) + buf->size = MIN_TEXT_BUF_ALLOC; + buf->base = xrealloc (buf->base, buf->size); + } +} + +size_t +text_buffer_add_string (struct text_buffer *buf, const char *str, size_t len) +{ + text_buffer_alloc (buf, len); + memcpy (buf->base + buf->off, str, len); + buf->off += len; + return len; +} + +size_t +text_buffer_fill (struct text_buffer *buf, int c, size_t len) +{ + char *p; + int i; + + text_buffer_alloc (buf, len); + + for (i = 0, p = buf->base + buf->off; i < len; i++) + *p++ = c; + buf->off += len; + + return len; +} + +void +text_buffer_add_char (struct text_buffer *buf, int c) +{ + char ch = c; + text_buffer_add_string (buf, &ch, 1); +} + +size_t +text_buffer_printf (struct text_buffer *buf, const char *format, ...) +{ + va_list ap; + size_t n; + + va_start (ap, format); + n = text_buffer_vprintf (buf, format, ap); + va_end (ap); + return n; +} + +#if defined(__MSDOS__) || defined(__MINGW32__) +/* Cannot use FILENAME_CMP here, since that does not consider forward- + and back-slash characters equal. */ +static int +fncmp (const char *fn1, const char *fn2) +{ + const char *s1 = fn1, *s2 = fn2; + + while (tolower (*s1) == tolower (*s2) + || (IS_SLASH (*s1) && IS_SLASH (*s2))) + { + if (*s1 == 0) + return 0; + s1++; + s2++; + } + + return tolower (*s1) - tolower (*s2); +} +#else +# define fncmp(s,t) strcmp(s,t) +#endif + +struct info_namelist_entry +{ + struct info_namelist_entry *next; + char name[1]; +}; + +int +info_namelist_add (struct info_namelist_entry **ptop, const char *name) +{ + struct info_namelist_entry *p; + + for (p = *ptop; p; p = p->next) + if (fncmp (p->name, name) == 0) + return 1; + + p = xmalloc (sizeof (*p) + strlen (name)); + strcpy (p->name, name); + p->next = *ptop; + *ptop = p; + return 0; +} + +void +info_namelist_free (struct info_namelist_entry *top) +{ + while (top) + { + struct info_namelist_entry *next = top->next; + free (top); + top = next; + } +} + |